简体   繁体   中英

Find the Highest Sum in a Combination of Numbers

Lets say I have this:

1A=6 2A=4.5  3A=6

1B=7 2B=6    3B=7.5

1C=6 2C=6.75 3C=9

I want to find the combination of numbers that yields the highest sum. None of the numbers before the letters can be used more than once and none of the letters after the numbers can be used more than once. eg. 1A+2B+3C, 1C+2B+3A are valid. 1A+1B+2B,3A+2B+3B,1A+2A+3A are invalid.

In this case the highest sum is 1A+2B+3C=21 . How would I find this result and combination using python?

Thanks in advance

For each of the entries with the same numeric prefix, find the maximum among them. Then sum up all those maximum values, and you will get the maximum sum with the given restriction.

If the numbers and the letters must be unique, then it becomes a problem that can be solved with Hungarian algorithm .

The Hungarian method is a combinatorial optimization algorithm that solves the assignment problem in polynomial time [...]

From the description of assignment problem :

The assignment problem is one of the fundamental combinatorial optimization problems in the branch of optimization or operations research in mathematics. It consists of finding a maximum weight matching in a weighted bipartite graph.

In its most general form, the problem is as follows:

There are a number of agents and a number of tasks. Any agent can be assigned to perform any task, incurring some cost that may vary depending on the agent-task assignment. It is required to perform all tasks by assigning exactly one agent to each task and exactly one task to each agent in such a way that the total cost of the assignment is minimized.

I'm not a python guy, so the following code might seem not that "python style", but the algorithm should be ok.

#test input. the matrix can be any n * n size.
matrix = [[6,7,6],[4.5,6,6.75],[6,7.5,9]]

#assistant array to track which numbers we have already used.
#check[i] = 1 if i has been used
check = [0]* len(matrix)

#max sum
max_sum = 0

def getMax(matrix,check,row,curr_sum):
    global max_sum
    #base case, we have reached the last letter.
    #check to see if this combination is max
    if(row==len(matrix)-1):
        for i in range(len(check)):
            if(check[i]==0 and (matrix[row][i]+curr_sum)>max_sum):
                max_sum = matrix[row][i]+curr_sum
    #recursive case, pick the current available number, go to next letter.
    else:
        for i in range(len(check)):
            if(check[i]==0):
                check[i]=1
                getMax(matrix,check,row+1,curr_sum+matrix[row][i])
                check[i]=0

getMax(matrix,check,0,0)

print max_sum

Note that it's a sort of brute force algorithm using recursion. In terms of time-complexity, better algorithm (eg dynamic programming approach) exists. You can add cache to the method to improve efficiency.

Also, if you want to know the combination, we need extra efforts to track the combination. (eg using another matrix to record)

This can be done with:

l1 = [6, 7, 6]
l2 = [4.5, 6, 6.75]
l3 = [6, 7.5, 9]

map(max, [l1, l2, l3])

Actually, python has libraries that will do this for you. See here: Munkres

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