您的位置:首页 > 其它

单机调度问题

2009-07-23 12:54 609 查看
来自:http://topic.csdn.net/u/20090504/21/1992403a-69b0-4a97-ada5-4ef8153f2078.html?seed=1381913772

--

假设有一台机器,以及在此机器上处理的n个作业a1,a2,...,an的集合。处理作业aj所需的时间为tj,作业aj的完成带来的收益为pj,作业
aj完成的最后期限为dj。机器在一个时刻只能处理一个作业,而且如果某作业被处理,那么一定要在连续的时间内进行处理。如果某作业aj在最后期限dj之
前完成,则获得收益pj,若在最后期限之前没有完成,则没有收益。请给出一个算法,来寻找能获得最大收益的调度,假设所有作业所需的处理时间都为整数。

解:

假设数据如下:

a1a2a3

a4

a5

a6

a7

t108

5

7

4

2

7

p54

9

4

5

1

3

d1039

50

47

36

11

23

法一(近似算法):

思路:每次对剩余作业重新计算优先级,选取优先级最高者投入处理。直至所有作业处理完毕。

优先级公式为prio=p/(d-currentTime-t)。

matlab程序如下:

clear;

a(1)=struct('t',10,'p',5,'d',10);

a(2)=struct('t',8,'p',4,'d',49);

a(3)=struct('t',5,'p',9,'d',50);

a(4)=struct('t',7,'p',4,'d',47);

a(5)=struct('t',4,'p',5,'d',36);

a(6)=struct('t',2,'p',1,'d',11);

a(7)=struct('t',7,'p',3,'d',23);

S=[0 0 0 0 0 0 0];%已处理的作业集

order=[];

curT=0;%当前时刻

prof=0;%当前获利

while(1)

maxprio=-1000000000;

maxI=-1;

%找a中优先级最高者

for i=1:7

if S(i)==0

%计算a(i)优先级

prio=a(i).p./(a(i).d-curT-a(i).t);

if prio>maxprio

maxprio=prio;

maxI=i;

end

end

end%得到maxI

%maxI加入S

S(maxI)=1;

order=[order,maxI];

curT=curT+a(maxI).t;

if curT<=a(maxI).d

prof=prof+a(maxI).p;

end

if veceq(S,[1 1 1 1 1 1 1])

break;

end

end

disp('最大收益:');

disp(prof);

disp('加工顺序:');

disp(order);

运行结果:

最大收益:

30

加工顺序:

1 7 5 3 4 2 6



法二(精确算法):

用动态规划算法,另外由于是调度问题,所以只要每次取S最小的状态进行转移,就可以改进为dijkstra算法。

matlab程序如下:

clear;

a(1)=struct('t',10,'p',5,'d',10);

a(2)=struct('t',8,'p',4,'d',49);

a(3)=struct('t',5,'p',9,'d',50);

a(4)=struct('t',7,'p',4,'d',47);

a(5)=struct('t',4,'p',5,'d',36);

a(6)=struct('t',2,'p',1,'d',11);

a(7)=struct('t',7,'p',3,'d',23);

statlist(1)=struct('time',0,'S',[0 0 0 0 0 0 0],'prof',0,'per',-1,'open',true);

while(1)

%找open=true的状态中S最小者

minS=1000000000;

minI=-1;

for i=1:length(statlist)

if statlist(i).open==true&&sum(statlist(i).S)<minS

minI=i;

minS=sum(statlist(i).S);

end

end%找到minI

statlist(minI).open=false;

if veceq(statlist(minI).S,[1 1 1 1 1 1 1])

break;

end

stat=statlist(minI);

%对状态stat作推进

for i=1:length(a)

if stat.S(i)==0

%将a(i)执行,stat转移到linstat

linstat=stat;

linstat.time=linstat.time+a(i).t;

linstat.S(i)=1;

if linstat.time<=a(i).d

linstat.prof=linstat.prof+a(i).p;

end

linstat.per=minI;

linstat.open=true;

%新状态加入状态列表

exist=false;

for j=1:length(statlist)

if veceq(statlist(j).S,linstat.S)

exist=true;

end

end%得到exist

if exist

if linstat.prof>statlist(j).prof

statlist(j)=linstat;

end

else

statlist=[statlist,linstat];

end

end

end

end

%显示结果

disp('最大收益:')

disp(statlist(minI).prof);

%回溯路径

i=minI;

rs=zeros(0,7);

while i~=-1

rs=[rs;statlist(i).S];

i=statlist(i).per;

end

%将路径处理成易读形式

order=[];

for i=1:size(rs,1)-1

rs(i,:)=rs(i,:)-rs(i+1,:);

order=[order,find(rs(i,:)==1)];

end

order=order(7:-1:1);

disp('加工顺序:');

disp(order);

运行结果:

最大收益:

30

加工顺序:

1 6 7 3 2 5 4



注:

(1),用到的辅助函数:

function yn=veceq(A,B)

%比较两个向量是否相等

if all(size(A)==size(B))&&all(A==B)

yn=true;

return;

end

yn=false;

end

(2),可见,对于本例而言,近似算法得到了与精确算法相同的结果。但近似算法是多项式算法,而精确算法不是多项式算法,但也比穷举所有排列复杂度低得多。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: