日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

算法设计与分析——回溯法——装载问题

發布時間:2023/12/4 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法设计与分析——回溯法——装载问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

0027算法筆記——【回溯法】回溯法與裝載問題

自己寫的代碼:

#include <iostream> using namespace std; template <class Type> class Loading {//friend Type MaxLoading(Type[],Type,int,int []);//private:public:void Backtrack(int i);int n, //集裝箱數*x, //當前解*bestx; //當前最優解Type *w, //集裝箱重量數組c, //第一艘輪船的載重量cw, //當前載重量bestw, //當前最優載重量r; //剩余集裝箱重量 };//template <class Type> //void Loading <Type>::Backtrack (int i);template<class Type> Type MaxLoading(Type w[], Type c, int n, int bestx[]);int main() { int n=10,m;int c=500,c2=121;int w[11]={ 0,21,54,21,45,20,65,320,1,20,54};int bestx[10];m=MaxLoading(w, c, n, bestx);cout<<"輪船的載重量分別為:"<<endl;cout<<"c(1)="<<c<<",c(2)="<<c2<<endl;cout<<"待裝集裝箱重量分別為:"<<endl;cout<<"w(i)=";for (int i=1;i<=n;i++){cout<<w[i]<<" ";}cout<<endl;cout<<"回溯選擇結果為:"<<endl;cout<<"m(1)="<<m<<endl;cout<<"x(i)=";for (int i=1;i<=n;i++){cout<<bestx[i]<<" ";}cout<<endl;int m2=0;for (int j=1;j<=n;j++){m2=m2+w[j]*(1-bestx[j]);}cout<<"m(2)="<<m2<<endl;if(m2>c2){cout<<"因為m(2)大于c(2),所以原問題無解!"<<endl;}return 0; }template <class Type> void Loading <Type>::Backtrack (int i)// 搜索第i層結點 {if (i > n)// 到達葉結點{ if (cw>bestw){for(int j=1;j<=n;j++) {bestx[j]=x[j];//更新最優解bestw=cw; }} return;}r-=w[i]; if (cw + w[i] <= c) // 搜索左子樹{ x[i] = 1;cw += w[i];Backtrack(i+1);cw-=w[i]; }if (cw + r > bestw){x[i] = 0; // 搜索右子樹Backtrack(i + 1); }r+=w[i]; }template<class Type> Type MaxLoading(Type w[], Type c, int n, int bestx[])//返回最優載重量 {Loading<Type>X;//初始化XX.x=new int[n+1];X.w=w;X.c=c;X.n=n;X.bestx=bestx;X.bestw=0;X.cw=0;//初始化rX.r=0;for (int i=1;i<=n;i++){X.r+=w[i];}X.Backtrack(1);delete []X.x;return X.bestw; }


第二程序:

#include<iostream> using namespace std;class Loading {public:int n;//當前集裝箱的個數 // int *x;//當前的解 int *bestx;//目前的最優解 int *w;//集裝箱的重量數組 int c;//第一艘輪船的裝載量 int cw;//當前的裝載量 int bestw;//目前的最優裝載量 // int r;//剩余集裝箱重量 void Backtrack(int i);//求第i層結點 }; void Loading::Backtrack(int i)//搜索第i層結點 {if(i>n)//搜索到了葉子結點 {if(cw>bestw)//當前的載重量>目前最優載重量 {bestw= cw;}else{return ;} }else//還沒有搜索到葉子結點時 {if(cw+w[i]<=c)//可以添加這個結點進入第一艘輪船,即左子樹 {cw=cw+w[i];//需要在當前的載重量中加上該節點的重量 Backtrack(i+1);//搜索下一層cw=cw-w[i];// 必須放到這里面 ,如果不算這個節點時,需要將剛加上的w【i】減去 } // else 添加上這個else會出錯 因為無論如何都要走右子樹 //不添加這個結點進入第一艘輪船,即右子樹 //{Backtrack(i+1);// } } }int MaxLoading(int w[],int c,int n) { //初始化 Loading Loading X;X.w=w;X.c=c;X.n=n;X.bestw=0;X.cw=0;X.Backtrack(1);return X.bestw;} int main() {cout<<"輸入輪船的載重量分別:";int c1,c2;cin>>c1>>c2;cout<<"輸入待裝集裝箱的個數:";int n;cin>>n;cout<<"輸入待裝集裝箱的重量序列:";int w[n+1];for(int i=1;i<=n;i++){cin>>w[i];} cout<<MaxLoading( w,c1,n); }


