最小重量零件问题----分支限界法

#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
 */
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值