views:

94

answers:

2

I know little of optimization problems, so hopefully this will be didactic for me:

rotors = [1, 2, 3, 4...]
widgets = ['a', 'b', 'c', 'd' ...]

assert len(rotors) == len(widgets)

part_values = [
(1, 'a', 34),
(1, 'b', 26),
(1, 'c', 11),
(1, 'd', 8),
(2, 'a', 5),
(2, 'b', 17),
....
]

Given a fixed number of widgets and a fixed number of rotors, how can you get a series of widget-rotor pairs that maximizes the total value where each widget and rotor can only be used once?

+4  A: 

What you have is a maximum weighted bipartite matching problem: on the left, you have widgets, on the right, rotors, and the weights of the connections are the point values. This Wikipedia article goes into how to solve it.

Claudiu
Ok, I know the hungarian algorithm can solve this. Wikipedia mentions Bellman-Ford and Dijkstra to solve it though. That would require them to be modified such that they find a longest augmenting path at each step. Can we really use Bellman-Ford and Dijkstra to find such longest paths?
IVlad
A: 

How far would a greedy algorithm get you? You could sort all widget-rotor pairs by score and simply walk down the list, skipping any that contained an already-used widget or rotor. Example:

2-b = 40  # yes
2-c = 30  # no, already used rotor 2
1-a = 20  # yes
4-a = 10  # no, already used widget a
3-c = 5   # yes
...
Kristo
This won't give the optimal result. For example, with 2 widgets and rotors and the weights: 1a=40, 1b=30, 2a=30, 2b=10, the optimal result (1b, 2a) is 60 but the greedy algorithm gives 50.
interjay
This method results in a better-than-random result, but not an optimal result.
ʞɔıu