有兩艘貨船,載重分別爲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; } } }