回朔法、分支限界法解0-1背包问题程序, Java, C#

Java回溯法:
package sun;
import java.util.*;
public class Knapsack0{ 
/* 
   用回溯法解决0-1背包问题  
   */ 
private double[] p,w;//分别代表价值和重量
private int n;
private double c,bestp,cp,cw;
private int x[]; //记录可选的物品
private int[] cx;
public Knapsack0(double pp[],double ww[],double cc){
   this.p=pp;this.w=ww;this.n=pp.length-1;
   this.c=cc;this.cp=0;this.cw=0;
   this.bestp=0;
   x=new int[ww.length];
   cx=new int[pp.length];
}
void knapsack(){
   backtrack(0);
}
void backtrack(int i){
   if(i>n){             //判断是否到达了叶子节点
    if(cp>bestp){
     for(int j=0;j<x.length;j++)
      x[j]=cx[j];
     bestp=cp;
    }
    return;
   }
   if(cw+w[i]<=c){//搜索右子树
    cx[i]=1;
    cw+=w[i];
    cp+=p[i];
    backtrack(i+1);
    cw-=w[i];
    cp-=p[i];
   }
   cx[i]=0;
   backtrack(i+1); //检查左子树
}
void printResult(){
 System.out.println("*****回溯法*****");
    System.out.println("*****物品个数:n=5");
    System.out.println("*****背包容量:c=10");
    System.out.println("*****物品重量数组:ww= {2,2,6,5,4}");
    System.out.println("*****物品价值数组:vv= {6,3,5,4,6}");
   System.out.println("*****最优值:="+bestp);
   System.out.println("*****选中的物品是:");
   for(int i=0;i<x.length;i++){
     System.out.print(x[i]+" ");
   }
}
public static void main(String[] args){
   double p[]={6,3,5,4,6}; 
   double w[]={2,2,6,5,4};
   int maxweight=10;
   Knapsack0 ks=new Knapsack0(p,w,maxweight);
   ks.knapsack();   //回溯搜索
   ks.printResult();
}
}

分支限界法:
package sun;
public class knapsack1 {
 static double c; 
 static int n;
 static double w[];
 static double p[];
 static double cw;
 static double cp;
 static int bestX[];
 static MaxHeap heap;
 //上界函数bound计算结点所相应价值的上界
 private static double bound(int i){
  double cleft=c-cw;
  double b=cp;
  while(i<=n&&w[i]<=cleft){
   cleft=cleft-w[i];
   b=b+p[i];
   i++;
  }
                //装填剩余容量装满背包
  if(i<=n)
   b=b+p[i]/w[i]*cleft;
  return b;
 }
        //addLiveNode将一个新的活结点插入到子集树和优先队列中
 private static void addLiveNode(double up,double pp,double ww,int lev,BBnode par,boolean ch){
  //将一个新的活结点插入到子集树和最大堆中
                BBnode b=new BBnode(par,ch);
  HeapNode node =new HeapNode(b,up,pp,ww,lev);
  heap.put(node);
 }
 private static double MaxKnapsack(){
            //优先队列式分支限界法,返回最大价值,bestx返回最优解
  BBnode enode=null;
  int i=1;
  double bestp=0;//当前最优值
  double up=bound(1);//当前上界
  while(i!=n+1){//非叶子结点
           //检查当前扩展结点的左儿子子结点
   double wt=cw+w[i];
   if(wt<=c){
    if(cp+p[i]>bestp)
     bestp=cp+p[i];
    addLiveNode(up,cp+p[i],cw+w[i],i+1,enode,true);
   }
   up=bound(i+1);
   if(up>=bestp)
    addLiveNode(up,cp,cw,i+1,enode,false);
   HeapNode node =(HeapNode)heap.removeMax();
   enode=node.liveNode;
   cw=node.weight;
   cp=node.profit;
   up=node.upperProfit;
   i=node.level;
  }
  for(int j=n;j>0;j--){
   
   bestX[j]=(enode.leftChild)?1:0;
   enode=enode.parent;
  }
  return cp;
 }

 
 public static double knapsack(double pp[],double ww[],double cc,int xx[]){
  //返回最大值,bestX返回最优解
                c=cc;
        n=pp.length-1;
        //定义以单位重量价值排序的物品数组
  Element q[]=new Element[n];
  double ws=0.0;
  double ps=0.0;
  for(int i=0;i<n;i++){
   q[i]=new Element(i+1,pp[i+1]/ww[i+1]);
   ps=ps+pp[i+1];
   ws=ws+ww[i+1];
  }
  if(ws<=c){
   return  ps;
  }           
  p=new double[n+1];
  w=new double[n+1];
  for(int i=0;i<n;i++){
   p[i+1]=pp[q[i].id];
   w[i+1]=ww[q[i].id];
  }
  cw=0.0;
  cp=0.0;
  bestX = new int[n+1];
  heap = new MaxHeap(n);
  double bestp = MaxKnapsack();
  for(int j=0;j<n;j++)
   xx[q[j].id]=bestX[j+1];
  
  return  bestp;
  
 }
 public static void main(String [] args){
  double w[]=new double[6];
  w[1]=2;w[2]=2;w[3]=6;w[4]=5;w[5]=4;
  double v[]=new double[6];
  v[1]=6;v[2]=3;v[3]=4;v[4]=5;v[5]=6;
  double c=10;
  int x[] = new int[6];
  double m = knapsack(v,w,c,x);
  System.out.println("*****分支限界法*****");
     System.out.println("*****物品个数:n=5");
     System.out.println("*****背包容量:c=10");
     System.out.println("*****物品重量数组:w= {2,2,6,5,4}");
     System.out.println("*****物品价值数组:v= {6,3,5,4,6}");
    System.out.println("*****最优值:="+m);
    System.out.println("*****选中的物品是:");
  for(int i=1;i<=5;i++)
   System.out.print(x[i]+" ");
  }
}

