算法设计与分析课程大作业.docx

上传人:b****1 文档编号:1148991 上传时间:2022-10-17 格式:DOCX 页数:10 大小:128.55KB
下载 相关 举报
算法设计与分析课程大作业.docx_第1页
第1页 / 共10页
算法设计与分析课程大作业.docx_第2页
第2页 / 共10页
算法设计与分析课程大作业.docx_第3页
第3页 / 共10页
算法设计与分析课程大作业.docx_第4页
第4页 / 共10页
算法设计与分析课程大作业.docx_第5页
第5页 / 共10页
点击查看更多>>
下载资源
资源描述

算法设计与分析课程大作业.docx

《算法设计与分析课程大作业.docx》由会员分享,可在线阅读,更多相关《算法设计与分析课程大作业.docx(10页珍藏版)》请在冰豆网上搜索。

算法设计与分析课程大作业.docx

算法设计与分析课程大作业

 

题目作业调度问题及算法分析

 

学院名称:

计算机与信息工程学院

专业名称:

计算机科学与技术

 

 

摘要:

在现代企业中,作业调度已成为提高资源利用率、从而提高企业运行效益的关键环节之一。

把各个作业分配到车间现有的设备上,并确定它们的先后次序,这是一项复杂的工作本文就作业调度排序问题进行了研究,通过对几个经典作业调度算法的分析讨论,总结了各个算法对作业调度的求解过程,并给出了每个算法的复杂度及性能分析。

关键词:

作业调度;动态规划;贪心算法;回溯法;

一.动态规划算法解决流水作业调度

1、问题描述

给定n个作业,每个作业有两道工序,分别在两台机器上处理。

一台机器一次只能处理一道工序,并且一道工序一旦开始就必须进行下去直到完成。

一个作业只有在机器1上的处理完成以后才能由机器2处理。

假设已知作业i在机器j上需要的处理时间为t[i,j]。

流水作业调度问题就是要求确定一个作业的处理顺序使得尽快完成这n个作业。

2、算法分析

直观上,一个最优调度应使机器M1没有空闲时间,且机器M2的空闲时间最少。

在一般情况下,机器M2上会有机器空闲和作业积压2种情况。

在一般情况下,机器M1开始加工S中作业时,机器M2还在加工其他作业,要等时间t后才可利用。

将这种情况下完成S中作业所需的最短时间记为T(S,t)。

流水作业调度问题的最优值为T(N,0)。

由流水作业调度问题的最优子结构性质可知,

(1)

(2)

从公式

(1)可以看出,该问题类似一个排列问题,求N个作业的最优调度问题,利用其子结构性质,对集合中的每一个作业进行试调度,在所有的试调度中,取其中加工时间最短的作业做为选择方案。

将问题规模缩小。

公式

(2)说明一般情况下,对作业集S进行调度,在M2机器上的等待时间,除了需要等该部件在M1机器上完成时间,还要冲抵一部分原来的等待时间,如果冲抵已成负值,自然仍需等待M1将作业做完,所以公式取max{t-ai,0}。

3.算法的描述

从分析可知,流水作业调度问题一定存在满足Johnson法则的最优调度,且容易由下面的算法确定。

流水作业调度问题的Johnson算法:

(1)令;

(2)将中作业依的非减序排列;将中作业依的非增序排列;

作业接种作业构成满足Johnson法则的最优调度。

4、部分算法实现

intFlowShop(intn,inta[],intb[],intc[])

