I have the following algorithm: I have a graph and a related I have a topological sorting (In graph theory, "a topological sort or topological ordering of a directed graph is a linear ordering of its vertices such that for every directed edge uv from vertex u to vertex v, u comes before v in the ordering. "). Given a start_position
and an end_position
(different from the start_one), I want to verify if shifting the element of the list that is at start_position
to the end_position
preserves the topological order, ie, if after the shifting I still have a topological order.
There are two cases : left_shift (if start_position
> end_position
) and right_shift (otherwise).
Here is my attempt:
def is_insert_ok(from_position:int, to_position:int, task_list:List[str], instance:pb.Problem):
# Problem has an attribute of all the tasks.
# it's a dictionnary whose keys are str and values are task objects
if from_position < to_position :
# right_shift
for task_temp in task_list[from_position+1:to_position+1]:
if task_list[from_position] in instance.all_tasks[task_temp].predecessors.keys():
return False
return True
if to_position < from_position :
# left shift
for task_temp in task_list[to_position:from_position]:
if task_temp in instance.all_tasks[task_list[from_position]].predecessors.keys():
return False
return True
What's wrong with that code? Well. Here is the thing, if I have some list and I want to compute
every possible shift for each element of the list, like in the function below:
def compute_neighbors(instance:pb.Problem, schedule:sl.Solution):
first_non_dummy_position = len(instance.orders) #there is some elements to ignore at the begining of the list because they can't be shifted
current_schedule = schedule
neighbors_list = []
task_list = current_schedule.activity_list.copy()
for first_task in task_list[first_non_dummy_position:]:
from_position = task_list.index(first_task)
for second_task in task_list[first_non_dummy_position:]:
task_list = current_schedule.activity_list.copy()
to_position = task_list.index(second_task)
if to_position != from_position:
if is_insert_ok(from_position,to_position, task_list, instance):
insert(from_position, to_position, task_list, instance) #see below the function insert
if task_list not in neighbors_list:
neighbors_list.append(task_list)
def insert(from_position:int, to_position:int, task_list:List[str], instance:pb.Problem):
element_to_insert = task_list.pop(from_position)
task_list.insert(to_position, element_to_insert)
When I have a list of length 2000, it took an eternity. Any ideas on how to make it faster?
I will welcome any attempt. Feel free to ask me if you don't understand something in my code.
if task_list not in neighbors_list
this is going to be expensive. The only case when you get duplicities is move right and move left by 1 position. Just skip one of these two cases.you should rearrange the program not to do the same things again and again and do only what you need.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.