//子空间中节点类型
 class BBnode{
 BBnode parent;//父节点
 boolean leftChild;//左儿子节点标志

 BBnode(BBnode par,boolean ch){
  parent=par;
  leftChild=ch;
 }
}

 class HeapNode implements Comparable{
 BBnode liveNode; // 活结点
 double upperProfit; //结点的价值上界
 double profit; //结点所相应的价值
 double weight; //结点所相应的重量
 int level; // 活结点在子集树中所处的层次号
 
 //构造方法
 public HeapNode(BBnode node, double up, double pp , double ww,int lev){
  liveNode = node;
  upperProfit = up;
  profit = pp;
  weight = ww;
  level = lev;
 }
 public int compareTo(Object o) {
 
  double xup = ((HeapNode)o).upperProfit;
  if(upperProfit < xup)
   return -1;
  if(upperProfit == xup)
   return 0;
  else
   return 1;
 }
}

 class Element implements Comparable{
 int id;
 double d;
 public Element(int idd,double dd){
  id=idd;
  d=dd;
 }
 public int compareTo(Object x){
  double xd=((Element)x).d;
  if(d<xd)return -1;
  if(d==xd)return 0;
  return 1;
 }
 public boolean equals(Object x){
  return d==((Element)x).d;
 }
}
 class MaxHeap{
  static HeapNode [] nodes;
  static int nextPlace;
  static int maxNumber;
  public MaxHeap(int n){
   maxNumber = (int)Math.pow((double)2,(double)n);
   nextPlace = 1;//下一个存放位置
   nodes = new HeapNode[maxNumber];
  }
  public static void put(HeapNode node){
   nodes[nextPlace] = node;
   nextPlace++;
   heapSort(nodes);
  
  }
  public static HeapNode removeMax(){
   HeapNode tempNode = nodes[1];
   nextPlace--;
   nodes[1] = nodes[nextPlace];
   heapSort(nodes);
   return tempNode;
  }
  private static void heapAdjust(HeapNode [] nodes,int s,int m){
   HeapNode rc = nodes[s];
   for(int j=2*s;j<=m;j*=2){
   
    if(j<m&&nodes[j].upperProfit<nodes[j+1].upperProfit)
     ++j;
   
    if(!(rc.upperProfit<nodes[j].upperProfit))
     break;
    nodes[s] = nodes[j];
    s = j;
   }
   nodes[s] = rc;
  }
  private static void heapSort(HeapNode [] nodes){
   for(int i=(nextPlace-1)/2;i>0;--i){
  
    heapAdjust(nodes,i,nextPlace-1);
   }
  }
 } 
http://zhidao.baidu.com/question/158833086.html

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace Test01Bag
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        public class Product
        {
            #region 商品类
            /// <summary>
            /// 商品重量泛型List存储
            /// </summary>
            private List<int> weight = new List<int>();

            public List<int> Weight
            {
                get{ return weight; }
                set{ weight = value; }
            }
            private List<int> value = new List<int>();
            /// <summary>
            /// 商品价值泛型List存储
            /// </summary>
            public List<int> Value
            {
                get { return this.value; }
                set{ this.value = value; }
            }
            private int count;
            /// <summary>
            /// 商品数量
            /// </summary>
            public int Count
            {
                get
                {
                    count = weight.Count;
                    return count;
                }
            }
            /// <summary>
            /// 添加商品信息
            /// </summary>
            /// <param name="w">重量</param>
            /// <param name="v">价值</param>
            /// <returns></returns>
            public int setWeightAddValve(int w, int v)
            {
                weight.Add(w);
                value.Add(v);
                return weight.Count;
            } 
            #endregion
        }
        public class Bag
        {
            #region 背包类
            int[,] help = new int[100, 100];
            int[] weight = new int[100];
            int[] value = new int[100];
            int count;
            int temp;
            // 背包容量
            private int valume;
            public int Valume
            {
                get{ return valume; }
                set { valume = value; }
            }
            private int maxvalue;

            public int Maxvalue
            {
                get { return maxvalue; }
                set{ maxvalue = value; }
            }
            /// <summary>
            /// 设定容量temp暂存
            /// </summary>
            /// <param name="v"></param>
            public void setValume(int v)
            {
                valume = v;
                temp = valume;
            }
            /// <summary>
            /// 引入数据
            /// </summary>
            /// <param name="newprd">Product</param>
            public void setProduct(Product newprd)
            {
                count = newprd.Count;
                weight = newprd.Weight.ToArray();
                value = newprd.Value.ToArray();
            }
            /// <summary>
            /// 买商品
            /// </summary>
            /// <returns></returns>
            public int buyproduct()
            {
                //初始化help表第一行为零
                for (int w = 0; w < valume; w++)
                {
                    help[0, w] = 0;
                }
                for (int i = 1; i <= count; i++)
                {
                    // //初始化help表第一l列为零
                    help[i, 0] = 0;
                    for (int w = 1; w <= valume; w++)
                    {
                        int temp = w - weight[i - 1];
                        if (weight[i - 1] <= w)
                        {
                            if (value[i - 1] + help[i - 1, temp] > help[i - 1, w])
                            {
                                help[i, w] = value[i - 1] + help[i - 1, temp];
                            }
                            else
                            {
                                help[i, w] = help[i - 1, w];
                            }
                        }
                        else
                        {
                            help[i, w] = help[i - 1, w];
                        }
                    }
                }
                maxvalue = help[count, valume];
                return maxvalue;
            }
            /// <summary>
            /// 显示结果买的商品状态存入ArrayList
            /// </summary>
            /// <returns></returns>
            public ArrayList showResult()
            {
                ArrayList result = new ArrayList();
                if (weight[0] == help[1, temp])
                {
                    result.Add("Buy!");
                }
                else
                {
                    result.Add("Not Buy!");
                }
                if (count >= 2)
                {
                    for (int i = count; i <= 2; i--)
                    {
                        if (help[i, temp] == help[i - 1, temp])
                        {
                            result.Add("Not Buy!");
                        }
                        else
                        {
                            result.Add("Buy!");
                        }
                        temp = temp - weight[i - 1];
                    }
                }
                return result;
            } 
            #endregion
        }
        /// <summary>
        /// 实例化
        /// </summary>
        Product newproduct = new Product();
        Bag newbag = new Bag();
        int i=1;
        private void Form1_Load(object sender, EventArgs e)
        {
            ///初始化
            onit();
        }
     public  void onit()
        {
            #region 程序初始化
         //清空
            newproduct.Value.Clear();
            newproduct.Weight.Clear();
            newbag.Valume = 0;
            lstboxResult.Items.Clear(); 
            #endregion
        }
        /// <summary>
        /// 存储商品信息函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAddProduct_Click(object sender, EventArgs e)
        {
            #region 添加商品信息
            try
            {

                int w = Convert.ToInt32(txtWeight.Text);
                int v = Convert.ToInt32(txtValue.Text);
                newproduct.setWeightAddValve(w, v);
                i++;
                label1.Text = "请输入商品(" + i.ToString() + ")的体积:";
                label3.Text = "请输入商品(" + i.ToString() + ")的价值:";
                txtWeight.Text = "";
                txtValue.Text = "";
            }
            catch
            {

                MessageBox.Show("你的输入有错误,请重新输入!");
                return;
            }
            
            #endregion
        }
        /// <summary>
        /// 问题解决函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnToBuy_Click(object sender, EventArgs e)
        {
            #region 解决背包问题
            try
            {
                int i = 1;
                int v = Convert.ToInt32(txtValume.Text);
                newbag.setValume(v);
                txtValume.Text = "";
                newbag.setProduct(newproduct);
                int x = newbag.buyproduct();
                lblMaxvalue.Text = "最大价值为:" + newbag.buyproduct().ToString();
                ArrayList result = newbag.showResult();
                int f = result.Count;
                foreach (string str in result)
                {
                    string message = "商品" + i.ToString() + "--------" + str;
                    lstboxResult.Items.Add(message);
                    i++;
                }
                onit();
            }
            catch
            {
                MessageBox.Show("你的输入有错误,请重新输入!");
                return;
            } 
            #endregion
                     
        }
    }
}

http://zhidao.baidu.com/question/101148292.html

    原文作者:分支限界法
    原文地址: https://blog.csdn.net/songyux6/article/details/8682737
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