Es gab einen Artikel in "Zuordnungsproblem, ungarisches Recht und ganzzahliges Planungsproblem", dass der Allzwecklöser langsam war. In diesem Artikel werde ich Ihnen zeigen, dass es schneller ist, den Code ein wenig zu ändern und "ein mathematisches Modell zu erstellen und es mit einem generischen Löser zu lösen".
Der Code ist unten. Zum Ausführen ist "pip install numpy pulp munkres" erforderlich.
import random
import time
import numpy as np
from munkres import Munkres
from pulp import PULP_CBC_CMD, LpProblem, LpVariable, lpDot, lpSum, value
class AssigmentProblem:
def __init__(self, size, seed=0):
self.size = size
random.seed(seed)
rng = range(self.size)
self.weight = np.array([[random.randint(1, 100) for i in rng] for j in rng])
def solve_hungarian(self):
start_tm = time.time()
m = Munkres()
result = m.compute(self.weight.tolist())
val = sum([self.weight[i, j] for i, j in result])
tm = time.time() - start_tm
print(f"hungarian {tm = :.2f} {val = }")
def solve_pulp(self):
m = LpProblem("AssignmentProblem")
rng = range(self.size)
x = np.array(LpVariable.matrix('x', (rng, rng), cat='Binary'))
m += lpDot(self.weight.flatten(), x.flatten())
start_tm = time.time()
for i in rng:
m += lpSum(x[i]) == 1
m += lpSum(x[:, i]) == 1
m.solve(PULP_CBC_CMD(mip=False, msg=False))
val = value(m.objective)
tm = time.time() - start_tm
print(f"pulp {tm = :.2f} {val = }")
if __name__ == "__main__":
p1 = AssigmentProblem(300)
p1.solve_hungarian()
p1.solve_pulp()
Tm
: Berechnungszeit (Sekunden), val
: Zielfunktionswerthungarian tm = 2.43 val = 352
pulp tm = 1.94 val = 352.0
Wie Sie sehen können, ist der Allzwecklöser schneller.
Referenz: Python in Optimierung
sum
schafft verschwendeten Speicher und ist langsam.――Der diesmal verwendete Allzwecklöser ist ein freier Löser namens cbc. Mit einem bezahlten Löser wird es schneller. ――In der Praxis ist häufig eine ungefähre Lösung ausreichend. Die Verwendung des ungefähren Lösungslösers ist ein Kompromiss mit der Genauigkeit der Lösung, der jedoch noch schneller ist. ――Die Daten sind diesmal ein vollständiges zweiteiliges Diagramm, aber in der Praxis sind die Daten oft spärlich. In diesem Fall ist es sogar noch schneller, da weniger Variablen vorhanden sind. ――Ich konnte das Zuordnungsproblem mit NetworkX lösen, aber es war zu langsam, um es zu vergleichen.
Recommended Posts