[PYTHON] Berechnen Sie mit scipy.optimize die optimale Lösung, um einen Weltrekord für zehn Arten von Wettbewerb aufzustellen

Einführung

Kennen Sie den Wettbewerb "Ten Kinds Competition"? In 2 Tagen wurden 10 Ereignisse von Laufen (100 m, 400 m, 1500 m, 110 mH), Springen (Hochspringen, Stangenhochspringen, Weitspringen), Werfen (Schusswechsel, Scheibenwurf, Speerwurf) durchgeführt, und die Aufzeichnungen jedes Ereignisses wurden bewertet und der Gesamtrekord Es ist ein Wettbewerb, an dem man teilnehmen kann. Der aktuelle Weltrekord (Juni 2020) liegt bei 9126 Punkten von Kevin MAYER.

Was soll ich übrigens tun, um diese Punktzahl effizient zu erhalten? Es scheint eine Idee zu geben, "bei allen Veranstaltungen gleich zu punkten", aber das ist nicht realistisch. Dies liegt daran, dass einige Ereignisse das Sammeln von Punkten erleichtern und andere das Sammeln von Punkten erschweren. Der Datensatz zum Erhalten von 900 Punkten in jedem Element lautet beispielsweise wie folgt. (Als Referenz sind auch japanische Rekorde für jeden der 10 Wettbewerbe enthalten.)

100m 400m 1500m 110mH Hochsprung laufen Stick Hochsprung Weitsprung Kanonenkugel werfen Disc werfen Werfen
900 Punkte 10.82 48.19 247.42 14.59 2.10 4.97 7.36 16.79 51.40 70.67
Japan Rekord für jedes der zehn Ereignisse 10.53 47.17 248.24 13.97 2.16 5.30 7.65 15.65 50.23 73.82

Um durch das Werfen einer Waffe oder einer Scheibe 900 Punkte zu erzielen, müssen Sie den japanischen Rekord brechen. Das ist nicht realistisch.

Wie kann man am einfachsten einen Weltrekord aufstellen? Anstatt nur 800 Punkte mit Gunball werfen zu bekommen, lassen Sie uns bei anderen Events 1000 Punkte bekommen, aber ich weiß nicht, ob es einfacher ist, 1000 Punkte in 100 m oder 1500 m zu bekommen ...

Die Antwort, die ich auf diese Frage gegeben habe, ist ** Die minimale Gesamtpunktzahl in der "Wertungstabelle ** (allgemein als ungarische Tabelle bekannt)" ** "**.

Was ist eine Wertungstabelle?

Dies ist eine Tabelle, die von der International Athletics Federation (IAAF) erstellt wurde und die die Aufzeichnungen der einzelnen Elemente bewertet. Die Berechnungsformel unterscheidet sich von der des 10. Wettbewerbs. Dies dient zum Vergleich nach Ereignissen, sodass Sie es wie folgt verwenden können: "Der von mir erstellte Rekord von 100 m 11.00 (886p) entspricht 6m83 (886p), wenn es sich um einen Weitsprung handelt."

Berechnet

Wir haben den "Mindestwert der Punktzahl des 10. Ereignisses berechnet (Einschränkung: Der Datensatz des 10. Ereignisses überschreitet 9126 Punkte)".

Nehmen wir zum Beispiel an, Sie streben bei der zweiten Art von 100 m und Gunball-Werfen insgesamt 1000 Punkte an. Die Gesamtpunktzahl bei 500 Punkten in jedem Event beträgt 972p, Die Gesamtpunktzahl bei 100m14.00 und Gunballwurf 13.32 beträgt 945p, und selbst wenn die Punktzahl gleich ist, scheint es, dass Sie leicht Punkte verdienen können. (Das eigentliche Problem ist anders ...)

Aufzeichnung Zehn Arten von Punkten Ergebnis : Aufzeichnung Zehn Arten von Punkten Ergebnis
100m 12.82 500 430 : 14.00 312 221
Kanonenkugel werfen 10.24 500 542 : 13.32 687 724
gesamt 1000 972 : 1000 945

Mit diesem Gefühl suche ich nach einer Möglichkeit, mit einer kleinen Punktzahl einen Weltrekord aufzustellen.

Rechenmethode

Die verwendete Optimierungsmethode minimiert in scipy.optimize.

Der Bereich des Rekords war eine Punktzahl von 1p zu einem Weltrekord. (Die Untergrenze des Streckenereignisses ist der Weltrekord, und die Obergrenze des Feldereignisses ist der Weltrekord.)

100m 400m 1500m 110mH Hochsprung laufen Stick Hochsprung Weitsprung Kanonenkugel werfen Disc werfen Werfen
untere Grenze 9.58 43.03 206.00 12.80 0.92 1.16 2.51 1.00 1.57 1.59
Höchstgrenze 16.79 78.01 380.04 25.43 2.45 6.18 8.95 23.12 74.08 98.48

