简体   繁体   中英

My code is taking too long, how to imrpve it?

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.

  • You are doing the same things over and over again. If you know, that you can not move the item 20 places to the right, then you can not move it 40 places either. And definitely not 2458 places.
  • if you know, that you can move the item 100 places to the right, in next run you test if you can move it 101 places and start with testing those 100 items again. Why, you tested them in previous loop.
  • 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 make a copy of the list even if you do not need it. Make a copy after you test that the insertion is ok and you really need it.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM