Ich beschloss, mit ihr in den Vergnügungspark zu gehen. Wie gehen Sie durch die Einrichtungen des Vergnügungsparks, um ihre Zufriedenheit zu maximieren? Aufgrund ihrer Ausgangssperre hat der Vergnügungspark jedoch nur 200 Minuten.
Sie können ein solches Problem mit [Kombinationsoptimierung] lösen (http://qiita.com/Tsutomu-KKE@github/items/bfbf4c185ed7004b5721). Es ist ähnlich wie das Rucksackproblem und das Problem der reisenden Verkäufer, aber lassen Sie es uns jetzt formulieren.
Variablen td> | $ x_ {fr, to} \ in \ {0, 1 \} ~ ~ \ forall fr, to \ in Facility $ td> | Gibt an, ob von Einrichtung $ fr $ zu Einrichtung $ nach $ (1) td> tr> gewechselt werden soll |
$ y_i ~ ~ \ forall i \ in Facility $ td> | Endzeit der Nutzung von Facility $ i $ (2) td> tr> | |
Zielfunktion td> | $ \ sum_ {fr, zu \ in Einrichtung} ~~~ {Zufriedenheit_ {fr} ~ x_ {fr, zu}} $ → Maximieren tr> td> | Gesamtzufriedenheit (3) td> tr> |
Einschränkungen td> | $ \ sum_ {fr, to \ in Facility | fr = i} ~~~ {x_ {fr, to}} = 1 ~~ ~ i = S $ td> | Der Eingang muss (4) td> tr> passieren |
$ \ sum_ {fr, zu \ in Einrichtung | fr = i} ~~~ {x_ {fr, zu}} \ le 1 ~~~ \ forall i \ in Einrichtung \ setminus S $ td> | Bis zu 1 verwenden Sie (4) td> tr> | |
$\sum_{fr,to \in der Einrichtung| fr=i}~~~{x_{fr,to}} = \sum_{fr,to \in der Einrichtung| to=i}~~~{x_{fr,to}} ~~~ \forall i \in der Einrichtung$ | Gleicher Ein- und Ausgang zur Einrichtung(5) | |
$ y_ {to} \ ge TM_ {fr, to} + TU_ {to} ~~~ \ forall fr, to \ in Facility, fr = S $ td> | Ende der Nutzung der Einrichtung Einstellen der Zeit (6) td> tr> | |
$ y_ {to} \ ge TM_ {fr, to} + TU_ {to} + y_ {fr} ~~~ \ forall fr, to \ in Facility, fr \ ne S $ td> | Festlegen der Endzeit für die Verwendung der Einrichtung (6) td> tr> weniger |
$ TM_ {fr, to} $ ist jedoch die Reisezeit von der Einrichtung $ fr $ bis $ to $, und $ TU_ {to} $ ist die Nutzungszeit in der Einrichtung $ to $. Außerdem ist die Randbedingung (6) nur gültig, wenn $ x_ {fr, to} $ 1 ist. Die erste Einrichtung S ist der Eingang zum Vergnügungspark und kehrt am Ende zum Eingang zurück. Dieselbe Einrichtung kann auch nur einmal verwendet werden.
Versuchen Sie es mit Python 3.5 von Jupyter. Wenn Sie Docker verwenden können, können Sie es mit tsutomu7 / jupyter oder tsutomu7 / alpine-python: jupyter ausführen.
Importieren Sie die zu verwendende Bibliothek und legen Sie die Zeichnung fest.
python3
%matplotlib inline
import numpy as np, pandas as pd, matplotlib.pyplot as plt
from collections import OrderedDict
from pulp import *
from pulp.constants import LpConstraintEQ as EQ, LpConstraintLE as LE
plt.rcParams['font.family'] = 'IPAexGothic'
plt.rcParams['font.size'] = 16
python3
n = 6
np.random.seed(2)
a = pd.DataFrame(OrderedDict([
('Einrichtung', ['S'] + [chr(65+i) for i in range(n-1)]),
('Zufriedenheitsgrad', np.random.randint(50, 100, n)),
('Nutzungszeit', np.random.randint(3, 6, n) * 10),
]))
a.loc[0, a.columns[1:]] = 0
Reisezeit= np.random.randint(1, 7, (n, n))
Reisezeit+=Reisezeit.T #Machen Sie eine symmetrische Matrix
a
Einrichtung | Zufriedenheitsgrad | Nutzungszeit |
---|---|---|
0 | S | 0 |
1 | A | 65 |
2 | B | 95 |
3 | C | 58 |
4 | D | 72 |
5 | E | 93 |
Mit OrderedDict können Sie die Reihenfolge der Spalten festlegen.
python3
def solve_route(a, limit):
n = a.shape[0]
m = LpProblem(sense=LpMaximize)
b = pd.DataFrame([(i, j, LpVariable('x%s%s'%(i,j), cat=LpBinary))
for i in a.Einrichtung für j in a.Einrichtung], columns=['fr','to','x']) # (1)
b['Reisezeit'] = Reisezeit.flatten()
b = b.query('fr!=to')
y = {i:LpVariable('y%s'%i) for i in a.Einrichtung} # そのEinrichtungの利用終了時刻(2)
m += lpDot(*pd.merge(b, a, left_on='fr', right_on='Einrichtung')
[['x', 'Zufriedenheitsgrad']].values.T) #Zielfunktion(3)
for i in a.Einrichtung:
m += LpConstraint(lpSum(b[b.fr==i].x), EQ if i=='S' else LE, rhs=1) # (4)
m += lpSum(b[b.fr==i].x) == lpSum(b[b.to==i].x) # (5)
M = b.Reisezeit.sum() + a.Nutzungszeit.sum() #Groß genug Wert
for _, r in b.iterrows():
m += y[r.to] >= r.Reisezeit+ a[a.Einrichtung==r.to].Nutzungszeit.sum() \
+ (0 if r.fr=='S' else y[r.fr]) - (1-r.x)*M # (6)
m += y['S'] <= limit # (7)
m.solve()
return value(m.objective), b[b.x.apply(value)>0]
objv, rs = solve_route(a, 200)
print('Totale Zufriedenheit= %g'%objv)
rs
>>>
Totale Zufriedenheit= 311
fr | to | x | Reisezeit |
---|---|---|---|
1 | S | A | xSA |
11 | A | E | xAE |
12 | B | S | xBS |
20 | C | B | xCB |
33 | E | C | xEC |
Wenn Sie vom Eingang (S) aus A-> E-> C-> B drehen, können Sie sehen, dass die Gesamtzufriedenheit auf 311 maximiert werden kann.
python3
%%time
rng = np.linspace(250, 130, 13)
rsl = [solve_route(a, i)[0] for i in rng]
plt.title('Veränderungen in der Zufriedenheit')
plt.xlabel('Maximale Aufenthaltsdauer')
plt.plot(rng, rsl);
>>>
CPU times: user 1.11 s, sys: 128 ms, total: 1.24 s
Wall time: 6.47 s
Je länger Sie zusammen verbringen, desto zufriedener sind Sie.
Dieses Problem wird zu einem schwierigen Problem, das als Optimierungsproblem für gemischte Ganzzahlen bezeichnet wird. Wenn die Anzahl der Einrichtungen zunimmt, wird es plötzlich unmöglich, sie zu lösen. In diesem Fall ist es notwendig, beispielsweise eine ungefähre Lösungsmethode zu entwickeln.
das ist alles
Recommended Posts