扬大算法实验.docx

上传人:b****7 文档编号:23787034 上传时间:2023-05-20 格式:DOCX 页数:23 大小:277.24KB
下载 相关 举报
扬大算法实验.docx_第1页
第1页 / 共23页
扬大算法实验.docx_第2页
第2页 / 共23页
扬大算法实验.docx_第3页
第3页 / 共23页
扬大算法实验.docx_第4页
第4页 / 共23页
扬大算法实验.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

扬大算法实验.docx

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

扬大算法实验.docx

扬大算法实验

实验一:

电路板排列问题

//电路板排列问题回溯法求解

//#include"stdafx.h"

#include

#include

usingnamespacestd;

ifstreamfin("5d11.txt");

classBoard

{

friendintArrangement(int**B,intn,intm,intbestx[]);

private:

voidBacktrack(inti,intcd);

intn,//电路板数

m,//连接板数

*x,//当前解

*bestx,//当前最优解

bestd,//当前最优密度

*total,//total[j]=连接块j的电路板数

*now,//now[j]=当前解中所含连接块j的电路板数

**B;//连接块数组

};

template

inlinevoidSwap(Type&a,Type&b);

intArrangement(int**B,intn,intm,intbestx[]);

intmain()

{

intm=5,n=8;

intbestx[9];

inti,j;

//B={1,2,3,4,5,6,7,8}

//N1={4,5,6},N2={2,3},N3={1,3},N4={3,6},N5={7,8}

cout<<"m="<

cout<<"N1={4,5,6},N2={2,3},N3={1,3},N4={3,6},N5={7,8}"<

cout<<"二维数组B如下:

"<

//构造B

int**B=newint*[n+1];

for(i=1;i<=n;i++)

{

B[i]=newint[m+1];

}

for(i=1;i<=n;i++)

{

for(j=1;j<=m;j++)

{

fin>>B[i][j];

cout<

}

cout<

}

cout<<"当前最优密度为:

"<

cout<<"最优排列为:

"<

for(i=1;i<=n;i++)

{

cout<

}

cout<

for(i=1;i<=n;i++)

{

delete[]B[i];

}

delete[]B;

return0;

}

voidBoard:

:

Backtrack(inti,intcd)//回溯法搜索排列树

