簡體   English   中英

遞歸背包

[英]Recursive Knapsack

我正在嘗試實現遞歸背包,我使用通用算法將其編寫如下:

int pack(int n, int s) {
    if (n < 0)
        return 0;
    if (List[n].s > s)
        return pack(n-1, s);
    else {
        int max =  Math.max(pack(n-1,s), pack(n-1, s -List[n].s) + List[n].v);
        return max;
    }
}

無論如何,我能知道包裝了哪些物品嗎?

更新:我只想要屬於最佳選擇的項目,並且我不想更改函數頭。

編輯使用數組來跟蹤項目,這是怎么回事?

int pack(int n , int s)
{
     if(n < 0)
     {
         counter =0;
         return 0;
     }
     if (itemsList[n].s > s)
     {
        return pack(n-1, s);
     }
     else
     {
         int max1 = pack(n-1,s);
         int max2 = pack(n-1, s - itemsList[n].s) + itemsList[n].v ;

        if(max2 > max1)
        {
            flag1[counter] = new item();
            flag1[counter] = itemsList[n];
            counter ++;
        }
         return max(max1, max2);
     }         
}

像這樣嗎?

int pack(int n, int s) {
    if (n < 0)
        return 0;
    if (List[n].s > s)
        return pack(n-1, s);
    else {
        int without = pack(n-1,s);
        int with = pack(n-1, s-List[n].s) + List[n].v;
        if (with >= without) {
            System.out.println(n);                
        }
        return Math.max(with, without);
    }
}

或者,您可以返回結果列表:

int pack(int n, int s) {
    return reallyPack(n, s, new ArrayList<Item>());
}

int reallyPack(int n, int s, List<Item> l) {
    if (n < 0)
        return 0;
    if (List[n].s > s)
        return reallyPack(n-1, s);
    else {
        int without = reallyPack(n-1,s);
        int with = reallyPack(n-1, s-List[n].s) + List[n].v;
        if (with >= without) {
            l.add(itemsList[n]);
        }
        return Math.max(with, without);
    }
}

當然,您仍然知道選擇了多少個項目:這只是返回列表的大小。

您可以跟蹤當前選中的所有項目(例如使用boolean[]字段)。 然后,您必須記住n < 0的pack調用中的最大值。

int maximum;
int currentMax;
boolean[] packed;
boolean[] maxPacked;

int pack(int n, int s) {
    if (n < 0) {
        if (maximum < currentMax) {
            // found better selection
            maximum = currentMax;
            // copy array
            for (int i = 0; i < packed.length; i++)
                 maxPacked[i] = packed[i];
        }
        return 0;
    }

    packed[n] = false;
    int maxWithout = pack(n-1, s);
    if (List[n].s > s) {
        return maxWithout;
    } else {
        packed[n] = true;
        currentMax += List[n].v;
        int maxWith = pack(n-1, s -List[n].s) + List[n].v;
        currentMax -= List[n].v;

        return Math.max(maxWith, maxWithout);
    }
}

void callingFunction() {
    int maxCost = //...;
    // always possible to choose no items
    maximum = 0;
    currentMax = 0;
    packed = new boolean[List.length];
    maxPacked = new boolean[List.length];

    pack(List.length-1, maxCost);
    // print best selection
    System.out.println(Arrays.toString(maxPacked));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM