algorithm-in-python/search/schedule.py

132 lines
3.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

''' mbinary
#########################################################################
# File : schedule.py
# Author: mbinary
# Mail: zhuheqin1@gmail.com
# Blog: https://mbinary.xyz
# Github: https://github.com/mbinary
# Created Time: 2018-11-30 12:00
# Description:
#########################################################################
'''
'''
回溯全空间搜索, 剪枝优化
设有n个任务由k个可并行工作的机器来完成完成任务i需要时间为 。试设计一个算法找出完成这n个任务的最佳调度使完成全部任务的时间最早。
'''
from time import time
from functools import total_ordering
@total_ordering
class record:
def __init__(self, nums=None):
if nums is None:
nums = []
self.nums = nums
self.sum = sum(nums)
def append(self, x):
self.nums.append(x)
self.sum += x
def pop(self):
x = self.nums.pop()
self.sum -= x
return x
def __repr__(self):
return repr(self.nums)
def __lt__(self, r):
return self.sum < r.sum
def __eq__(self, r):
return self.sum == r.sum
def tolist(self):
return self.nums.copy()
def __hash__(self):
return self.sum
def schedule(works, k):
def backtrackSearch(i, lsts):
nonlocal best, rst
if i == n:
cost = max(r.sum for r in lsts)
if best > cost:
best = cost
rst = [st.tolist() for st in lsts]
else:
for cur in set(lsts):
if best > cur.sum+works[i]:
cur.append(works[i])
backtrackSearch(i+1, lsts)
cur.pop()
def findInitial(i, lst):
nonlocal best
if i == n:
cost = max(lst)
if best > cost:
best = cost
else:
mn = lst[0]
idx = 0
visited = set()
for j, cur in enumerate(lst):
if cur not in visited:
visited.add(cur)
if mn > cur:
mn = cur
idx = j
lst[idx] += works[i]
findInitial(i+1, lst)
lst[idx] -= works[i]
n = len(works)
print()
print('machine Num:', n)
print('works :', works)
rst = None
works.sort(reverse=True) # key step
best = sum(works[:n-k+1])
t = time()
findInitial(0, [0]*k) # key step
t1 = time()-t
print('init solution: {} cost time {:.6f}s'.format(best, t1))
t = time()
backtrackSearch(0, [record() for i in range(k)])
t2 = time()-t
print('final solution: {} cost time {:.6f}s'.format(best, t2))
print('schedule plan:', rst)
return best, rst
if __name__ == '__main__':
from random import randint
schedule([47, 20, 28, 44, 21, 45, 30, 39, 28, 33], 3)
schedule([98, 84, 50, 23, 32, 99, 22, 76, 72, 61, 81, 39, 76, 54, 37], 5)
schedule([39, 39, 23, 45, 100, 69, 21, 81, 39, 55,
20, 86, 34, 53, 58, 99, 36, 45, 46], 8)
'''
machine Num: 19
works : [39, 39, 23, 45, 100, 69, 21, 81, 39, 55, 20, 86, 34, 53, 58, 99, 36, 45, 46]
works 经过逆序排序
init solution: 135 cost time 0.000196s
final solution: 126 cost time 0.022922s
schedule plan: [[100, 21], [99, 23], [86, 39], [81, 45], [69, 53], [58, 45, 20], [55, 36, 34], [46, 39, 39]]
works 没有经过排序
init solution: 168 cost time 0.000179s
final solution: 126 cost time 10.646307s
schedule plan: [[39, 86], [39, 34, 53], [23, 99], [45, 39, 36], [100, 20], [69, 55], [21, 58, 46], [81, 45]]
'''