Advertisement
Guest User

Untitled

a guest
Feb 8th, 2022
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.74 KB | None | 0 0
  1. from ortools.sat.python import cp_model
  2. from dataclasses import dataclass
  3. from collections.abc import Iterable
  4. import itertools
  5.  
  6. def flatten(l):
  7.     for el in l:
  8.         if isinstance(el, Iterable) and not isinstance(el, (str, bytes)):
  9.             yield from flatten(el)
  10.         else:
  11.             yield el
  12.  
  13. # def flatten(container):
  14. #     for i in container:
  15. #         if isinstance(i, (list,tuple)):
  16. #             for j in flatten(i):
  17. #                 yield j
  18. #         else:
  19. #             yield i
  20.  
  21.  
  22. model = cp_model.CpModel()
  23.  
  24.  
  25. horizon = 15
  26. workers = [1, 2, 3, 4]       # worker id
  27. workers_job_num = [3, 1, 1, 2]  # how much jobs every worker have
  28. job_types = [1, 2, 3, 4, 5]     # job type id
  29. job_type_num = [2, 1, 2, 1, 1]  #how much jobs every type have
  30. jobs = [(1, 1, 1, 3, 1),           # job id, job type, start, length, worker id
  31.         (2, 1, 6, 3, 1),
  32.         (3, 2, 1, 1, 1),
  33.         (4, 3, 4, 2, 2),
  34.         (5, 3, 10, 2, 3),
  35.         (6, 4, 7, 4, 4),
  36.         (7, 5, 9, 1, 4)]
  37.  
  38.  
  39. intervals_by_worker = []
  40. bools_by_worker = []
  41. start_by_worker = []
  42. end_by_worker = []
  43. for w in workers:
  44.     intervals_by_type = []
  45.     bools_by_type = []
  46.     start_by_type = []
  47.     end_by_type = []
  48.     for jt in job_types:
  49.         intervals_by_job_by_type = []       # all the jobs of some type for a worker
  50.         bools_by_job_by_type = []
  51.         start_by_job_by_type = []
  52.         end_by_job_by_type = []
  53.         for job in jobs:
  54.             if (jt == job[1]) and (w == job[4]):        # if jobType == current type of job and worker assigned to the job
  55.                 performed_at = model.NewBoolVar("performed by %dw %dj %dt" % (w, job[0], jt))
  56.                 start = model.NewIntVar(0, horizon, "start of %dw %dj %dt" % (w, job[0], jt))
  57.                 end = model.NewIntVar(0, horizon, "end of %dw %dj %dt" % (w, job[0], jt))
  58.                 optint = model.NewOptionalIntervalVar(start, job[3], end, performed_at, "interval of %dw %dj %dt" % (w, job[0], jt))
  59.                 bools_by_job_by_type.append(performed_at)
  60.                 intervals_by_job_by_type.append(optint)
  61.                 start_by_job_by_type.append(start)
  62.                 end_by_job_by_type.append(end)
  63.         intervals_by_type.append(intervals_by_job_by_type)
  64.         bools_by_type.append(bools_by_job_by_type)
  65.         start_by_type.append(start_by_job_by_type)
  66.         end_by_type.append(end_by_job_by_type)
  67.     intervals_by_worker.append(intervals_by_type)
  68.     bools_by_worker.append(bools_by_type)
  69.     start_by_worker.append(start_by_type)
  70.     end_by_worker.append(end_by_type)
  71.  
  72.  
  73. print("eereer")
  74.  
  75. ########################################################
  76. # разделяем работы по рабочему
  77. jobIntervals_by_worker = []
  78. for w in intervals_by_worker:
  79.     merged = list(itertools.chain(*w))
  80.     jobIntervals_by_worker.append(merged)
  81. print("eereer")
  82.  
  83.  
  84. # s = 4
  85. # l = 1
  86. # f = s+1
  87. # sleep_interval = model.NewIntervalVar(s, l, f, "test sleep interval for every worker")
  88. # sleep_interval = model.NewIntervalVar(1, 1, 2, "test sleep interval for every worker")
  89.  
  90. # for iw in range(len(ih)):
  91. #     jobIntervals_by_worker[iw] += flatten(ih[iw])
  92.  
  93.  
  94.  
  95.  
  96. # работы одного рабочего
  97. for ji in jobIntervals_by_worker:
  98.     # ji += [sleep_interval]      # append test sleep interval
  99.     model.AddNoOverlap(ji)
  100.  
  101. ########################################################
  102. # разделяем работы по типу работы
  103. jobIntervals_by_type = []
  104.  
  105. for t in job_types:
  106.     jobIntervals_by_type.append([])
  107.  
  108. # for i_hour in intervals_by_hour:
  109. for i_worker in intervals_by_worker:
  110.     for i_type in range(len(i_worker)):
  111.         jobIntervals_by_type[i_type] += flatten(i_worker[i_type])
  112.  
  113. # работы одного типа не пересекаются
  114. for ji in jobIntervals_by_type:
  115.     model.AddNoOverlap(ji)
  116.  
  117. ########################################################
  118. # разделяем performed_at по типам работы
  119. performedAt_by_type = []
  120. for t in job_types:
  121.     performedAt_by_type.append([])
  122.  
  123. # for b_hour in bools_by_hour:
  124. for b_worker in bools_by_worker:
  125.     for b_type in range(len(b_worker)):
  126.         performedAt_by_type[b_type] += flatten(b_worker[b_type])
  127.  
  128. # Количество performed_at (и соответственно интервалов) должно быть меньше равно необходимому
  129. for i in range(len(performedAt_by_type)):
  130.     model.Add(cp_model.LinearExpr.Sum(performedAt_by_type[i]) <= job_type_num[i])
  131.  
  132. ########################################################
  133. # разделяем performed_at по рабочим
  134. # разделяем работы по рабочему
  135. # jobIntervals_by_worker = []
  136. performedAt_by_worker = []
  137. for b in bools_by_worker:
  138.     merged = list(itertools.chain(*b))
  139.     jobIntervals_by_worker.append(merged)
  140.  
  141. # performedAt_by_worker = []
  142. # for t in workers:
  143. #     performedAt_by_worker.append([])
  144. #
  145. # for b_hour in bools_by_hour:
  146. #     for b_w in range(len(b_hour)):
  147. #         performedAt_by_worker[b_w] += flatten(b_hour[b_w])
  148.  
  149. # Количество performed_at (и соответственно интервалов) должно быть меньше равно необходимому
  150. for i in range(len(performedAt_by_worker)):
  151.     model.Add(cp_model.LinearExpr.Sum(performedAt_by_worker[i]) <= workers_job_num[i])
  152. ########################################################
  153. # maxit = list(itertools.chain(*bools_by_worker))
  154. model.Maximize(cp_model.LinearExpr.Sum(flatten(bools_by_worker)))
  155.  
  156.  
  157. print("ssssss")
  158. solver = cp_model.CpSolver()
  159. solver.parameters.log_search_progress = True
  160. status = solver.Solve(model)
  161.  
  162. print("##################################")
  163. print("Всего работ", len(jobs))
  164. print("Распределено работ", solver.ObjectiveValue())
  165. print("##################################")
  166. if status == cp_model.FEASIBLE or status == cp_model.OPTIMAL or status == cp_model.UNKNOWN:
  167.     # for h in range(len(bools_by_hour)):
  168.     for w in range(len(bools_by_worker)):
  169.         for jt in range(len(bools_by_worker[w])):
  170.             for job in range(len(bools_by_worker[w][jt])):                  # jobs of one type
  171.                 # print(solver.Value(bools_by_hour[h][w][jt][job]))
  172.                 if solver.Value(bools_by_worker[w][jt][job]) == 1:
  173.                     print(bools_by_worker[w][jt][job].Name())
  174.                     print(solver.Value(start_by_worker[w][jt][job]), solver.Value(end_by_worker[w][jt][job]))
  175.                     #     print("qwqwqw")
  176. else:
  177.     print("Unfeasible")
  178.  
  179. # сделать список работ для каждого рабочего по типу работы. Количество таких работ <= количеству для рабочего
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement