#include<bits/stdc++.h>
using namespace std;
int part_n;//需要零件的个数
int service_m;//每个人零件服务商的个数
int max_value;//最大价值
double **value_information;//价值表
double *least_value;//每个零件的最小价值
double **weight_information;//重量表
double *least_weight;//最小重量表
vector<int> Best_solution;//最优解
double Best_weight = 1000000;//最优重量
double Best_value;//最优价值
class Node{//结构体
public:
double _weight;//该节点的重量
double _value;//该节点的价值
int _t;//该节点的层数
vector<int> _solution;//当前解
double _best_value;//能得到的最小价值
double _best_weight;//能得到的最小重量
bool operator < (const Node &n) const//重构类的符号
{
return _best_weight > n._best_weight;
}
void Init_Node(Node node, int n)//由父节点类初始化
{
_solution = node._solution;
_t = node._t + 1;
_solution[_t] = n;
_weight = node._weight + weight_information[_t][n];
_best_weight = _weight;
_value = node._weight + value_information[_t][n];
_best_value = _value;
for(int i = _t + 1; i < part_n; i++)
{
_best_weight += least_weight[i];
_best_value += least_value[i];
}
}
bool Judge()//剪枝函数
{
return ((_best_weight < Best_weight) && (_best_value <= max_value));
}
};
priority_queue<Node> Queue;//活化队列
bool Branch_limiting_method()//分支限界法
{
while(!Queue.empty())
{
Node *node;
if(Queue.top()._t == part_n - 1)//叶节点直接结束
{
Best_weight = Queue.top()._best_weight;
Best_solution = Queue.top()._solution;
Best_value = Queue.top()._value;
return false;
}
for(int i = 0; i < service_m; i++)//扩展子节点
{
node = new Node;
node->Init_Node(Queue.top(), i);
if(node->Judge())//如果不满足剪枝函数
Queue.push(*node);
else
delete node;
}
Queue.pop();
}
return false;
}
int main()
{ //初始化
cin >> part_n >> service_m >> max_value;
value_information = new double*[part_n];
weight_information = new double*[part_n];
least_value = new double[part_n];
least_weight = new double[part_n];
for(int i = 0; i < part_n; i++)
{
double min_value = 100000;
value_information[i] = new double[service_m];
for(int j = 0; j < service_m; j++)
{
cin >> value_information[i][j];
if(min_value > value_information[i][j])
min_value = value_information[i][j];
}
least_value[i] = min_value;//获取最小价值零件
}
for(int i = 0; i < part_n; i++)
{
double min_weight = 100000;
weight_information[i] = new double[service_m];
for(int j = 0; j < service_m; j++)
{
cin >> weight_information[i][j];
if(min_weight > weight_information[i][j])
min_weight = weight_information[i][j];
}
least_weight[i] = min_weight;//获取最小重量零件
}
//
Node node;
for(int i = 0; i < part_n; i++)
node._solution.push_back(i);
node._t = -1;
node._weight = 0;
node._value = 0;
Queue.push(node);
if(Branch_limiting_method())
{
cout << "没有解" << endl;
return 0;
}
cout << "Best_weight: " << Best_weight << " Best_value : " << Best_value << endl<<"零件选择: ";
for(int i = 0; i < part_n; i++)
cout << " " << Best_solution[i] + 1;
}
//输入样例:
/*
3 3 4
1 2 3
3 2 1
2 2 2
1 2 3
3 2 1
2 2 2
*/
最小重量零件问题----分支限界法
最新推荐文章于 2023-01-06 12:22:17 发布