每日演算法第103期:演算法實驗5(三種方法解決01揹包問題:動態規劃,回溯,分支限界)

小孩shw發表於2020-12-23

實驗內容

  1. 使用貪心演算法、回溯法、分支限界法解決0-1揹包問題;
  2. 通過上機實驗進行演算法實現;
  3. 儲存和列印出程式的執行結果,並結合程式進行分析,上交實驗報告。

動態:

package org.csu.shiyan_5;

import sun.dc.pr.PRError;

public class  Dinggui0_1BAG{
    public static void main(String[] args) {
        int MaxWeight = 10;
        int NumofItems = 5;
        int []weight = new int[]{2,2,6,5,4};
        int[] value = new int []{6,3,5,4,6};
        System.out.println("最後的結果為");
        System.out.println(solution(MaxWeight,NumofItems,weight,value));
        System.out.println("表格為");
        for(int j = 1;j<=NumofItems;j++){
            for(int i = 1;i<=MaxWeight;i++){
                System.out.print(solution(i,j,weight,value));
                System.out.print("\t");
            }
            System.out.println();
        }
    }


    public static int solution(int N,int W,int []weight,int []value){
        int [][]map = new int[N+1][W+1];
        for(int i = 1;i<=W;i++){
            int values = value[i-1];
            int weights = weight[i-1];
            for(int j = 0;j<=N;j++){
                if(j<weights){
                    map[j][i] = map[j][i-1];
                    continue;
                }
                map[j][i] = Math.max(map[j][i-1],map[j-weights][i-1]+values);
            }

        }
        return map[N][W];
    }

}


在這裡插入圖片描述
回溯:

package org.csu.shiyan_5;

import java.util.Scanner;
class back{
    public int value = 0;
    public int weight = 0;
    back(){}
}
public class Feizhixianjie0_2BAG {
    static int cw,cp,bestp,n,c;

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("請輸入物品的個數:");
        n = input.nextInt();
        System.out.println("請輸入揹包的容量:");
        c = input.nextInt();
        back []b = new back[1000];
        System.out.println("請輸入每個物品的價值和重量:");
            for(int i=1;i<=n;i++) {
                b[i] = new back();
                b[i].value =  input.nextInt();
                b[i].weight =  input.nextInt();
            }

            Backtrack(1,b);
        System.out.println("最優解為:");
        System.out.println(bestp);
        }
    public static float bound(int t,back []b)
    {
        float a=cp;
        int i;
        for(i=t;i<=n;i++)
            a+=b[i].value;
        return a;
    }
   public static  void Backtrack(int t,back[]b)
    {
        if(t>n)
        {
            if(cp>bestp)
                bestp=cp;
            return;
        }
        if(cw+b[t].weight<c)
        {
            cw+=b[t].weight;
            cp+=b[t].value;
            Backtrack(t+1,b);
            cw-=b[t].weight;
            cp-=b[t].value;
        }
        if(bound(t+1,b)>bestp)
            Backtrack(t+1,b);
    }

}



在這裡插入圖片描述
分支限界法:

package org.csu.shiyan_5;

import java.util.Scanner;
class back1{
    public int value = 0;
    public int weight = 0;
    back1(){}
}
public class Huisufa0_1PBAG{
    static int cw,cp,bestp,n,c;

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("請輸入物品的個數:");
        n = input.nextInt();
        System.out.println("請輸入揹包的容量:");
        c = input.nextInt();
        back1 []b1 = new back1[1000];
        System.out.println("請輸入每個物品的價值和重量:");
        for(int i=1;i<=n;i++) {
            b1[i] = new back1();
            b1[i].value =  input.nextInt();
            b1[i].weight =  input.nextInt();
        }
        for(int i = 1;i < n;i++ ) {
            if (cmp(b1[i], b1[i + 1])) {
                int t = b1[i].weight;
                b1[i].weight = b1[i + 1].weight;
                b1[i + 1].weight = t;

                t = b1[i].value;
                b1[i].value = b1[i + 1].value;
                b1[i + 1].value = t;
            }
        }
        Backtrack(1,b1);
        System.out.println("最優解為:");
        System.out.println(bestp);
    }

    public static boolean cmp(back1 b1,back1 b2)
    {
        if(b1.value*1.0/b1.weight>b2.value*1.0/b2.weight)
            return true;
        return false;
    }

    public static float bound(int t,back1 []b)
    {
        float a=cp;
        int left=c-cw;

        while(t<=n)
        {
            if(left > b[t].weight) {
                a += b[t].value;
                left -= b[t].weight;
                t++;
            }
        }
        if(t<=n)
        {
            a+=b[t].value*left*1.0/b[t].weight;
        }
        return a;
    }
    public static  void Backtrack(int t,back1[]b) {
        if (t > n) {
            if (cp > bestp)
                bestp = cp;
            return;
        }
        if (cw + b[t].weight < c) {
            cw += b[t].weight;
            cp += b[t].value;
            Backtrack(t + 1,b);
            cw -= b[t].weight;
            cp -= b[t].value;
        }
        if (bound(t + 1,b) > bestp)
            Backtrack(t + 1,b);
    }

}



在這裡插入圖片描述

相關文章