[PYTHON] Lassen Sie uns den Gewinner des Bingo bestimmen

Problem

Ich werde auf der Jahresendparty des Unternehmens Bingo spielen. Sie wurden gebeten, ein System für Bingo zu entwickeln. Es gibt jedoch die folgenden Anforderungen (Fiktion).

(Referenz: Ähnliche Geschichte)

Denkweise

Mit der Kombinationsoptimierung können Sie Kombinationen finden, die verschiedene Bedingungen berücksichtigen. Die Gewinner werden entsprechend der Gewinnwahrscheinlichkeit ausgewählt und sortiert. Entsprechend der Reihenfolge beträgt die $ i $ -te Punktzahl $ 2 ^ {1-i} $. Indem wir die Summe der Punkte maximieren, werden wir die Gewinner so weit wie möglich nach der Gewinnwahrscheinlichkeit auswählen. Das Verhältnis von Männern und Frauen und das Verhältnis der Abteilungen werden von der Zielfunktion abgezogen, indem der vom Verhältnis abweichende Betrag bestraft wird.

Löse mit Python

Laden Sie die Teilnehmerinformationen in pandas.DataFrame (wenn der Code nicht ausgeführt werden kann, laden Sie die CSV von der URL herunter und laden Sie sie).

import numpy as np, pandas as pd, urllib
from pulp import lpDot, lpSum
from ortoolpy import model_max, addbinvars, addvars, addvals

url = 'https://www.dropbox.com/s/refo0vfj5wbmv2h/bingo.csv?dl=1'
with urllib.request.urlopen(url) as fp:
    df = pd.read_csv(fp)

Partitur und Variablenerstellung

Jede Zeile von DataFrame (df) ist ein Teilnehmer. Die Gewinnwahrscheinlichkeit (Spalte "Rate") wird als Verhältnis zum Gewinnen in der Reihenfolge "numpy.random.choice" verwendet. Berechnen Sie die Punktzahl mit dieser Reihenfolge als Index und fügen Sie sie in die Spalte "Punktzahl" ein. Die Optimierung maximiert die Summe der Ergebnisse.

Fügen Sie eine Spalte mit Variablen hinzu, die angeben, ob Sie gewonnen haben oder nicht, "Var". Außerdem ist "pena1" eine Strafe, die vom Verhältnis von Männern und Frauen abweicht. Sei "pena2" die Höhe der Strafe, die von der Zugehörigkeitsquote abweicht.

nn = len(df)  #Anzahl der Personen
rnd = np.random.choice(df.index, nn, False, df.Rate / df.Rate.sum())
df['Score'] = pd.Series(2.0**-np.arange(nn), index=rnd)  #Ergebnis
addbinvars(df)  #Variable (ob gewinnend oder nicht) als Var-Spalte hinzugefügt
pena1, pena2 = addvars(2)  #Zwei Strafen für die Abweichung vom Verhältnis
print(df)
Name IsMale Div Rate Score Var
0 Hidehito Asakura True Abteilung Allgemeine Angelegenheiten 2 0.000488 v000001
1 Ryoharu Miyakawa True Buchhaltung 1 0.001953 v000002
2 Kenji Furuhashi True Abteilung Allgemeine Angelegenheiten 2 0.000977 v000003
3 Fumi Motomura False Abteilung Allgemeine Angelegenheiten 3 0.000015 v000004
4 Keiji Otsubo True Buchhaltung 1 0.000002 v000005
5 Kazutaka Hatakeyama True Abteilung Allgemeine Angelegenheiten 2 0.000031 v000006
6 Wakana Takeuchi False Buchhaltung 2 0.000008 v000007
7 Kana Yoda False Personalabteilung 2 0.015625 v000008
8 Keisuke Furuta True Personalabteilung 3 0.125000 v000009
9 Kei Ishikawa True Personalabteilung 1 0.000061 v000010
10 Eriko Tominaga False Personalabteilung 2 1.000000 v000011
11 Sato Tobita False Abteilung Allgemeine Angelegenheiten 1 0.003906 v000012
12 Seito Kamiyama True Personalabteilung 2 0.250000 v000013
13 Ryuichiro Tabata True Abteilung Allgemeine Angelegenheiten 3 0.500000 v000014
14 Rie Kamei False Buchhaltung 1 0.000004 v000015
15 Atsuka Sone False Abteilung Allgemeine Angelegenheiten 1 0.000244 v000016
16 Kiyoshiro Kasuga True Buchhaltung 2 0.007812 v000017
17 Akisa Nakai False Buchhaltung 3 0.062500 v000018
18 Yukio Kinjo False Personalabteilung 2 0.031250 v000019
19 Yoshikatsu Kakinuma True Abteilung Allgemeine Angelegenheiten 1 0.000122 v000020

