分支定界法

原创 2006年05月30日 11:11:00
分支定界法的思想是:首先确定目标值的上下界,边搜索边减掉搜索树的某些支,提高搜索效率。

原文见:http://it.pjschool.com.cn/Article/ArticleShow.asp?ArticleID=231

例1:设有A,B,C,D,E 5人从事j1,j2,j3,j4,j5 5项工作每人只能从事一项,它们的

效益表如下:

  j1 j2 j3 j4 j5
A 13 11 10 4 7
B 13 10 10 8 5
C 5 9 7 7 4
D 15 12 10 11 5
E 10 11 8 8 4

求最佳安排,使效益最高?

 

原文代码重写如下,希望增加点可读性。

 

program PlanJob;

const MAX_SIZE = 20;

type
  TIntArray = array[1..MAX_SIZE] of Integer;
  PNode = ^Node;
  Node = record
    Job2Man: TIntArray;     // Job2Man[n] = m, job-n assign to person-m
    Man2Job: TIntArray;    // Man2Job[n] = m, person-n assign to job-m
    UpperVal: Integer; // upper value
    JobsDep: Integer;   // jobs decided, as search depth
    Next: PNode;
  end;

var
   CurNode: PNode;      // Current node
   NewNode: PNode;      // New branch node
   DelNode: PNode;      // for delete
   GoalNode: PNode;     // the goal
   GoalMaxVal: Integer; // goal max value
   CurMan, CurJob: Integer;     // Current Man and Job of current Node

   Size: Integer;       // Person number, also task number
   Values: array[1..MAX_SIZE, 1..MAX_SIZE] of Integer;

function CalUpperValue(ANode: PNode): Integer;
var
  Res: Integer;
  Man, Job: Integer;
  JobMaxVal: Integer;
begin
  Res := 0;
  with ANode^ do
  begin
    for Job := 1 to Size do
    begin
      if Job <= JobsDep then
      begin
        Man := Job2Man[Job];
        Res := Res + Values[Man, Job];
        Continue;
      end;

      // else find the max value for Job
      JobMaxVal := 0;
      for Man := 1 to Size do
      begin
        if (JobMaxVal < Values[Man,Job]) and (Man2Job[Man] = 0) then
          JobMaxVal := Values[Man,Job];
      end;
      Res := Res + JobMaxVal;
    end;    // for Job
  end;    // with ANode^
  CalUpperValue := Res;
end;

function InitNode(): PNode;
var
  Man, Job: Integer;
  FInput: Text;
  Res: PNode;
begin
  Assign(FInput, 'input.txt');
  Reset(FInput);
  Read(FInput, Size);
  Readln(FInput);
  for Man := 1 to Size do
  begin
    for Job := 1 to Size do
      Read(FInput, Values[Man,Job]);
    Readln(FInput);
  end;

  New(Res);
  with Res^ do
  begin
    for Man := 1 to Size do
    begin
      Man2Job[Man] := 0;
      Job2Man[Man] := 0;
    end;
    JobsDep := 0;
    UpperVal := CalUpperValue(Res);
    Next := nil;
  end;
  InitNode := Res;
end;

procedure Insert(ANode: PNode; From: PNode);
var
  PrevNode, NextNode: PNode;
begin
  NextNode := From;
  repeat
    PrevNode := NextNode;
    NextNode := PrevNode^.Next;
  until (NextNode = nil) or (ANode^.UpperVal >= NextNode^.UpperVal);
  PrevNode^.Next := ANode;
  ANode^.Next := NextNode;
end;

procedure PrintNode(ANode: PNode);
var
  Man, Job: Integer;
  AllJobAssigned: Boolean;
begin
  AllJobAssigned := true;
  for Job := 1 to Size do
  begin
    Man := ANode^.Job2Man[Job];
    if 0 <> Man then
      Writeln('Job ', Job, ' assign to man ',
        Man, ', value ', Values[Man, Job])
    else
      AllJobAssigned := false;
  end;
  Writeln;
  if AllJobAssigned then
    Writeln('Value = ', ANode^.UpperVal)
  else
    Writeln('UpperVal = ', ANode^.UpperVal);
end;

begin
  CurNode := InitNode();
  GoalMaxVal := 0;

  repeat
    CurJob := CurNode^.JobsDep + 1;
    for CurMan := 1 to Size do
    begin
      if CurNode^.Man2Job[CurMan] <> 0 then
        Continue;

      // New search branch
      New(NewNode);
      NewNode^ := CurNode^;
      NewNode^.JobsDep := CurJob;
      NewNode^.Man2Job[CurMan] := CurJob;
      NewNode^.Job2Man[CurJob] := CurMan;
      NewNode^.UpperVal := CalUpperValue(NewNode);

      if NewNode^.UpperVal < GoalMaxVal then
        Dispose(NewNode)        // discard this branch if smaller than limit
      else
        Insert(NewNode, CurNode);

      if CurJob < Size then Continue;   // for CurMan

      // all job assigned, update goal
      if NewNode^.UpperVal > GoalMaxVal then
      begin
        GoalNode := NewNode;
        GoalMaxVal := GoalNode^.UpperVal
      end;  // if
    end;    // for CurMan

    DelNode := CurNode;
    CurNode := CurNode^.Next;
    Dispose(DelNode);
  until (CurNode^.UpperVal <= GoalMaxVal)
    or (CurNode = nil);    // end of repeat

  PrintNode(GoalNode);
  Readln;
