当前位置:首页 >> IT/计算机 >>

回溯算法 0-1 背包算法 c++


回溯算法 0-1 背包算法 2009-12-03 10:38:04 阅读 218 评论 0 【实验目的】 学习掌握回溯算法。

字号:大中小 订阅 .

【实验内容】 用回溯法求解 0—1 背包问题,并输出问题的最优解。0—1 背包问题描述如下: 给定 n 种物品和一背包。物品 i 的重量是 Wi,其价值为 Vi,背包的容量是 c,问应如何选择 装入背包中的物品,使得装入背包中物品的总价值最大。

【实验条件】 Microsoft Visual C++ 6.0

【需求分析】 对于给定 n 种物品和一背包。在容量最大值固定的情况下,要求装入的物品价值最大化。

【设计原理】 一、回溯法: 回溯法是一个既带有系统性又带有跳跃性的的搜索算法。 它在包含问题的所有解的解空间树 中, 按照深度优先的策略, 从根结点出发搜索解空间树。 算法搜索至解空间树的任一结点时, 总是先判断该结点是否肯定不包含问题的解。 如果肯定不包含, 则跳过对以该结点为根的子 树的系统搜索,逐层向其祖先结点回溯。否则,进入该子树,继续按深度优先的策略进行搜 索。回溯法在用来求问题的所有解时,要回溯到根,且根结点的所有子树都已被搜索遍才结 束。而回溯法在用来求问题的任一解时,只要搜索到问题的一个解就可以结束。这种以深度 优先的方式系统地搜索问题的解的算法称为回溯法,它适用于解一些组合数较大的问题。 二、算法框架: 1、问题的解空间:应用回溯法解问题时,首先应明确定义问题的解空间。问题的解空间应

到少包含问题的一个(最优)解。 2、回溯法的基本思想:确定了解空间的组织结构后,回溯法就从开始结点(根结点)出发, 以深度优先的方式搜索整个解空间。 这个开始结点就成为一个活结点, 同时也成为当前的扩 展结点。在当前的扩展结点处,搜索向纵深方向移至一个新结点。这个新结点就成为一个新 的活结点,并成为当前扩展结点。如果在当前的扩展结点处不能再向纵深方向移动,则当前 扩展结点就成为死结点。 换句话说, 这个结点不再是一个活结点。 此时, 应往回移动 (回溯) 至最近的一个活结点处, 并使这个活结点成为当前的扩展结点。 回溯法即以这种工作方式递 归地在解空间中搜索,直至找到所要求的解或解空间中已没有活结点时为止。 运用回溯法解题通常包含以下三个步骤: (1)针对所给问题,定义问题的解空间; (2)确定易于搜索的解空间结构; (3)以深度优先的方式搜索解空间,并且在搜索过程中用剪枝函数避免无效搜索; 3、递归回溯:由于回溯法是对解空间的深度优先搜索,因此在一般情况下可用递归函数来 实现回溯法。 【概要设计】 0—1 背包问题是一个子集选取问题,适合于用子集树表示 0—1 背包问题的解空间。在搜索 解空间树是,只要其左儿子节点是一个可行结点,搜索就进入左子树,在右子树中有可能包 含最优解是才进入右子树搜索。否则将右子树剪去。 int c;//背包容量 int n; //物品数 int *w;//物品重量数组 int *p;//物品价值数组 int cw;//当前重量 int cp;//当前价值 int bestp;//当前最优值 int *bestx;//当前最优解 int *x;//当前解

int Knap::Bound(int i)//计算上界 void Knap::Backtrack(int i)//回溯

int Knapsack(int p[],int w[],int c,int n) //为 Knap::Backtrack 初始化

【详细设计】 #include<iostream> using namespace std;

class Knap { friend int Knapsack(int p[],int w[],int c,int n );

public: void print() { for(int m=1;m<=n;m++) { cout<<bestx[m]<<" ";

} cout<<endl; };

private: int Bound(int i); void Backtrack(int i);

int c;//背包容量 int n; //物品数 int *w;//物品重量数组 int *p;//物品价值数组 int cw;//当前重量 int cp;//当前价值 int bestp;//当前最优值 int *bestx;//当前最优解 int *x;//当前解

};

int Knap::Bound(int i)

