这是一个比较简单的二进制程序。
我建议用蛮力修剪。如果您在任何时候超过了允许的重量,您不需要尝试其他项目的组合,您可以丢弃整棵树。
哦等等,你有负权重吗?始终包括所有负权重,然后按上述方法处理正权重。还是负重的物品也有负值?
包括所有具有正值的负重量项目。排除所有权重为正、值为负的项目。
对于具有负值的负重量物品,减去它们的重量(增加背包容量)并使用表示不拿走该物品的伪物品。伪项目将具有正的权重和价值。用蛮力进行修剪。
class Knapsack
{
double bestValue;
bool[] bestItems;
double[] itemValues;
double[] itemWeights;
double weightLimit;
void SolveRecursive( bool[] chosen, int depth, double currentWeight, double currentValue, double remainingValue )
{
if (currentWeight > weightLimit) return;
if (currentValue + remainingValue < bestValue) return;
if (depth == chosen.Length) {
bestValue = currentValue;
System.Array.Copy(chosen, bestItems, chosen.Length);
return;
}
remainingValue -= itemValues[depth];
chosen[depth] = false;
SolveRecursive(chosen, depth+1, currentWeight, currentValue, remainingValue);
chosen[depth] = true;
currentWeight += itemWeights[depth];
currentValue += itemValues[depth];
SolveRecursive(chosen, depth+1, currentWeight, currentValue, remainingValue);
}
public bool[] Solve()
{
var chosen = new bool[itemWeights.Length];
bestItems = new bool[itemWeights.Length];
bestValue = 0.0;
double totalValue = 0.0;
foreach (var v in itemValues) totalValue += v;
SolveRecursive(chosen, 0, 0.0, 0.0, totalValue);
return bestItems;
}
}