裝載問題-分支界限法
阿新 • • 發佈:2018-12-02
分支界限法解裝載問題和解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; } } }