2.5.1题目描述

分配问题要求将n个任务分配给n给人,每个人完成任务的代价不同,要求分配的结果最优,此题可以使用回溯求解。

2.5.2程序使用说明

Java环境1.8.0_111

IDE:eclipse

需要两个文件Node.java,Assignment.java直接编译两个文件,然后直接运行Assignment.java文件,在控制台查看结果。

2.5.3简要分析和设计

假设存在四个人a,b,c,d,任务1,任务2,任务3,任务4,和对应的代价矩阵如下

图二 矩阵(来源于算法设计与分析基础第三版)

采用分支界限法,需要计算最优边界Lb,Lb=已分配任务的代价+剩余未分配任务中最小的代价,然后构造状态空间树,上面例子的状态空间树如下:

图三  空间树(来源于算法设计与分析基础第三版)

开始节点表示还未给任何人分配任务,然后在开始节点的基础上寻找可扩展节点,由于此时a有四种选择,则有四个扩展节点,然后分别计算可扩展节点的lb,如果lb小于cost,则将其加入优先队列,然后从优先队列中选择一个最优的,作为新的扩展节点,然后在当前节点的基础上为继续进行上述步骤,当有一个节点的状态表示为已将四个节点分配完成,且花费的代价小于已有cost,则更新cost值,然后继续从优先队列里增加值和取值,直到优先队列为空,则最小花费即为最优选择。

2.5.4测试用例

{{9, 2, 7, 8},

{6, 4, 3, 7},

{5, 8, 1, 8},

{7, 6, 9, 4}}

结果:

人员以此选择工作为:2 1 3 4

最小花费:13

2.5.5源代码

目录结构:

package three.one;

import java.util.ArrayList;

import java.util.Comparator;

import java.util.PriorityQueue;

/**

*

* @author ym

*

*/

public class Assignment {

//对应花费

private int[][] cost={

{9, 2, 7, 8},

{6, 4, 3, 7},

{5, 8, 1, 8},

{7, 6, 9, 4}

};

//构造比较函数

Comparator<Node>  comparator = new Comparator<Node>() {

public int compare(Node o1, Node o2) {

return o1.getLb()-o2.getLb();

};

};

//存储优先队列

PriorityQueue<Node> priorityQueue = new PriorityQueue<Node>(comparator);

//记录当前最优解

int results = 0;

//存储节点

Node resultNode=null;

public Node initRootNode(){

Node root = new Node();

int lb=0;

for(int i=0;i<cost.length;i++){

int min=cost[i][0];

for(int j=1;j<cost[0].length;j++){

if(min>cost[i][j]){

min=cost[i][j];

}

}

lb+=min;

}

root.setLb(lb);//设置lb

return root;

}

/**

* 计算一个初始值上界

* @return

*/

public int  mostBound(){

int bound=0;

for(int i=0;i<cost.length;i++){

int max=cost[i][0];

for(int j=1;j<cost[i].length;j++){

if(max<cost[i][j]){

max=cost[i][j];

}

}

bound+=max;

}

return bound;

}

//设置结果

public void setResults(int results) {

this.results = results;

}

/**

* 计算lb

* @param node

* @return

*/

public void calculateLb(Node node){

int lb=0;

ArrayList<Integer> upperNode =node.getUpperNode();

int size=upperNode.size();

for(int i=0;i<size;i++){//计算已选person的界

lb+=cost[i][upperNode.get(i)];

}

for(int i=size;i<cost.length;i++){//计算剩余person的最小界

int min=cost[i][0];

for(int j=1;j<cost[i].length;j++){

if(min>cost[i][j]){

min=cost[i][j];

}

}

lb+=min;

}

node.setLb(lb);//更新节点lb

}

/**

* 计算孩子节点

* @param node

* @return

*/

public ArrayList<Node> getChildNodes(Node node){

ArrayList<Node> childNodes = new ArrayList<Node>();//孩子节点

int i=node.getPerson()+1;

int order=0;

ArrayList<Integer> upperNode = node.getUpperNode();//获取已经选择的job

for(int j=0;j<cost[i].length;j++){

if(upperNode==null||order>=upperNode.size()){

Node temp =getNode( i,j,upperNode);//设置节点

childNodes.add(temp);

}

else{

if(order<upperNode.size()&&!upperNode.contains(j)){//构造子节点

Node temp =getNode(i,j,upperNode);//设置节点

childNodes.add(temp);

}

else

order++;

}

}

return childNodes;

}

/**

*

*

* @param i

* @param j

* @param list

* @return

*/

public Node getNode(int i,int j,ArrayList<Integer> list){

ArrayList<Integer> uppers=new ArrayList<Integer>();

if(list!=null&&list.size()>0){

uppers.addAll(list);

}

uppers.add(j);

Node temp = new Node(uppers);

temp.setPerson(i);

temp.setJob(j);

calculateLb(temp);

return temp;

}

/**

*

* @param node

*/

public void assiginment(Node node){

setResults(mostBound());//计算最大界

priorityQueue.add(node);

while(!priorityQueue.isEmpty()){

Node currentNode = priorityQueue.poll();

if(currentNode.getPerson()<cost.length-1){

ArrayList<Node> childNodes = getChildNodes(currentNode);

for(Node child:childNodes){

if(child.getLb()<results){

priorityQueue.add(child);

}

}

}

else{

if(currentNode.getLb()<results){

results=currentNode.getLb();

resultNode=currentNode;

}

}

}

}

public int getResults() {

return results;

}

public Node getResultNode() {

return resultNode;

}

public static void main(String[] args){

Assignment at = new Assignment();

Node root=at.initRootNode();

at.assiginment(root);

ArrayList<Integer> list = at.getResultNode().getUpperNode();

System.out.println("人员以此选择工作为:");

for(int i=0;i<list.size();i++){

System.out.print(" "+(list.get(i)+1));

}

System.out.println();

System.out.println("最小花费:");

System.out.print(at.getResults());

}

}

