For a vehicle routing problem, I need to check for a certain list with multiple routes, what the insertion of a certain city would do for the total length of that route list. All the cities are represented by integer numbers.
Basically I need to insert an integer element into every possible "location", and then proceed to calculate the shortest distance of all possibilities. Consider this nested list of routes:
rl = [[0, 7, 40, 41, 96, 34, 75, 127, 48, 65, 79, 27, 126, 78, 0],
[0, 56, 45, 2, 67, 66, 59, 124, 82, 133, 102, 54, 57, 0],
[0, 35, 97, 81, 87, 80, 61, 98, 101, 52, 83, 60, 109, 39, 53, 0]]
Where 0 is the headquarters, here is where the route starts and ends every day. Say I need to insert a city which is represented by a 9.
Expected output would than be:
[[0, 9, 7, 40, 41, 96, 34, 75, 127, 48, 65, 79, 27, 126, 78, 0], ...rest of list]
[[0, 7, 9, 40, 41, 96, 34, 75, 127, 48, 65, 79, 27, 126, 78, 0], ...rest of list]
[[0, 7, 40, 9 41, 96, 34, 75, 127, 48, 65, 79, 27, 126, 78, 0], ...rest of list]
[[0, 7, 40, 41, 9 96, 34, 75, 127, 48, 65, 79, 27, 126, 78, 0], ...rest of list]
and so on, until every possible location has been tried and appended to feasible_matrix.
I wrote the following function to achieve this:
def check_possible_insertions(city, route_list):
feasible_matrix = []
for i, route in enumerate(route_list):
for j, value in enumerate(route[1:]):
possibility = route_list.copy()
possibility[i].insert(j+1, city)
feasible_matrix.append(possibility)
return feasible_matrix
Where i first create a "feasible" matrix, then loop over all the routes. Then, for every possible position in a route (second for-loop), I create a copy of route_list (The original route list passed as parameter). Then I insert the city in the right route [i] at the right place (j) and append the possibility to my feasible_matrix.
At least, that's how this code should work in my mind. A function call check_possible_insertions(9, rl)
tells me the code doesn't behave as expected: It's simply inserting #j number of 9's at the front of every route. Am overlooking something but cannot figure out what. What am I doing wrong?
You are only shallow copying the whole list of lists. You meant to shallow copy an individual route:
possibility = route.copy()
possibility.insert(j, city)
Also in your inner loop value
is unused, so a possible version of your function is:
def check_possible_insertions(city, route_list):
feasible_matrix = []
for i, route in enumerate(route_list):
new_list=[]
feasible_matrix.append(new_list)
for j in range(1, len(route)):
possibility = route.copy()
possibility.insert(j, city)
new_list.append(possibility)
return feasible_matrix
This generates a list of lists of routes, which could be reduced down to a new rl
when the optimal route is found. eg:
rl = [[0, 7, 40, 78, 0],
[0, 56, 45, 2, 0],
[0, 35, 97, 60, 0]]
result = check_possible_insertions(9,rl)
print(result)
Output:
[[[0, 9, 7, 40, 78, 0], [0, 7, 9, 40, 78, 0], [0, 7, 40, 9, 78, 0], [0, 7, 40, 78, 9, 0]], [[0, 9, 56, 45, 2, 0], [0, 56, 9, 45, 2, 0], [0, 56, 45, 9, 2, 0], [0, 56, 45, 2, 9, 0]], [[0, 9, 35, 97, 60, 0], [0, 35, 9, 97, 60, 0], [0, 35, 97, 9, 60, 0], [0, 35, 97, 60, 9, 0]]]
The problem is that route_list.copy()
creates a shallow copy, the inner list are the same objects, as an example:
rl = [[0, 7, 40, 41, 96, 34, 75, 127, 48, 65, 79, 27, 126, 78, 0],
[0, 56, 45, 2, 67, 66, 59, 124, 82, 133, 102, 54, 57, 0],
[0, 35, 97, 81, 87, 80, 61, 98, 101, 52, 83, 60, 109, 39, 53, 0]]
cp = rl.copy()
cp[0].insert(0, 9)
for i in rl:
print(i)
Output
[9, 0, 7, 40, 41, 96, 34, 75, 127, 48, 65, 79, 27, 126, 78, 0]
[0, 56, 45, 2, 67, 66, 59, 124, 82, 133, 102, 54, 57, 0]
[0, 35, 97, 81, 87, 80, 61, 98, 101, 52, 83, 60, 109, 39, 53, 0]
As you can see the first list of rl
was modified because it is the same as the first in cp
.
As a solution, you could use deepcopy
import copy
def check_possible_insertions(city, route_list):
feasible_matrix = []
for i, route in enumerate(route_list):
for j, value in enumerate(route[1:]):
possibility = copy.deepcopy(route_list)
possibility[i].insert(j+1, city)
feasible_matrix.append(possibility)
return feasible_matrix
Output (first 5 results)
[[0, 9, 7, 40, 41, 96, 34, 75, 127, 48, 65, 79, 27, 126, 78, 0], [0, 56, 45, 2, 67, 66, 59, 124, 82, 133, 102, 54, 57, 0], [0, 35, 97, 81, 87, 80, 61, 98, 101, 52, 83, 60, 109, 39, 53, 0]]
[[0, 7, 9, 40, 41, 96, 34, 75, 127, 48, 65, 79, 27, 126, 78, 0], [0, 56, 45, 2, 67, 66, 59, 124, 82, 133, 102, 54, 57, 0], [0, 35, 97, 81, 87, 80, 61, 98, 101, 52, 83, 60, 109, 39, 53, 0]]
[[0, 7, 40, 9, 41, 96, 34, 75, 127, 48, 65, 79, 27, 126, 78, 0], [0, 56, 45, 2, 67, 66, 59, 124, 82, 133, 102, 54, 57, 0], [0, 35, 97, 81, 87, 80, 61, 98, 101, 52, 83, 60, 109, 39, 53, 0]]
[[0, 7, 40, 41, 9, 96, 34, 75, 127, 48, 65, 79, 27, 126, 78, 0], [0, 56, 45, 2, 67, 66, 59, 124, 82, 133, 102, 54, 57, 0], [0, 35, 97, 81, 87, 80, 61, 98, 101, 52, 83, 60, 109, 39, 53, 0]]
[[0, 7, 40, 41, 96, 9, 34, 75, 127, 48, 65, 79, 27, 126, 78, 0], [0, 56, 45, 2, 67, 66, 59, 124, 82, 133, 102, 54, 57, 0], [0, 35, 97, 81, 87, 80, 61, 98, 101, 52, 83, 60, 109, 39, 53, 0]]
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.