Überprüfen Sie die Anzahl der Personen nach Geschlecht und Abteilung.

print(df.groupby('IsMale').Div.value_counts())
IsMale  Div
Falsche Personalabteilung 3
Buchhaltungsabteilung 3
Abteilung für allgemeine Angelegenheiten 3
Abteilung für wahre allgemeine Angelegenheiten 5
Personalabteilung 3
Buchhaltungsabteilung 3
Name: Div, dtype: int64

Erstellen Sie ein mathematisches Modell und lösen Sie es

ns = 7  #Anzahl der Gewinner

m = model_max()  #Mathematisches Modell
m += lpDot(df.Score, df.Var) - nn * (pena1 + pena2)  #Zielfunktion
m += lpSum(df.Var) == ns  #Anzahl der Gewinner
for _, gr in df.groupby('IsMale'):  #Halten Sie das Verhältnis nach Geschlecht konstant
    m += lpSum(gr.Var) <= ns * len(gr) / nn + pena1
for _, gr in df.groupby('Div'):  #Halten Sie das Verhältnis nach Abteilung konstant
    m += lpSum(gr.Var) <= ns * len(gr) / nn + pena2
m.solve()  #Lösung
addvals(df)  #Ergebnis als Val-Spalte hinzufügen
print(df[df.Val > 0])  #Gewinner
Name IsMale Div Rate Score Var Val
10 Eriko Tominaga False Personalabteilung 2 1.000000 v000011 1.0
11 Sato Tobita False Abteilung Allgemeine Angelegenheiten 1 0.003906 v000012 1.0
12 Seito Kamiyama True Personalabteilung 2 0.250000 v000013 1.0
13 Ryuichiro Tabata True Abteilung Allgemeine Angelegenheiten 3 0.500000 v000014 1.0
16 Kiyoshiro Kasuga True Buchhaltung 2 0.007812 v000017 1.0
17 Akisa Nakai False Buchhaltung 3 0.062500 v000018 1.0
19 Yoshikatsu Kakinuma True Abteilung Allgemeine Angelegenheiten 1 0.000122 v000020 1.0

Die Gewinner stehen fest. Schauen wir uns die Anzahl der Personen nach Geschlecht und Abteilung an.

print(df[df.Val > 0].groupby('IsMale').Div.value_counts())
IsMale  Div
Falsche Personalabteilung 1
Buchhaltungsabteilung 1
Abteilung für allgemeine Angelegenheiten 1
Abteilung für wahre allgemeine Angelegenheiten 2
Personalabteilung 1
Buchhaltungsabteilung 1
Name: Div, dtype: int64

Sieht gut aus.

Zusammenfassung

――Eine Kombination, die verschiedene Bedingungen erfüllt, wird durch eine Methode erhalten, die als Kombinationsoptimierung bezeichnet wird.

(Ich persönlich hoffe, dass für diesen Artikel keine Nachfrage besteht.)

das ist alles

Recommended Posts

