1、扬大算法实验实验一:电路板排列问题/电路板排列问题 回溯法求解/#include stdafx.h#include #include using namespace std;ifstream fin(5d11.txt); class Board friend int Arrangement(int *B, int n, int m, int bestx); private: void Backtrack(int i,int cd); int n, /电路板数 m, /连接板数 *x, /当前解 *bestx,/当前最优解 bestd, /当前最优密度 *total, /totalj=连接块j的
2、电路板数 *now, /nowj=当前解中所含连接块j的电路板数 *B; /连接块数组;template inline void Swap(Type &a, Type &b);int Arrangement(int *B, int n, int m, int bestx);int main() int m = 5,n = 8; int bestx9;int i,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 coutm=m,n=nendl; coutN1=4,5,6,N2=2,3,N3=1,3,N4=3,6,N5=7,8e
3、ndl; cout二维数组B如下:endl; /构造B int *B = new int*n+1; for( i=1; i=n; i+) Bi = new intm+1; for( i=1; i=n; i+) for( j=1; jBij; coutBij ; coutendl; cout当前最优密度为:Arrangement(B,n,m,bestx)endl; cout最优排列为:endl; for( i=1; i=n; i+) coutbestxi ; coutendl; for( i=1; i=n; i+) delete Bi; delete B; return 0;void Board
4、:Backtrack(int i,int cd)/回溯法搜索排列树int j,k; if(i = n) for( j=1; j=n; j+) bestxj = xj; bestd = cd; else for( j=i; j=n; j+) /选择xj为下一块电路板 int ld = 0; for( k=1; k0 & totalk!=nowk) ld +; /更新ld if(cdld) ld = cd; if(ldbestd)/搜索子树 Swap(xi,xj); Backtrack(i+1,ld); Swap(xi,xj); /恢复状态 for( k=1; k=m; k+) nowk -= B
5、xjk; int Arrangement(int *B, int n, int m, int bestx) Board X;int i,j; /初始化X X.x = new intn+1; X.total = new intm+1; X.now = new intm+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.totali = 0; X.nowi = 0; /初始化x为单位排列并计算total for( i=1; i=n; i+) X.xi =
6、i; for( j=1; j=m; j+) X.totalj += Bij; /回溯搜索 X.Backtrack(1,0); delete X.x; delete X.total; delete X.now; return X.bestd;template inline void Swap(Type &a, Type &b) Type temp=a; a=b; b=temp;运行结果: 实验二:连续邮资问题#includeusing namespace std; class Stampfriend int MaxStamp(int ,int ,int );private: int Bound(
7、int i); void Backtrack(int i,int r); int n;/邮票面值数 int m;/每张信封最多允许贴的邮票数 int maxvalue;/当前最优值 int maxint;/大整数 int maxl;/邮资上界 int *x;/当前解 int *y;/贴出各种邮资所需最少邮票数 int *bestx;/当前最优解 ;void Stamp:Backtrack(int i,int r) for(int j=0;j=xi-2*(m-1);j+) if(yjm) for(int k=1;k=m-yj;k+) if(yj+kyj+xi-1*k) yj+xi-1*k=yj+
8、k; while(yrn) if(r-1maxvalue) maxvalue=r-1; for(int j=1;j=n;j+) bestxj=xj; return; int *z=new intmaxl+1; for(int k=1;k=maxl;k+) zk=yk; for(j=xi-1+1;j=r;j+) xi=j; Backtrack(i+1,r); for(int k=1;k=maxl;k+) yk=zk; delete z;int MaxStamp(int n,int m,int bestx) Stamp X; int maxint=32767; int maxl=1500; X.n
9、=n; X.m=m; X.maxvalue=0; X.maxint=maxint; X.maxl=maxl; X.bestx=bestx; X.x=new int n+1; X.y=new int maxl+1; for(int i=0;i=n;i+) X.xi=0; for(i=1;i=maxl;i+) X.yi=maxint; X.x1=1; X.y0=0; X.Backtrack(2,1); cout当前最优解:; for(i=1;i=n;i+) coutbestxi ; coutendl; delete X.x; delete X.y; return X.maxvalue;void m
10、ain() int *bestx; int n; int m; coutn; coutm; bestx=new intn+1; for(int i=1;i=n;i+) bestxi=0; cout最大邮资:MaxStamp(n,m,bestx)endl; 实验结果:实验三:0/1背包问题#include #include int n;/物品数量double c;/背包容量double v100;/各个物品的价值double w100;/各个物品的重量double cw = 0.0;/当前背包重量double cp = 0.0;/当前背包中物品价值double bestp = 0.0;/当前最优
11、价值double perp100;/单位物品价值排序后int order100;/物品编号int put100;/设置是否装入/按单位价值排序void knapsack() int i,j; int temporder = 0; double temp = 0.0; for(i=1;i=n;i+) perpi=vi/wi; for(i=1;i=n-1;i+) for(j=i+1;j=n;j+) if(perpin) bestp = cp; return; if(cw+wibestp)/符合条件搜索右子数 backtrack(i+1);/计算上界函数double bound(int i) dou
12、ble leftw= c-cw; double b = cp; while(i=n&wi=leftw) leftw-=wi; b+=vi; i+; if(i=n) b+=vi/wi*leftw; return b;int main() int i; printf(请输入物品的数量和容量:); scanf(%d %lf,&n,&c); printf(请输入物品的重量和价值:); for(i=1;i=n;i+) printf(第%d个物品的重量:,i); scanf(%lf,&wi); printf(价值是:); scanf(%lf,&vi); orderi=i; knapsack(); back
13、track(1); printf(最有价值为:%lfn,bestp); printf(需要装入的物品编号是:); for(i=1;i=n;i+) if(puti=1) printf(%d ,orderi); return 0;实验结果: 实验四:旅行售货员问题/5d9 旅行员售货问题 回溯法求解/#include stdafx.h#include #include using namespace std;ifstream fin(5d9.txt); const int N = 4;/图的顶点数 templateclass Traveling template friend Type TSP(T
14、ype *a, int n); private: void Backtrack(int i); int n, / 图G的顶点数 *x, / 当前解 *bestx; / 当前最优解 Type *a, / 图G的领接矩阵 cc, / 当前费用 bestc; / 当前最优值 int NoEdge; / 无边标记 ; template inline void Swap(Type &a, Type &b);templateType TSP(Type *a, int n);int main()int i,j; cout图的顶点个数 n=Nendl; int *a=new int*N+1; for(i=0;
15、i=N;i+) ai=new intN+1; cout图的邻接矩阵为:endl; for( i=1;i=N;i+) for( j=1;jaij; coutaij ; coutendl; cout最短回路的长为:TSP(a,N)endl; for( i=0;i=N;i+) delete ai; delete a; a=0; return 0;templatevoid Traveling:Backtrack(int i) if (i = n) if (axn-1xn != 0 & axn1 != 0 & (cc + axn-1xn + axn1 bestc | bestc = 0) for (in
16、t j = 1; j = n; j+) bestxj = xj; bestc = cc + axn-1xn + axn1; else for (int j = i; j = n; j+) / 是否可进入xj子树? if (axi-1xj != 0 & (cc + axi-1xi bestc | bestc = 0) / 搜索子树 Swap(xi, xj); cc += axi-1xi; /当前费用累加 Backtrack(i+1); /排列向右扩展,排列树向下一层扩展 cc -= axi-1xi; Swap(xi, xj); templateType TSP(Type *a, int n)in
17、t i,j; Traveling Y; Y.n=n; Y.x=new intn+1; Y.bestx=new intn+1; for(int i=1;i=n;i+) Y.xi=i; Y.a=a; Y.cc=0; Y.bestc=0; Y.NoEdge=0; Y.Backtrack(2); cout最短回路为:endl; for(int i=1;i=n;i+) coutY.bestxi ; coutY.bestx1endl; delete Y.x; Y.x=0; delete Y.bestx; Y.bestx=0; return Y.bestc;template inline void Swap
18、(Type &a, Type &b) Type temp=a; a=b; b=temp;运行结果: 实验五:m着色问题/#include stdafx.h#include #include using namespace std;const int N = 5;/图的顶点数const int M = 3;/色彩数ifstream fin(5d8.txt); class Color friend int mColoring(int, int, int *); private: bool Ok(int k); void Backtrack(int t); int n, /图的顶点数 m, /可用的
19、颜色数 *a, /图的邻接矩阵 *x; /当前解 long sum; /当前已找到的可m着色方案数;int mColoring(int n,int m,int *a);int main() int i,j; int *a = new int *N+1; for( i=1;i=N;i+) ai = new intN+1; cout图G的邻接矩阵为:endl; for( i=1; i=N; i+) for( j=1; jaij; coutaij ; coutendl; cout图G的着色方案如下:endl; cout当m=M时,图G的可行着色方案数目为:mColoring(N,M,a)endl;
20、for( i=1;in) sum+; for ( i=1; i=n; i+) cout xi ; cout endl; else for ( i=1;i=m;i+) xt=i; if (Ok(t) Backtrack(t+1); bool Color:Ok(int k)/ 检查颜色可用性int j; for (j=1;j=n;j+) if (akj=1)&(xj=xk) /相邻且颜色相同 return false; return true;int mColoring(int n,int m,int *a) Color X;int i; /初始化X X.n = n; X.m = m; X.a = a; X.sum = 0; int *p = new intn+1; for( i=0; i=n; i+) pi = 0; X.x = p; X.Backtrack(1); delete p; return X.sum;运行结果为:
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1