Ein Versuch, ein häufiges MM-Diagrammproblem nicht manuell, sondern mit Python zu lösen.
Thema "Geben Sie die Mindestzykluszeit und die Prozesszuweisung an die Arbeitnehmer im Kreislaufprozess an."
condition
process_time_lst = [6, 3, 3, 10, 6, 8, 4, 5]
move_cost_lst = [1, 2, 3]
num_of_workers = 3
Was ich wissen möchte ist: "Welchen Prozess sollten Bären, Kaninchen und Schweine übernehmen?"
Erstellen Sie zunächst ein Wörterbuch mit Prozessnamen und deren Arbeit.
image
# Input:
[6, 3, 3, 10, 6, 8, 4, 5]
# Output:
{'process0':6, 'process1':3, ... , 'process7':5}
code
def generate_process_lst(process_time_lst):
lst = ['process'+str(val) for val in range(len(process_time_lst))]
return lst
process_lst = generate_process_lst(process_time_lst)
process_time_dict = {process:cost for process, cost in zip(process_lst, process_time_lst)}
Als nächstes führen wir eine Vorverarbeitung für die Berechnung durch. Fügen Sie zwischen allen Prozessen "move" ein, was bedeutet, dass Sie zum nächsten Prozess wechseln.
image
# Input
['process0', 'process1', ... , 'process7']
# Output
['process0', 'move', 'process1', 'move', ... , 'move', 'process7']
code
def generate_process_and_move_lst(process_lst):
len_lst = len(process_lst) - 1
process_and_move_lst = process_lst.copy()
for i in range(len_lst):
process_and_move_lst.insert(len_lst - i, 'move')
return process_and_move_lst
process_and_move_lst = generate_process_and_move_lst(process_lst)
Erstellen Sie als Nächstes eine Indexliste, in der die Liste "process_and_move_lst" getrennt ist.
image
# Input
['process0', 'move', 'process1', 'move', ... , 'move', 'process7']
# Output
[(0, 1, 2), (0, 1, 3), ... , (11, 13, 14), (12, 13, 14)]
code
import itertools
def generate_combi_lst(process_and_move_lst, num_of_workers):
len_lst = len(process_and_move_lst)
idx_lst = [x for x in range(len_lst)]
combi_lst = list(itertools.combinations(idx_lst, num_of_workers))
return combi_lst
combi_lst = generate_combi_lst(process_and_move_lst, num_of_workers)
Verwenden Sie die geschnitzte Indexliste, um eine Kombination von Prozesslisten zu generieren, die jedem Mitarbeiter zugewiesen werden.
image
# Input
['process0', 'move', 'process1', 'move', ... , 'move', 'process7']
[(0, 1, 2), (0, 1, 3), ... , (11, 13, 14), (12, 13, 14)]
# Output(image)* Es ist Teil der eigentlichen Ausgabeliste, da es schwierig ist zu verstehen, was Sie tun.
worker0 : ['move', 'process1', 'move']
worker1 : ['process2', 'move', 'process3', 'move', 'process4', 'move', 'process5', 'move', 'process6', 'move']
worker2 : ['process7', 'move', 'process0']
code
def generate_process_group_lst(process_and_move_lst, combi_lst):
process_group_lst = []
for combi in combi_lst:
if combi[0] != 0:
tmplst = [process_and_move_lst[0:combi[0]]]
else:
tmplst = []
for idx, val in enumerate(combi):
start = val
if idx == len(combi) - 1:
end = len(process_and_move_lst)
else:
end = combi[idx + 1]
tmplst.append(process_and_move_lst[start:end])
if combi[0] != 0:
tmplst[-1].append('move')
tmplst[-1] = tmplst[-1] + tmplst[0]
tmplst = tmplst[1:]
process_group_lst.append(tmplst)
return process_group_lst
process_group_lst = generate_process_group_lst(process_and_move_lst, combi_lst)
Wir berechnen die erforderliche Anzahl von Schritten für jeden Arbeiter.
image
# Input(image)* Es ist schwer zu verstehen, was Sie tun(Abkürzung
worker0 : ['move', 'process1', 'move']
worker1 : ['process2', 'move', 'process3', 'move', 'process4', 'move', 'process5', 'move', 'process6', 'move']
worker2 : ['process7', 'move', 'process0']
# Output(image)
[7, 39, 13] # move:1, process1:3, move:1, return_cost:2 → total 7
code
def calc_return_cost(process_set, process_time_dict, move_cost_lst):
tmplst = [val for val in process_set if val in process_time_dict.keys()]
if len(tmplst) == 0:
return_cost = move_cost_lst[0]
elif len(tmplst) == 1:
if len(process_set) == 2:
return_cost = move_cost_lst[0]
else:
return_cost = move_cost_lst[1]
else:
start_num = int(tmplst[0][-1])
end_num = int(tmplst[-1][-1])
if process_set[0] == 'move':
start_num -= 1
if process_set[-1] == 'move':
end_num += 1
tmp = abs(start_num - end_num)
distance = min( tmp, (len(process_time_dict.keys()) - tmp) )
if distance == 1:
return_cost = move_cost_lst[0]
elif distance == 2:
return_cost = move_cost_lst[1]
else:
return_cost = move_cost_lst[2]
return return_cost
def calc_cycleTime(process_group_lst, process_time_dict, move_cost_lst):
ct_lst = []
for process_group in process_group_lst:
ct_tmp_lst = []
for process_set in process_group:
ct = 0
ct += process_set.count('move') * move_cost_lst[0]
ct += sum([process_time_dict[val] for val in process_set if val in process_time_dict.keys()])
ct += calc_return_cost(process_set, process_time_dict, move_cost_lst)
ct_tmp_lst.append(ct)
ct_lst.append(ct_tmp_lst)
return ct_lst
ct_lst = calc_cycleTime(process_group_lst, process_time_dict, move_cost_lst)
Berechnen Sie die Zykluszeit für jede Prozesszuordnungskombination für jeden Mitarbeiter.
image
# Input
[[8, 2, 47], [8, 5, 44], ... ,[6, 2, 49], [6, 2, 49]]
# Output
[47, 44, ..., 49, 49]
code
max_ct_lst = [max(lst) for lst in ct_lst]
Berechnen Sie, welche Kombination die kürzeste Zykluszeit hat Rufen Sie den Index ab, in dem die Kombination vorhanden ist.
image
# Input
[47, 44, ..., 49, 49]
# Output
[58, 211]
code
min_ct = min(max_ct_lst)
min_ct_idx_lst = [idx for idx, val in enumerate(max_ct_lst) if val == min_ct]
Schließlich die Anzeige der minimalen Zykluszeit und Die Prozesszuordnung zu den Arbeitern, die dies erreichen, wird angezeigt.
image
# Output
minimumCT:21s
condition:
Worker0:['process0', 'move', 'process1', 'move', 'process2', 'move'], time=18s
Worker1:['process3', 'move', 'process4', 'move'], time=20s
Worker2:['process5', 'move', 'process6', 'move', 'process7'], time=21s
condition:
Worker0:['process1', 'move', 'process2', 'move', 'process3'], time=20s
Worker1:['move', 'process4', 'move', 'process5', 'move'], time=20s
Worker2:['process6', 'move', 'process7', 'move', 'process0', 'move'], time=21s
code
print(f'minimumCT:{min_ct}s')
for idx in min_ct_idx_lst:
print('condition:')
for worker, process in enumerate(process_group_lst[idx]):
print(f'Worker{worker}:{process}, time={ct_lst[idx][worker]}s')
Wenn alle Codes verbunden sind, wird es wie folgt.
code
import itertools
def generate_process_lst(process_time_lst):
lst = ['process'+str(val) for val in range(len(process_time_lst))]
return lst
def generate_process_and_move_lst(process_lst):
len_lst = len(process_lst) - 1
process_and_move_lst = process_lst.copy()
for i in range(len_lst):
process_and_move_lst.insert(len_lst - i, 'move')
return process_and_move_lst
def generate_combi_lst(process_and_move_lst, num_of_workers):
len_lst = len(process_and_move_lst)
idx_lst = [x for x in range(len_lst)]
combi_lst = list(itertools.combinations(idx_lst, num_of_workers))
return combi_lst
def generate_process_group_lst(process_and_move_lst, combi_lst):
process_group_lst = []
for combi in combi_lst:
if combi[0] != 0:
tmplst = [process_and_move_lst[0:combi[0]]]
else:
tmplst = []
for idx, val in enumerate(combi):
start = val
if idx == len(combi) - 1:
end = len(process_and_move_lst)
else:
end = combi[idx + 1]
tmplst.append(process_and_move_lst[start:end])
if combi[0] != 0:
tmplst[-1].append('move')
tmplst[-1] = tmplst[-1] + tmplst[0]
tmplst = tmplst[1:]
process_group_lst.append(tmplst)
return process_group_lst
def calc_return_cost(process_set, process_time_dict, move_cost_lst):
tmplst = [val for val in process_set if val in process_time_dict.keys()]
if len(tmplst) == 0:
return_cost = move_cost_lst[0]
elif len(tmplst) == 1:
if len(process_set) == 2:
return_cost = move_cost_lst[0]
else:
return_cost = move_cost_lst[1]
else:
start_num = int(tmplst[0][-1])
end_num = int(tmplst[-1][-1])
if process_set[0] == 'move':
start_num -= 1
if process_set[-1] == 'move':
end_num += 1
tmp = abs(start_num - end_num)
distance = min( tmp, (len(process_time_dict.keys()) - tmp) )
if distance == 1:
return_cost = move_cost_lst[0]
elif distance == 2:
return_cost = move_cost_lst[1]
else:
return_cost = move_cost_lst[2]
return return_cost
def calc_cycleTime(process_group_lst, process_time_dict, move_cost_lst):
ct_lst = []
for process_group in process_group_lst:
ct_tmp_lst = []
for process_set in process_group:
ct = 0
ct += process_set.count('move') * move_cost_lst[0]
ct += sum([process_time_dict[val] for val in process_set if val in process_time_dict.keys()])
ct += calc_return_cost(process_set, process_time_dict, move_cost_lst)
ct_tmp_lst.append(ct)
ct_lst.append(ct_tmp_lst)
return ct_lst
process_time_lst = [6, 3, 3, 10, 6, 8, 4, 5]
move_cost_lst = [1, 2, 3]
num_of_workers = 3
process_lst = generate_process_lst(process_time_lst)
process_time_dict = {process:cost for process, cost in zip(process_lst, process_time_lst)}
process_and_move_lst = generate_process_and_move_lst(process_lst)
combi_lst = generate_combi_lst(process_and_move_lst, num_of_workers)
process_group_lst = generate_process_group_lst(process_and_move_lst, combi_lst)
ct_lst = calc_cycleTime(process_group_lst, process_time_dict, move_cost_lst)
max_ct_lst = [max(lst) for lst in ct_lst]
min_ct = min(max_ct_lst)
min_ct_idx_lst = [idx for idx, val in enumerate(max_ct_lst) if val == min_ct]
print(f'minimumCT:{min_ct}s')
for idx in min_ct_idx_lst:
print('condition:')
for worker, process in enumerate(process_group_lst[idx]):
print(f'Worker{worker}:{process}, time={ct_lst[idx][worker]}s')
Wie oben erwähnt, habe ich versucht, das Mensch-Maschine-Diagramm mit Python zu lösen.