[PYTHON] Über Menüs durch Kombinationsoptimierung nachdenken

Problem

Der Arzt sagte mir, ich solle die Kalorien in meiner wöchentlichen Diät begrenzen. Zusätzlich wurde die minimal erforderliche Menge an Nährstoff A und Nährstoff B angegeben. Wie kann ich so viel wie möglich essen, was ich mag?

Formulierung

Dies ist das Zuordnungsproblem in Problem der Kombinationsoptimierung. Nehmen wir an, dass die Kandidaten für das Kochen angegeben sind, und drücken wir mit der 0-1-Variablen $ x $ aus, welche ausgewählt werden sollen.

Variablen $ x_i \ in \ {0, 1 \} $ $ i $ Gibt an, ob das dritte Gericht ausgewählt werden soll >
Zielfunktion $ \ sum_i {Preference_i x_i} $ $ \ rightarrow $ Maximum
Einschränkungen $ \ sum_i {x_i} = 7 $ Wählen Sie 7 Tage
$ \ sum_i {kalorie _i x_i} \ le 90 $ Kalorienlimit
$ \ sum_i {Nährstoffe A_i x_i} \ ge 95 $ Mindestakquisitionsbetrag
$ \ sum_i {Nährstoffe B_i x_i} \ ge 95 $ Mindestakquisitionsbetrag

Versuchen Sie, mit Python zu lösen

Die Optimierungsbibliothek lautet [pulp](http://qiita.com/Tsutomu-KKE@github/items/bfbf4c185ed7004b5721#%E3%82%BD%E3%83%95%E3%83%88%E3%81% AE% E3% 82% A4% E3% 83% B3% E3% 82% B9% E3% 83% 88% E3% 83% BC% E3% 83% AB). Zuerst erstellen wir Dummy-Daten.

python


import numpy as np, pandas as pd
from pulp import *
menu = ['Rindfleischschale', 'Oyakodon', 'Schweinekotelett auf Reis', 'Thunfischschale', 'Negitoro Schüssel', 'Chirashi Sushi',
        'Mao Aubergine', 'Doria', 'Omelettreis', 'Gebratener Reis', 'Curry und Reis']
n = len(menu)
np.random.seed(1)
a = pd.DataFrame({
        'Kochname': menu,
        'Kalorie': np.random.randint(10,20,n),
        'Nährstoff A.': np.random.randint(10,20,n),
        'Nährstoff B.': np.random.randint(10,20,n),
        'Präferenz': np.random.randint(10,20,n),
    })
print(a)
Kochname Präferenz Kalorie Nährstoff A. Nährstoff B.
0 Rindfleischschale 18 15 14
1 Oyakodon 13 18 15
2 Schweinekotelett auf Reis 19 19 12
3 Thunfischschale 18 15 14
4 Negitoro Schüssel 17 10 12
5 Chirashi Sushi 13 10 14
6 Mao Aubergine 16 11 17
7 Doria 15 17 17
8 Omelettreis 11 16 19
9 Gebratener Reis 19 19 11
10 Curry und Reis 13 12 17

Lass es uns lösen.

python


m = LpProblem(sense=LpMaximize) #Maximierungsproblem
a['x'] = [LpVariable('x%d'%i, cat=LpBinary) for i in range(n)] #wählen/TU es nicht
m += lpDot(a.Präferenz, a.x) # Präferenzを最大化
m += lpSum(a.x) == 7 #Eine Woche Menü
m += lpDot(a.Kalorie, a.x) <= 90
m += lpDot(a.Nährstoff A., a.x) >= 95
m += lpDot(a.Nährstoff B., a.x) >= 95
m.solve()
if m.status == 1: # Optimal
    a['val'] = a.x.apply(lambda v: value(v)) #Ergebnis
    print(a[a.val == 1].Kochname)
>>>
0 Rindfleischschale
3 Eisenfeuerschale
4 Negitoro Schüssel
5 Chirashi Sushi
6 Mao Auberginen
7 Doria
10 Curryreis

Docker Wenn Sie es mit Docker versuchen möchten, führen Sie die folgenden Schritte aus, um den Host in Ihrem Browser zu öffnen, und Jupyter wird gestartet. Die Bibliothek ist auch unterschiedlich installiert.

docker run -d -p 80:8888 tsutomu7/jupyter

das ist alles

Recommended Posts