J'ai essayé de le résoudre en combinant et en optimisant "Programmation de la méthode gagnante des courses de chevaux".
20 septembre 2013 C'est un tableau des victoires et des chevaux dans une course de courses de chevaux de Nagoya. Demandez combien de billets de paris acheter pour chaque ligne de ce tableau.
from ortoolpy import addbinvars, lpSum, model_min, pd
def sample_data_frame() -> pd.DataFrame:
"""20 septembre 2013 Nagoya Horse Racing 1 Race Table
:return: 「First=1er numéro d'arrivée, deuxième=2 numéro d'arrivée (-1 victoires), cotes=Tableau des "chances"
"""
ls = list(range(1, 8))
df1 = pd.DataFrame({ #Gagner
"First": ls,
"Second": [-1] * 7,
"Odds": [14.7, 72.6, 1.4, 2.3, 151.8, 18.0, 66.8],
})
df2 = pd.DataFrame({ #Cheval seul
'First': [i for i in ls for _ in ls[1:]],
'Second': [j for i in ls for j in ls if i != j],
'Odds': [
347.2, 37.4, 54.0, 662.7, 169.6, 607.5, 455.6, 177.8, 197.1,
1457.9, 331.4, 2429.8, 23.0, 86.8, 5.4, 50.7, 13.0, 177.8, 10.3,
49.3, 1.9, 90.0, 5.9, 123.6, 1214.9, 1457.9, 74.4, 455.6, 560.8,
3644.7, 119.5, 347.2, 27.6, 43.2, 486.0, 455.6, 1041.4, 2429.8,
1214.9, 911.2, 3644.7, 911.2
]
})
return pd.concat([df1, df2]).reset_index(drop=True)
df = sample_data_frame()
# First=1er numéro d'arrivée, deuxième=2 numéro d'arrivée (-1 victoires), cotes=Chances
df[:3] #3 premières lignes
First | Second | Odds | |
---|---|---|---|
0 | 1 | -1 | 14.7 |
1 | 2 | -1 | 72.6 |
2 | 3 | -1 | 1.4 |
def solve(df: pd.DataFrame, num: int, alpha: float) -> pd.DataFrame:
"""Trouvez le nombre d'achats
:param df:Table variable
:param num:Nombre maximum d'achats
:param alpha:Rapport de retour
:return:Table des variables (la colonne Val est le nombre d'achats)
"""
n = len(df[df.Second == -1]) #Nombre de lignes à gagner
m = model_min(dfi=df) #Modèle mathématique
df["Mono"] = None #Que ce soit pour acheter une victoire
df.loc[: n - 1, "Mono"] = addbinvars(n)
m += lpSum(df.Var) #Fonction objectif (nombre total d'achats)
m += lpSum(df.Var) <= num #Nombre maximum d'achats
for row in df[:n].itertuples():
m += row.Odds * row.Var >= num * alpha * row.Mono
df.loc[df.First == row.First, "Mono"] = row.Mono
for row in df[n:].itertuples():
m += row.Odds * row.Var >= num * alpha * (1 - row.Mono)
m.solve()
df["Prize"] = df.Odds * df.Val * 100
return df[df.Val > 0] if m.status == 1 else None
res = solve(df, num=1000, alpha=1.08)
res
First | Second | Odds | Var | Mono | Val | Prize | |
---|---|---|---|---|---|---|---|
1 | 2 | -1 | 72.6 | v000002 | v000051 | 15 | 108900 |
3 | 4 | -1 | 2.3 | v000004 | v000053 | 470 | 108100 |
4 | 5 | -1 | 151.8 | v000005 | v000054 | 8 | 121440 |
5 | 6 | -1 | 18 | v000006 | v000055 | 60 | 108000 |
7 | 1 | 2 | 347.2 | v000008 | v000050 | 4 | 138880 |
8 | 1 | 3 | 37.4 | v000009 | v000050 | 29 | 108460 |
9 | 1 | 4 | 54 | v000010 | v000050 | 20 | 108000 |
10 | 1 | 5 | 662.7 | v000011 | v000050 | 2 | 132540 |
11 | 1 | 6 | 169.6 | v000012 | v000050 | 7 | 118720 |
12 | 1 | 7 | 607.5 | v000013 | v000050 | 2 | 121500 |
19 | 3 | 1 | 23 | v000020 | v000052 | 47 | 108100 |
20 | 3 | 2 | 86.8 | v000021 | v000052 | 13 | 112840 |
21 | 3 | 4 | 5.4 | v000022 | v000052 | 200 | 108000 |
22 | 3 | 5 | 50.7 | v000023 | v000052 | 22 | 111540 |
23 | 3 | 6 | 13 | v000024 | v000052 | 84 | 109200 |
24 | 3 | 7 | 177.8 | v000025 | v000052 | 7 | 124460 |
43 | 7 | 1 | 1041.4 | v000044 | v000056 | 2 | 208280 |
44 | 7 | 2 | 2429.8 | v000045 | v000056 | 1 | 242980 |
45 | 7 | 3 | 1214.9 | v000046 | v000056 | 1 | 121490 |
46 | 7 | 4 | 911.2 | v000047 | v000056 | 2 | 182240 |
47 | 7 | 5 | 3644.7 | v000048 | v000056 | 1 | 364470 |
48 | 7 | 6 | 911.2 | v000049 | v000056 | 2 | 182240 |
res.Val.sum ()
).
Quel que soit le cheval de 1 à 7, la ligne «Prix» est supérieure à 108 000 yens.ʻAlpha = 1.08` doit être trouvé par une recherche de 2 minutes. C'est incroyable que ce soit 100% rentable, pas une théorie de bureau.
c'est tout
Recommended Posts