Pull_Fwd inkl. Rectify funktionstüchtig TODO: Accept + Simanneal + Output

This commit is contained in:
lukasstracke 2017-07-10 23:17:33 +02:00
parent a7f1a86748
commit 6be2e20cc7
2 changed files with 48 additions and 21 deletions

View file

@ -13,17 +13,23 @@ def pull_fwd(solution):
Returns the modified solution and the tasks index. Returns the modified solution and the tasks index.
""" """
old_idx = random.randint(1, len(solution)-1) old_idx = random.randint(1, len(solution)-1)
print("old_idx" + str(old_idx))
while(solution[old_idx][1][0] == solution[old_idx-1][1][0]): while(solution[old_idx][1][0] == solution[old_idx-1][1][0]):
old_idx -= 1 old_idx -= 1
#Catch case of the op to be pulled being 0
print("old_idx" + str(old_idx))
if(old_idx == 0):
return pull_fwd(solution)
new_idx = random.randint(0, old_idx-1) new_idx = random.randint(0, old_idx-1)
for task in solution[new_idx:old_idx]: for task in solution[new_idx:old_idx]:
if(task[1][0] == solution[old_idx][1][0]): if(task[1][0] == solution[old_idx][1][0]):
break #break
else: return pull_fwd(solution)
task = solution[old_idx] #else:
solution.remove(task) task = solution[old_idx]
solution.insert(new_idx, task) solution.remove(task)
return (solution, new_idx) solution.insert(new_idx, task)
return rectify(solution, new_idx)
def accept(solution): def accept(solution):
@ -41,13 +47,16 @@ def rectify(solution, idx):
Transform solution by adapting the begin times and delaying Transform solution by adapting the begin times and delaying
tasks on the same machine if affected. tasks on the same machine if affected.
""" """
solution[idx][0] = solution[idx+1][0] solution[idx] = (solution[idx+1][0],) + solution[idx][1:]
update_begin(solution, idx) update_begin(solution, idx)
correct_indices(solution, idx) correct_indices(solution, idx)
for task in solution[idx:]: for i in range(idx, len(solution)-1):
correct_machine(solution, solution.index(task)) print("i: " + str(i))
correct_precedence(solution, solution.index(task)) correct_machine(solution, i)
print(solution)
correct_precedence(solution, i)
print(solution)
def update_begin(solution, idx): def update_begin(solution, idx):
""" """
@ -57,19 +66,23 @@ def update_begin(solution, idx):
global problem global problem
task = solution[idx] task = solution[idx]
if(idx == 0):
solution[idx] = (0,) + solution[idx][1:]
return
#find the next task with condition=true, if exists #find the next task with condition=true, if exists
machine = ( x for x in solution[idx-1::-1] if problem[x[1]][1] == problem[task[1]][1] ) machine = ( x for x in solution[idx-1::-1] if problem[x[1]][1] == problem[task[1]][1] )
prev_mach = next(machine, None) #returns the task or None prev_mach = next(machine, None) #returns the task or None
job = ( x for x in solution[idx-1::-1] if task[1][0] == x[1][0] ) job = ( x for x in solution[idx-1::-1] if task[1][0] == x[1][0] )
prev_job = next( job, None) prev_job = next(job, None)
end_mach = 0 end_mach = 0
end_job = 0 end_job = 0
if prev_mach: if prev_mach:
end_mach = problem[prev_mach[1]][0] + prev_mach[0] end_mach = problem[prev_mach[1]][0] + prev_mach[0]
if prev_job: if prev_job:
end_job = problem[prev_job[1]][0] + prev_job[0] end_job = problem[prev_job[1]][0] + prev_job[0]
solution[idx][0] = max(end_mach, end_job, task[0]) solution[idx] = (max(end_mach, end_job, task[0]),) + solution[idx][1:]
def correct_indices(solution, idx): def correct_indices(solution, idx):
@ -93,7 +106,8 @@ def correct_machine(solution, idx):
conflict = next(( x for x in possible_conf if x[0] < end ), None) conflict = next(( x for x in possible_conf if x[0] < end ), None)
if(conflict): if(conflict):
idx = solution.index(conflict) idx = solution.index(conflict)
solution[idx][0] = end solution[idx] = (end,) + solution[idx][1:]
correct_indices(solution,idx)
def correct_precedence(solution, idx): def correct_precedence(solution, idx):
@ -101,12 +115,21 @@ def correct_precedence(solution, idx):
Check precedence relation and correct if needed. Check precedence relation and correct if needed.
""" """
task = solution[idx] task = solution[idx]
end = problem[task[1][0] + task[0] end = problem[task[1]][0] + task[0]
possible_conf = ( x for x in solution[idx+1:] if x[1][0] == task[1][0] ) possible_conf = ( x for x in solution[idx+1:] if x[1][0] == task[1][0] )
conflict = next(( x for x in possible_conf if x[0] < end ), None) conflict = next(( x for x in possible_conf if x[0] < end or x[1][1] < task[1][1]), None)
if(conflict): if(conflict):
idx = solution.index(conflict) idx = solution.index(conflict)
solution[idx][0] = end print("idx->" + str(idx))
if(conflict[0] < end):
solution[idx] = (end,) + solution[idx][1:]
correct_indices(solution,idx)
if(conflict[1][1] < task[1][1]):
new_start = solution[idx][0] + solution[idx][1][1]
print("new_start: " + str(new_start))
solution.remove(task)
task = (new_start,) + task[1:]
solution.insert(idx, task)
def generate(old_solution, steps): def generate(old_solution, steps):
""" """
@ -115,9 +138,13 @@ def generate(old_solution, steps):
""" """
solution = old_solution[:] solution = old_solution[:]
options = [pull_fwd, accept] options = [pull_fwd, accept]
option = random.choice(options) while(steps > 0):
return option(solution) option = random.choice(options)
solution = option(solution)
if(option == accept):
break
steps -= 1
return solution
def mock(): def mock():
""" """

View file

@ -1,10 +1,10 @@
from Parser import JobShopProblem as Problem from Parser import JobShopProblem as Problem
def enumerate(problem): def enumerate(problem):
schedule = ( (job, task) for job in range(0, problem.jobs) for task in range(0, problem.get_tasks_by_job(job)) ) schedule = ( (job, task) for job in range(0, problem.jobs) for task in range(0, len(problem.get_tasks_by_job(job))) )
begin = 0 begin = 0
solution = [] solution = []
for task in schedule: for task in schedule:
solution.append((begin, task)) solution.append((begin, task))
begin += problem[task[0]][task[1]][0] begin += problem[task][0]
return solution return solution