背包问题求解
(1)背包问题的描述:
已知有n种物品和一个可容纳M重量的背包,每种物品i的重量为w1。假定将物品 i 的一部分xi放入背包就会得到pixi的效益,这里0<=xi<=0,pi>0, 。显然,由于背包容量是M,因此,要求所有选中要装入背包的物品总重量不得超过M.。如果这n件物品的总重量不超过M,则把所有物品装入背包自然获得最大效益。现需解决的问题是,在这些物品重量的和大于M的情况下,该如何装包,使得得到更大的效益值。
(2)用贪心策略求解背包问题
首先需确定最优的量度标准。这里考虑三种策略:
策略1:按物品价值p降序装包,
策略2:按物品重w升序装包
策略3:按物品价值与重量比值w的降序装包
(3)分别以上面三种策略分别求以下情况背包问题的解.
n=7,M=15,
(p1,,,,)=(10,5,15,7,6,18,3)
(w1.......)=(2,3,5,7,1,4,1)。
以下代码中的findNext()中的第二个参数为策略编号。测试选用策略三,为了测试算法一次性写得,不是很规范。
<?php
class Stone{
public $p=0;
public $w=0;
public $jude=0;
public function __construct($p,$w){
$this->p=$p;
$this->w=$w;
$this->jude=$p/$w;
}
}
function compare($a,$b,$find){
switch($find){
case "max":
$res=($a>$b);break;
case "min":
$res=($a<$b);break;
default:
echo "invaild compare !";
}
return $res;
}
function findNext($stone,$strategy){
switch($strategy){
case 1:
$comp='p';$find='max';break;
case 2:
$comp='w';$find="min";break;
case 3:
$comp='jude';$find="max";break;
default:
echo "invaild stragey !";
}
$head=each($stone);
$index=$head['value'];
$rm=$head['key'];
foreach ($stone as $key=>$value){
$a= $value->$comp;
@$b=$index->$comp;
if(compare($a,$b,$find)){
$index=$value;
$rm=$key;
}
}
unset($stone[$rm]);
return $index;
}
$p=array(10,5,15,7,6,18,3);
$w=array(2,3,5,7,1,4,1);
$M=15;$W=0;
$sort=array();
$stone=array();
for($i=0;$i<count($p);$i++){
$a=$p[$i];
$b=$w[$i];
$stone[$i]=new Stone($a,$b);
}
while($W<$M){
$add=findNext(&$stone,3);
if($W+$add->w>=$M)break;
$sort[]=$add;
$W+=$add->w;
// echo $W;
}
var_dump($sort);
echo $W;