裝載問題-回溯法

        有兩艘貨船,載重分別爲w一、w2,物品總重量不超過載重總量w1+w2,問物品是否均可以裝下。如,w1=w2=10,物品g1=g2=9,g3=2,則沒法裝下;w1=w2=5,w3=10,則能夠裝下。
java

        這是個典型的裝載問題,多箱多物能否容納。思路是儘量將前邊的箱子裝滿,判斷剩餘物品是否能夠裝入最後一個箱子。
node

package test;

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

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

    private List<Node> nodeList=new ArrayList<>();

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

    /**
     * 回溯算法
     * 創建左右子結點是爲了造成物理上的樹結構,實際對應這個算法能夠不創建左右子結點,由於構建樹和計算結果同步進行,得到結果後就中止了,不會再次使用構建好的樹
     */
    public void backtracking(){
        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;
        }
        //【1】裝第一艘貨船,儘量多的裝
        Node parentNode=new Node();
        parentNode.setSurplusWeight(rucksackWeight1);
        again(goodsList, parentNode,0);
        Collections.sort(nodeList, 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=nodeList.get(0);
        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("兩貨船沒法裝下全部物品");
        }


    }

    private void again(List<Goods> goodsList, Node parentNode,int i) {
        if (i>=goodsList.size()){
            nodeList.add(parentNode);
            return;
        }
        Goods goods=goodsList.get(i);
        int surplus=parentNode.getSurplusWeight()-goods.getWeight();
        if (surplus>=0){
            Node leftNode=new Node();
            leftNode.setSurplusWeight(surplus);
            parentNode.setLeftNode(leftNode);
            leftNode.getGoodsList().addAll(parentNode.getGoodsList());
            leftNode.getGoodsList().add(goods);
            again(goodsList,leftNode,i+1);
        }
        Node rightNode=new Node();
        rightNode.setSurplusWeight(parentNode.getSurplusWeight());
        parentNode.setRightNode(rightNode);
        rightNode.getGoodsList().addAll(parentNode.getGoodsList());
        again(goodsList,rightNode,i+1);
    }

    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 List<Goods> goodsList=new ArrayList<>();

        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;
        }
    }
}
相關文章
相關標籤/搜索