分支界限法解装载问题和解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;
}
}
}
转载于:https://blog.51cto.com/zuohao1990/2325067