裝載問題 ——回溯法


---裝載問題 ——回溯法
tags: 回溯法
grammar_cjkRuby: true

一 問題描述
enter description here
二 問題分析
1. 解空間為子集樹
2.可以設置減枝函數
具體設計為:設置右子樹上界函數
三 代碼設計

package backtracking_loading;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Arrays;

public class bin {
    public static void main(String[] args) throws IOException {
        int []w={0,20,10,40,30,50,60,70};
        int c=180;
        loading myLoading=new loading(c, w);
    }

}
class loading {
    int c;    	//第一艘船的載重量
    int []w;  	//集裝箱數組
    int cw;   	//當前載重量
    int bestw;  //動態最優解
    int n;      //集裝箱個數
    int []cx;   //記錄遞歸路徑
    int []x;    //最優遞歸路勁
    int rw;     //剩余重量 
    public loading(int c,int []w) throws IOException {
        this.c=c;
        this.w=w;
        this.cw=0;
        this.bestw=0;
        this.n=w.length-1;
        this.x=new int[w.length];   //記錄遞歸最優路徑
        this.cx=new int[w.length];  //記錄遞歸當前路勁
        this.rw=0;
        for(int i=1; i<w.length; i++)
        {
            rw+=w[i];
        }
        Loading(1);
        display();
    }
    public void Loading(int i) {
        //遞歸出口
        if(i>n)   //遍歷完一個分支
        {
            if(cw>bestw)
            {
                //更新最優解
                bestw=cw;
                x=Arrays.copyOf(cx,cx.length);
            }
            return;
        }
        //減枝函數 
        rw-=w[i];    //剩余重量,不考慮第i個集裝箱
        //左子樹 1 
        if(cw+w[i]<=c)
        {
            cw+=w[i];
            cx[i]=1;     //裝入
            Loading(i+1);
            cw-=w[i];   //回溯,相當關鍵
        }
        if(cw+rw>bestw)
        {
            //右子樹 0
            cx[i]=0;          //不裝入
            Loading(i+1);
        }
        rw+=w[i];              //結點回溯
    }
    public void display() throws IOException {
    	BufferedWriter fout=new BufferedWriter(new FileWriter("out.txt"));
    	fout.write("c="+c);
        fout.newLine();
        fout.write("bestw="+bestw);
        fout.newLine();
        fout.write("x[i]:");
        fout.newLine();
        for(int i=1; i<x.length; i++)
        {
            fout.write("x["+i+"]="+x[i]);
            fout.newLine();
        }
        fout.flush();
    }
}

四 運行結果
enter description here

五 總結收獲

  1. 熟悉回溯法

六 不足
1.回溯法聯系的例子太少了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM