1. 程式人生 > 其它 >第五章演算法實踐

第五章演算法實踐

1. 請用回溯法的方法分析“最小重量機器設計問題”

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int n,m,d;
int bestw=10000000;
//重量
int w_arr[100][100];
//花費
int c_arr[100][100];
//當前重量
int cw=0;
//當前價格
int cc=0;

//當前選了哪家的
int flag[100];
//最後的最優方案
int flag2[100];
void find_best(int i)
{
if(i>n)
{
//碰見最優值就更新
if(cw<bestw)
{
for(int k=1;k<=m;k++)
{
//把最優值的標識陣列更新
flag2[k]=flag[k];
}
bestw=cw;
}
return;
}

for(int j=1; j<=m; j++)
{
flag[i]=j;
cw+=w_arr[i][j];
cc+=c_arr[i][j];
if(cw<bestw && cc<=d)
{
find_best(i+1);
}
//恢復初值
cw-=w_arr[i][j];
cc-=c_arr[i][j];
flag[i]=0;


}
}
int main()
{
//初始化
memset(flag,-1,sizeof(flag));
memset(flag2,-1,sizeof(flag2));
//輸入
cin>>n>>m>>d;
for(int i=1; i<=n; i++) //部件號
{
for(int j=1; j<=m; j++) //商家號
{
cin>>c_arr[i][j];//從j商家買的i部件花費
}
}
for(int i=1; i<=n; i++) //部件號
{
for(int j=1; j<=m; j++) //商家號
{
cin>>w_arr[i][j];//從j商家買的i部件重量
}
}
find_best(1);
//輸出
cout<<bestw<<endl;
for(int i=1;i<=n;i++)
{
cout<<flag2[i]<<" ";
}
return 0;
}

1.2 說明 “最小重量機器設計問題"的解空間樹

1.3 在遍歷解空間樹的過程中,每個結點的狀態值是什麼

當前的重量:用於記錄前t個部件選擇供應商後的部件總重量

當前價值:為了滿足價值不超過d的條件要進行當前前t個部件的總價值

2. 你對回溯演算法的理解

首先初始化當前價格cc=0,當前重量cw=0,此外,還要設定一個變數c_arr表示選擇機器的總重量,初始化其為每個部件從1號供應商購買的重量。在迴圈選擇i號機器時,判斷從j號供應商購買機器後的價格是否大於bestw,不大於則選擇,否則不選,繼續選擇下一供應商進行判斷。在得到一個合適的供應商後,繼續選擇下一機器的供應商,從第一個選到最後一個供應商。當所有機器選擇結束後,判斷得到的總重量是否比之前的c_arr小,如果小就賦給c_arr,然後從這一步開始,回溯到上一機器,選擇下一合適供應商,繼續搜尋可行解,直到將整個排列樹搜尋完畢。這樣,最終得到的c_arr即為最優解。