深度搜索定界
原文
http://it.pjschool.com.cn/Article/ArticleShow.asp?ArticleID=231原文题为分支定界, 深度搜索定界是其中例2,
例1代码已重写为
http://blog.csdn.net/jq0123/archive/2006/05/30/762957.aspx此为例2代码重写.
根据
http://www.skyheart.com.cn/html/DATASTRUCTE/20060528103723307.htm分支定界 (branch and bound) 算法是一种在问题的解空间树上搜索问题的解的方法。但与回溯算法不同,分支定界算法采用广度优先或最小耗费优先的方法搜索解空间树,并且,在分支定界算法中,每一个活结点只有一次机会成为扩展结点。
些例不算是分支定界算法, 而是回溯算法, 应用了限界函数( bounding function)来定界.
原代码对于如下数据输出为27,错误。
3 12
11 7 5 5 4 7
11 7 5 5 4 7
输出应为
11 11 4
7 7 7 5
7 5 5 5 4
Time=26
{http://it.pjschool.com.cn/Article/ArticleShow.asp?ArticleID=231分支定界法的思想是:首先确定目标值的上下界,边搜索边减掉搜索树的某些支,提高搜索效率。2. 2 深度搜索定界例2:设定有n台处理机p1,p2,......pn,和m个作业j1,j2,...jm,处理机可并行工作,作业未完成不能中断,作业ji在处理机上的处理时间为ti,求解最佳方案,使得完成m项工作的时间最短?说明:本题有两重搜索法,搜索处理机和搜索作业,当m,n较大时,搜索处理机不可能?搜索作业容易确定上下界,容易剪支。若输入文件是:3 611 7 5 5 4 7输出结果如下:7 75 5 411time=14 }program Jobs;const MAXN = 100; MAXM = 1000;var JobReqTime: array[1..MAXM] of Integer; // jobs count on processor-I JobNums, BestJobNums: array[1..MAXN] of Integer; // TimeBlocks[Proc, Seq]: the Seq block time of Proc // TimeBlocks[2, 4] = 12 means processor-2's 4th job requires 12 time. TimeBlocks, BestTmBlocks: array[1..MAXN, 1..MAXM] of Integer; MaxTimeTotal: Integer; // = ProcUsedTime[1] ProcUsedTime: array[1..MAXN] of Integer; JobDone: array[1..MAXM] of Boolean; Least: Integer; I, J: Integer; FreeProc: Integer; ProcNum, JobNum: Integer; // Number of Processors and Jobs Rest: Integer;procedure print;var I, J: Integer;begin for I := 1 to ProcNum do begin for J := 1 to BestJobNums[I] do Write(BestTmBlocks[I, J], ' '); Writeln; end ; Writeln('Time=', MaxTimeTotal);end;procedure InitReadParams;var F: Text; I, J: Integer; temp: Integer;begin Assign(F, 'input.txt'); Reset(F); Readln(F, ProcNum, JobNum); Rest := 0; for I := 1 to JobNum do begin Read(F, JobReqTime[I]); Inc(Rest, JobReqTime[I]); end; Close(F); Least := Trunc(Rest div ProcNum); { 确定下界 } // Sort requested times, decsending. for I := 1 to JobNum - 1 do for J := I + 1 to JobNum do if JobReqTime[I] < JobReqTime[J] then begin temp := JobReqTime[I]; JobReqTime[I] := JobReqTime[J]; JobReqTime[J] := temp; end;end;{Processor can reject job if required time too much.1. ProcUsedTime[] should less than MaxTimeTotal2. ProcUsedTime[] should not ascend}function ProcRejectJob(AProc, AJob: Integer): Boolean;var NewUsedTime: Integer;begin NewUsedTime := ProcUsedTime[AProc] + JobReqTime[AJob]; if 1 = AProc then ProcRejectJob := NewUsedTime >= MaxTimeTotal else ProcRejectJob := NewUsedTime > ProcUsedTime[AProc - 1];end;procedure AddJobToProc(AJob, AProc: Integer);begin Inc(JobNums[AProc]); TimeBlocks[AProc, JobNums[AProc]] := JobReqTime[AJob]; Inc(ProcUsedTime[AProc], JobReqTime[AJob]); Dec(Rest, JobReqTime[AJob]);end;procedure RemoveJobFromProc(AJob, AProc: Integer);begin Dec(JobNums[AProc]); Dec(ProcUsedTime[AProc], JobReqTime[AJob]); Inc(Rest, JobReqTime[AJob]);end;{ 从AJob..JobNum中选取作业放在处理机AProc上 }procedure SearchFrom(AJob, AProc: Integer);var I: Integer;begin if MaxTimeTotal = Least then Exit; for I := AJob to JobNum do begin if JobDone[I] then Continue; if ProcRejectJob(AProc, I) then Continue; JobDone[I] := True; AddJobToProc(I, AProc); // try to add more jobs SearchFrom(I + 1, AProc); RemoveJobFromProc(I, AProc); JobDone[I] := False; end; // for I if Rest = 0 then begin BestJobNums := JobNums; BestTmBlocks := TimeBlocks; MaxTimeTotal := ProcUsedTime[1]; // ProcUsedTime[1] is always the largest end else if Rest > (ProcNum - AProc) * ProcUsedTime[AProc] then Exit // stop this search branch else if AProc < ProcNum then SearchFrom(1, AProc + 1);end;begin InitReadParams; { 确定上界 } FillChar(ProcUsedTime, SizeOf(ProcUsedTime), 0); FillChar(BestTmBlocks, SizeOf(BestTmBlocks), 0); FillChar(BestJobNums, SizeOf(BestJobNums), 0); for I := 1 to JobNum do begin // find the most free proccessor FreeProc := 1; for J := 2 to ProcNum do if ProcUsedTime[J] < ProcUsedTime[FreeProc] then FreeProc := J; // assign job-I to most free proc ProcUsedTime[FreeProc] := ProcUsedTime[FreeProc] + JobReqTime[I]; BestJobNums[FreeProc] := BestJobNums[FreeProc] + 1; BestTmBlocks[FreeProc, BestJobNums[FreeProc]] := JobReqTime[I]; end; MaxTimeTotal := 0; for I := 1 to ProcNum do if ProcUsedTime[I] > MaxTimeTotal then MaxTimeTotal := ProcUsedTime[I]; // start to search FillChar(JobDone, SizeOf(JobDone), False); FillChar(ProcUsedTime, SizeOf(ProcUsedTime), 0); FillChar(TimeBlocks, SizeOf(TimeBlocks), 0); FillChar(JobNums, SizeOf(JobNums), 0); SearchFrom(1, 1); print; ReadLn;end.
分享到:
相关推荐
支限界法类又称为剪枝限界法或分支定界法,它类似于回溯法,也是一种在问题的解空间树T上搜索问题解的算法。它与回溯法有两点不同:①回溯法只通过约束条件剪去非可行解,而分支限界法不仅通过约束条件,而且通过...
在分支定界过程中,在剪支后如何从搜索树中剩下的节点(子问题)中选择一个节点继续进行分支也将影响整个分支定界的收敛速度,本文我们将使用深度优先策略。 深度优先含义如下:把分支定界树的层数定义为节点的深度...
Data Structures, Algorithms, and Applications in C++, Second ...第21章 分支定界 21.1 算法思想 21.2 应用 21.2.1 货箱装载 21.2.2 0/1背包问题 21.2.3 最大完备子图 21.2.4 旅行商问题 21.2.5 电路板排列
此函数解决混合整数线性规划问题。 它使用 MATLAB 优化工具箱自带的 linprog.m 函数。 它采用分支定界算法。 它使用深度优先搜索。
py课程已应用...:使用python的应用数据科学课程(熊猫,matplotlib,scikit-learn,nltk,networkx等) dicrete ...:CS的离散数学课程(基本算法,野蛮力量,分支定界等) DeepLearning.AI TensorFlow开发人员专业...
Konane-基本搜索 Konane是一款适合两名玩家的夏威夷游戏。 该板包含36个puka或插槽,排列成6行X 6列。... 使用深度优先搜索,最佳优先搜索,广度优先搜索以及最终分支定界算法,为用户提供确定下一个最佳移动的能力。
代码实现了详细的分支定界 (B&B) 代码,为 CLAD 估计器 MIP 优化模型定制。 该代码有 4 处改进,它们是: 深度优先搜索 (DFS)。 分支为 10(首先尝试 1,然后为二进制变量尝试 0)。 使用贪婪规则实现分支优先级。 ...
该项目的目标是实施一个程序,该程序将解决任意平铺难题,并引入丰富的离散数学/组合数学分支,其中涉及平铺,对称,计数,解空间搜索,分支定界修剪。 最初进行了蛮力搜索。 为了进一步优化算法,避免出现死角和不...
编程范式(贪婪、回溯、分支定界、DP、分而治之、蛮力等) 图论(有向,无向,加权,有根(IN&OUT)和无根树,DAG等) 数学(数论、计算几何、组合学、线性代数等) 其他(字符串处理、位操作等) 实施问题 练习,...
分支定界算法 蛮力算法 随机算法 简单的递归算法: 直接解决基本情况 用一个简单的子问题递归 做一些额外的工作来将更简单的子问题的解决方案转换为给定问题的解决方案。 例子: 要计算列表中元素的数量: 测试某个...
11.4.6 深度优先分支定界搜索的并行形式 11.4.7 IDA*的并行形式 11.5 并行最佳优先搜索 11.6 并行搜索算法的加速比异常 11.7 书目评注 习题 第12章 动态规划 12.1 动态规划概述 12.2 串行一元DP形式 ...
希望这种搜索寻根的工作使教材更为丰满、充实.实际研究工作 者的思路、方法对于初学者来说是很有价值但又难以获得的.例如在研究工作 中如何获取和处理信息、处理好数学和物理的关系、不断调整研究步骤、深 入理解...
9.5.2 Kruskal算法 9.6 深度优先搜索的应用 9.6.1 无向图 9.6.2 双连通性 9.6.3 欧拉回路 9.6.4 有向图 9.6.5 查找强分支 9.7 NP完全性介绍 9.7.1 难与易 9.7.2 NP类 9.7.3 NP完全问题 小结 ...
图论算法9.1 若干定义9.1.1 图的表示9.2 拓扑排序9.3 最短路径算法9.3.1 ...深度优先搜索的应用9.6.1 无向图9.6.2 双连通性9.6.3 欧拉回路9.6.4 有向图9.6.5 查找强分支9.7 NP完全性介绍9.7.1 难与易9.7.2 NP类9.7.3 NP...
·在第21.4节中,我们换掉了对不相交-集合-并(disjoint-set-union)数据结构运行时间的证明,代之以利用潜势方法(potential method)导出一个紧致界的证明。 ·在第22.5节中,对强连通子图算法正确性的证明更简单、...
·在第21.4节中,我们换掉了对不相交-集合-并(disjoint-set-union)数据结构运行时间的证明,代之以利用潜势方法(potential method)导出一个紧致界的证明。 ·在第22.5节中,对强连通子图算法正确性的证明更简单、...