【问题标题】:C++ Part of brute-force knapsackC++ 部分蛮力背包
【发布时间】:2017-05-07 09:52:51
【问题描述】:

读者, 好吧,我想我只是有点脑子坏了。 我正在实施背包,我想我曾经实施过 1 或 2 次蛮力算法。所以我决定再做一个。 这就是我塞进去的东西。

让我们决定 W 是最大权重,而 w(min) 是最小权重元素,我们可以像 k=W/w(min) 次一样放入背包中。我之所以解释这一点,是因为你,读者,更清楚我为什么需要问我的问题。

现在。如果我们想象我们有 3 种类型的东西可以放在背包里,我们的背包可以存储大约 15 个单位的质量,让我们分别计算每个单位的重量作为它的数量。所以我们可以放 15 个第一种类型的东西,或者 7 个第二种类型的东西和 1 个第一种类型的东西。但是,22222221[7ed]12222222[7ed] 这样的组合对我们来说意味着相同。计算它们是浪费我们为决策支付的任何类型的资源。 (开个玩笑,因为如果我们有更便宜的算法,bf 就是浪费,但我很感兴趣)

我猜我们需要遍历所有可能组合的选择类型称为“重复组合”。 C'(n,k) 的数量计为 (n+k-1)!/(n-1)!k!。 (当我输入消息时,我发现我的理论有一个漏洞。我们可能需要添加一个空的、零权重零价格的项目来保留可用空间,它可能只是将 n 增加 1)

那么,怎么了。

https://rosettacode.org/wiki/Combinations_with_repetitions

因为这个问题在这里已经很好地描述了^我真的不想以这种方式使用堆栈,我想在单个周期中生成变化,这是 from i=0 to i<C'(n,k)

所以,如果我能做到,它是如何工作的? 我们有

int prices[n]; //appear mystically
int weights[n]; // same as previous and I guess we place (0,0) in both of them.
int W, k; // W initialized by our lord and savior
k = W/min(weights);

int road[k], finalroad[k]; //all 0
int curP = curW = maxP = maxW = 0;
for (int i = 0; i < rCombNumber(n, k); i ++) {
  /*guys please help me to know how to generate this mask which is consists of indices from 0 to n (meaning of each element) and k is size of mask.*/
  curW = 0;
  for (int j = 0; j < k; j ++)
    curW += weights[road[j]];
  if (curW < W) {
    curP = 0;
    for (int l = 0; l < k; l ++)
      curP += prices[road[l]];
    if (curP > maxP) {
      maxP = curP;
      maxW = curW;
      finalroad = road;
    }
  }
}

mask, road -- 是一个索引数组,每个索引可以等于 0 到 n;并且必须由每个选择中的 k 个元素从 { 0, 1, 2, ... , n } 生成为 C'(n,k) (上面有关它的链接)(结合顺序不重要的重复)

就是这样。证明我错了或帮助我。非常感谢提前_

是的,算法当然会花费很多时间,但看起来它应该可以工作。我对此很感兴趣。

更新:

我错过了什么?

http://pastexen.com/code.php?file=EMcn3F9ceC.txt

【问题讨论】:

  • 我不知道你在问什么
  • 我需要知道,如何在从零到 NumberOfrcomb(n,k) 的循环中一次生成 romb(n,k) 个元素。
  • 如果我们有 n = 4; (从 0 到 3 的元素)和 k = 3;如何在没有自称函数的情况下在单个周期中生成,组合如
  • 000 100 110 111、120 121 122 123 130 131 132 133 等等。
  • stackoverflow.com/questions/29669259/… 这个答案很接近,但我不明白他为什么需要排列和 2**n。

标签: c++ algorithm brute-force knapsack-problem imperative-programming


【解决方案1】:

答案是由 Minoru 提供的 https://gist.github.com/Minoru/745a7c19c7fa77702332cf4bd3f80f9e , 只增加第一个元素就足够了,然后我们计算所有进位,设置我们执行进位的位置并将计数重置值作为要重置和重置的元素的最大值。

这是我的代码:

#include <iostream>

using namespace std;
static long FactNaive(int n)
{
    long r = 1;
    for (int i = 2; i <= n; ++i)
        r *= i;
    return r;
}
static long long CrNK (long n, long k)
{
    long long u, l;
    u = FactNaive(n+k-1);
    l = FactNaive(k)*FactNaive(n-1);
    return u/l;
}

int main()
{
    int numberOFchoices=7,kountOfElementsInCombination=4;
    int arrayOfSingleCombination[kountOfElementsInCombination] = {0,0,0,0};
    int leftmostResetPos = kountOfElementsInCombination;
    int resetValue=1;

    for (long long iterationCounter = 0; iterationCounter<CrNK(numberOFchoices,kountOfElementsInCombination); iterationCounter++)
    {
        leftmostResetPos = kountOfElementsInCombination;

        if (iterationCounter!=0)
        {
            arrayOfSingleCombination[kountOfElementsInCombination-1]++;
            for (int anotherIterationCounter=kountOfElementsInCombination-1; anotherIterationCounter>0; anotherIterationCounter--)
            {
                if(arrayOfSingleCombination[anotherIterationCounter]==numberOFchoices)
                {
                    leftmostResetPos = anotherIterationCounter;
                    arrayOfSingleCombination[anotherIterationCounter-1]++;
                }
            }
        }

        if (leftmostResetPos != kountOfElementsInCombination)
        {
            resetValue = 1;

            for (int j = 0; j < leftmostResetPos; j++)
            {
                if (arrayOfSingleCombination[j] > resetValue)
                {
                    resetValue = arrayOfSingleCombination[j];
                }
            }

            for (int j = leftmostResetPos; j != kountOfElementsInCombination; j++)
            {
                arrayOfSingleCombination[j] = resetValue;
            }
        }

        for (int j = 0; j<kountOfElementsInCombination; j++)
        {
            cout<<arrayOfSingleCombination[j]<<" ";
        }
        cout<<"\n";

    }

    return 0;
}

非常感谢,稔

【讨论】:

    猜你喜欢
    • 2015-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多