Reputation: 177
Assume we have a python list
list = [[1,2,3],[4,5,6],[7,8,9]]
I define the sum as the following,
sum: is the total sum of single entries (different index) from each of the sublists.
This sounds complex so I will give an example,
for the above list, 1 + 5 + 9 is one of the sums because 1 is from the first sublist and 5 is from the second sublist and 9 is from the 3rd sublist and they all have different positions in their corresponding sublist.
so i can't have 1 + 4 + 7
because 1,4 & 7 are first entries in their sublists.
I can't have 1 + 5 + 8
because 5 & 8 are both second entries in their list and so on
for example, and I want to find the highest sum of the total of individual entries of each of the sublist !!
How can I iterate over all these possible sums and then get the highest out of all these sums.
For the above list, we have 3^3=27 different sums.
And is there an efficient way to do it with python ?
Upvotes: 1
Views: 491
Reputation: 8059
I don't know about execution efficiency, but for code writing efficiency you can consider:
for k in itertools.permutations(lst):
print(sum([j[i] for i, j in enumerate(k)]))
Will only work for square list as in OP example.
Upvotes: 0
Reputation: 2153
This is a classic problem that can be solved using Hungarian algorithm. There is an implementation in sklearn:
from sklearn.utils.linear_assignment_ import linear_assignment
import numpy as np
M = [[1,2,3],[4,5,6],[7,8,9]]
M = np.array(M) #convert to numpy array
result = linear_assignment(M)
answer = sum(M[cell[0]][cell[1]] for cell in result)
Iterate over all possible sums is a bad idea (O(N!)). The algorithm above must run in O(N^3).
Upvotes: 8
Reputation: 54163
The naive implementation uses itertools.product
to produce all possible pairings, then filters out the ones that won't work due to indexing issues.
from itertools import product
lst = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
with_indices = [ [(idx, val) for idx, val in enumerate(sublst)] for sublst in lst]
# [ [(0, 1), (1, 2), (2, 3)],
# [(0, 4), (1, 5), (2, 6)],
# [(0, 7), (1, 8), (2, 9)] ]
total_product = product(*with_indices)
filtered_product = [
[p[0][1], p[1][1], p[2][1]] for p in total_product if
len(set([p[0][0], p[1][0], p[2][0]])) == 3]
# p[0][1], p[1][1], p[2][1] refers to original values
# p[0][0], p[1][0], p[2][0] refers to original indices
# asserting the length of the set of indices is 3 ensures that all are unique.
# [[1, 5, 9],
# [1, 6, 8],
# [2, 4, 9],
# [2, 6, 7],
# [3, 4, 8],
# [3, 5, 7]]
result = max(filtered_product, key=sum)
Upvotes: 0