Die Formel zur Berechnung der Punktzahl des Zehn-Arten-Wettbewerbs ist in [Wikipedia](https://ja.wikipedia.org/wiki/ten-kind-Wettbewerb #score) beschrieben. Die Formel für die Wertungstabelle konnte nicht offiziell gefunden werden, scheint jedoch anhand der folgenden Formel berechnet zu werden.

a × (Datensatz + b) ^ 2 + c (Die Koeffizienten sind unten aufgeführt)

Es ist überraschend einfach.

Nachfolgend sind die in der Berechnung verwendeten Befehle aufgeführt.

python


import numpy as np
import pandas as pd
import copy
import sys
from scipy.optimize import minimize, BFGS, LinearConstraint, Bounds
from math import floor
import matplotlib.pyplot as plt

##Faktoren für die Wertungstabelle
w_score = np.array([
    [24.64221166,-16.99753156,-0.218662048], #100m
    [1.021013043,-78.99469306,0.0029880052], #400m
    [0.0406599253,-384.9950051,0.001205591], #1500m 
    [7.665206128,-25.79302259,0.0141087786], #110mH
    [32.14570816,11.59368894,-5026.080842],  #HJ
    [3.045719921,39.33586031,-4993.213828],  #PV
    [1.931092873,48.34861905,-4993.807793],  #LJ
    [0.0423461436,684.8281542,-19915.72457], #SP
    [0.0040063129,2232.983411,-20003.52492], #DT
    [0.0024031525,2879.797864,-19950.96836]])#JT

##Zehn Arten von Wettbewerbskoeffizienten
w_dec = np.array([
    [25.4347,18,1.81],   #100m
    [1.53775,82,1.81],   #400m
    [0.03768,480,1.85],  #1500m
    [5.74352,28.5,1.92], #110mH
    [0.8465,75,1.42],  #HJ
    [0.2797,100,1.35], #PV
    [0.14354,220,1.4], #LJ
    [51.39,1.5,1.05],  #SP
    [12.91,4,1.1],     #DT
    [10.14,7,1.08]])   #JT

##Zielfunktion (Wertungstabelle)
def calc_score(x):
    total_score = 0
    for i in range(10):
        total_score += w_score[i,0] * (x[i] + w_score[i,1])**2 + w_score[i,2]
    return total_score

##Einschränkungsfunktion (10 Arten von Wettbewerbsergebnissen)
def calc_dec(x):
    n = 0
    total_point = 0
    target_point = 9126

    for i in range(10):
        if i in (0,1,2,3):
            total_point += w_dec[i,0] * (w_dec[i,1] - x[i]) ** w_dec[i,2] #100m, 400m, 1500m, 110mH
        elif i in (4,5,6):
            total_point += w_dec[i,0] * (x[i] *100 - w_dec[i,1]) ** w_dec[i,2] #Hochsprung laufen,Weitsprung,Stick Hochsprung
        else:
            total_point += w_dec[i,0] * (x[i] - w_dec[i,1]) ** w_dec[i,2] #Kanonenkugel werfen,Disc werfen,Werfen
        return_point = total_point - target_point
    return return_point

bounds = Bounds(world_rec[0:4] + min_rec[4:10] , min_rec[0:4] + world_rec[4:10])

cons = (
    {'type': 'ineq', 'fun': calc_dec} 
)

x0 = np.array([10, 46.19, 247.42, 13.59, 1.8, 3.5, 6.06, 10.79, 31.40, 53.67]) #Der Anfangswert ist angemessen

Es wird fast nichts beschrieben außer der Erstellung von Funktionen. Es ist sehr einfach, das Optimierungsproblem damit zu lösen ...

Ergebnis

1. 1. Mindestpunktzahl beim Erreichen des Weltrekords (9126 Punkte)

python


result = minimize(calc_score, x0, constraints=cons, method="SLSQP", bounds=bounds)
print(result)
#     fun: 8707.88035324152
#     jac: array([-141.92468262,  -27.99401855,   -5.38891602,  -70.75549316,
#        902.8885498 ,  277.25720215,  221.29797363,   59.95800781,
#         18.4855957 ,   14.31445312])
# message: 'Optimization terminated successfully.'
#    nfev: 569
#     nit: 38
#    njev: 34
#  status: 0
# success: True
#       x: array([ 14.11782497,  65.28575996, 318.7265988 ,  21.17765192,
#         2.45      ,   6.18      ,   8.95      ,  23.12      ,
#        74.08      ,  98.48      ])

100m:14.11 400m:65.28 1500m:318.72 110mH:21.72 Hochsprung: 2,45 (Weltrekord) Bar Hochsprung: 6,18 (Weltrekord) Weitsprung: 8,95 (Weltrekord) Gunballwurf: 23.12 (Weltrekord) Scheibenwurf: 74.08 (Weltrekord) Wurf: 98,48 (Weltrekord)

Gesamtpunktzahl: 8707

Das Ergebnis war! ww Die Punktzahl steigt exponentiell an, wenn Sie also bei einem Feldereignis mit einer hohen Wachstumsrate Ihr Bestes geben Bedeutet das, dass selbst wenn das Streckenereignis angemessen ist, ein Weltrekord aufgestellt wird ...

2. Mindestpunktzahl beim Erreichen des japanischen Rekords (8308 Punkte)

Es ist langweilig, wenn es nur der Weltrekord ist, also habe ich auch die japanische Rekordversion ausprobiert. Die Obergrenze ist "Japanischer Rekord für jede der zehn Sportarten".

python


#Es wird nur das Ergebnis beschrieben
result = minimize(calc_score, x0, constraints=cons, method="SLSQP", bounds=bounds)
print(result)
#     fun: 8397.295007256867
#     jac: array([-262.33532715,  -58.31018066,   -7.70007324, -130.22009277,
#        884.24414062,  271.89660645,  216.27709961,   59.32495117,
#         18.29467773,   14.19604492])
# message: 'Optimization terminated successfully.'
#    nfev: 521
#     nit: 30
#    njev: 30
#  status: 0
# success: True
#       x: array([ 11.67464597,  50.4396491 , 290.30574658,  17.29878908,
#         2.16      ,   5.3       ,   7.65      ,  15.65      ,
#        50.23      ,  73.82      ])

100m:11.67 400m:50.43 1500m:290.30 110mH:17.29 Laufender Hochsprung: 2.16 (10 Arten japanischer Rekorde) Stick Hochsprung: 5.30 (10 Arten japanischer Rekord) Weitsprung: 7,65 (10 Arten japanischer Rekorde) Gunmaru-Wurf: 15,65 (10 Arten japanischer Rekord) Scheibenwurf: 50,23 (10 Arten japanischer Schallplatten) Speerwurf: 73,82 (10 Arten japanischer Schallplatten)

Gesamtpunktzahl: 8397p

Das Ergebnis war das. Die Tendenz, bei Feldwettbewerben Punkte zu erzielen, bleibt gleich ... Übrigens beträgt die Punktzahl, wenn der richtige Spieler einen japanischen Rekord aufstellt, 8609p Mit dem oben Gesagten wird es möglich sein, einen japanischen Rekord effizient um etwa 200p w einzustellen

Bonus

Obwohl es nichts mit scipy zu tun hat, habe ich versucht, die Punktzahl der zehn Arten von Wettbewerben und die Berechnungsformel der Wertungstabelle grafisch darzustellen.

##Grafikausgabe
fig, ax = plt.subplots(5, 2, figsize=(14, 25)) 

for i in range(10):
    pltx = np.arange(min(min_rec[i],world_rec[i]), max(min_rec[i],world_rec[i]), 0.01)
    plty = w_score[i,0] * (pltx + w_score[i,1])**2 + w_score[i,2]
    if i in (0,1,2,3):
        plty_p = w_dec[i,0] * (w_dec[i,1] - pltx) ** w_dec[i,2] #100m, 400m, 1500m, 110mH
    elif i in (4,5,6):
        plty_p = w_dec[i,0] * (pltx *100 - w_dec[i,1]) ** w_dec[i,2] #Hochsprung laufen,Weitsprung,Stick Hochsprung
    else:
        plty_p = w_dec[i,0] * (pltx - w_dec[i,1]) ** w_dec[i,2]
    
    ax[i//2, i%2].set_ylim([0,1400])
    ax[i//2, i%2].plot(pltx, plty, color="blue", label="Scoring")
    ax[i//2, i%2].plot(pltx, plty_p,color="orange", label="Decathlon")
    ax[i//2, i%2].set_title(label[i], size=15)
    ax[i//2, i%2].set_xlabel('Record')
    ax[i//2, i%2].set_ylabel('Score / Point')
    ax[i//2, i%2].axvline(x=world_rec[i], ymin=0, ymax=100, ls="--", color="red", label="World Record")
    ax[i//2, i%2].axvline(x=national_dec_rec[i], ymin=0, ymax=100, ls="--", color="green", label="National Decathlon Record")
    ax[i//2, i%2].grid(which = "major", axis = "both", alpha = 0.8,
        linestyle = "--", linewidth = 0.8)
    ax[i//2, i%2].legend(loc='best')

plt.tight_layout()

img.png

Im Bereich mit hoher Punktzahl habe ich das Gefühl, dass das Streckenereignis für die 10 Kategorien eine niedrigere Punktzahl aufweist als das Feldereignis (= selbst wenn eine hohe Punktzahl angegeben wird, ist es schwierig, sich in der Punktzahl wiederzugeben). Ich glaube, Sie können verstehen, warum wir zu dem Schluss gekommen sind, dass "um eine hohe Punktzahl mit der minimalen Punktzahl zu erzielen, eine hohe Punktzahl im Feld erzielt werden". ..

Am Ende

scipy.optimize könnte von mir als Statistiker-Amateur verwendet werden. Sehr angenehm ... Wir hoffen, dass dieser Artikel die Anzahl der Personen (und Personen, die an dem 10-Arten-Wettbewerb interessiert sind) erhöht, die Optimierungsprobleme problemlos lösen können.

Recommended Posts

Berechnen Sie mit scipy.optimize die optimale Lösung, um einen Weltrekord für zehn Arten von Wettbewerb aufzustellen
Suche nach einer Lösung für das N-Queen-Problem mit einem genetischen Algorithmus (2)
Suche nach einer Lösung für das N-Queen-Problem mit einem genetischen Algorithmus (1)
Schreiben Sie ein Skript, um die Entfernung mit dem Elasticsearch 5-System schmerzfrei zu berechnen
[Django lernt mit der Klinge des Teufels] So erhalten Sie einen Abfragesatz für die Vorwärts- / Rückwärtsreferenz
[Einführung in die Udemy Python3 + -Anwendung] 47. Verarbeiten Sie das Wörterbuch mit einer for-Anweisung
Ein Leitfaden für IoT mit MicroPython bis zur letzten Minute
Eine einfache Problemumgehung für Bots, um zu versuchen, Tweets mit demselben Inhalt zu veröffentlichen
Beachten Sie die Lösung, da Django nicht mit pip installiert werden konnte
[Einführung in Python] So erhalten Sie den Datenindex mit der for-Anweisung
So berechnen Sie die Volatilität einer Marke
Begrüßen Sie die Welt mit Python mit IntelliJ
Speichern Sie das Objekt in einer Datei mit pickle
So legen Sie einen freigegebenen Ordner mit dem Host-Betriebssystem in CentOS7 auf Virtual BOX fest
Versuchen Sie, mit matplotlib aus den Daten von "Schedule-kun" eine Kampfaufzeichnungstabelle zu erstellen.
Suchen Sie eine Richtlinie für die Anzahl der Prozesse / Threads, die auf dem Anwendungsserver festgelegt werden sollen
So legen Sie die Entwicklungsumgebung für jedes Projekt mit VSCode + Python-Erweiterung + Miniconda fest
So erstellen Sie ein Untermenü mit dem Plug-In [Blender]
Die Geschichte, eine harte Zeit mit der gemeinsamen Menge HTTP_PROXY = ~ zu haben
Übergang zum Update-Bildschirm mit dem Django-Tag
Berechnen Sie das Produkt von Matrizen mit einem Zeichenausdruck?
Python> Liste> Partitionen = [0] * len (all_filepaths) / Partitionen [: test_set_size] = [1] * Nachdem Sie eine Liste mit test_set_size> 0 erstellt haben, setzen Sie den vorderen Teil auf 1.
Definieren Sie eine Aufgabe zum Festlegen der Fabric-Umgebung in YAML
Wahrscheinlich der einfachste Weg, um mit Python 3 ein PDF zu erstellen
Experimentieren Sie mit Python, um ein PDF für Selbstversorger für Kindle zu erstellen
Der erste Schritt beim Erstellen einer serverlosen Anwendung mit Zappa
Erstellen Sie einen Twitter-BOT mit dem GoogleAppEngine SDK für Python
Eine Geschichte über den Umgang mit dem CORS-Problem
Die übliche Art, einen Kernel mit Jupyter Notebook hinzuzufügen
Die Geschichte, den privaten Schlüssel mit chmod auf 600 zu setzen
Ich möchte vorerst eine Docker-Datei erstellen.
Versuchen Sie, mit DCGAN + ein Death Metal-ähnliches Jackenbild zu erzeugen, und kratzen Sie die Metalldatenbank-Site dafür ab
Beispiel für eine Python-Codelösung --1.6 Komprimierung von Zeichenketten
Python-Code Lösungsbeispiel --1.7 Matrixrotation
"Ein Buch zum Trainieren von Programmierkenntnissen für den Kampf in der Welt" Beispiel für eine Python-Codelösung --2.8 Schleifenerkennung
Für diejenigen, die nicht wissen, wie man ein Passwort mit Jupyter auf Docker festlegt