8516830 发表于 2017-3-28 14:13:10

背包问题的PHP算法

引用

<?php
// http://tieba.baidu.com/f?kz=283979751
/*
设有n 种物品,每种物品有一个重量及一个价值。但每种物品的数量是无限的,同时有一个背包,最大载重量为M,今从n 种物品中选取若干件(同一种物品可以多次选取),使其重量的和小于等于M,而价值的和为最大。
Input
第一行:两个整数,M(背包容量,M<= 200)和N(物品数量,N<= 30); 第2..N+1 行:每行二个整数Wi,Ui,表示每个物品的重量和价值。
Output
仅一行,一个数,表示最大总价值。
Sample Input
12 4
21
33
45
79
Sample Output
15
*/
set_time_limit(30);
define(’NOWTIME’,time());
function microtime_float()
{
    list($usec, $sec) = explode(” “, microtime());
$sec=$sec-NOWTIME;
    return ((float)$usec + (float)$sec);
}
//初始化数组
/*
$bbw=12;
$arywp=array();
$arywp[]=array(’d',2,1);
$arywp[]=array(’c',3,3);
$arywp[]=array(’b',4,5);
$arywp[]=array(’a',7,9);
*/
$time_start = microtime_float();
//开始计算
$wpnum=count($arywp);
$wpnum=20; //允许的物品类型数量
$bbw=rand(5*$wpnum,50*$wpnum); //背包允许最大重量
for($i1=0;$i1<$wpnum;$i1++){ //初始化每个物品类型的重量和价值
$arywp[$i1]=”w”.$i1; //名称
$arywp[$i1]=rand(50,80); //重量
$arywp[$i1]=rand(20,50); //价值
$arywp[$i1]=$arywp[$i1]/$arywp[$i1];//单位重量的最大价值
}
function cmp($a, $b){
$returnvalue=0;
    if ($a == $b) {
$returnvalue=0;
    } else {
   $returnvalue = ($a > $b) ? -1 : 1;
}
return $returnvalue;
}
//按单位最大价值排序
usort($arywp, “cmp”);
print_r($arywp);
echo ” <br />\n”;
//递归函数,计算剩余空间的允许物品最大价值
function getmaxval($bbw,$arywp){
//最大单位物品的重量、价值、数量
$use_w=0;
$use_v=0;
$ary_userwp=array();
//当前空间的允许物品最大价值
$maxwgt=0;
$maxval=0;
$maxuserwp=array();

$wp = array_shift($arywp);
$num= floor(($bbw-$use_w)/$wp); //最大单位物品的最大允许个数
//echo ” countmax : $num * “.$wp.”<br/>\n”;
if(count($arywp)==0 || $bbw-$use_w==$wp*$num){ //没有剩余物品或刚好填满 //递归结束条件
if($num>0){
   $maxwgt+=$wp*$num;
   $maxval+=$wp*$num;
   $maxuserwp[$wp]=$num;
}
} else {
for($i=0;$i<=$num;$i++){ //计算最大单位物品不同数量时的最大价值
   $use_w=$wp*$i;
   $use_v=$wp*$i;
   $ary_userwp[$wp]=$i;
   if(($num-$i)*$wp/($bbw-$use_w) < $arywp){ //剩余空间的单位价值小于下件物品的单位价值
    list($subuse_w,$subuse_v,$subusewp)=getmaxval($bbw-$use_w,$arywp);
   } else {
    $subuse_w=0;
    $subuse_v=0;
    $subusewp=array();
   }
   if($use_v+$subuse_v>$maxval || $maxval==0){ //比较最大价值
    $maxwgt=$use_w+$subuse_w;
    $maxval=$use_v+$subuse_v;
    if($i>0){
   $maxuserwp=array_merge($ary_userwp,$subusewp);
    } else{
   $maxuserwp=$subusewp;
    }
   }
}
//print_r($maxuserwp);
//echo ” maxwgt : $maxwgtmaxval : $maxval<br/>\n”;
}
//返回 使用的重量,最大价值、使用的物品数量数组
return array($maxwgt,$maxval, $maxuserwp);
}
//开始计算
$arysulte= getmaxval($bbw,$arywp);
//输出结果
echo ” bbw “.$bbw.” “;
print_r($arysulte);
$time_end = microtime_float();
$runtime = $time_end – $time_start;
echo ” runtime : “.$runtime;
?>

原文链接http://www.bao00long.cn/2009/package.html
页: [1]
查看完整版本: 背包问题的PHP算法