最近、競馬用のアルゴリズムをいくつか作っていますが、何か不正をしたいわけではなく、こういうアルゴリズムって普段あんまり考えていなくて、自分的に勉強になったので、作ったスニペットなどをブログに残しておきます。
競馬の馬券は全て100円
今までほとんど宝くじ以外のギャンブルをやったことが無かったので、競馬の知識なんて皆無でした。
宝くじは、メインのものは、全て1口300円なのに対して、競馬って1口100円なんですね。
こんな知識すらなかったのですが、競馬というギャンブルは、数字を思考する非常に高度なシミュレーションゲームという事も競馬新聞を読むと理解できます。
そして競馬サイト(JRAや地方競馬)の「払戻金額」ページを見てみると、毎日何かしらの万馬券が出ているという事にも驚かされます。
100円買って、1万円以上のリターンがあるという事ですね。
仮に1万円だったとして、10口買っていれば1000円買って10万円になるって、宝くじよりも夢ありますね。
宝くじって、10枚かって、3000円でせいぜい300円なんだから、上位当選する以外は、ほぼリターン率が悪すぎますね。
もちろん確率という見方もありますが、競馬や宝くじの各協会が定めているギャンブルチケットに対する、還元率というのが法律で定まっているようです。
参考:日本のギャンブル還元率
競馬が74.1%に対し、宝くじって、45.7%って、極めて低いんですね。
やはりギャンブルやるよりも、地道に積み立てるほうが、自分に合っていると感じました。
競馬の馬券購入いろいろ
競馬好きな方と話をしているときに、「軸ながし」とか、「マルチ」っていう単語を聞き、???となっていたのですが、内容が分かってしまうと何の事はない、組み合わせの事だと理解出来ます。
「単勝」は1位の馬を当てるだけのシンプルなものなので、出走馬が18頭いたとしたら、18パターンしか存在しません。
これが、もっとも組み合わせが多い「三連単」は、1位、2位、3位をそれぞれ馬番を当てると言うことで、18頭の出走馬の全ての組み合わせを購入すると、4896パターンになります。
この金額を購入すると、489,600円で、50万近くの投資になりますが、いくら一番払戻金額の高い三連単でも、50万のリターンというのは、そうそうでないので、こんな買い方をするのは、素人でもやらないでしょうね。
馬券は軸ながしが基本
競馬が奥深いと思ったのは、この「軸ながし」という買い方で、1位の馬を決めて、2位と3位を複数抑えて、その組み合わせで買うことで、投資リスクを抑えて、リターンを投資額より上回らせる事ができるんですね。
これで生計を立てているという人がいるというのもうなずけるぐらい説得力はあります。
軸ながしのサンプルとしては、1レースで18頭の出走馬がいた場合、7番の馬が1位と予想した場合、2位と3位に、1番から5番の5頭を購入した場合、21パターンの購入パターンが計算されます。
もちろん、1位も含めて2位、3位を選出できるのが、予想の腕の見せどころなのでしょうが、三連単の場合、当たればこの金額は、かなりの確率でリターンが上回ります。
このブログでは、競馬でもうける事をレクチャーするつもりはないので、この後、購入のパターン数の出し方をプログラミングしてみたいと思います。
パターン計算アルゴリズム
基本的に一番ややこしそうな「三連単」でのパターン計算を基本に書きますね。
BOXパターン
(1位、2位、3位を絞り込んだ複数におけるマトリクス的な組み合わせ)
(n) * (n-1) * (n-2)
# ex)5頭選出の場合
5 * (5-1) * (5-2) = 60
# ex)8頭選出の場合
8 * (8-1) * (8-2) = 336
1位の軸ながし
1位を1頭、2位、3位を同じ複数の組み合わせ
# ex) 2位、3位に5頭を選出した場合
5 * (5-1) = 20
# ex) 2位、3位に8頭を選出した場合
8 * (8-1) = 56
順位それぞれバラバラに複数購入の場合
今回一番悩ましかったのがこのパターンで、あまりこうした買い方をする事はなさそうですが、以下のような条件を元にプログラムしてみました。
・1位、2位、3位、それぞれに、複数可能(単一も可能)
・それぞれの順位で、部分的な重複も可能
// $data [ [1位軍] , [2位軍] , [3位軍] ]
function getBakenPatterns($data){
// return $data;
$cnt = 0;
// 1位
for($i1=0,$c1=count($data[0]); $i1<$c1; $i1++){
$num1 = $data[0][$i1];
// 2位
for($i2=0,$c2=count($data[1]); $i2<$c2; $i2++){
$num2 = $data[1][$i2];
if($num1 == $num2){continue;}
// 3位
for($i3=0,$c3=count($data[2]); $i3<$c3; $i3++){
$num3 = $data[2][$i3];
if($num1 == $num3 || $num2 == $num3){continue;}
$cnt++;
}
}
}
return $cnt;
}
この関数に、予想データを渡すと、その組み合わせ数を得られるというスニペットです。
ただし、注意事項として、受け渡すデータは、コメントにもある通り、1位、2位、3位のそれぞれの馬番を配列で持たせた、二重配列で送る必要があります。
この点、一般フォーマットが定まっていなかったので、関数単体でのルール定義にしておきました。
エンジニアの人で、競馬購入システムなどを組み立てる必要がある場合の計算に使ってください。
0 件のコメント:
コメントを投稿