装载问题 ——回溯法

---装载问题 ——回溯法
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.回溯法联系的例子太少了

原文地址:https://www.cnblogs.com/Howbin/p/9923114.html