Multiple methods for rectify, merge of mapping. TODO: rectify loop

This commit is contained in:
Maximilian Schlosser 2017-07-09 18:57:52 +02:00
parent 8ed9d800c3
commit 85e61f91fb
2 changed files with 82 additions and 30 deletions

View file

@ -4,7 +4,8 @@ import random
def pull_fwd(solution):
""" Pull a task from a pseudo-random position to the position of
"""
Pull a task from a pseudo-random position to the position of
a random task forward. If the task directly in front is part
of the same job, pull that instead. The first task can never
be pulled forward. Will not rectify solutions.
@ -15,57 +16,108 @@ def pull_fwd(solution):
while(solution[old_idx][1][0] == solution[old_idx-1][1][0]):
old_idx -= 1
new_idx = random.randint(0, old_idx-1)
for task in solution[new:old_idx]:
for task in solution[new_idx:old_idx]:
if(task[1][0] == solution[old_idx][1][0]):
break
else:
new_solution = solution[:]
task = solution[old_idx]
new_solution.remove(task)
new_solution.insert(new_idx, task)
return (new_solution, new_idx)
solution.remove(task)
solution.insert(new_idx, task)
return (solution, new_idx)
def accept(solution):
""" Accept the current generated solution and evaluate it.
"""
Accept the current generated solution and evaluate it.
Maybe skip this during the first step to generate a more
random solution.
"""
return 3
#TODO: Loop over successors
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.
"""
global problem
solution[idx][0] = solution[idx+1][0]
#move previous task on the same machine back if clash
""" task = solution[idx][1]
prev_task = solution[idx-1][1]
while(problem[task[0]][task[1]][1] == problem[prev_task[0]][prev_task[1]][1]):
solution[idx-1][0] += problem[task[0]][task[1]][0]
solution[idx], solution[idx-1] = solution[idx-1], solution[idx]
idx -= 1
task = solution[idx][1]
prev_task = solution[idx-1][1]
del prev_task
update_begin(solution, idx)
correct_indices(solution, idx)
for task in solution[idx:]:
correct_machine(solution, solution.index(task))
correct_precedence(solution, solution.index(task))
def update_begin(solution, idx):
"""
Update the start time of the given task.
"""
#make parallel
solution[idx][0] = solution[idx-1][0]
global problem
task = solution[idx]
machine = ( x for x in solution[idx-1::-1] if problem[x[1]][1] == problem[task[1]][1] )
prev_mach = next(machine, None)
job = ( x for x in solution[idx-1::-1] if task[1][0] == x[1][0] )
prev_job = next( job, None)
end_mach = 0
end_job = 0
if prev_mach:
end_mach = problem[prev_mach[1]][0] + prev_mach[0]
if prev_job:
end_job = problem[prev_job[1]][0] + prev_job[0]
solution[idx][0] = max(end_mach, end_job, task[0])
def correct_indices(solution, idx):
"""
Adapt solution to reestablish ascending order of execution times.
"""
task = solution[idx]
tasks = [ x for x in solution[idx:] if x[0] < task[0]]
if tasks:
solution.remove(task)
solution.insert(idx + len(tasks), task)
def correct_machine(solution, idx):
"""
Push jobs on machines back if conflicts exist.
"""
task = solution[idx]
end = problem[task[1]][0] + task[0]
possible_conf = ( x for x in solution[idx+1:] if problem[x[1]][1] == problem[task[1]][1])
conflict = next(( x for x in possible_conf if x[0] < end ), None)
if(conflict):
idx = solution.index(conflict)
solution[idx][0] = end
def correct_precedence(solution, idx):
"""
Check precedence relation and correct if needed.
"""
task = solution[idx]
end = problem[task[1][0] + task[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)
if(conflict):
idx = solution.index(conflict)
solution[idx][0] = end
def generate(solution, steps):
"""Generate a new solution from an existing solution with a
"""
Generate a new solution from an existing solution with a
specified number of max steps.
"""
solution = solution[:]
options = [pull_fwd, accept]
option = random.choice(options)
return option(solution)
def mock():
""" Reads a mock problem and creates the corresponding enumerated
"""
Reads a mock problem and creates the corresponding enumerated
solution. Should clean up the namespace afterwards.
"""
global problem

View file

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