扬大算法实验.docx
- 文档编号:23787034
- 上传时间:2023-05-20
- 格式:DOCX
- 页数:23
- 大小:277.24KB
扬大算法实验.docx
《扬大算法实验.docx》由会员分享,可在线阅读,更多相关《扬大算法实验.docx(23页珍藏版)》请在冰豆网上搜索。
扬大算法实验
实验一:
电路板排列问题
//电路板排列问题回溯法求解
//#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<<"图的邻接矩阵为:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 实验