{intj,k;

if(i==n)

{

for(j=1;j<=n;j++)

{

bestx[j]=x[j];

}

bestd=cd;

}

else

{

for(j=i;j<=n;j++)

{

//选择x[j]为下一块电路板

intld=0;

for(k=1;k<=m;k++)

{

now[k]+=B[x[j]][k];

if(now[k]>0&&total[k]!

=now[k])

{

ld++;

}

}

//更新ld

if(cd>ld)

{

ld=cd;

}

if(ld

{

Swap(x[i],x[j]);

Backtrack(i+1,ld);

Swap(x[i],x[j]);

//恢复状态

for(k=1;k<=m;k++)

{

now[k]-=B[x[j]][k];

}

}

}

}

}

intArrangement(int**B,intn,intm,intbestx[])

{

BoardX;

inti,j;

//初始化X

X.x=newint[n+1];

X.total=newint[m+1];

X.now=newint[m+1];

X.B=B;

X.n=n;

X.m=m;

X.bestx=bestx;

X.bestd=m+1;

//初始化total和now

for(i=1;i<=m;i++)

{

X.total[i]=0;

X.now[i]=0;

}

//初始化x为单位排列并计算total

for(i=1;i<=n;i++)

{

X.x[i]=i;

for(j=1;j<=m;j++)

{

X.total[j]+=B[i][j];

}

}

//回溯搜索

X.Backtrack(1,0);

delete[]X.x;

delete[]X.total;

delete[]X.now;

returnX.bestd;

}

template

inlinevoidSwap(Type&a,Type&b)

{

Typetemp=a;

a=b;

b=temp;

}

运行结果:

实验二:

连续邮资问题

#include

usingnamespacestd;

classStamp

{

friendintMaxStamp(int,int,int[]);

private:

intBound(inti);

voidBacktrack(inti,intr);

intn;//邮票面值数

intm;//每张信封最多允许贴的邮票数

intmaxvalue;//当前最优值

intmaxint;//大整数

intmaxl;//邮资上界

int*x;//当前解

int*y;//贴出各种邮资所需最少邮票数

int*bestx;//当前最优解

};

voidStamp:

:

Backtrack(inti,intr)

{

for(intj=0;j<=x[i-2]*(m-1);j++)

if(y[j]

for(intk=1;k<=m-y[j];k++)

if(y[j]+k

y[j+x[i-1]*k]=y[j]+k;

while(y[r]

r++;

if(i>n){

if(r-1>maxvalue){

maxvalue=r-1;

for(intj=1;j<=n;j++)

bestx[j]=x[j];

}

return;

}

int*z=newint[maxl+1];

for(intk=1;k<=maxl;k++)

z[k]=y[k];

for(j=x[i-1]+1;j<=r;j++){

x[i]=j;

Backtrack(i+1,r);

for(intk=1;k<=maxl;k++)

y[k]=z[k];

}

delete[]z;

}

intMaxStamp(intn,intm,intbestx[]){

StampX;

intmaxint=32767;

intmaxl=1500;

X.n=n;

X.m=m;

X.maxvalue=0;

X.maxint=maxint;

X.maxl=maxl;

X.bestx=bestx;

X.x=newint[n+1];

X.y=newint[maxl+1];

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

X.x[i]=0;

for(i=1;i<=maxl;i++)

X.y[i]=maxint;

X.x[1]=1;

X.y[0]=0;

X.Backtrack(2,1);

cout<<"当前最优解:

";

for(i=1;i<=n;i++)

cout<

cout<

delete[]X.x;

delete[]X.y;

returnX.maxvalue;

}

voidmain(){

int*bestx;

intn;

intm;

cout<<"请输入邮票的个数:

";

cin>>n;

cout<<"请输入每张信封最多允许贴的邮票数:

";

cin>>m;

bestx=newint[n+1];

for(inti=1;i<=n;i++)

bestx[i]=0;

cout<<"最大邮资:

"<

}

实验结果:

 

实验三:

0/1背包问题

#include

#include

intn;//物品数量

doublec;//背包容量

doublev[100];//各个物品的价值

doublew[100];//各个物品的重量

doublecw=0.0;//当前背包重量

doublecp=0.0;//当前背包中物品价值

doublebestp=0.0;//当前最优价值

doubleperp[100];//单位物品价值排序后

intorder[100];//物品编号

intput[100];//设置是否装入

//按单位价值排序

voidknapsack()

{

inti,j;

inttemporder=0;

doubletemp=0.0;

for(i=1;i<=n;i++)

perp[i]=v[i]/w[i];

for(i=1;i<=n-1;i++)

{

for(j=i+1;j<=n;j++)

if(perp[i]

{

temp=perp[i];

perp[i]=perp[i];

perp[j]=temp;

temporder=order[i];

order[i]=order[j];

order[j]=temporder;

temp=v[i];

v[i]=v[j];

v[j]=temp;

temp=w[i];

w[i]=w[j];

w[j]=temp;

}

}

}

//回溯函数

voidbacktrack(inti)

{

doublebound(inti);

if(i>n)

{

bestp=cp;

return;

}

if(cw+w[i]<=c)

{

cw+=w[i];

cp+=v[i];

put[i]=1;

backtrack(i+1);

cw-=w[i];

cp-=v[i];

}

if(bound(i+1)>bestp)//符合条件搜索右子数

backtrack(i+1);

}

//计算上界函数

doublebound(inti)

{

doubleleftw=c-cw;

doubleb=cp;

while(i<=n&&w[i]<=leftw)

{

leftw-=w[i];

b+=v[i];

i++;

}

if(i<=n)

b+=v[i]/w[i]*leftw;

returnb;

}

 

intmain()

{

inti;

printf("请输入物品的数量和容量:

");

scanf("%d%lf",&n,&c);

printf("请输入物品的重量和价值:

");

for(i=1;i<=n;i++)

{

printf("第%d个物品的重量:

",i);

scanf("%lf",&w[i]);

printf("价值是:

");

scanf("%lf",&v[i]);

order[i]=i;

}

knapsack();

backtrack

(1);

printf("最有价值为:

%lf\n",bestp);

printf("需要装入的物品编号是:

");

for(i=1;i<=n;i++)

{

if(put[i]==1)

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

}

return0;

}

}

实验结果:

 

实验四:

旅行售货员问题

//5d9旅行员售货问题回溯法求解

//#include"stdafx.h"

#include

#include

usingnamespacestd;

ifstreamfin("5d9.txt");

constintN=4;//图的顶点数

template

classTraveling

{

template

friendTypeTSP(Type**a,intn);

private:

voidBacktrack(inti);

intn,//图G的顶点数

*x,//当前解

*bestx;//当前最优解

Type**a,//图G的领接矩阵

cc,//当前费用

bestc;//当前最优值

intNoEdge;//无边标记

};

template

inlinevoidSwap(Type&a,Type&b);

template

TypeTSP(Type**a,intn);

intmain()

{inti,j;

cout<<"图的顶点个数n="<

int**a=newint*[N+1];

for(i=0;i<=N;i++)

{

a[i]=newint[N+1];

}

cout<<"图的邻接矩阵为:

"<

for(i=1;i<=N;i++)

{

for(j=1;j<=N;j++)

{

fin>>a[i][j];

cout<

}

cout<

}

cout<<"最短回路的长为:

"<

for(i=0;i<=N;i++)

{

delete[]a[i];

}

delete[]a;

a=0;

return0;

}

template

voidTraveling:

:

Backtrack(inti)

{

if(i==n)

{

if(a[x[n-1]][x[n]]!

=0&&a[x[n]][1]!

=0&&

(cc+a[x[n-1]][x[n]]+a[x[n]][1]

{

for(intj=1;j<=n;j++)bestx[j]=x[j];

bestc=cc+a[x[n-1]][x[n]]+a[x[n]][1];

}

}

else

{

for(intj=i;j<=n;j++)

{

//是否可进入x[j]子树?

if(a[x[i-1]][x[j]]!

=0&&(cc+a[x[i-1]][x[i]]

{

//搜索子树

Swap(x[i],x[j]);

cc+=a[x[i-1]][x[i]];//当前费用累加

Backtrack(i+1);//排列向右扩展,排列树向下一层扩展

cc-=a[x[i-1]][x[i]];

Swap(x[i],x[j]);

}

}

}

}

template

TypeTSP(Type**a,intn)

{inti,j;

TravelingY;

Y.n=n;

Y.x=newint[n+1];

Y.bestx=newint[n+1];

for(inti=1;i<=n;i++)

{

Y.x[i]=i;

}

Y.a=a;

Y.cc=0;

Y.bestc=0;

Y.NoEdge=0;

Y.Backtrack

(2);

cout<<"最短回路为:

"<

for(inti=1;i<=n;i++)

{

cout<";

}

cout<

delete[]Y.x;

Y.x=0;

delete[]Y.bestx;

Y.bestx=0;

returnY.bestc;

}

template

inlinevoidSwap(Type&a,Type&b)

{

Typetemp=a;

a=b;

b=temp;

}

运行结果:

实验五:

m着色问题

//#include"stdafx.h"

#include

#include

usingnamespacestd;

constintN=5;//图的顶点数

constintM=3;//色彩数

ifstreamfin("5d8.txt");

classColor{

friendintmColoring(int,int,int**);

private:

boolOk(intk);

voidBacktrack(intt);

intn,//图的顶点数

m,//可用的颜色数

**a,//图的邻接矩阵

*x;//当前解

longsum;//当前已找到的可m着色方案数

};

intmColoring(intn,intm,int**a);

intmain(){

inti,j;

int**a=newint*[N+1];

for(i=1;i<=N;i++){

a[i]=newint[N+1];

}

cout<<"图G的邻接矩阵为:

"<

for(i=1;i<=N;i++){

for(j=1;j<=N;j++){

fin>>a[i][j];

cout<

}

cout<

}

cout<<"图G的着色方案如下:

"<

cout<<"当m="<

"<

for(i=1;i<=N;i++){

delete[]a[i];

}

delete[]a;

}

voidColor:

:

Backtrack(intt)

{inti;

if(t>n){

sum++;

for(i=1;i<=n;i++)

cout<

cout<

}

else{

for(i=1;i<=m;i++){

x[t]=i;

if(Ok(t))Backtrack(t+1);

}}}

boolColor:

:

Ok(intk)//检查颜色可用性

{intj;

for(j=1;j<=n;j++){

if((a[k][j]==1)&&(x[j]==x[k])){//相邻且颜色相同

returnfalse;

}

}

returntrue;}

intmColoring(intn,intm,int**a){

ColorX;

inti;//初始化X

X.n=n;X.m=m;

X.a=a;X.sum=0;

int*p=newint[n+1];

for(i=0;i<=n;i++){

p[i]=0;

}

X.x=p;

X.Backtrack

(1);

delete[]p;

returnX.sum;

}

运行结果为:

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

当前位置:首页 > 高中教育 > 其它课程

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

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