{inti;

Jobtype*d=newJobtype[n];

for(i=0;i

{

d[i].key=a[i]>b[i]?

b[i]:

a[i];//按Johnson法则分别取对应的b[i]或a[i]值作为关键字

d[i].job=a[i]<=b[i];//给符合条件a[i]

d[i].index=i;

}

BubbleSort(d,n);

//对数组d按关键字升序进行排序

intj=0,k=n-1;

for(i=0;i

{

if(d[i].job)

{

c[j++]=d[i].index;

//将排过序的数组d,取其中作业序号属于N1的从前面进入

}

else

{c[k--]=d[i].index;

//属于N2的从后面进入,从而实现N1的非减序排序,N2的非增序排序

}

}

j=a[c[0]];

k=j+b[c[0]];

for(i=1;i

{

j+=a[c[i]];

//M1在执行c[i]作业的同时,M2在执行c[i-1]号作业,最短执行时间取决于M1与M2谁后执行完

k=j

k+b[c[i]]:

j+b[c[i]];//计算最优加工时间

}

deleted;

returnk;

}

5.运行结果

6、时空效率分析

算法Flowshop的主要计算时间花在对作业集的排序上。

在这里,我们使用冒泡排序法(BubbleSort),因此,在最坏情况下算法FlowJob所需要的计算时间为。

所需要的空闲显然是。

二.贪心算法解多机调度问题

1、问题描述

多机调度问题要求给出一种作业调度方案,使所给的n个作业在尽可能短的时间内由m台机器加工处理完成。

约定,每个作业均可在任何一台机器上加工处理,但未完工前不允许中断处理。

作业不能拆分成更小的子作业。

这个问题是NP完全问题,到目前为止还没有有效的解法。

对于这一类问题,用贪心选择策略有时可以设计出较好的近似算法。

2、算法分析

贪心算法只需按顺序以数组方式提供各作业的加工时间和机器的台数;求出作业的个数,若小于机器台数,就将作业逐个分配给就近的机器,所需要的加工时间,即为最长作业所需时间。

若作业数大于机器台数,将作业按加工时间的多少降序排序,以机器数建立最小堆,先将前m个作业分配给m个机器,最小堆顶是最小的元素(即m个作业中加工时间最少的作业),将其移出并加上后续作业的加工时间,再插入堆,这时会改变原来的状态,升到堆顶的机器加工总时间最少,它再移出加后续作业的加工时间,在插入堆,依此类推,直到全部作业结束。

堆中的最大值就是完成所有作业所需的最短时间。

3.部分算法实现

typedefstructNode

{intID,avail;}manode;//ID机器编号avail每次作业的初始时间

manodemachine[N];jobnodejob[N];

/*找出下个作业执行机器*/

manode*Find_min(manodea[],intm)

{manode*temp=&a[0];

for(inti=1;i

{if(a[i].availavail)

temp=&a[i];}

returntemp;}

/*对作业时间由大到小进行排序*/

voidSort(jobnodet[],intn)

{jobnodetemp;

for(inti=0;i

for(intj=n-1;j>i;j--)

{if(job[j].time>job[j-1].time)

{temp=job[j];

job[j]=job[j-1];

job[j-1]=temp;}

}

}

voidmain()

{

for(i=0;i

{cin>>job[i].time;

job[i].ID=i+1;}

printf("输入机器数目(机器编号按输入顺序处理)\n");

cin>>m;

for(i=0;i

{machine[i].ID=i+1;

machine[i].avail=0;}

putchar('\n');

if(n<=m)

{printf("为每个作业分配一台机器,可完成任务!

\n");return;}

Sort(job,n);

for(i=0;i

{ma=Find_min(machine,m);

printf("将机器:

M%d从%d->%d的时间段分配给作业:

%d\n",

putchar('\n');

printf("该批作业处理完成所需加工时间为:

%d\n",temp);

}

4.计算复杂性分析

当n≤m时,所有作业可以一次安排给各机器,算法greedy需要o

(1)时间。

当n>m时,排序耗时O(nlogn)。

初始化堆需要O(m)时间。

关于堆的removeMin和put运算共耗时O(nlogm),因此算法greedy所需的计算时间为O(nlogn+nlogm)=O(nlogn)。

5.运行结果

三.回溯法解决批作业调度问题

1.问题描述

输入:

1.      任务数N

2.      机器数M

3.      随机序列长度t[i],其中t[i]=x表示第i个任务完成需要时间单位x,

输出:

1.      开销时间besttime,表示最佳调度需要时间单位

2.      最佳调度序列bestx[],其中bestx[i]=x,表示将第i个任务分配给第x个机器执行。

2.算法思想

解空间的表示:

一个深度为N的M叉树。

t[i]:

第i个任务的时间

x[i]=j:

当前输出结果

Res[i]=j:

表示第i个任务要运行在第j台机器上

time_machine[i]:

第i个机器上的运行时间

基本思路:

1、搜索从开始结点(根结点)出发,以DFS搜索整个解空间。

2、每搜索完一条路径则记录下time_min和Res[i]序列,开始结点就成为一个活结点,

同时也成为当前的扩展结点。

在当前的扩展结点处向纵深方向移至一个新结点,

并成为一个新的活结点,也成为当前扩展结点。

3、如果在当前的扩展结点处不能再向纵深方向扩展,则当前扩展结点就成为死结点。

此时,应往回移动(回溯)至最近的一个活结点处,并使这个活结点成为当前的扩展

结点;直至找到一个解或全部解。

3.部分算法实现

boolplacetest(intk)

{inttime_max_K=time_machine[1];

for(inti=2;i<=K;i++)

{if(time_machine[i]>time_max_K)

time_max_K=time_machine[i];}

if(time_max_K>time_min)

returnfalse;

else

returntrue;

}

voidBacktrack(intk,intt[],intx[])

{if(k>N)

{inttime_max_K=time_machine[1];

for(inti=2;i<=K;i++)

{if(time_machine[i]>time_max_K)

time_max_K=time_machine[i];

}

if(time_max_K

{time_min=time_max_K;

for(inti=1;i<=N;i++)

Res[i]=x[i]}}

else

{for(inti=1;i<=K;i++)

{x[k]=i;//将第k个任务放到第i个机器上面

if(placetest(k))

{

time_machine[i]+=t[k];

Backtrack(k+1,t,x);

time_machine[i]-=t[k];

}

}

4.运行结果

5.时间复杂性分析

由于没有使用限界函数进行优化,算法时间和空间复杂度呈指数级增长。

所以该算法不适合较大规模的计算。

蓝线表示机器数一定M=3时,n增大时求解最佳调度对所消耗的时间,该趋势随着指数增加。

四.作业调度算法比较

在流水作业调

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > IT计算机 > 计算机软件及应用

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1