-
Notifications
You must be signed in to change notification settings - Fork 89
/
Copy pathweighted_interval_scheduling.py
88 lines (67 loc) · 2.41 KB
/
weighted_interval_scheduling.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
"""
Weighted Interval Scheduling
Explained YouTube video: https://www.youtube.com/watch?v=iIX1YvbLbvc
Implementation walkthrough video: https://www.youtube.com/watch?v=dU-coYsd7zw
Programmed by Aladdin Persson <aladdin.persson at hotmail dot com>
2020-02-13 Initial programming
2020-03-28 Cleaned up code by making WeightedIntervalScheduling class
Time complexity: O(nlogn)
"""
import bisect
class WeightedIntervalScheduling(object):
def __init__(self, I):
self.I = sorted(I, key=lambda tup: tup[1]) # (key = lambda tup : tup[1])
self.OPT = []
self.solution = []
def previous_intervals(self):
start = [task[0] for task in self.I]
finish = [task[1] for task in self.I]
p = []
for i in range(len(self.I)):
# finds idx for which to input start[i] in finish times to still be sorted
idx = bisect.bisect(finish, start[i]) - 1
p.append(idx)
return p
def find_solution(self, j):
if j == -1:
return
else:
if (self.I[j][2] + self.compute_opt(self.p[j])) > self.compute_opt(j - 1):
self.solution.append(self.I[j])
self.find_solution(self.p[j])
else:
self.find_solution(j - 1)
def compute_opt(self, j):
if j == -1:
return 0
elif (0 <= j) and (j < len(self.OPT)):
return self.OPT[j]
else:
return max(
self.I[j][2] + self.compute_opt(self.p[j]), self.compute_opt(j - 1)
)
def weighted_interval(self):
if len(self.I) == 0:
return 0, self.solution
self.p = self.previous_intervals()
for j in range(len(self.I)):
opt_j = self.compute_opt(j)
self.OPT.append(opt_j)
self.find_solution(len(self.I) - 1)
return self.OPT[-1], self.solution[::-1]
# Small Example
# if __name__ == '__main__':
# # They are labeled as: (start, end, weight)
# t1 = (0,3,3)
# t2 = (1,4,2)
# t3 = (0,5,4)
# t4 = (3,6,1)
# t5 = (4,7,2)
# t6 = (3,9,5)
# t7 = (5,10,2)
# t8 = (8,10,1)
# I = [t1,t2,t3,t4,t5,t6,t7,t8]
# weightedinterval = WeightedIntervalScheduling(I)
# max_weight, best_intervals = weightedinterval.weighted_interval()
# print('Maximum weight: ' + str(max_weight))
# print('The best items to take are: ' + str(best_intervals))