{ //计算上界 int cleft=c-cw;//剩余容量 int b=cp; //以物品单位重量价值递减序装入物品 while(i<=n&&w[i]<=cleft) { cleft-=w[i]; b+=p[i]; i++; } //装满背包 if(i<=n) b+=p[i]/w[i]*cleft; return b; }

void Knap::Backtrack(int i) { if(i>n) {

if(bestp<cp) { for(int j=1;j<=n;j++) bestx[j]=x[j]; bestp=cp; } return; } if(cw+w[i]<=c) //搜索左子树 { x[i]=1; cw+=w[i]; cp+=p[i]; Backtrack(i+1); cw-=w[i]; cp-=p[i]; } if(Bound(i+1)>bestp)//搜索右子树 { x[i]=0; Backtrack(i+1); }

}

class Object { friend int Knapsack(int p[],int w[],int c,int n); public: int operator<=(Object a)const { return (d>=a.d); } private: int ID; float d; };

int Knapsack(int p[],int w[],int c,int n) { //为 Knap::Backtrack 初始化 int W=0;

int P=0; int i=1; Object *Q=new Object[n]; for(i=1;i<=n;i++) { Q[i-1].ID=i; Q[i-1].d=1.0*p[i]/w[i]; P+=p[i]; W+=w[i]; } if(W<=c) return P;//装入所有物品 //依物品单位重量排序 float f; for( i=0;i<n;i++) for(int j=i;j<n;j++) { if(Q[i].d<Q[j].d) { f=Q[i].d; Q[i].d=Q[j].d; Q[j].d=f;

}

}

Knap K; K.p = new int[n+1]; K.w = new int[n+1]; K.x = new int[n+1]; K.bestx = new int[n+1]; K.x[0]=0; K.bestx[0]=0; for( i=1;i<=n;i++) { K.p[i]=p[Q[i-1].ID]; K.w[i]=w[Q[i-1].ID]; } K.cp=0; K.cw=0; K.c=c; K.n=n; K.bestp=0;

//回溯搜索 K.Backtrack(1); K.print(); delete [] Q; delete [] K.w; delete [] K.p; return K.bestp; }

void main() { int *p; int *w; int c=0; int n=0; int i=0;

cout<<"请输入背包个数:"<<endl; cin>>n; p=new int[n+1]; w=new int[n+1]; p[0]=0;

w[0]=0;

cout<<"请输入个背包的价值:"<<endl; for(i=1;i<=n;i++) cin>>p[i];

cout<<"请输入个背包的重量:"<<endl; for(i=1;i<=n;i++) cin>>w[i];

cout<<"请输入背包容量:"<<endl; cin>>c;

cout<<Knapsack(p,w,c,n)<<endl;

}


相关文章:
回溯算法(C++版)
回溯算法(C++版) - 回溯算法的定义: 回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。回溯算法的基本思想是: 从一条路往前走,能进则进,不能进...
马踏棋盘回溯算法C++源代码
暂无评价|0人阅读|0次下载 | 举报文档 马踏棋盘回溯算法C++源代码_IT/计算机...回溯+贪心_马踏棋盘 1页 免费 回溯算法解决背包问题 源... 5页 免费 ...
最佳调度问题(回溯算法)
(k+1,t,x); time_machine[i] -= t[k]; } } } } 三、结果与分析: 算法源代码(C++描述) /* 最佳调度问题(回溯算法) 设有 n 个任务由 k 个可...
回溯法求解TSP问题
{ //如果长度值较大,直接回溯选择下一个城市 return; } for (int i = 0...4、通过这次实验对 TSP 算法C++解法有了进一步的了解,把理论知识应用于 ...
旅行售货员问题C.C++程序实现及其效率分析
旅行售货员问题 1)回溯法求解问题的一般思路,回溯法求解本问题的思路及其 C/C++程序实现及效率分析。 2)分支限界求解问题的一般思路,分支限界求解本问题的...
工作分配问题
二、 实验目的 1、理解回溯法的基本思想。 2、掌握设计回溯算法的步骤。 3、针对具体问题,能应用回溯法设计有效算法。 4、用 C++实现回溯算法,并且分析回溯算法...
实验四 用回溯法解n皇后问题等
二、实验环境 装有 Visual C++6.0,VS2005 的计算机。 本次实验共计 3 学时。 三、实验内容 1、熟悉回溯法思想 掌握如何进行问题的算法表示和描述。 掌握 n ...
更多相关标签: