1

I simplified the problem to the following description:

If produce a thing, we need to go through three devices : A, B, C, and it must pass through these devices the order of A->B->C. The device to select an address (from 0 to 7) for installation before it can be used, The installation cost of the device is different for different addresses, as shown in the figure below, as shown below

enter image description here

The addresses are in the order of the arrows. Device A can choose to install at address 0, and the cost is 800, or it can be installed at address 1, the cost is 700. Other devices have similar installation locations and costs The following is a correct placement method(A choose 2, B choose 3, C choose 5):

enter image description here

If we first install device A in 2 and device C in 3, then B has no address to install, which is a wrong installation method.

enter image description here

Finding a correct installation method is very simple, but because the cost of installing equipment at different addresses is different, how to find a cost-optimized solution under the correct premise? Because of the large scale of the problem, I want to use a heuristic search algorithm. How to design the algorithm? Thank you very much if you can answer my question!

Li.sili
  • 39
  • 3
  • You can reduce this to the well studied problem ***minimum-weight maximum marriage in a bipartite graph***, also called the ***assignment problem***. See wikipedia: https://en.wikipedia.org/wiki/Assignment_problem – Stef May 11 '22 at 12:10
  • For instance with library scipy in python: [scipy.optimize.linear_sum_assignment](https://docs.scipy.org/doc/scipy-0.18.1/reference/generated/scipy.optimize.linear_sum_assignment.html) – Stef May 11 '22 at 12:26

1 Answers1

2

This isn’t an assignment problem because of the ordering constraint on the installations. A dynamic program will do. In Python 3:

import math

input_instance = [
    ("A", [(0, 800), (1, 700), (2, 500), (3, 1000)]),
    ("B", [(2, 200), (3, 1500)]),
    ("C", [(3, 1000), (4, 200), (5, 500), (6, 700)]),
]

LAST_ADDRESS = 0
TOTAL_COST = 1
INSTALLATIONS = 2
solutions = [(-math.inf, 0, [])]

for device, address_cost_pairs in input_instance:
    next_solutions = []
    i = 0
    for address, cost in sorted(address_cost_pairs):
        if address <= solutions[i][LAST_ADDRESS]:
            continue
        while i + 1 < len(solutions) and solutions[i + 1][LAST_ADDRESS] < address:
            i += 1
        next_solutions.append(
            (
                address,
                solutions[i][TOTAL_COST] + cost,
                solutions[i][INSTALLATIONS] + [(device, address)],
            )
        )
    del solutions[:]
    total_cost_limit = math.inf
    for solution in next_solutions:
        if total_cost_limit <= solution[TOTAL_COST]:
            continue
        solutions.append(solution)
        total_cost_limit = solution[TOTAL_COST]
    if not solutions:
        break
else:
    print(*solutions[-1][1:])

Output:

1100 [('A', 1), ('B', 2), ('C', 4)]
David Eisenstat
  • 64,237
  • 7
  • 60
  • 120