有两艘货船,载重分别为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 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 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() {
@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 goodsList1=first.getGoodsList();
for (Goods goods:goodsList1){
System.out.print(goods.getName()+",");
}
System.out.println();
}
else {
System.out.println("两货船无法装下所有物品");
}
}
private void again(List 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 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 getGoodsList() {
return goodsList;
}
public void setGoodsList(List goodsList) {
this.goodsList = goodsList;
}
}
}