1. 程式人生 > >裝載問題-分支界限法

裝載問題-分支界限法

        分支界限法解裝載問題和解01揹包問題十分類似,都是建立樹之後廣度優先遍歷各結點,建立佇列,約束條件是第一艘貨船的承載能力,最後選擇承載重量最大的一個組合,然後將剩餘物品全部放在第二艘貨船,判斷是否可以裝下,可以獲得結果。

package test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * Created by saishangmingzhu on 2018/11/30.
 */
public class BinPackingProblem {

    public static void main(String[] arg) {
        new BinPackingProblem().branchAndBoundMethod();
    }

    /**
     * 分支界限法-佇列式
     */
    public void branchAndBoundMethod() {
        int rucksackWeight1=10;
        int rucksackWeight2=10;
        List<Goods> goodsList=new ArrayList<>();
        goodsList.add(new Goods("書",1));
        goodsList.add(new Goods("足球",3));
        goodsList.add(new Goods("大箱子",7));
        goodsList.add(new Goods("macbook",3));
        goodsList.add(new Goods("iphone",1));
        goodsList.add(new Goods("禮盒",5));
//        //裝不下的情況
//        goodsList.add(new Goods("書",2));
//        goodsList.add(new Goods("足球",9));
//        goodsList.add(new Goods("大箱子",9));
        int allWeight=0;
        for (Goods goods:goodsList){
            allWeight=allWeight+goods.getWeight();
        }
        if (allWeight>rucksackWeight1+rucksackWeight2){
            System.out.println("物品總重量已超出兩貨船總承載");
            return;
        }
        int goodsListSize=goodsList.size();
        //【1】定義二叉樹的節點,包括左右子節點、剩餘空間、當前總價值
        //【2】起始根節點
        Node root=new Node();
        root.setSurplusWeight(rucksackWeight1);
        root.setLevel(0);
        Node parentNode=root;
        //【3】定義佇列
        List<Node> queueNodeList=new ArrayList<>();
        List<Node> queueLeafNodeList=new ArrayList<>();
        queueNodeList.add(parentNode);
        while (queueNodeList.size()>0){
            parentNode=queueNodeList.get(0);
            int nextLevel=parentNode.getLevel()+1;
            if (nextLevel>goodsListSize){
                queueLeafNodeList.add(parentNode);
            } else {
                Goods g = goodsList.get(parentNode.getLevel());
                int surplus = parentNode.getSurplusWeight() - g.getWeight();
                if (surplus >= 0) {
                    Node node = new Node();
                    node.setLevel(nextLevel);
                    node.setSurplusWeight(surplus);
                    node.getGoodsList().addAll(parentNode.getGoodsList());
                    node.getGoodsList().add(g);
                    queueNodeList.add(node);
                }
                Node node = new Node();
                node.setLevel(nextLevel);
                node.setSurplusWeight(parentNode.getSurplusWeight());
                node.getGoodsList().addAll(parentNode.getGoodsList());
                queueNodeList.add(node);
            }
            queueNodeList.remove(0);
        }
        Collections.sort(queueLeafNodeList, new Comparator<Node>() {
            @Override
            public int compare(Node o1, Node o2) {
                int surplus=o1.getSurplusWeight()-o2.getSurplusWeight();
                if (surplus<0)
                    return -1;
                else if (surplus>0)
                    return 1;
                return 0;
            }
        });
        Node first=queueLeafNodeList.get(0);
        System.out.println();
        if (allWeight-(rucksackWeight1-first.getSurplusWeight())<=rucksackWeight2){
            System.out.println("兩貨船可以裝下所有物品");
            System.out.println("第一艘貨船需裝如下物品,其餘物品裝第二艘貨船");
            List<Goods> goodsList1=first.getGoodsList();
            for (Goods goods:goodsList1){
                System.out.print(goods.getName()+",");
            }
            System.out.println();
        }
        else {
            System.out.println("兩貨船無法裝下所有物品");
        }
    }


    class Goods{
        private String name;
        private int weight;

        public Goods(String name, int weight) {
            this.name = name;
            this.weight = weight;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getWeight() {
            return weight;
        }

        public void setWeight(int weight) {
            this.weight = weight;
        }
    }

    class Node{
        private int surplusWeight;
        private Node leftNode;
        private Node rightNode;
        private int level;
        private List<Goods> goodsList=new ArrayList<>();

        public int getLevel() {
            return level;
        }

        public void setLevel(int level) {
            this.level = level;
        }

        public int getSurplusWeight() {
            return surplusWeight;
        }

        public void setSurplusWeight(int surplusWeight) {
            this.surplusWeight = surplusWeight;
        }

        public Node getLeftNode() {
            return leftNode;
        }

        public void setLeftNode(Node leftNode) {
            this.leftNode = leftNode;
        }

        public Node getRightNode() {
            return rightNode;
        }

        public void setRightNode(Node rightNode) {
            this.rightNode = rightNode;
        }

        public List<Goods> getGoodsList() {
            return goodsList;
        }

        public void setGoodsList(List<Goods> goodsList) {
            this.goodsList = goodsList;
        }
    }
}