}
}
voidmain()
{
CHuffmanchf("");
();
();
system("pause");
}
用回溯方法求解n后问题
一、设计要求:
问题:
对任意给定的n求解n后问题。
具体要求:
1.封装n后问题为类,编写以下两种算法进行求解:
(1)递归回溯方法;
(2)迭代回溯方法。
(选)
2.对任意给定的n,要求输出其解向量(所有解),并输出其解数;
3.构造n后问题的解数表格(由程序自动生成):
n后数
解数
第一个解
4
2
(2,4,1,3)
5
…
…
6
…
…
…
…
…
二、选择的方案:
回溯法:
确定了解空间的组织结构后,回溯法就从开始结点(根结点)
出发,以深度优先搜索的方式搜索整个解空间。
这个开始结点就成为一个活结点,同时也成为当前的扩展结点。
在当前的扩展结点处,搜索向纵深方向移至一个新结点。
这个新结点就成为一个新的活结点,并成为当前扩展结点。
如果在当前的扩展结点处不能再向纵深方向移动,则当前的扩展结点就成为死结点。
此时,应往回移动(回溯)至最近的一个活结点处,并使这个活结点成为当前的扩展结点。
回溯法即以这种工作方式递归地在解空间中搜索,直至找到所要求的解或解空间中已无活结点时为止。
三、所用仪器、设备:
计算机、VisualC++软件。
四、实验方法与步骤:
输入:
皇后的个数N;输出:
N皇后问题的解的个数以及它的所有可行解。
n皇后问题;数组a中,a[i]表示第i个皇后放在第i行和第a[i]列,a[0]存放所有可行解的数目;利用棋盘的对称性,找到一个可行解后,其转置也是一个可行解,所以,只需把第一个皇后从第1列一直扫描到第(n+1)/2列即可,其他解可以根据对称性给出。
问题的解可表示为x[1:
n],表示皇后i放在棋盘的第i行的第x[i]列。
a)x[i]≠x[j],i≠j:
不允许将任何两个皇后放在同一列上;
b)|j-i|≠|x[j]-x[i]|:
不允许两个皇后位于同一条斜线上。
每个解元素生成之后,考察下一个元素能否在本元素的下一列放置,如果place函数的条件均不满足,则放置之,否则则向后放置,如果所有的元素位置都不行,则母元素的列数向后移动一个,再进行循环的考虑,此为回溯思想。
五、实验结果与数据处理:
六、实验心得:
算法附件:
classCQueen
{
public:
CQueen();x[k-1]时,判断x[k]能否放置
voidBackTrack(intt);
w[n]
价值
v[1]
v[2]
…
v[n]
具体要求:
1.将背包问题进行类的封装;
2.能对任意给定的n种物品的重量、价值及背包限重,输出以上表格(或纵向输出);
3.输出背包问题的解;
本题要求采用STL库中的排序算法数据进行排序。
二、选择的方案:
首先计算每种物品单位重量的价值Vi/Wi,然后依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包。
若将这种物品全部装入背包后,背包内的物品总重量未超出C,则选择单位重量价值次高的物品,并尽可能多的装入背包。
依此策略一直进行下去,直到背包装满为止。
采用贪婪准则:
每次选择p/w最大的物品放入背包。
调用函数库里的排序为sort()函数,括号内部为首地址与未地址。
注意在这之前的计算每种物品单位重量的价值Vi/Wi后,进行排序。
三、所用仪器、设备:
计算机、VisualC++软件。
四、实验方法与步骤:
此问题的形式化描述是,给定c>0,w[i]>0,v[i]>0,1≤i≤n,要求找出一个n元0-1向量(x1,x2,…,xn),0≤x[i]≤1,1≤i≤n,使得∑w[i]*x[i]≤c,而且∑v[i]*x[i]达到最大。
用贪心算法解部分背包问题,首先计算每种物品单位重量的价值v[i]/w[i],然后依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包,若将这种物品全部装入背包,背包内的物品总重量没有超过c,则把它全部装入,背包总价值增加v[i],然后选择单位重量价值次高的物品,如果物品重量w[i]超出了背包内剩余的容量c,则选择w[i]的c/w[i]部分放入背包,背包内总价值增加c*v[i]/w[i]。
根据上述分析设定几个基本变量:
intn,c;分别是物品的个数和背包的容量
floatp[],pack=,avg[];p为每个物品的价值,pack表示背包内所有物品的价值和,avg表示每个物品的单位重量价值
intw[];表示物品的重量
五、实验结果与数据处理:
算法附件:
#include<>
#definemaxn11
voidmain()
{
intn=0,c=0,ss;
floattemp=,p[maxn],pack=,avg[maxn];
intw[maxn],list[maxn];
cout<<"请输入物品的个数n和背包的容量c:
"<cin>>n>>c;
cout<<"请输入每件物品的价值和大小:
"<for(inti=1;i<=n;i++)过本次试验的学习,我熟悉了分治策略、贪心算法、回溯算法等有用的优秀的算法,复习了数据结构课上学到的构造Huffman树的方法。
本次实验的过程中,我学会了文件的读写,这对我来说是一件值得庆贺的事情,我们真应该多学习一点,对以后少走一些弯路是有帮助的!
希望我们都能够好好学习算法,多多思考,能够在解决实际问题上多多优化自己的程序!
2.构建知识框架,不管学习什么,概念是基础,所有的知识框架都是建立在基础概念之上的。
3.对算法的学习,个人认为,对算法的学习是学习数据结构的关键。
在第二遍看课本的过程中,要注重对算法的掌握。
对于一个算法,读一遍可能能读懂,但不可能完全领会其中的思想。
掌握一个算法,并不是说将算法背过,而是掌握算法的思想。
我们需要的是耐心。
每看一遍就会有这一遍的收获。
读懂算法之后,自己再默写算法,写到不会的地方,看看课本想想自己为什么没有想到。
反复练习,直到能顺利写出算法为止。
个人认为,这是行之有效的方法。
这样,不仅可以更加深入的领会算法思想,还会逐渐发现算法的巧妙之处,从而对数据结构及算法产生兴趣。