end.

 


input.txt:

5
13     11     10     4     7
13     10     10     8     5
5     9     7     7     4
15     12     10     11     5
10     11     8     8     4

output:

Job 1 assign to man 4, value 15
Job 2 assign to man 5, value 11
Job 3 assign to man 2, value 10
Job 4 assign to man 3, value 7
Job 5 assign to man 1, value 7

Value = 50


如果扩展为10*10,
input.txt:
10
13     11     10     4     7    13     11     10     4     7     
13     10     10     8     5       13     10     10     8     5     
5     9     7     7     4       5     9     7     7     4     
15     12     10     11     5       15     12     10     11     5     
10     11     8     8     4       10     11     8     8     4     
13     11     10     4     7    13     11     10     4     7     
13     10     10     8     5       13     10     10     8     5     
5     9     7     7     4       5     9     7     7     4     
15     12     10     11     5       15     12     10     11     5     
10     11     8     8     4       10     11     8     8     4     

运行约两分钟。
output :
Job 1 assign to man 9, value 15
Job 2 assign to man 5, value 11
Job 3 assign to man 2, value 10
Job 4 assign to man 8, value 7
Job 5 assign to man 6, value 7
Job 6 assign to man 4, value 15
Job 7 assign to man 10, value 11
Job 8 assign to man 7, value 10
Job 9 assign to man 3, value 7
Job 10 assign to man 1, value 7

Value = 100

分支定界算法求解带有约束条件的最短路径问题

知识点:分支定界; Dijkstra; c++读取txt文件到二维数组这个题目是北航研究生算法课的,因为以前主要写java,用c++写作业的时候遇到了一些读文件啊,深度优先遍历图的问题啥的,所以记录下...
  • u013527937
  • u013527937
  • 2016年12月21日 17:04
  • 2000

五大常用算法之分支定界法

看了五大常用算法之一这篇博文,感觉理解了很多,可是纯粹都是理论,缺少一些示例,所以准备综合一篇博文,以帮助自己记忆,原文: 一、基本描述     类似于回溯法,也是一种在问题的解空...
  • feiyangtianyao
  • feiyangtianyao
  • 2014年06月29日 16:51
  • 9948

分支定界算法(Branch and Bound)

转自http://archerwq.bokee.com/18657621.html 分支定界 (branch and bound) 算法是一种在问题的解空间树上搜索问题的解的方法。但与回...
  • cocopang324
  • cocopang324
  • 2013年12月18日 23:57
  • 3993

分支定界算法源程序

  • 2012年08月29日 15:33
  • 3KB
  • 下载

搜索与回溯 5.6

题目叙述: 设有A,B,C,D,E 5人从事j1,j2,j3,j4,j5 5项工作每人只能从事一项,它们的效益表如下:  j1 j2 j3 j4 j5 A 13 11 10 4 7 B ...
  • SSL_ZZY
  • SSL_ZZY
  • 2016年11月24日 16:06
  • 318

分支定界法

分支定界法的思想是:首先确定目标值的上下界,边搜索边减掉搜索树的某些支,提高搜索效率。原文见:http://it.pjschool.com.cn/Article/ArticleShow.asp?Art...
  • jq0123
  • jq0123
  • 2006年05月30日 11:11
  • 8668

假设系统按单值方式运行且采用最短作业优先算法,有J1,J2,J3,J4共4个作业同时到达,则以下哪几种情况下的平均周转时间为10分钟?

假设系统按单值方式运行且采用最短作业优先算法,有J1,J2,J3,J4共4个作业同时到达,则以下哪几种情况下的平均周转时间为10分钟? 正确答案: B C   你的答案: B C (...
  • chengonghao
  • chengonghao
  • 2016年08月09日 10:35
  • 1226

回溯法和分支定界法

概述​ 要求解一个问题,最可靠的方法是:列出所有候选解,然后逐个检查,理论上在遍历了所有的候选解之后,就能得到所需要的解。但是,对于实际运用中的问题,候选解的规模庞大,即使使用速度最快的...
  • Mind_V
  • Mind_V
  • 2017年06月26日 16:22
  • 684

分支定界法——旅行商(TSP)问题

问题描述给定一个n顶点网络(有向或无向),找出一个包含n个顶点且具有最小耗费的换路。任何一个包含网络所有顶点的换路称为一个旅行。旅行商问题(Traveling Salesman Problem,TSP...
  • Mind_V
  • Mind_V
  • 2017年07月01日 12:56
  • 856

Mate-基于标签的框架

Mate 将会成为Flex领域的另一个热点。它使用设置(configuration)来调用Service,处理结果,同样也使用设置文件来更新绑定对象(Bindable object)。从某个角度来说:...
  • babylon_0049
  • babylon_0049
  • 2011年06月18日 16:20
  • 461
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:分支定界法
举报原因:
原因补充:

(最多只允许输入30个字)