使用背包变体的最佳 MLB 阵容
Optimal MLB lineup using Knapsack variant
我正在编写一个程序,以使用背包解决方案找到最佳的 MLB 阵容。为此,我传入了球员数据,其中包含球员计算出的价值和薪水。就背包问题而言,薪水将是我的"weight"。
我的问题不是能select球员,而是select最佳阵容。我要选择一个投手、一个中锋、一垒手、二垒手、三垒手、游击手和三名外野手。我可以成功地完成这一切。我希望我的"weight"是36000,但我目前只选择一个总共21000的阵容。
这是我的背包代码:
CalculateLineUp.prototype.findOptimalLineUp = function(data, capacity) {
var items = data.data;
var idxItem = 0,
idxCapSpace = 0,
idxPosition = 0,
oldMax = 0,
newMax = 0,
numItems = items.length,
weightMatrix = new Array(numItems+1),
keepMatrix = new Array(numItems+1),
positionArray = new Array("P", "C", "1B", "2B", "3B", "SS", "OF", "OF", "OF"),
solutionSet = [];
// Setup matrices
for(idxItem = 0; idxItem < numItems + 1; idxItem++){
weightMatrix[idxItem] = new Array(capacity+1);
keepMatrix[idxItem] = new Array(capacity+1);
}
// Build weightMatrix from [0][0] -> [numItems-1][capacity-1]
for (idxItem = 0; idxItem <= numItems; idxItem++){
for (idxCapSpace = 0; idxCapSpace <= capacity; idxCapSpace++){
// Fill top row and left column with zeros
if (idxItem === 0 || idxCapSpace === 0){
weightMatrix[idxItem][idxCapSpace] = 0;
}
// If item will fit, decide if there's greater value in keeping it,
// or leaving it
else if (items[idxItem-1]["Salary"] <= idxCapSpace){
newMax = items[idxItem-1]["Value"] + weightMatrix[idxItem-1][idxCapSpace-items[idxItem-1]["Salary"]];
oldMax = weightMatrix[idxItem-1][idxCapSpace];
// Update the matrices
if(newMax > oldMax ){
weightMatrix[idxItem][idxCapSpace] = newMax;
keepMatrix[idxItem][idxCapSpace] = 1;
}
else{
weightMatrix[idxItem][idxCapSpace] = oldMax;
keepMatrix[idxItem][idxCapSpace] = 0;
}
}
//Else, item can't fit; value and weight are the same as before
//else
//weightMatrix[idxItem][idxCapSpace] = weightMatrix[idxItem-1][idxCapSpace];
}
}
// Traverse through keepMatrix ([numItems][capacity] -> [1][?])
// to create solutionSet
idxCapSpace = capacity;
idxItem = numItems;
for(idxItem; idxItem < capacity; idxItem--){
if(keepMatrix[idxItem][idxCapSpace] === 1 && !this.filledAllPositions(items[idxItem - 1]["Position"])){
solutionSet.push(items[idxItem - 1]);
idxCapSpace = idxCapSpace - items[idxItem - 1]["Salary"];
}
}
return {"maxValue": weightMatrix[numItems][capacity], "set": solutionSet};
};
我是不是犯了一个我没有看到的明显错误,还是我的逻辑完全错误?
您检查的是解决方案集吗?接受位置的逻辑不包含在背包逻辑中,这意味着解决方案集是背包解决方案之上的过滤器。你确实得到了正确的背包解决方案,但是因为在解决方案之上,你正在检查位置是否已经被填满,一些项目从 solutionSet 中被删除(争夺相同位置的项目)和总重量减少。
我正在编写一个程序,以使用背包解决方案找到最佳的 MLB 阵容。为此,我传入了球员数据,其中包含球员计算出的价值和薪水。就背包问题而言,薪水将是我的"weight"。
我的问题不是能select球员,而是select最佳阵容。我要选择一个投手、一个中锋、一垒手、二垒手、三垒手、游击手和三名外野手。我可以成功地完成这一切。我希望我的"weight"是36000,但我目前只选择一个总共21000的阵容。
这是我的背包代码:
CalculateLineUp.prototype.findOptimalLineUp = function(data, capacity) {
var items = data.data;
var idxItem = 0,
idxCapSpace = 0,
idxPosition = 0,
oldMax = 0,
newMax = 0,
numItems = items.length,
weightMatrix = new Array(numItems+1),
keepMatrix = new Array(numItems+1),
positionArray = new Array("P", "C", "1B", "2B", "3B", "SS", "OF", "OF", "OF"),
solutionSet = [];
// Setup matrices
for(idxItem = 0; idxItem < numItems + 1; idxItem++){
weightMatrix[idxItem] = new Array(capacity+1);
keepMatrix[idxItem] = new Array(capacity+1);
}
// Build weightMatrix from [0][0] -> [numItems-1][capacity-1]
for (idxItem = 0; idxItem <= numItems; idxItem++){
for (idxCapSpace = 0; idxCapSpace <= capacity; idxCapSpace++){
// Fill top row and left column with zeros
if (idxItem === 0 || idxCapSpace === 0){
weightMatrix[idxItem][idxCapSpace] = 0;
}
// If item will fit, decide if there's greater value in keeping it,
// or leaving it
else if (items[idxItem-1]["Salary"] <= idxCapSpace){
newMax = items[idxItem-1]["Value"] + weightMatrix[idxItem-1][idxCapSpace-items[idxItem-1]["Salary"]];
oldMax = weightMatrix[idxItem-1][idxCapSpace];
// Update the matrices
if(newMax > oldMax ){
weightMatrix[idxItem][idxCapSpace] = newMax;
keepMatrix[idxItem][idxCapSpace] = 1;
}
else{
weightMatrix[idxItem][idxCapSpace] = oldMax;
keepMatrix[idxItem][idxCapSpace] = 0;
}
}
//Else, item can't fit; value and weight are the same as before
//else
//weightMatrix[idxItem][idxCapSpace] = weightMatrix[idxItem-1][idxCapSpace];
}
}
// Traverse through keepMatrix ([numItems][capacity] -> [1][?])
// to create solutionSet
idxCapSpace = capacity;
idxItem = numItems;
for(idxItem; idxItem < capacity; idxItem--){
if(keepMatrix[idxItem][idxCapSpace] === 1 && !this.filledAllPositions(items[idxItem - 1]["Position"])){
solutionSet.push(items[idxItem - 1]);
idxCapSpace = idxCapSpace - items[idxItem - 1]["Salary"];
}
}
return {"maxValue": weightMatrix[numItems][capacity], "set": solutionSet};
};
我是不是犯了一个我没有看到的明显错误,还是我的逻辑完全错误?
您检查的是解决方案集吗?接受位置的逻辑不包含在背包逻辑中,这意味着解决方案集是背包解决方案之上的过滤器。你确实得到了正确的背包解决方案,但是因为在解决方案之上,你正在检查位置是否已经被填满,一些项目从 solutionSet 中被删除(争夺相同位置的项目)和总重量减少。