1. 程式人生 > >0-1揹包問題簡單實現程式碼(動態規劃)

0-1揹包問題簡單實現程式碼(動態規劃)

import java.util.Scanner;

/**
 * @ClassName Backpack
 * @Description 0-1揹包問題
 * @Author lzq
 * @Date 2018/12/6 17:51
 * @Version 1.0
 **/

class GType {
    double value;    //價值
    double weight;  //重量
    char isSelect;  //是否被選中
}


public class Backpack {
    private static double MaxValue;   //方案最大價值
    private static double totalValue;  //物品總價值
    private static double maxWt;    //能裝下的最大數量
    private static int num;   //物品數量
    private static char[] seltemp;  //臨時陣列

    /**
     * 動態規劃演算法
     * @param goods
     * @param i
     * @param wt
     * @param vt
     */
    private void backpack(GType[] goods,int i,double wt,double vt) {
        int k;
        if(wt+goods[i].weight <= maxWt) {  //將物品i放置在當前方案,並判斷小於等於揹包重量限制
            seltemp[i] = 1;   //選中第i個物品
            if(i < num-1) {  //如果物品i不是最後一個物品
                backpack(goods,i+1,wt+goods[i].weight,vt);  //遞迴呼叫,繼續新增物品
            }else {
                for(k = 0;k < num;k++) {
                    goods[k].isSelect = seltemp[k];
                }
                MaxValue = vt;    //儲存當前方案的最大值
            }
        }
        seltemp[i] = 0;   //取消物品i的選擇狀態
        if(vt - goods[i].value > MaxValue) {  //還可以繼續新增物品
            if(i < num-1) {
                backpack(goods,i+1,wt,vt-goods[i].value);  //遞迴呼叫
            }else {
                for(k = 0;k < num;k++) {
                    goods[k].isSelect = seltemp[k];
                }
                MaxValue = vt-goods[i].value;
            }
        }

    }

    /**
     * 開始
     */
    public void start() {
        Scanner scanner = new Scanner(System.in);
        System.out.println("揹包最大容量:");
        maxWt = scanner.nextInt();
        System.out.println("可選物品數量:");
        num = scanner.nextInt();
        GType[] goods = new GType[num];
        seltemp = new char[num];
        totalValue = 0;
        for(int i = 0;i < num;i++) {
            GType t = new GType();
            System.out.println("輸入第"+(i+1)+"件物品的重量和價值:");
            t.weight = scanner.nextDouble();
            t.value = scanner.nextDouble();
            totalValue += t.value;  //統計所有物品的總價值
            goods[i] = t;
        }
        System.out.println("揹包能裝的最大值:"+maxWt);
        for(int i = 0;i < num;i++) {
            System.out.println("第"+(i+1)+"件物品的重:"+goods[i].weight+"價值:"+goods[i].value);
        }
        for(int i = 0;i < num;i++) {
            seltemp[i] = 0;
        }
        MaxValue = 0;
        backpack(goods,0,0.0,totalValue);
        double sumWeight = 0;
        System.out.println("可以將以下物品放入揹包,是的能裝的物品價值最大!");
        for(int i = 0;i < num;i++) {
            if(goods[i].isSelect == 1) {
                System.out.println("第"+(i+1)+"件物品的重:"+goods[i].weight+"價值:"+goods[i].value);
                sumWeight += goods[i].weight;
            }
        }
        System.out.println("總重量:"+sumWeight+"\t總價值:"+MaxValue);
    }
}

測試程式碼:

public static void main(String[] args) {
        Backpack backpack = new Backpack();
        backpack.start();
    }

執行結果:

揹包最大容量:
8
可選物品數量:
5
輸入第1件物品的重量和價值:
6 48
輸入第2件物品的重量和價值:
5 40
輸入第3件物品的重量和價值:
2 12
輸入第4件物品的重量和價值:
1 8
輸入第5件物品的重量和價值:
1 7
揹包能裝的最大值:8.0
第1件物品的重:6.0價值:48.0
第2件物品的重:5.0價值:40.0
第3件物品的重:2.0價值:12.0
第4件物品的重:1.0價值:8.0
第5件物品的重:1.0價值:7.0
可以將以下物品放入揹包,是的能裝的物品價值最大!
第1件物品的重:6.0價值:48.0
第4件物品的重:1.0價值:8.0
第5件物品的重:1.0價值:7.0
總重量:8.0	總價值:63.0

在這裡插入圖片描述