有兩艘貨船,載重分別爲w1、w2,物品總重量不超過載重總量w1+w2,問物品是否都可以裝下。如,w1=w2=10,物品g1=g2=9,g3=2,則無法裝下;w1=w2=5,w3=10,則可以裝下。
這是個典型的裝載問題,多箱多物可否容納。思路是儘可能將前邊的箱子裝滿,判斷剩餘物品是否可以裝入最後一個箱子。
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>() {br/>@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; }
}
}