Lassen Sie uns den Gewinner des Bingo bestimmen
Lassen Sie uns die Position der Feuerwehr durch Kombinationsoptimierung bestimmen
Untersuchen wir den Mechanismus von Kaijis Chinchirorin
Lassen Sie uns den Datumsverlauf durch Kombinationsoptimierung festlegen
Der Beginn von cif2cell
Die Bedeutung des Selbst
Verwenden wir die API des allgemeinen Fensters für Regierungsstatistiken (e-Stat).
Lassen Sie uns jetzt die Mehrdeutigkeit des Bindestrichs (-) des Befehls su beseitigen! !!
Lassen Sie uns die Grundlagen des Python-Codes von TensorFlow aufschlüsseln
der Zen von Python
Die Geschichte von sys.path.append ()
Verwenden wir die Python-Version des Confluence-API-Moduls.
Verwenden wir die offenen Daten von "Mamebus" in Python
Lassen Sie uns die medizinische Kollapshypothese des neuen Koronavirus testen
[Ev3dev] Lassen Sie uns den Mechanismus der LCD-Steuerung (Bildschirmsteuerung) verstehen
Lassen Sie uns die Emotionen von Tweet mit Chainer (1.) analysieren.
Rache der Typen: Rache der Typen
[Python] Lassen Sie uns die URL der Django-Administrator-Site ändern
Überqueren wir die Wand des linkshändigen Koordinatensystems und des rechtshändigen Koordinatensystems.
Visualisieren wir das Handelsvolumen der TSE-Aktien - jpxlab sample
Pepper entscheidet über den Gewinner, indem er die Größe des Applaus des Publikums misst
Lassen Sie uns die Eisenbahndaten der nationalen Landnummern verwenden
Lassen Sie uns die Analyse der sinkenden Daten der Titanic so durchführen
Lassen Sie uns den Befehl pünktlich mit dem Bot der Zwietracht ausführen
Lassen Sie uns das Timing von Barus vorhersagen und den Film langsam genießen
Lassen Sie uns den Entwicklungsstatus der Stadt anhand des Satellitenbildes erraten.
Stellen wir uns die Anzahl der mit Matplotlib mit dem Coronavirus infizierten Personen vor
Verwenden wir den verteilten Ausdruck von Wörtern schnell mit fastText!
Richten Sie die Version von chromedriver_binary aus
Scraping das Ergebnis von "Schedule-Kun"
10. Zählen der Anzahl der Zeilen
Die Geschichte des Baus von Zabbix 4.4
Auf dem Weg zum Ruhestand von Python2
Lassen Sie uns von der Linie suchen
Vergleichen Sie die Schriftarten von Jupyter-Themen
Holen Sie sich die Anzahl der Ziffern
Lassen Sie uns die Luft Gacha drehen
Erläutern Sie den Code von Tensorflow_in_ROS
Verwenden Sie die Clustering-Ergebnisse erneut
GoPiGo3 des alten Mannes
Berechnen Sie die Anzahl der Änderungen
Ändern Sie das Thema von Jupyter
Die Popularität von Programmiersprachen
Ändern Sie den Stil von matplotlib
Über die Komponenten von Luigi
Filtern Sie die Ausgabe von tracemalloc
Simulation des Inhalts der Brieftasche
Die Kraft der Pandas: Python
[Anmerkung] Versuchen wir, den Stromverbrauch vorherzusagen! (Teil 1)
Werfen wir einen Blick auf die Feature-Map von YOLO v3
Messen Sie die Testabdeckung von Push-Python-Code auf GitHub.
[Python] Lassen Sie uns die Anzahl der Elemente im Ergebnis bei der Operation des Sets reduzieren
Fassen wir den Grad der Kopplung zwischen Modulen mit Python-Code zusammen
[Word2vec] Lassen Sie uns das Ergebnis der Verarbeitung von Unternehmensbewertungen in natürlicher Sprache visualisieren