java分支界限法装载_装载问题-分支界限法

分支界限法解装载问题和解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 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 queueNodeList=new ArrayList<>();

List 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() {

@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 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 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 getGoodsList() {

return goodsList;

}

public void setGoodsList(List goodsList) {

this.goodsList = goodsList;

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
装载问题是指在给定的一批集装箱中选取若干个装上一艘载重量为C的轮船,如何才能使装上的集装箱重量最大。这是一个NP完全问题,可以使用分支限界法解决分支限界法是一种用于求解最优化问题的通用算法。它通过将问题的解空间划分为若干个子集,每个子集对应一个可行解,然后通过限制条件和目标函数来剪枝,从而逐步缩小搜索空间,最终找到最优解。 下面是使用队列式分支限界法求解装载问题的Python代码: ```python import queue class Node: def __init__(self, level, weight, value, bound): self.level = level self.weight = weight self.value = value self.bound = bound def bound(node, n, c, w, v): if node.weight >= c: return 0 else: bound = node.value j = node.level + 1 totweight = node.weight while j < n and totweight + w[j] <= c: totweight += w[j] bound += v[j] j += 1 if j < n: bound += (c - totweight) * v[j] / w[j] return bound def knapsack(n, c, w, v): q = queue.Queue() u = Node(-1, 0, 0, 0) v = Node(-1, 0, 0, bound(u, n, c, w, v)) maxvalue = 0 q.put(v) while not q.empty(): u = q.get() if u.bound > maxvalue: i = u.level + 1 u1 = Node(i, u.weight + w[i], u.value + v[i], 0) if u1.weight <= c and u1.value > maxvalue: maxvalue = u1.value u1.bound = bound(u1, n, c, w, v) if u1.bound > maxvalue: q.put(u1) u2 = Node(i, u.weight, u.value, 0) u2.bound = bound(u2, n, c, w, v) if u2.bound > maxvalue: q.put(u2) return maxvalue w = [90, 80, 40, 30, 20, 12, 10] v = [90, 80, 40, 30, 20, 12, 10] c = 152 n = len(w) print("最大装载重量为:", knapsack(n, c, w, v)) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值