算法实验报告.docx

上传人:b****6 文档编号:3226329 上传时间:2022-11-20 格式:DOCX 页数:25 大小:75.02KB
下载 相关 举报
算法实验报告.docx_第1页
第1页 / 共25页
算法实验报告.docx_第2页
第2页 / 共25页
算法实验报告.docx_第3页
第3页 / 共25页
算法实验报告.docx_第4页
第4页 / 共25页
算法实验报告.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

算法实验报告.docx

《算法实验报告.docx》由会员分享,可在线阅读,更多相关《算法实验报告.docx(25页珍藏版)》请在冰豆网上搜索。

算法实验报告.docx

算法实验报告

中南大学

算法设计与分析

实验报告

学生姓名惠苗壮

指导教师郑瑾

学院信息科学与工程学院

专业班级计科0904班

学号0909091627

完成时间2011年12月18日

目录

一.实验目的………………………………………1

二.实验要求………………………………………1

三.实验内容………………………………………1

四.实验分析………………………………………1

五.实验结果………………………………………15

六.实验心得………………………………………20

一.实验目的:

1.掌握动态规划、回溯法、分支限定法的原理。

2.能独立完成上述算法的实现。

3.能用上述算法解决问题。

二.实验要求:

1.给出相应的测试结果。

2.给出源代码及相应的注释。

3.所有的输入和输出都用文件处理。

三.实验内容:

1.实现求n皇后问题和子集和数问题的回溯算法。

2.用动态规划的方法实现0/1背包问题。

3.用分支限界法实现0/1背包问题。

4.用深度优化的方法遍历一个图,并判断图中是否有回路存在,如果有,请输出回路。

四.实验分析:

实验一:

实现求n皇后问题和子集和数问题的回溯算法。

问题说明:

按照国际象棋的规则在N*N的棋盘上放置彼此不受攻击的皇后问题。

数据表示:

用n个数彼此用“,”隔开来表示那个皇后的最后位置,如:

4皇后问题中,最后结果为1,3,0,2,表示第0列的皇后的位置在1,第1列的皇后的位置在3,第2列皇后的位置在0,第4列的皇后的位置在2.n皇后以此类推。

代码如下:

#include"stdio.h"

#include"stdlib.h"

#include"math.h"

intx[4]={0};

 

intPlace(intk)//判断第k行当前列是否可以放置皇后

{

for(inti=0;i

{

if(x[i]==x[k]||(abs(x[i]-x[k])-abs(i-k))==0)

{

return0;

}

}

return1;

}

voidNQueens(intk)

{

x[k]=-1;

while

(1)

{x[k]=x[k]+1;

while((x[k]<4)&&(!

Place(k)))x[k]=x[k]+1;

if(x[k]<4)

{if(k<3)NQueens(k+1);

else

{

for(inti=0;i<4;i++)

{

printf("%d,",x[i]);

}

printf("\n");

}

}

elsereturn;

}

}

intmain(intargc,char*argv[])

{

NQueens(0);

system("PAUSE");

}

实验二:

用动态规划的方法实现0/1背包问题。

问题说明:

给定n种物品和一背包。

物品i的重量是w,其价值是v,背包的容量为C。

求应怎样装入物体使得装入背包中的物体总价值最大。

算法说明:

采用动态规划的方法,将待求解问题分解成若干个子问题,然后从这些子问题的解得到原问题的解。

在该问题中需要决定x1..xn的值。

假设按i=1,2,...,n的次序来确定xi的值。

如果置x1=0,则问题转变为相对于其余物品(即物品2,3,.,n),背包容量仍为c的背包问题。

若置x1=1,问题就变为关于最大背包容量为c-w1的问题。

现设r?

{c,c-w1}为剩余的背包容量。

  在第一次决策之后,剩下的问题便是考虑背包容量为r时的决策。

不管x1是0或是1,[x2,.,xn]必须是第一次决策之后的一个最优方案,如果不是,则会有一个更好的方案[y2,.,yn],因而[x1,y2,.,yn]是一个更好的方案。

  假设n=3,w=[100,14,10],p=[20,18,15],c=116。

若设x1=1,则在本次决策之后,可用的背包容量为r=116-100=16。

[x2,x3]=[0,1]符合容量限制的条件,所得值为15,但因为[x2,x3]=[1,0]同样符合容量条件且所得值为18,因此[x2,x3]=[0,1]并非最优策略。

即x=[1,0,1]可改进为x=[1,1,0]。

若设x1=0,则对于剩下的两种物品而言,容量限制条件为116。

总之,如果子问题的结果[x2,x3]不是剩余情况下的一个最优解,则[x1,x2,x3]也不会是总体的最优解。

在此问题中,最优决策序列由最优决策子序列组成。

假设f(i,y)表示剩余容量为y,剩余物品为i,i+1,...,n时的最优解的值,即:

利用最优序列由最优子序列构成的结论,可得到f的递归式为:

  当j>=wi时:

 f(i,j)=max{f(i+1,j),f(i+1,j-wi)+vi}①式

  当0<=j时:

  fn(1,c)是初始时背包问题的最优解。

  以本题为例:

若0≤y<10,则f(3,y)=0;若y≥10,f(3,y)=15。

利用②式,可得f(2,y)=0(0≤y<10);f(2,y)=15(10≤y<14);f(2,y)=18(14≤y<24)和f(2,y)=33(y≥24)。

因此最优解f(1,116)=max{f(2,116),f(2,116-w1)+p1}=max{f(2,116),f(2,16)+20}=max{33,38}=38。

现在计算xi值,步骤如下:

若f(1,c)=f(2,c),则x1=0,否则x1=1。

接下来需从剩余容量c-w1中寻求最优解,用f(2,c-w1)表示最优解。

依此类推,可得到所有的xi(i=1.n)值。

  在该例中,可得出f(2,116)=33≠f(1,116),所以x1=1。

接着利用返回值38-p1=18计算x2及x3,此时r=116-w1=16,又由f(2,16)=18,得f(3,16)=14≠f(2,16),因此x2=1,此时r=16-w2=2,所以f(3,2)=0,即得x3=0

代码如下;

#include

#include

#include"math.h"

usingnamespacestd;

intw[5]={2,2,6,5,4};

intv[5]={6,3,5,4,6};

intlength=5;

intc=10;

intm[5][10];

voidknapsack(int*v,int*w,intc,intm[][10])

{

intn=length-1;

intjMax=min(w[n]-1,c);

for(intj=0;j<=jMax;j++)

{

m[n][j]=0;

}

for(intj=w[n];j<=c;j++)

{

m[n][j]=v[n];

}

for(inti=n-1;i>1;i--)

{

jMax=min(w[i]-1,c);

for(intj=0;j<=jMax;j++)//背包容量没有i物品大,则从i-n选物品装入包的中价值等于从i+1~n

m[i][j]=m[i+1][j];

for(intj=w[i];j<=c;j++)

m[i][j]=max(m[i+1][j],m[i+1][j-w[i]]+v[i]);//包可以装入i,则分两种情况,一种是装i,一种是不装i,从中选最大

}

m[1][c]=m[2][c];

if(c>=w[1])

m[1][c]=max(m[1][c],m[1][c-w[1]]+v[1]);

}

voidtraceback(intm[][10],int*w,intc,int*x)

{

intn=length-1;

for(inti=0;i

{

if(m[i][c]==m[i+1][c])

x[i]=0;

else

{

x[i]=1;

c-=w[i];

}

}

x[n]=(m[n][c]>0)?

1:

0;

}

intmain(intargc,char*argv[])

{

intx[5];

knapsack(v,w,c,m);

traceback(m,w,c,x);

for(inti=0;i<5;i++)

{

if(x[i]==1)

printf("%d",w[i]);

}

//printf("%d",x[i]);

system("PAUSE");

returnEXIT_SUCCESS;

}

实验三:

用分支限界法实现0/1背包问题。

算法分析:

采用分支限定法,对物品的选取与否构成一棵解树,左子树表示不装入,右表示装入,通过检索问题的解树得出最优解,并用结点上界杀死不符合要求的结点。

代码如下:

#include"stdlib.h"

#include"math.h"

#include"iostream"

usingnamespacestd;

//子集空间树结点

classbbnode

{

friendclassKnap;

friendintKnapsack(intp[],intw[],intc,intn,intbestx[]);

private:

bbnode*parent;//指向父结点的指针

boolLChild;//左儿子结点标志

};

//对大堆结点

classHeapNode

{

friendclassKnap;

public:

operatorint()const{returnuprofit;}

intuprofit,//结点的价值上界

profit;//结点所相应的价值

intweight;//结点所相应的重量

intlevel;//活结点在子集树种所处的层序号

bbnode*ptr;//指向活结点在子集树种相应结点的指针

};

typedefstructHeap

{

intcapacity;

intsize;

HeapNode*Elem;

}Heap,*MaxHeap;

MaxHeapinitH(intmaxElem)

{

MaxHeapH;

H=(MaxHeap)malloc(sizeof(Heap));

H->capacity=maxElem;

H->Elem=(HeapNode*)malloc((maxElem)*sizeof(HeapNode));

H->size=0;

returnH;

}

voidInsertH(HeapNodex,MaxHeapH)

{

inti,sindex=0;

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1