package three.one;

import java.util.ArrayList;

/**

* Node类

* @author ym

*

*/

public class Node{

int person=-1;

int job=-1;

int weight=0;

int lb=0;

ArrayList<Integer> upperNode;

public Node(){

}

public Node(ArrayList<Integer> upperNode){

this.upperNode=upperNode;

}

public int getPerson() {

return person;

}

public void setPerson(int person) {

this.person = person;

}

public int getJob() {

return job;

}

public void setJob(int job) {

this.job = job;

}

public int getWeight() {

return weight;

}

public void setWeight(int weight) {

this.weight = weight;

}

public int getLb() {

return lb;

}

public void setLb(int lb) {

this.lb = lb;

}

public ArrayList<Integer> getUpperNode() {

return upperNode;

}

public void setUpperNode(ArrayList<Integer> upperNode) {

this.upperNode = upperNode;

}

}

分支界限法 任务分配问题相关推荐

  1. 算法分析与设计第二版(李春葆)第六章分支界限法

    分支界限法类似于回溯法,一般回溯法目标是找出所有解,二分支界限法是找出满足条件的一个解或者最优解 算法 解空间树搜索方式 存储结点的常用数据结构 结点存储特性 常用应用 回溯法 深度优先搜索 栈 活结 ...

  2. 最大团问题-分支界限法

    最大团问题-分支界限法 遍历所有点构造二叉树: 广度遍历树,遍历过程中判断当前结点的点数据时,是否构成完全子图,如果不能则只将右结点加入队列,每次选取队列中完全子图最大的结点作为活结点,无子结点时到达 ...

  3. 从0-1背包问题学习回溯法、分支界限法、动态规划

    一.0-1背包问题的描述 下面将使用回溯法.分支界限法.动态规划法来分析和解决此问题. 二.回溯法 (1)算法步骤 (2)代码如下(没有裁剪函数): 用i和n来判断结束与否,是因为解空间结构是完全二叉 ...

  4. 单源路径分支界限java_单源最短路径-分支界限法

    单源最短路径-分支界限法-优先队列式.这里使用无回路的有向图,便于构建树.构建好树后,从根结点作为起始源,加入结点队列,然后判断获取队列中最短的路径结点做为活结点,将活结点的所有子结点加入队列,移除活 ...

  5. 五大常用算法——分治法,动态规划,回溯法,分支界限法,贪心算法

    (1) 分治法 将一个难以直接解决的大问题,分割成一些规模较小的相同问题 快速排序 快排也是分治的一个实例,快排每一趟会选定一个数,将比这个数小的放左面,比这个数大的放右面, 然后递归分治求解两个子区 ...

  6. 算法分析课设(十一)博物馆守卫问题、世界名画陈列馆问题(分支界限法)

    免责声明 不想打字了.. 题目 在某博物馆中摆放了非常重要的文物,为了节省人力,该博物馆专门购买了警卫机器人来看管这些文物.该博物馆的房间排列整齐,房间的大小相同.每个警卫机器人能够巡查的范围除本身所 ...

  7. 算法设计-分支界限法——装载问题

    算法介绍 分支界限法: 分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树. 在分支限界法中,每一个活结点只有一次机会成为扩展结点.活结点一旦成为扩展结点,就一次性产生其所有儿 ...

  8. 旅行售货员问题 java_旅行售货员问题-分支界限法

    旅行售货员问题分支界限法 package test; import java.util.ArrayList; import java.util.Collections; import java.uti ...

  9. 分支界限法0 1背包 c语言,分支限界法之布线问题(1)

    一.要求: 1.输入电路板区域n*m以及布线的起始位置和结束位置: 2.输出布线方案: 3.可以使用c或者vc实现 二.问题分析及实验原理: 在n*m的方格阵列中存在封锁区域(布线时必须绕开的区域), ...

  10. TSP旅行商问题之分支界限法法求解(C语言)

    #include <stdio.h> #include <malloc.h>#define NoEdge 1000struct MinHeapNode {int lcost; ...

最新文章

  1. redis 发布订阅实际案例_Redis源码分析之发布订阅+慢查询+排序以及监视器
  2. 慢查询工具percona安装
  3. java jigsaw_60秒内使用Java 9的Project Jigsaw的JavaFX HelloWorld
  4. 计算机组成原理中英对照篇,信息科学系课程介绍(中英对照).doc
  5. CodeForces 580A Kefa and First Steps
  6. ELF文件和BIN文件
  7. 蚂蚁Service Mesh大规模落地实践与展望
  8. CoreGraphics之CGContextSaveGState与UIGraphicsPushContext
  9. mysql每天销售汇总_MySQL - 所有项目的每个总销售额
  10. azure vnc控制台_使用扩展和标签控制Azure成本
  11. 全面解读设备状态监测
  12. android 自定义viewgroup 布局,Android 自定义ViewGroup(一)
  13. Passive Aggressive Alogrithm
  14. 练习4闭合导线平差计算
  15. Web前端期末大作业-农产品一体化平台网页设计(HTML+CSS+JS)
  16. 个人网站建设记录 及Markdown使用实践
  17. 微信小程序 家校通 中小学家校联系电子作业系统
  18. 【Wordle】Day8:昨天忘了的后果就是今天输了
  19. 论文中流程图用什么软件画
  20. 万里长征——基础IO

热门文章

  1. 高通8953 Android 9.0 打开user调试串口
  2. diy计算机工作站,程序猿 篇一:迟到的 618 攒机实录:自建巨硬工作站
  3. 海贼王java7723_我的世界海贼王模组7723首发版
  4. iOS常用第三方库大全
  5. SpringCloud 微服务网关Gateway常用限流算法以及简单实现
  6. mtk audio笔记
  7. PIXHAWK飞控固件及代码基础介绍
  8. 【搜索引擎】Google打不开问题解决
  9. 蚩尤战团--管理分布
  10. Quick MTF,镜头图像质量测试应用程序