算法设计与分析: 5-32 子集树问题

5-32 子集树问题


问题描述

试设计一个用回溯法搜索子集空间树的函数。该函数的参数包括结点可行性判定函数和上界函数等必要的函数,并将此函数用于解装载问题。
装载问题描述如下:有一批共 n 个集装箱要装上艘载重量为 c 的轮船,其中集装箱 i 的重量为 wi 。找出一种最优装载方案,将轮船尽可能装满,即在装载体积不受限制的情况下,将尽可能重的集装箱装上轮船。

第一行有 2 个正整数 n 和 c。n 是集装箱数,c 是轮船的 载重量。接下来的 1 行中有 n 个正整数,表示集装箱的重量。


Java

package Chapter5HuiSuFa;

import java.util.Scanner;

public class ZiJiShu {

    private static int n,c;
    private static int[] x,bestx,w;
    private static int r,cw,bestw;

    public static void main(String[] args){
        Scanner input = new Scanner(System.in);

        while (true){
            bestw = 0;
            cw = 0;
            r = 0;

            n = input.nextInt();
            c = input.nextInt();

            w = new int[n+1];
            x = new int[n+1];
            bestx = new int[n+1];

            for(int i=1; i<=n; i++)
                w[i] = input.nextInt();

            for(int i=1; i<=n; i++)
                r += w[i];

            backtrack(1);

            output();
        }
    }

    private static void backtrack(int t){
        if(t > n) record();
        else
            for(int i=0; i<=1; i++){
                x[t] = i;
                if(constraint(t) && bound(t)){
                    change(t);
                    backtrack(t+1);
                    restore(t);
                }
            }
    }

    private static void record(){
        if(cw > bestw){
            bestw = cw;
            for(int i=1; i<=n; i++)
                bestx[i] = x[i];
        }
    }

    private static boolean constraint(int t){
        if(x[t]==0 || x[t]==1 && cw+w[t]<=c) return true;
        else return false;
    }

    private static boolean bound(int t){
        if(x[t]==1 || x[t]==0 && cw+r-w[t]>bestw) return true;
        else return false;
    }

    private static void change(int t){
        if(x[t] == 1) cw+=w[t];
        r -= w[t];
    }

    private static void restore(int t){
        if(x[t] == 1) cw-=w[t];
        r += w[t];
    }

    private static void output(){
        System.out.println(bestw);
        for(int i=1; i<=n; i++)
            System.out.print(bestx[i]+" ");
    }
}

Input & Output

5 10
7 2 6 5 4
10
0 0 1 0 1 


30 566
93 60 57 47 7 88 41 60 95 6 82 20 28 79 20 53 69 71 44 96 64 68 23 27 13 45 68 66 69 99 
566
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 0 1 1 1 1 

Reference

王晓东《计算机算法设计与分析》(第3版)P187

猜你喜欢

转载自blog.csdn.net/ioio_/article/details/81154166