用贪婪法求解船舶装卸问题python版.docx
《用贪婪法求解船舶装卸问题python版.docx》由会员分享,可在线阅读,更多相关《用贪婪法求解船舶装卸问题python版.docx(9页珍藏版)》请在冰豆网上搜索。
![用贪婪法求解船舶装卸问题python版.docx](https://file1.bdocx.com/fileroot1/2022-10/14/3938566c-c514-4900-bac2-7df2354ba7ee/3938566c-c514-4900-bac2-7df2354ba7ee1.gif)
用贪婪法求解船舶装卸问题python版
一、课落款称
用贪婪法求解船舶装卸问题
二、课题内容和要求
设计要求:
学习算法设计中贪婪法的思想,设计算法编程解决如下现实问题:
码头上有n艘船舶同时等待装卸,而码头每次只能装卸一艘船舶。
船舶i需要装卸的时刻为ti,1≤i≤n。
应如何安排这n艘船舶的装卸顺序才能使得总的等待时刻达到最小?
(总的等待时刻是每艘船舶的等待时刻的总和)
(1)给出求解此问题的贪婪算法;
(2)说明你所给出的算法的时刻复杂性。
三、需求分析
功能分析:
贪婪算法是指,在对问题求解时,老是做出在当前看来是最好的选择。
也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。
贪婪算法不是对所有问题都能取得整体最优解,但对范围相当普遍的许多问题他能产生整体最优解或是整体最优解的近似解。
1.本程序要求利用的算法为贪婪法,那么咱们就要对它有必然的熟悉和了解。
因求解问题是老是要做出当前看来是最好的选择,所以咱们就要有一个约束条件来对符合要求的解进行甄选。
2.寻觅最优解:
假设有n条船停在码头,每艘船的编号别离是1~i(1<=i<=n),装卸时刻都是t[i],因为每次只能装卸1艘船,那么在装卸的时候剩余船的等待时刻就是t[i]。
每艘船的等待时刻就是如下的关系式:
Boat1:
0
Boat2:
0+t[1]
Boat3:
0+t[1]+t[2]
Boat4:
0+t[1]+t[2]+t[3]
Boat5:
0+t[1]+t[2]+t[3]+t[4]
Boat6:
0+t[1]+t[2]+t[3]+t[4]+t[5]
Boat7:
0+t[1]+t[2]+t[3]+t[4]+t[5]+t[6]
……
……
Boatn:
0+t[1]+t[2]+t[3]+t[4]+t[5]+t[6]+......+t[n-1]
所以,所有船舶的总等待时刻:
T总=n*0+(n-1)*t[1]+(n-2)*t[2]+(n-3)*t[3]+...+2*t[n-2]+t[n-1]
+0*t[n]
上式的含义是:
当第一艘船在卸货的时候,剩下的n-1艘船都要等待时长t[1],第二艘船在卸货的时候,剩下的n-2艘船都要继续等待时长t[2],...,剩下的情形以此类推。
现在咱们能够得出,让需要被等待时刻最多的t[1]若是越短,所有船舶等待的总时刻就会越短,所以猜想,t[1]>t[2]>t[3]>...>t[n-2]>t[n-1]
下面证明上面的猜想:
(用反证法)
若是让t[1]和t[2]的位置互换,即
T总1=n*0+(n-1)*t[2]+(n-2)*t[1]+(n-3)*t[3]+...+2*t[n-2]+t[n-1]+0*t[n]
现在T总1-T总=((n-1)*t[2]+(n-2)*t[1])-((n-1)*t[1]+(n-2)*t[2])
=t[2]-t[1]>0
所以T总1-T总>0,即T总1>T总
同理:
任意互换t[i]和t[j],总能取得T总1>T总,所以能够证明猜想成立。
所以能够取得挑选函数的算法,即:
每次挑选需要卸载时刻t[i]最短的船进行卸载,现在全数船舶的总等待时刻最短。
四、概要设计(利用Python语言实现)
1.概念船舶类:
classBoat(object):
def__init__(self,bNum,tNeed,tWait):
=bNum
=tNeed
=tWait
2.等待船舶列表初始化为空:
boatWaitList=[]
3.结束卸货船舶列表初始化为空:
boatFinishList=[]
开始
4.算法流程图:
初始化船舶信息,其中船舶卸货需要的时间tn为随机产生
foriinrange(NUM):
(Boat(i,randint(1,MAXTIME),0))
i=0
遍历NUM次boatWaitList,每次找出最小卸货时间,并添加到boatFinishList中。
然后删除此船舶信息,并把等待的船舶加上此船的卸货时间
foriinrange(NUM):
temp=NUM+1
minTime=MAXTIME
forjinrange(len(boatWaitList)):
ifboatWaitList[j].timeNeedminTime=boatWaitList[j].timeNeed
temp=j
iYES
NO
遍历结束卸货列表boatFinishList,求出每艘船的等待时间和所有穿的总等待时间
foriinrange(NUM):
timeSum+=boatFinishList[i].timeWait
结束
五、详细设计
#-*-coding:
gbk-*-
fromrandomimportrandint
#给出船舶总数
NUM=20
#预定一个最大卸货时刻
MAXTIME=20
#总等待时刻初始值为零
timeSum=0
#----------------------------------初始化船舶信息----------------------------------#
#概念Boat类,它有三个成员变量,别离为:
船舶编号boatNum,卸货需要的时刻timeNeed,
#卸货前需要等待的时刻timeWait
classBoat(object):
def__init__(self,bNum,tNeed,tWait):
=bNum
=tNeed
=tWait
#概念正在正待的船舶列表
boatWait=[]
#概念已经完成卸货的船舶列表
boatFinish=[]
print"\n全数%s艘船需要的时刻别离为:
"%NUM
#初始化所有船舶的信息,编号从0到NUM-1,需要时刻从1到MAXTIME中间随机,等待时刻设为0
foriinrange(NUM):
(Boat(i,randint(1,MAXTIME),0))
print"第%s艘船需要%s分钟."%(boatWait[i].boatNum+1,boatWait[i].timeNeed)
#-------------------------------------开始卸货-------------------------------------#
print"\n船舶卸货的顺序为:
"
#遍历NUM次等待船舶列表boatWait
foriinrange(NUM):
#temp值为记录当前等待船舶列表boatWait中,卸货需要的时刻最短的船舶在当前boatWait中的位置
temp=NUM+1
#minTime记录当前boatWait列表中,卸货所需的最短时刻
minTime=MAXTIME
#遍历当前第i次遍历的等待船舶列表boatWait
forjinrange(len(boatWait)):
#从0号船舶开始,若是当前船舶卸货所需的时刻小于minTime,则把它的时刻值赋给minTime
#同时记录下此船在当前boatWait中的位置
ifboatWait[j].timeNeed<=minTime:
minTime=boatWait[j].timeNeed
temp=j
#第i次遍历boatWait后,把卸货时刻最短的船舶boatWait[temp]加到完成卸货船舶列表boatFinish中
(boatWait[temp])
#在第i次遍历的bootWait列表中删除上面找出的最短时刻船舶
delboatWait[temp]
#对等待船舶列表中的所有船舶,加上上面找出的最短等待时刻minTime
forkinrange(len(boatWait)):
boatWait[k].timeWait+=minTime
#-------------------------------------卸货完成-------------------------------------#
#遍历卸货完成船舶列表boatFinish,求出船舶总等待时刻
foriinrange(NUM):
timeSum+=boatFinish[i].timeWait
print"第%s艘船,它等待了%s分钟."%(boatFinish[i].boatNum+1,boatFinish[i].timeWait)
print"\n所有船舶的总等待时刻为:
%s分钟,平均等待时刻为%s分钟"%(timeSum,timeSum/NUM)
六、测试数据及其结果分析
对NUM和MAXTIME去不同的值,能够取得不同级别的模拟结果:
1.设置NUM=20,MAXTIME=20
2.设置NUM=20,MAXTIME=10
3.设置NUM=10,MAXTIME=20
4.设置NUM=10,MAXTIME=10
七、调试进程中的问题
最初的想法很简单,既然每次都要找到卸货时刻最短的船,那不如在程序开始之前,就把船的序号依照卸货时刻的长短进行排序,如此一来只用遍历那个有序列表即可。
后来在做的进程中发觉如此并非是很简单,因为如此做只是在每次取值的时候变得简便,若是需要计算每艘船的等待时刻和所有穿的等待时刻之和的时候,仍是会很费事,所以后来改用每次遍历等待船舶列表,掏出最小值,同时顺便着就把其它船的等待时刻加了上去,最后求总等待时刻也很简单。
八、程序设计总结
这次程序设计很简单,主要在算法的正确性证明上发了些功夫,具体实现起来很简单。
加上Python语言壮大的列表功能,所以只用了30多行代码即完成。