1.問題描述:
設某一機器由n個部件組成,每一種部件都可以從m個不同的**商處購得。設 w
ij是從**商j 處購得的部件i的重量,c
ij是相應的**。
試設計乙個回溯演算法,
對於給定的機器部件重量和機器部件**,計算總**不超過c的最小重量機器設計。
2.解題思路:
3.演算法設計:
回溯法要求要給出約束條件,很明顯:總**不超過c,
設當前已選部件的重量和為cw,**之和為cc,
當前最優重量用bestw表示,初始化bestw=∞;
限界條件:cw
a.部件有n個,**商有m個,分別用w[i][j]和c[i][j]儲存從**商j 處購得的部件i的重量和相應**,d為總**的上限。
b.用遞迴函式backtrack(i)來實現回溯法搜尋排列樹(形式引數i表示遞迴深度)。
① 若cp>d,則為不可行解,剪去相應子樹,返回到i-1層繼續執行。
② 若cw>=sum,則不是最優解,剪去相應子樹,返回到i-1層繼續執行。
④ 用for迴圈對部件i從m個不同的**商購得的情況進行選擇(1≤j≤m)。
c.主函式呼叫一次knapsack(1)即可完成整個回溯搜尋過程,最終得到的sum即為所求最小總重量。
4.**:
程式中最大的迴圈出現在遞迴函式backtrack(i)中,而此函式遍歷排列樹的時間複雜度為o(n!),故該演算法的時間複雜度為o(n!)。
[cpp]view plain
copy
#include
#include
using
namespace
std;
intw[100][100];
//w[i][j]為第i個零件在第j個**商的重量
intc[100][100];
//c[i][j]為第i個零件在第j個**商的**
intbestx[100];
//bestx[i]表示一次搜尋到底後的最優解,用來存放第i個零件的**商,
intx[100];
//x[i]臨時存放第i個零件的**商
intcw=0,cc=0,bestw=10000;
intcost;
//限定**
intn;
//部件數
intm;
//**商數
void
backtrack(
intt)
else
} } }
intmain()
/*測試資料:33
另一種寫法:
[cpp]view plain
copy
#include
#define n 1000
using
namespace
std;
intn,m,d,cp=0,cw=0,sum=0;
intc[n][n],w[n][n];
void
backtrack(
inti)
for(
intj=1;j<=m;j++)
} int
main()
for(
inti=1;i<=n;i++)
for(
intj=1;j<=m;j++)
cin>>w[i][j];
backtrack(1);
cout
);
return
0;
}
回溯法求解最小機器重量設計問題
題目 設某一機器由n個部件組成,部件編號為1n,每一種部件都可以從m個不同的 商處購得,商編號為1m。設wij是從 商j處購得的部件i的重量,cij是相應的 對於給定的機器部件重量和機器部件 計算總 不超過d的最小重量機器設計。注意 輸出結果中第一行最後沒有空格。比如下面的輸出樣例中1 3 1後面沒...
回溯法 求解最小機器重量問題 C 演算法
題目內容 設某一機器由n個部件組成,部件編號為1 n,每一種部件都可以從m個不同的 商處購得,商編號為1 m。設wij是從 商j處購得的部件i的重量,cij是相應的 對於給定的機器部件重量和機器部件 計算總 不超過d的最小重量機器設計。注意 輸出結果中第一行最後沒有空格。比如下面的輸出樣例中1 3 ...
最小重量機器設計問題 回溯法)
include include using namespace std define maxn 1000 int n 部件個數 int m 供貨商個數 int max c 最大 int w maxn maxn int c maxn maxn 費用 int cc 當前 int cw 當前重量 int ...