第三程序:

#include<iostream> using namespace std;class Loading {public:int n;//當前集裝箱的個數 // int *x;//當前的解 int *bestx;//目前的最優解 int *w;//集裝箱的重量數組 int c;//第一艘輪船的裝載量 int cw;//當前的裝載量 int bestw;//目前的最優裝載量 int r;//剩余集裝箱重量 void Backtrack(int i);//求第i層結點 }; void Loading::Backtrack(int i)//搜索第i層結點 {if(i>n)//搜索到了葉子結點 {if(cw>bestw)//當前的載重量>目前最優載重量 {bestw= cw;}else{return ;} }else//還沒有搜索到葉子結點時 {r-=w[i];//因為在初始化的時候就已經把該節點的重量加到了r中去了 if(cw+w[i]<=c)//可以添加這個結點進入第一艘輪船,即左子樹 {cw=cw+w[i];//需要在當前的載重量中加上該節點的重量 Backtrack(i+1);//搜索下一層cw=cw-w[i];// 必須放到這里面 ,如果不算這個節點時,需要將剛加上的w【i】減去 } //不添加這個結點進入第一艘輪船,即右子樹 if(cw+r>bestw)//剪枝函數 {Backtrack(i+1);}r+=w[i];//不管如何都要在加上這個w[i] } }int MaxLoading(int w[],int c,int n) { //初始化 Loading Loading X;X.w=w;X.c=c;X.n=n;X.bestw=0;X.cw=0;X.r=0;for(int i=1;i<=n;i++){X.r+=w[i];} X.Backtrack(1);return X.bestw;} int main() {cout<<"輸入輪船的載重量分別:";int c1,c2;cin>>c1>>c2;cout<<"輸入待裝集裝箱的個數:";int n;cin>>n;cout<<"輸入待裝集裝箱的重量序列:";int w[n+1];for(int i=1;i<=n;i++){cin>>w[i];} cout<<MaxLoading( w,c1,n); }


第四程序:
輸出帶有序列

#include<iostream> using namespace std; class Loading {public:int n;//集裝箱的個數 int *w;//每個集裝箱對應的重量 int c;//第一艘船的載重量int *x;//用于存儲當前的解序列int *bestx;//用于存儲目前的最優解 int bestw;//目前最優的載重量int cw;//當前的載重量 int r;//當前剩余的集裝箱的重量 void Backtrack(int i); }; void Loading::Backtrack(int i) {if(i>n)//搜索到了葉子結點 {if(cw>bestw)//當前的載重量>目前最優載重量 {for(int i=1;i<=n;i++){bestx[i] = x[i];}bestw= cw;}else{return ;} }else//還沒有搜索到葉子結點時 {r-=w[i];//因為在初始化的時候就已經把該節點的重量加到了r中去了 if(cw+w[i]<=c)//可以添加這個結點進入第一艘輪船,即左子樹 {x[i] = 1;cw=cw+w[i];//需要在當前的載重量中加上該節點的重量 Backtrack(i+1);//搜索下一層cw=cw-w[i];// 必須放到這里面 ,如果不算這個節點時,需要將剛加上的w【i】減去 } //不添加這個結點進入第一艘輪船,即右子樹 if(cw+r>bestw)//剪枝函數 {x[i] = 0;Backtrack(i+1);}r+=w[i];//不管如何都要在加上這個w[i] } } int MaxLoading(int n,int *w,int c,int *bestx) {Loading X;X.n = n;X.w = w;X.bestx = bestx;X.c = c;X.bestw = 0;X.cw = 0;X.r = 0;X.x = new int [n+1];for(int i=1;i<=n;i++){X.r += w[i];}X.Backtrack(1);delete []X.x;return X.bestw; } int main() {cout<<"輸入輪船的載重量分別:";int c1,c2;cin>>c1>>c2;cout<<"輸入待裝集裝箱的個數:";int n;cin>>n;cout<<"輸入待裝集裝箱的重量序列:";int w[n+1];for(int i=1;i<=n;i++){cin>>w[i];} int bestx[n+1];int total_w=0;for(int i=1;i<=n;i++){total_w+=w[i];}if(total_w-MaxLoading( n,w,c1,bestx)>c2){cout<<"no solution"<<endl;return 0;}else{cout<<MaxLoading( n,w,c1,bestx)<<endl;for(int i=1;i<=n;i++){cout<<" "<<bestx[i];}}}

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的算法设计与分析——回溯法——装载问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。