当前位置:首页 >> 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 背包问题算法 (回溯法) /** 本程序实现 0-1 背包问题算法 (回溯法) **/ #include <iostr...
0-1背包问题的解决(回溯法).doc
0-1背包问题的解决(回溯法)_解决方案_计划/解决方案_实用文档。算法设计分析,通过回溯法和动态规划的方法解决0-1背包问题。 前面这块转贴原理及 c++代码实现的...
回溯法求0-1背包问题.doc
回溯法0-1背包问题 - 《算法设计与分析》实验报告 学日号: 期: 姓得名: 分: 一、实验内容: 用回溯法求解 0/1 背包问题 注:给定 n 种物品和一个容量...
回溯算法解决0-1背包问题(DOC).doc
回溯算法解决 0-1 背包问题 实验日期:2016 年 5 月 18 日一、实验类型: ...让自己对算法的掌握更加牢固,也让自己能够熟练的利用 C++语言来 实现算法,同时...
实验3._回溯法的应用-0-1背包等问题.doc
实验4. 回溯法的应用- 0-1 背包等问题 实验内容本实验要求基于算法设计与分析...对于算法实现,可以自由选择 C, C++, Java,甚至于其他程序 设计语言。 实验步骤...
动态规划解决算法0-1背包问题实验报告(含源代码).doc
2.掌握动态规划、贪心算法回溯法、分支限界法的原理,并能够按其原理 编程实现解决 0-1 背包问题,以加深对上述方法的理解。 实验环境:Visual C++ 6.0 二. ...
0-1背包问题四种不同算法的实现.doc
0-1背包问题四种不同算法的实现_电脑基础知识_IT/计算机_专业资料。兰州交通...[i]; 方案三:回溯法 1、回溯法的基本原理与分析 回溯是一种系统地搜索问题...
回溯法实验0 1背包问题 C++.doc
回溯法实验0 1背包问题 C++ - #include <iostream
回溯算法(C++版).doc
回溯算法(C++版) - 回溯算法的定义: 回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。回溯算法的基本思想是: 从一条路往前走,能进则进,不能进...
回溯法解决01背包问题_图文.ppt
回溯法解决01背包问题 - 回溯法解决01背包问题 回溯法解决01背包问题 1算法思想 2、问题描述 3、设计实现 回溯法解决01背包问题 回溯法:是一个既带有系统性又...
0 1本背包问题C.C 程序实现及其效率分析.pdf
2) 贪心算法0-1 背包问题求解中的应用 3) 回溯法求解问题的一般思路,回溯法求解本问题的思路及其 C/C++程序实现与算法的效 率分析。 4) 分支限界法求解...
算法实验报告01背包问题.doc
姓名: 学号: 班级: "0-1"背包问题的动态规划算法一、 实验目的与要求:熟悉 C/C++语言的集成开发环境; 通过本实验加深对贪心算法、动态规划和回溯算法的理解。 ...
第5章 搜索与回溯算法(C++版)_图文.ppt
第5章 搜索与回溯算法(C++版)_计算机软件及应用_IT/计算机_专业资料。第五章...=0) k++; if (k>sqrt(i)) return 1; else return 0; } 【例2】设...
2015算法设计与分析复习试题及答案.pdf
7. 以深度优先方式系统搜索问题解的算法称为 8.0-1 背包问题的回溯算法所需...for(r=n-2;r>=0;r--) // 自底向上递归计算 for(c=0; 1 ;c++) if...
蛮力动规贪心回溯法的01背包和TSP问题.doc
二、 实验设备及环境: 微型计算机、Visual C++/JAVA 三、 实验内容及要求: ...(x[t],x[i]); } k++; } } } (2)利用回溯算法,求解 0/1 背包问题...
第5章 搜索与回溯算法(C++版)_图文.ppt
第5章 搜索与回溯算法(C++版) - 超级好的资料,保证是精品文档... 第5章 搜索与回溯算法(C++版)_教学案例/设计...(t+1); b[i]=0; } } int print() {...
第九章 回溯法算法设计_图文.ppt
第九章 回溯法算法设计 - 石志国 《算法分析与设计(C++描述)》课件... 石志国 《算法分析与设计(C++描述)》课件 ...0-1背包 9.1 回溯法有许多问题, 有许多问题...
搜索与回溯算法C版_图文.ppt
回溯是搜索算法中的一种控制策略。它的基本思想是:为了求得 问题的解,先选择...d[i-j+7])) //寻找放置皇后的位置 //由于C++不能操作负数组,因此考虑加7...
背包问题 实验报告.doc
1. 要求分别用动态规划、贪心算法回溯法和分支限界法求解 0-1 背包问题; 2...不 过那是 C++代码,有些封装好的方法在 Java 里好像没能找到对应的 方法,...
算法试题及答案.doc
for(r=n-2;r>=0;r--) //自底向上递归计算 for(c=0; 1 ;c++) 1-...题(本题 15 分) 分别用贪心算法、 动态规划法、 回溯法设计 0-1 背包问题...
更多相关标签: