01背包问题分支限界java,算法(七)-01背包问题分支限界法-优先队列

问题描述:

算法思想:

代码实现:

/*

测试数据:

n = 5

packageWeight = 10

weight = {2,2,6,5,4}

value = {6,3,5,4,6}

*/

#include

#include

using namespace std;

class AnswerWay

{

public:

AnswerWay *parent;//指向父亲结点

bool way;//是左边进入还是右边进入

};

class Node

{

public:

//比较优先级

operator float () const

{

return priority;

}

float priority;//结点的优先级

int nowValue;//当前结点的价值

int nowWeight;//当前重量

int level;//当前的层数

AnswerWay *answer;//结点路径

};

class Package

{

public:

void getMaxValue();//获取最大值

private:

void addPriorityQueue(float, int, int, int, bool);//加入优先队列

float bound(int);//求出价值上界

int maxValue();//背包的可容纳最大价值

void sort();//对物品单位价值进行排序

void init();//对package的各个属性进行初始化

void destructor();//清理new产生的空间

void getError()//测试错误,可删除

{

for(int i = 0; i <= n; i++)

cout<

}

private:

int packageWeight;//背包的重量

int n;//物品的总数

int* weight;//每个物品的重量

int* value;//每个物品的价值

int nowWeight;//背包的当前重量

int nowValue;//背包的当前价值

int level;//当前层次

priority_queue prQueue;//优先队列

AnswerWay *answer;//结点路径

bool* bestWay;//最优解

};

/*清除new产生的空间*/

void Package::destructor()

{

delete[] weight;

delete[] value;

delete[] bestWay;

}

//对外函数,获取到背包的最优值

void Package::getMaxValue()

{

init();

sort();

//获取最优值

cout<

//获取最优解

cout<

for(int i = 1; i <= n; i++)

if(bestWay[i])

cout<

destructor();

}

/*计算背包的最优值*/

int Package::maxValue()

{

/*不需要定义书中wt变量*/

int bestValue = 0;//当前最优值

float priority = bound(1);//价值上界,也就是将要加入优先队列中的优先级

Node node = Node();//结点应放在外面定义

while(level != (n+1))

{

if((nowWeight+weight[level]) <= packageWeight)

{

if((nowValue+value[level]) > bestValue)

bestValue = nowValue + value[level];

//左儿子的价值上界是包括了该结点的

addPriorityQueue(priority, nowValue+value[level], nowWeight+weight[level], level+1, true);

}

//level+1是因为这一层的物品没有放进背包,对右儿子来说,剩余价值就是从level+1开始

priority = bound(level+1);

if(priority >= bestValue)

addPriorityQueue(priority, nowValue, nowWeight, level+1, false);

/*从优先队列中获取到优先级最高的元素*/

node = prQueue.top();

prQueue.pop();

/*更新当前各个属性值*/

nowWeight = node.nowWeight;

nowValue = node.nowValue;

priority = node.priority;

answer = node.answer;

level = node.level;

}

for(int i = n; i > 0; i--)

{

bestWay[i] = answer->way;

answer = answer->parent;

}

return bestValue;

}

/*对物品单位价值进行排序*/

void Package::sort()

{

float tempUnitValue;//临时单位价值

int tempValue;//临时价值

int tempWeight;//临时重量

float *unitValue = new float[n+1];//物品的单位价值

unitValue[0] = 0;

for(int i = 1; i <= n; i++)

unitValue[i] = float(value[i])/float(weight[i]);

for(int i = 1; i <= n; i++)

{

for(int j = i; j <= n; j++)

{

if(unitValue[i] < unitValue[j])

{

tempUnitValue = unitValue[i];

unitValue[i] = unitValue[j];

unitValue[j] = tempUnitValue;

tempValue = value[i];

value[i] = value[j];

value[j] = tempValue;

tempWeight = weight[i];

weight[i] = weight[j];

weight[j] = tempWeight;

}

}

}

delete[] unitValue;

}

/*对package的各个属性进行初始化*/

void Package::init()

{

cout<

cin>>packageWeight;

cout<

cin>>n;

weight = new int[n+1];

weight[0] = 0;

cout<

for(int i = 1; i <= n; i++)

cin>>weight[i];

value = new int[n+1];

value[0] = 0;

cout<

for(int i = 1; i <= n; i++)

cin>>value[i];

nowValue = 0;

nowWeight = 0;

level = 1;

answer = 0;

bestWay = new bool[n+1];

for(int i = 0; i <= n; i++)

bestWay[i] = false;

}

/*加入优先队列,参数priority,nowValue,nowWeight,level不同于Package类中的属性*/

void Package::addPriorityQueue(float priority, int nowValue, int nowWeight, int level, bool ch)

{

AnswerWay *answerTemp = new AnswerWay;

answerTemp->parent = answer;

answerTemp->way = ch;

Node node = Node();

node.priority = priority;

node.nowValue = nowValue;

node.nowWeight = nowWeight;

node.level = level;

node.answer = answerTemp;

prQueue.push(node);

}

/*求价值上界(从根节点的价值到当前结点的价值再加上剩余价值)函数,必须先对物品的单位价值从大到小排序*/

float Package::bound(int tempLevel)

{

int leftPackageWeight = packageWeight - nowWeight;

float priority = nowValue;

while(tempLevel <= n && weight[tempLevel] <= leftPackageWeight)

{

leftPackageWeight -= weight[tempLevel];

priority += value[tempLevel];

tempLevel++;

}

if(tempLevel <= n)

priority += (value[tempLevel]*0.1)/(weight[tempLevel]*0.1)*leftPackageWeight;

return priority;

}

int main()

{

Package package = Package();

package.getMaxValue();

system("pause");

return 0;

}

喜欢 (9)or分享 (0)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值