【发布时间】:2015-11-03 10:59:12
【问题描述】:
显然不能将其称为 Stack Overflow 上的问题,但是我目前正在尝试了解如何在背包问题中以项目组的形式集成约束。在这种情况下,我的数学技能被证明是相当有限的,但是我非常积极地既要按预期进行这项工作,又要弄清楚每个方面的作用(按此顺序,因为事情在工作时更有意义)。
话虽如此,我在Rosetta Code 找到了一个绝对漂亮的实现,并清理了一些变量名,以帮助自己从一个非常基本的角度更好地理解这一点。
不幸的是,我很难弄清楚如何应用此逻辑来包含项目组。我的目的是建立梦幻球队,为每个球员提供我自己的价值和体重(积分/薪水),但没有团队(在我的情况下是职位)我无法这样做。
谁能指出我正确的方向?我正在审查其他语言的代码示例以及对整个问题的其他描述,但是我希望通过任何可能的方式来实现这些组。
<?php
function knapSolveFast2($itemWeight, $itemValue, $i, $availWeight, &$memoItems, &$pickedItems)
{
global $numcalls;
$numcalls++;
// Return memo if we have one
if (isset($memoItems[$i][$availWeight]))
{
return array( $memoItems[$i][$availWeight], $memoItems['picked'][$i][$availWeight] );
}
else
{
// At end of decision branch
if ($i == 0)
{
if ($itemWeight[$i] <= $availWeight)
{ // Will this item fit?
$memoItems[$i][$availWeight] = $itemValue[$i]; // Memo this item
$memoItems['picked'][$i][$availWeight] = array($i); // and the picked item
return array($itemValue[$i],array($i)); // Return the value of this item and add it to the picked list
}
else
{
// Won't fit
$memoItems[$i][$availWeight] = 0; // Memo zero
$memoItems['picked'][$i][$availWeight] = array(); // and a blank array entry...
return array(0,array()); // Return nothing
}
}
// Not at end of decision branch..
// Get the result of the next branch (without this one)
list ($without_i,$without_PI) = knapSolveFast2($itemWeight, $itemValue, $i-1, $availWeight,$memoItems,$pickedItems);
if ($itemWeight[$i] > $availWeight)
{ // Does it return too many?
$memoItems[$i][$availWeight] = $without_i; // Memo without including this one
$memoItems['picked'][$i][$availWeight] = array(); // and a blank array entry...
return array($without_i,array()); // and return it
}
else
{
// Get the result of the next branch (WITH this one picked, so available weight is reduced)
list ($with_i,$with_PI) = knapSolveFast2($itemWeight, $itemValue, ($i-1), ($availWeight - $itemWeight[$i]),$memoItems,$pickedItems);
$with_i += $itemValue[$i]; // ..and add the value of this one..
// Get the greater of WITH or WITHOUT
if ($with_i > $without_i)
{
$res = $with_i;
$picked = $with_PI;
array_push($picked,$i);
}
else
{
$res = $without_i;
$picked = $without_PI;
}
$memoItems[$i][$availWeight] = $res; // Store it in the memo
$memoItems['picked'][$i][$availWeight] = $picked; // and store the picked item
return array ($res,$picked); // and then return it
}
}
}
$items = array("map","compass","water","sandwich","glucose","tin","banana","apple","cheese","beer","suntan cream","camera","t-shirt","trousers","umbrella","waterproof trousers","waterproof overclothes","note-case","sunglasses","towel","socks","book");
$weight = array(9,13,153,50,15,68,27,39,23,52,11,32,24,48,73,42,43,22,7,18,4,30);
$value = array(150,35,200,160,60,45,60,40,30,10,70,30,15,10,40,70,75,80,20,12,50,10);
## Initialize
$numcalls = 0;
$memoItems = array();
$selectedItems = array();
## Solve
list ($m4, $selectedItems) = knapSolveFast2($weight, $value, sizeof($value)-1, 400, $memoItems, $selectedItems);
# Display Result
echo "<b>Items:</b><br>" . join(", ", $items) . "<br>";
echo "<b>Max Value Found:</b><br>$m4 (in $numcalls calls)<br>";
echo "<b>Array Indices:</b><br>". join(",", $selectedItems) . "<br>";
echo "<b>Chosen Items:</b><br>";
echo "<table border cellspacing=0>";
echo "<tr><td>Item</td><td>Value</td><td>Weight</td></tr>";
$totalValue = 0;
$totalWeight = 0;
foreach($selectedItems as $key)
{
$totalValue += $value[$key];
$totalWeight += $weight[$key];
echo "<tr><td>" . $items[$key] . "</td><td>" . $value[$key] . "</td><td>".$weight[$key] . "</td></tr>";
}
echo "<tr><td align=right><b>Totals</b></td><td>$totalValue</td><td>$totalWeight</td></tr>";
echo "</table><hr>";
?>
【问题讨论】:
-
你能清楚地定义问题和期望的最终结果吗?这将有助于及时理解代码,而不是手动弄清楚。
-
如果你为一个问题设置了赏金,你真的应该尝试更加活跃。
-
您是否尝试使用来自 [this] (stackoverflow.com/questions/29729609/…) 帖子的信息?
-
期望的最终结果是基本上让项目属于组和每个组的多个点。这被用于确定最佳梦幻足球阵容,在我的情况下,将有一个 QB、2 RB、3 WR、1 TE、1 DEFENSE。每个项目(玩家)都有一个位置,并且需要适合该位置。
-
补充一点信息,在这种特殊情况下,每个“项目”基本上都是球员,权重是他们的薪水,价值是他们得分。上面的脚本工作得很好,只是我需要弄清楚如何将玩家分成几组。没有那个,我最终可能会得到 5 个 QB 球员,其中只允许 1 个。
标签: php html algorithm math knapsack-problem