采用回溯法,把解空间的组织结构组织成三叉树,三叉树的第0层代表刚开始时还没选部件的状态,第1层代表选好了第1个零件,第2层代表选好了前2个部件,第3层代表选好了3个部件。首先对每一种部件按照重量从小到大排序,然后深度优先搜索这个三叉树。约束条件为加上这个部件后的价格不超过cost,限界条件为加上这个部件后依然有希望取得比目前已找到的最优方案更小的重量。只有同时满足这两个条件才往下搜索这个子树,否则搜索另一棵子树。当搜索到叶子节点时说明找到了目前的最佳方案。
#include <iostream>
using namespace std;
struct Weight_cost
{
int weight;
int cost;
int provider;
};
int best_weight = 999, current_cost = 0, current_weight = 0;
void sort_by_weight(Weight_cost**& w_c_p, int n, int m) //对数组w_c_p的每一行按照重量排列
{
int min;
Weight_cost tmp;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m - 1; j++)
{
min = j;
for (int k = j + 1; k < m; k++)
{
if (w_c_p[i][k].weight < w_c_p[i][min].weight)
{
min = k;
}
}
tmp = w_c_p[i][j];
w_c_p[i][j] = w_c_p[i][min];
w_c_p[i][min] = tmp;
}
}
}
int bound(int i, Weight_cost** &w_c_p, int current_weight, int n) //界限函数
{
int remain_weight = 0;
for (; i < n; i++)
{
remain_weight += w_c_p[i][0].weight;
}
return current_weight + remain_weight;
}
// 回溯
void traceback(int t, Weight_cost**& w_c_p, int n, int m, int current_choose[], int best_result[], int cost)
{
if (t == n) // 当到叶子节点的时候,找到目前为止的最佳方案
{
for (int i = 0; i < n; i++)
{
best_result[i] = current_choose[i]; //保存目前的最佳选择
}
best_weight = current_weight; //保存目前的最佳重量
return;
}
for (int i = 0; i < m; i++)
{
//只有同时满足约束条件和限界条件才往下搜索
if ((current_cost + w_c_p[t][i].cost <= cost) && (bound(t + 1, w_c_p, current_weight + w_c_p[t][i].weight, n) < best_weight))
{
current_cost += w_c_p[t][i].cost;
current_weight += w_c_p[t][i].weight;
current_choose[t] = w_c_p[t][i].provider;
traceback(t + 1, w_c_p, n, m, current_choose, best_result, cost); //深度优先搜索第t+1层及往后结点
current_cost -= w_c_p[t][i].cost;
current_weight -= w_c_p[t][i].weight;
current_choose[t] = 0;
}
}
}
int main(void)
{
int n, m, cost;
cin >> n >> m >> cost;
Weight_cost** w_c_p = new Weight_cost * [n]; //创建n行m列数组
int* current_choose = new int[n];
int* best_result = new int[n];
for (int i = 0; i < n; i++)
{
current_choose[i] = 0;
best_result[i] = 0;
}
for (int i = 0; i < n; i++)
{
w_c_p[i] = new Weight_cost[m];
}
for (int i = 0; i < n; i++) //输入重量
{
for (int j = 0; j < m; j++)
{
cin >> w_c_p[i][j].weight;
}
}
for (int i = 0; i < n; i++) //输入价格
{
for (int j = 0; j < m; j++)
{
cin >> w_c_p[i][j].cost;
w_c_p[i][j].provider = j + 1;
}
}
cout << endl;
sort_by_weight(w_c_p, n, m);
traceback(0, w_c_p, n, m, current_choose, best_result, cost);
cout << best_weight << endl;
for (int i = 0; i < n; i++)
cout << best_result[i] << ' ';
cout << endl;
return 0;
}
运行结果: