はじめに
牛丼チェーンの「吉野家」と「すき家」などの同業他社が同じ交差点の角に並んで建っているのを見て、「わざわざ同じ場所に集まるんだろう?」 と疑問に思ったことはありませんか?
実は、経済学的な理由があります。ハロルド・ホテリングが提唱した 「競合する企業は互いに立地を近づけていく傾向がある」という原理 が、「ホテリングの法則」と呼ばれています。
今回は、この法則を検証するため1次元・2次元・3次元の空間でシミュレーションできるWebアプリを作りました。
ホテリングの法則とは
ホテリングの法則とは、どんなものなのか簡単に説明したいと思います。
A店舗とB店舗があり、周囲には住民が均一に分布しているとします。
ルール
各店舗は以下のルールに従って行動します。
① ユーザーは最も近い店舗へ行く(=その店舗の売り上げになる)
② 獲得ユーザー数が最も少ない店舗が、最もユーザーを獲得できる位置に移動する
処理イメージ
B店舗が一番ユーザーを獲得できる場所はA店舗のすぐ右になります。

この繰り返しが起きると、最終的に2店舗とも中央に集まります。
これがナッシュ均衡(どちらも動いても得をしない状態)です。
社会全体の観点では、両端の住民が遠くまで歩かなければならないため非効率ですが、個々の事業者にとっては合理的な行動です。
アルゴリズム
シミュレーションの核となる「最適位置を探す」アルゴリズムを紹介します。
基本的な考え方
各住民は最も近い店舗を選びます。あるストアが「今の位置から動いたとき、何人の客を獲得できるか」をフィールド上のすべての候補地について計算し、最も多く獲得できる位置に移動します。
距離の定義
次元ごとに使う距離関数が異なります。
1次元
|a - b|
2次元
\sqrt{(a_x - b_x)^2 + (a_y - b_y)^2}
3次元
\sqrt{(a_x - b_x)^2 + (a_y - b_y)^2 + (a_z - b_z)^2}
※2次元・3次元の内部実装では比較に距離の二乗を使い、√(ルート) を省略して高速化しています。
処理の高速化
愚直に実装すると「全候補地 × 全住民 × 全店舗」の計算が必要になり非常に遅くなります。
そこで次のような2ステップで高速化しています。
ステップ1:各住民について、対象店舗以外の最近傍店舗を事前計算
const minOther = people.map((p) => {
let minD = Infinity, minI = Infinity;
for (let i = 0; i < stores.length; i++) {
if (i === storeIdx) continue; // 対象店舗はスキップ
const d = dist2(p, stores[i]);
if (d < minD || (d === minD && i < minI)) { minD = d; minI = i; }
}
return { d: minD, i: minI }; // 他店舗への最短距離を記録
});
ステップ2:全候補地でその事前計算結果と比較するだけで判定
for (let x = 0; x < N; x++) {
for (let y = 0; y < N; y++) {
let c = 0;
for (let pi = 0; pi < people.length; pi++) {
const dx = people[pi].x - x;
const dy = people[pi].y - y;
const d = dx * dx + dy * dy; // 二乗距離(sqrt不要で高速)
// 候補地のほうが近ければ獲得
if (d < minOther[pi].d ||
(d === minOther[pi].d && storeIdx < minOther[pi].i)) c++;
}
if (c > bestCount) { bestCount = c; best = { x, y }; }
}
}
ステップ1を先に行っておくことで、ステップ2では「候補地までの距離と事前計算した値を比べるだけ」で判定できます。事前計算を行わない場合は、全候補地で全住民×全店舗の距離を毎回計算し直すため、店舗数が増えるほど処理が遅くなります。
完成したもの
1次元シミュレーション
横方向だけのシミュレーションです。
実行ボタンを押すと、最も市場シェアが低い店舗が自動的に最適位置へ移動し続けます。繰り返すと、店舗が隣り合わせになり、だんだんと店舗が中央に集まる様子が確認できます。
2次元シミュレーション
XY座標上でシミュレーションします。
1次元と同様に自動実行を繰り返すと、複数の店舗がフィールドの中心付近に密集していきます。
3次元シミュレーション
Three.jsを使って3次元空間上でシミュレーションします。
3次元においても同様に、店舗は空間の中心へ引き寄せられるように収束していきます。
宇宙空間でもホテリングの法則は通用しそうです。
競合店舗を増やしてみる
3店舗以上の競合がある場合、ホテリングの法則は適用されないと言われています。
実際に描画してみると、ボロノイ図のように各店舗の勢力圏が色分けされます。ステップ実行しても、すべての店舗が同じ場所に集中することはなく、最下位争いをする小競り合いは発生するものの、ホテリングの法則のような収束傾向は見られませんでした。
おわりに
今回はホテリングの法則を1次元・2次元・3次元でシミュレーションしました。
理論として語られていることを実際に視覚化したり、競合店舗を増やして試したりできるのが、シミュレーターの面白いところですね。また、同一チェーンの店舗を増やしてみたり、実際の地図上でシミュレートしたりしても面白そうです。
興味のある方は、Webページを用意していますのでぜひ触ってみてください。
Webシミュレーター
GitHub リポジトリ
ここまで読んでいただきありがとうございました。






