[英]Recursive Scheduling algorithm does not work correctly Python
我创建了一个递归调度算法,该算法采用了一组包含开始时间和结束时间的Event对象。 这些时间是随机生成的,开始时间始终小于结束时间。 时间是0-24之间的数字(一天24小时,24 == 0)
这是随机事件数组生成器的代码:
def randomEventArray(s):
e = []
rand1 = 0
rand2 = 0
for i in range(s):
rand1 = random.randint(0,21)
rand2 = random.randint(rand1+1,23)
e.append(Event(rand1,rand2))
return e
这是Event对象的代码:
class Event:
def __init__(self, start, end):
self.startTime = start
self.endTime = end
def __repr__(self):
return str(self)
def __str__(self):
return (str([self.startTime,self.endTime]))
现在是引起问题的部分。 我创建了一段代码,该代码递归地处理了生成的事件数组,并列出了可以在24小时内举行的最多事件。 任何事件都不应重叠。
这是创建的递归贪婪算法:
def scheduleGD2(E):
events = []
scheduleRecGD2(E,0,0, events)
return events[:]
def scheduleRecGD2(E, eventPos, startTime,events):
while eventPos < len(E) and E[eventPos].startTime < startTime:
eventPos += 1
if eventPos == len(E):
return []
minEndPos = eventPos
for i in range(eventPos+1, len(E)):
if E[i].endTime < E[minEndPos].endTime:
minEndPos = i
events.append(E[minEndPos])
return scheduleRecGD2(E, minEndPos+1, E[minEndPos].endTime, events)
E = randomEventArray(20)
print(scheduleGD2(E))
该算法的预期输出是具有最多事件的数组,这些事件可以在单个24小时内同时发生而不会重叠。 例如
[[0, 1], [1, 3], [4, 8], [9, 17], [17, 24]]
但是,我收到以下输出:
[[0, 1], [12, 16], [12, 16], [5, 17], [21, 22]]
这清楚地显示了Arr [2]与Arr [1](Arr [2] .StartTime(12)<Arr [1] .EndTime [16])重叠,这是不应该发生的。
有什么问题,为什么会这样?
我对您的代码进行了调试,包括用简单的对元组替换“事件”包。
def scheduleRecGD2(E, eventPos, startTime, events):
print("ENTER Rec", "eventPos", eventPos, "\tstartTime", startTime, "\n\tevents", events)
while eventPos < len(E) and E[eventPos][0] < startTime:
eventPos += 1
if eventPos == len(E):
return []
minEndPos = eventPos
print("\tFIRST: minEndPos", minEndPos, E[minEndPos])
for i in range(eventPos+1, len(E)):
if E[i][1] < E[minEndPos][1]:
minEndPos = i
events.append(E[minEndPos])
print("\tTRACE: minEndPos", minEndPos, E[minEndPos])
return scheduleRecGD2(E, minEndPos+1, E[minEndPos][1], events)
# Main program
E = randomEventArray(8)
print(E)
print(scheduleGD2(E))
输出:
[(15, 20), (4, 7), (17, 20), (18, 23), (2, 7), (8, 23), (15, 23), (18, 20)]
ENTER Rec eventPos 0 startTime 0
events []
FIRST: minEndPos 0 (15, 20)
TRACE: minEndPos 1 (4, 7)
ENTER Rec eventPos 2 startTime 7
events [(4, 7)]
FIRST: minEndPos 2 (17, 20)
TRACE: minEndPos 4 (2, 7)
ENTER Rec eventPos 5 startTime 7
events [(4, 7), (2, 7)]
FIRST: minEndPos 5 (8, 23)
TRACE: minEndPos 7 (18, 20)
ENTER Rec eventPos 8 startTime 20
events [(4, 7), (2, 7), (18, 20)]
[(4, 7), (2, 7), (18, 20)]
分析
您的算法多次跳闸。 最重要的是,当您第二次进入该例程时,您会找到具有可接受的开始时间的第一条记录,并将其结束时间作为“击败数字”。 从那时起,您将完全忽略呼叫中给定的开始时间以及其余事件的开始时间, 仅查找超出相对任意间隔的结束时间的内容。
您可以通过这种方式继续浏览列表,随意更改给定的开始时间,直到到达列表的末尾。
修理
请遵循在线提供的许多解决方案:首先,按照结束时间的顺序对列表进行排序,然后按照开始时间进行排序。 现在,遍历列表很简单,找到第一个可用的开始时间比列表中最近添加的元组晚(a)。 (b)不少于当前结束时间。
鉴于解决方案的可用性,我将其留给学生作为练习。 从对随机化例程的简单更改开始:
return sorted(e)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.