【问题标题】:0-1 Knapsack - Dynamic TopDown-Recursive Approach in C#0-1 背包 - C# 中的动态自上而下递归方法
【发布时间】:2018-07-11 22:10:20
【问题描述】:

您好,我正在尝试解决经典的背包问题,但到目前为止,我只设法实现了从我的角度来看可行并产生正确结果的朴素递归:

    static int[] objValue;
    static int[] objWeight;

    static void Main(string[] args)
    {
        objValue = new int[] { 0, 11, 8, 4, 12, 4, 6, 9, 10 };
        objWeight = new int[] { 0, 4, 2, 2, 5, 6, 3, 5, 7 };
        int objNumber = objWert.Count() - 1;
        int maxWeight = 12;
        Console.WriteLine(Knapsack(objNumber, maxWeight));
        Console.ReadLine();

    }
    public static int Knapsack(int i, int w)
    {
        if (i == 0 || w==0)
        {
            return 0;
        }

        if(objWeight[i] > w)
        {
            return Knapsack(i - 1, w);
        }
        else
        {
            int case1 = Knapsack(i - 1, w);
            int case2 = objValue[i]+Knapsack(i - 1, w - 
            objWeight[i]);
            return Math.Max(case1,case2);
        }
    } 

到目前为止,这几乎就是基本算法本身,即使我有时会对索引感到困惑。它有效....但现在我的动态方法:

    static int objNumber;
    static int maxWeight;
    static int[] objValue;
    static int[] objWeight;
    static int[,] costTable;

    static void Main(string[] args)
    {
        objValue = new int[] { 0, 10, 5, 7, 12, 8, 6};
        objWeight = new int[] { 0, 6, 1, 2, 5, 4, 3};

        objNumber = objValue.Count()-1;
        maxWeight = 10;

        costTable = new int[objNumber+1, maxWeight+1];
        for (int i = 0; i <= objNumber; i++)
        {
            for (int w = 0; w <= maxWeight; w++)
            {
                if(i==0||w==0)
                { costTable[i, w] = 0; }
                else
                costTabelle[i, w] = -1;
            }
        }

        int result = Knapsack(objNumber, maxWeight);
        Console.WriteLine(result);
        Console.ReadLine();

    }
    public static int Knapsack(int i, int w)
    {
        if (costTable[i, w] != -1)
        {
            return costTable[i, w];
        }

        if (i<=0||w<=0)
        {
            return 0;
        }

        if(objWeight[i] > w)
        {
            costTable[i,w]=Knapsack(i - 1, w);
            return costTable[i, w];
        }
        else
        {
            int case1 = Knapsack(i - 1, w);
            int case2 = objValue[i]+Knapsack(i - 1, w - 
            objWeight[i]);
            costTable[i,w]= Math.Max(case1,case2);
            return costTable[i, w];


        }

    }

如您所见,我只添加了一点代码来保存所有对应的节点/可能性。但是,我似乎在某处犯了错误,可能是返回函数或索引之一,因为我的 costTable 看起来像这样:

就我理解的算法而言,表中不应该有任何-1。我希望你能给我一些见解,从 12 小时开始研究这个问题,但找不到错误!

【问题讨论】:

    标签: c# recursion dynamic-programming knapsack-problem


    【解决方案1】:

    据我了解,完全没有错误。显然,在您的实现中,状态表中 -1 的初始值表示负无穷大的值(这很有效,因为输入中的所有值都是非负的,并且递归关系使用值的最大化)。这些值保留在表中,其中没有在递归中检查状态,可能是这种情况。

    话虽如此,您使用的实现不是真的 dynamic programming 而是memoization,因为您使用递归实现并通过将已知状态值存储在查找表中来限制其运行时间。但是,在技术上很难在这些概念之间划清界限。

    【讨论】:

      猜你喜欢
      • 2021-11-10
      • 2019-08-28
      • 1970-01-01
      • 1970-01-01
      • 2011-12-28
      • 1970-01-01
      • 1970-01-01
      • 2016-06-27
      • 1970-01-01
      相关资源
      最近更新 更多