当前位置:首页 >> 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;

}


相关文章:
回溯算法 0-1 背包算法 c++.doc
回溯算法 0-1 背包算法 c++ - 回溯算法 0-1 背包算法 2009-12-03 10:38:04 阅读 218 评论 0 【实验目的】 学习掌握回溯算法。 字号:大中小 订阅 . ...
回溯算法解决0-1背包问题(DOC).doc
回溯算法解决 0-1 背包问题 实验日期:2016 年 5 月 18 日一、实验类型: ...让自己对算法的掌握更加牢固,也让自己能够熟练的利用 C++语言来 实现算法,同时...
0-1背包问题的解决(回溯法).doc
0-1背包问题的解决(回溯法)_解决方案_计划/解决方案_实用文档。算法设计分析,通过回溯法和动态规划的方法解决0-1背包问题。 前面这块转贴原理及 c++代码实现的...
回溯法实验0 1背包问题 C++.doc
回溯法实验0 1背包问题 C++ - #include <iostream
回溯算法0-1背包问题.doc
回溯算法0-1背包问题 - 实验目的是使学生消化理论知识, 加深对讲授内容的理解, 尤其是一些算法的实现及其 应用,培养学生独立编程和调试程序的能力,使学生对...
回溯法求0-1背包问题.doc
回溯法求0-1背包问题 - 《算法设计与分析》实验报告 学日号: 期: 姓得名: 分: 一、实验内容: 用回溯法求解 0/1 背包问题 注:给定 n 种物品和一个容量...
回溯法实验(0-1背包问题).doc
回溯法实验(0-1背包问题) - 算法分析与设计实验报告 第五 次附加实验 姓名 时间 实验名称 12.26 上午 学号 地点 班级 工训楼 309 回溯法实验(0-1 背包...
回溯法解0-1背包问题实验报告.doc
实验4 一 、实验要求 回溯法解 0-1 背包问题 1.要求用回溯法求解 0-1 背包问题; 2.要求交互输入背包容量,物品重量数组,物品价值数组; 3.要求显示结果。 ...
动态规划解决算法0-1背包问题实验报告(含源代码).doc
2.掌握动态规划、贪心算法回溯法、分支限界法的原理,并能够按其原理 编程实现解决 0-1 背包问题,以加深对上述方法的理解。 实验环境:Visual C++ 6.0 二. ...
0-1背包问题的各种算法求解.doc
0-1背包问题的各种算法求解_信息与通信_工程科技_专业资料。一.动态规划求解 0...<程序代码:>(环境:c++) #include<iostream.h> #define max 100 //最多物品...
分支限界法求0-1背包问题实验程序以及代码(C++).doc
分支限界法求0-1背包问题实验程序以及代码(C++)_...分支限界算法0-1背包问... 8页 1下载券 实验...1页 免费 分别用回溯法和分支限界... 暂无评价...
基于C#的01背包问题的回溯算法.doc
基于C#的01背包问题的回溯算法 - 龙源期刊网 http://www.qikan.com.cn 基于 C#的 01 背包问题的回溯算法 作者:陈自力 来源:《电脑知识与技术》2016 年...
0-1背包问题(回溯法).doc
0-1背包问题(回溯法) - 0-1 背包问题(回溯法) 实验报告 姓 名: 学 号: 指导老师: 一.算法设计名称: 0-1 背包问题(回溯法) 二.实验内容 问题描述: ...
回溯法、分支限界法解0-1背包问题(计算机算法设计与分....doc
实验报告 课程名称: 算法设计与分析 实验名称:回溯法、分支限界法解 0-1 背包...不过那是 C++代码, 有些封装好的方法在 Java 里好像没能找到对应的方法,所以...
0-1背包 回溯法.doc
0-1背包 回溯法 - 《算法分析与设计》实验报告 实验三 实验地点 班级 A5
用动态规划法与回溯法实现0-1背包问题的比较_论文.pdf
用动态规划法与回溯法实现0-1背包问题的比较 - 0-1背包问题是运筹学中的著名问题。也是计算机算法中的一个经典问题。本文采用动态规划法和回溯法对该问题进行求解...
实验3._回溯法的应用-0-1背包等问题.doc
实验4. 回溯法的应用- 0-1 背包等问题 实验内容本实验要求基于算法设计与分析...对于算法实现,可以自由选择 C, C++, Java,甚至于其他程序 设计语言。 实验步骤...
0-1背包(动态规划、回溯)和背包(贪心)实验报告.doc
设计目的 通过上机实验: 深刻理解和掌握 0-1 背包(动态规划算法、 回溯算法)和背包(贪心算法)的问题 描述、算法设计思想、程序设计、算法复杂性分析、他们的区别...
回溯算法之01背包问题JAVA源程序.pdf
回溯算法之01背包问题JAVA源程序_电子/电路_工程科技_专业资料。实验报告 11 ...(如果上周没完成,这周完成) 2、编写程序,采用回溯法实现0-1背包问题。 四、...
算法实验报告01背包问题.doc
姓名: 学号: 班级: "0-1"背包问题的动态规划算法一、 实验目的与要求:熟悉 C/C++语言的集成开发环境; 通过本实验加深对贪心算法、动态规划和回溯算法的理解。 ...