【问题标题】:Need help in finalizing this Best Fit Algorithm在最终确定此最佳拟合算法时需要帮助
【发布时间】:2017-04-26 21:58:34
【问题描述】:

对不起,问个简单的问题:

我正在使用以下例程来查找整数的所有组合,它们的总和等于或小于某个整数 K。

假设我有一个容量为 K 的玻璃杯和一些啤酒瓶。我想知道我可以挑选哪些瓶子,并尽可能多地喝啤酒!

let K = 4; // my glass
let Input = [1, 2, 0.5, 1.5, 2, 0.75, 3, 4]; // beer bottles
let allCombinations = [];

for(var i = 0; i < Input.length; i++)
{
    let currentCombination = [];

    if(Input[i] <= K)
        currentCombination.push(Input[i]);

    let difference = K - Input[i];

    for(var j = i + 1; j < Input.length; j++)
    {
        if(Input[j] <= difference)
        {
            currentCombination.push(Input[j]);
            difference -= Input[j];
        }
    }
    allCombinations.push(currentCombination);
}

输入:

K = 4

[1, 2, 0.5, 1.5, 2, 0.75, 3, 4]

电流输出:

[1, 2, 0.5]

[2, 0.5, 1.5]

[0.5, 1.5, 2]

[1.5, 2]

[2, 0.75]

[0.75, 3]

[3]

[4]

但我想要更多的啤酒选择!某些组合不包括在内:

预期输出:

以上所有,加上:

[1, 2, 1.5]

[1, 2, 0.75]

[2, 0.5, 0.75]

[2, 2]

[1, 3]

等等..

【问题讨论】:

  • 仅供参考,这听起来像是背包问题:en.wikipedia.org/wiki/Knapsack_problem 我想如果不需要最大化啤酒量,并且只想列举所有可能性,它会更简单。那么这是一个简单的 n^2 搜索,不是吗?从一种啤酒开始,尝试添加其他不会溢出的啤酒,然后重复。
  • ^ 超级!谢谢!稍后我将为每个输入项添加“权重”值。背包问题会返回所有组合,而不仅仅是最好的组合吗?
  • 背包问题的问题是没有没有快速解决方案。它是NP完全的。无论您是找到最好的一个或所有这些都无关紧要 - 解决它的唯一方法是迭代所有解决方案。当我说“n^2”时我错了。这是n! (n 阶乘)我相信。

标签: javascript algorithm


【解决方案1】:

我的猜测是这是次优的,但您可以使用递归算法来生成所有可能的排列,检查每个排列以确定它是否是唯一的组合,并将唯一的解决方案添加到解决方案列表中:

  combinations = [];
  function getCombinationsLessThan(currentCombination, choices, remainingSum) {

    // Check if currentCombination should be added to the solutions list
    if (remainingSum < 0) {
      return      // Sum is too large; terminate recursion
    } else if (currentCombination.length > 0) {

      currentCombination.sort();    // Sort all combinations so comparison can be made sequentially
      var uniquePermutation = true;

      for (var i=0; i<combinations.length; i++) {

        if (currentCombination.length == combinations[i].length) {

          for (var j=0; currentCombination[j]==combinations[i][j] && j<combinations[i].length; j++);  // Pass

          if (j == currentCombination.length) {
            // For loop got all the way through combinations[i], so currentCombination = combinations[i]
            uniquePermutation = false;
            break;
          }

        }
      }

      if (uniquePermutation) {
        combinations.push(currentCombination);
      }

    }

    for (var i=0; i<choices.length; i++) {

      // Copy choices
      var newChoices = choices.slice();           

      // Cut out the i'th element and add to the current combination
      var newCombination = currentCombination.concat(newChoices.splice(i,1));

      var newRemainingSum = remainingSum - choices[i];
      getCombinationsLessThan(newCombination, newChoices, newRemainingSum);
    
    }
  }

  var k = 4;
  var choices = [1, 2, 0.5, 1.5, 2, 0.75, 3, 4];
  getCombinationsLessThan([], choices, k);
  
  var result = '';
  for (var i=0; i<combinations.length; i++) {
    result += combinations[i] + '\n';
  }
  console.log(result);

这会产生以下结果:

1
1,2
0.5,1,2
0.75,1,2
0.5,1
0.5,1,1.5
0.5,0.75,1,1.5
0.5,0.75,1
1,1.5
0.75,1,1.5
0.75,1
1,3
2
0.5,2
0.5,1.5,2
0.5,0.75,2
1.5,2
2,2
0.75,2
0.5
0.5,1.5
0.5,0.75,1.5
0.5,0.75
0.5,3
1.5
0.75,1.5
0.75
0.75,3
3
4

【讨论】:

  • ciq,你需要。请给我一分钟?
【解决方案2】:

我同意。这听起来确实像背包问题:确定在背包中排除或包含物品是否会导致不超过容器容量的更高值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-07
    • 2013-07-24
    • 1970-01-01
    • 1970-01-01
    • 2012-04-29
    相关资源
    最近更新 更多