はじめに: なぜ迷路なのか
迷路には不思議な引力があります。
入口に立ったとき、出口までの道は見えません。壁に囲まれ、分岐で迷い、行き止まりに突き当たり、引き返します。解いた瞬間、ようやく全体像が見えます。その見えなかったものが見える感覚が、私を惹きつけるのです。
ではもし、その見えるようになるものが——絵だったら?
迷路を解き、ペンで正解の道を辿る。塗り終わって紙を離して見ると、自分が描いたはずのない絵が浮かんでいくー。ポートレート。ロゴ。風景。自分の手が迷路を解いていたはずなのに、気づいたら絵を描いていた——そんな体験です。
それが、私の迷路好きの原点です。
かつては手で創っていたのですが、今一から作るには、自分にある時間と集中力はあまりにも限られすぎていました。
一つ一つの仕組みはAIでできるかもしれないが、統合できる気がしない。
そんな思いを2025年12月に抱えながら、歩を進めてきました。
第1章: 原点
1.1 最初の問い
2025年12月。プロジェクトの第一歩は、地味に始まりました。
最初のコミットログに刻まれたのは、feat: V1.1 file size limit (413) and structured loggingという一行。ファイルサイズの制限設定と、動作を記録するためのログ機能の実装――。それは、壮大な理想とは裏腹に、極めて事務的な作業からのスタートでした。
しかし、その地味なコードの裏側で、私はある一つの「巨大な問い」と格闘していました。
「入力画像の輪郭に沿った『一筆書き』のパスから迷路を構築し、それを解き終えたときに元の画像が鮮明に浮かび上がる。そんなことが、果たして数学的・視覚的に可能なのだろうか?」
ここで、少しだけ想像力を働かせてみてください。この問いが秘めている無理難題がいかに高い壁であるかを。
単に迷路を生成するだけなら、既存のアルゴリズムを転用すれば事足ります。ランダムに壁を立てれば、それなりの迷路は完成します。あるいは、画像の暗い部分に通路を集中させれば、なんとなく絵らしく見えるかもしれません。しかし、本当に難しいのは、迷路としての厳密な整合性と画像としての再現性を、主観的に美しさを伴って同時に成立させることにあります。
この挑戦には、私を立ち往生させる3つの高い壁が立ちはだかっていました。
第1の難問:情報の変換——画像を迷路の言語へ翻訳する
一つ目は、画像の情報をどうやって迷路の構造へと落とし込むかという問題です。
画像は、色、輝度、エッジ(輪郭)といった要素で構成されています。これらを壁にするのか、それとも通路にするのか。単純に暗い場所を壁にするというルールを作ったとしても、それだけでは迷路として破綻してしまいます。
なぜなら、壁を配置しすぎれば通路が途絶えて孤立したエリアが生まれますし、通路を広げすぎれば迷路の体をなさなくなるからです。絵としての正解を維持しながら、迷路としての通れる・通れないのルールを両立させる変換アルゴリズムが必要不可欠でした。
第2の難問:一意解の保証——ただ一本の運命の道を引く
二つ目は、正解が必ず一つであることを数学的に保証する難しさです。
パズルとして成立するためには、入口から出口へ至る経路が、正確に一本でなければなりません。もし正解ルートが複数あれば、解く際の手応えは損なわれ、絵としての密度もバラバラになってしまいます。逆に正解ルートが途中で途切れてゼロになれば、それはもはやパズルですらありません。
広大なグリッドの中で、数千、数万という分岐を制御しながら、たった一条の光のような正解を一本だけ通す。この一意解の保証は、直感に頼る制作では到底到達できない領域でした。
第3の難問:定量的評価——見えるという主観を数値で測る
そして、最も厄介だったのが、解くと絵が出るという現象をどう評価するかです。
「よく見える」「なんとなく見える」といった判断は、個人の主観に過ぎません。開発者が主観に頼ってしまうと、少しうまくいっただけでこれで完成だと錯覚してしまい、本当の意味での改善サイクルが止まってしまいます。
人間が見て「美しい」「あの絵だ」と感じる感動を、あえて冷徹な数値として評価し、客観的にスコアリングする仕組みを作らなければ、プロジェクトはいつか独りよがりの迷走に陥ってしまいます。
三位一体の迷宮
これら3つの難問が、それぞれ独立していればまだ救いがありました。しかし、本当に困難を極めたのは、これらが互いに複雑に干渉し合うという点です。
画像の情報を迷路に変換する画期的な手法を思いついても、それを適用した瞬間に一意解が崩壊して迷路が解けなくなる。一意解を優先してガチガチに構造を固めると、今度は絵が出るという視覚的楽しさが犠牲になる。そして、それらを評価する数値がなければ、自分が今正しい方向に進んでいるのかさえ分からなくなる――。
3つの問いを解くためには、常に3つすべてを同時に意識し、バランスを取り続けなければなりませんでした。一箇所の糸を引けば全体が歪む。このプロジェクトが、一見シンプルに見えて底知れない奥深さを秘めている理由は、まさにこの同時成立の難しさに集約されていたのです。
最初からすべての答えを持っていたわけではありません。むしろ、五里霧中の中、失敗の山を築きながら一歩ずつ進むほかありませんでした。
3つの問いを解くために、3つの問いを同時に意識する必要がありました。これが、このプロジェクトが単純に見えて奥深い理由です。
1.2 38バージョンの試行錯誤:理論と現実の狭間での格闘
迷路生成という一見単純なタスクは、画像再現という制約が加わった瞬間に、数学的にも視覚的にも極めて難解なパズルへと変貌しました。開発日報に刻まれた38の足跡を、その中身に踏み込んで紐解きます。
正解の道から枝を伸ばす素朴なアプローチ(v1 - v16)
開発の初期段階、私が没頭していたのは、迷路生成における最も古典的かつ直感的な手法の改良でした。それは、まずキャンバスの上にスタートからゴールへと至る一本の揺るぎない正解ルートを、あたかも大樹の幹のように描き、その後に空いたスペースを埋めるようにして行き止まりの枝をランダムに生やしていくというアプローチです。
この手法は、一見すれば非常に理にかなっているように思えました。なぜなら、最初に正解の道を固定してしまえば、パズルとしての解けることは最初から保証されているからです。あとは、その周囲をいかに複雑なフェイクの道で埋め尽くし、挑戦者を惑わせるか。その密度の制御さえできれば、理想の絵画迷路に近づけるはずだと信じて疑いませんでした。しかし、この正解を先に作るという素朴な発想こそが、後に私を底なしの泥沼へと引きずり込む最大の原因となったのです。
当時のコードを振り返ると、そこには安全な枝という記述が散見されます。これは、枝を伸ばす際に、すでに存在する正解ルートや他の枝を破壊しないように、慎重に一本ずつ植樹していく処理を指していました。私は、まるで盆栽を整えるかのような細心さで、ピクセル単位の迷路を構築しようとしていました。入力画像の暗い部分、つまり絵の輪郭や影になる部分には、枝をより長く、より複雑に絡み合わせるようにアルゴリズムを調整しました。これによって、遠目から見たときには濃淡が生まれ、絵が浮かび上がるはずだったのです。
しかし、現実は残酷でした。この幹と枝のアプローチには、数理的な欠陥が潜んでいたのです。枝をランダムに伸ばしていくと、どうしても他の道と数ピクセルという至近距離まで接近する場面が出てきます。当時のアルゴリズムでは、たとえ1ピクセルでも壁があれば道は繋がっていないと判定していましたが、人間が肉眼でそれを見たとき、あるいは画像を解釈するプログラムがわずかなノイズを拾ったとき、その極細の壁は実質的に存在しないも同然の状態になります。
特に深刻だったのは、枝が成長して自分自身のルーツとは別の場所で正解ルートに接触しそうになる現象です。もし、行き止まりであるはずの枝の先端が、正解ルートの後半部分と意図せず繋がってしまったらどうなるでしょうか。本来なら迷路の半分以上を歩まなければ辿り着けないゴールへ、開始数秒で到達できてしまう悪魔の近道が誕生してしまいます。
私はこの問題を解決するために、バージョンを重ねるごとにスタブ(切り株)やツリー構造の制約といったルールを次々とコードに書き加えました。枝が伸ばせる方向を厳格に制限し、他の道との距離を一定以上に保つための衝突判定処理を、重厚な鎧のように積み上げていったのです。しかし、ルールを厳しくすればするほど、今度は別の問題が牙を剥きました。道同士が互いに避け合うようになった結果、迷路の中に手付かずの空白地帯が目立つようになったのです。
絵画迷路において、空白地帯は致命的です。それは絵に不自然な白い穴が開くことを意味します。画像の情報を忠実に反映したいという願いから密度を上げようとすれば、どこかで道が接触してショートカットが生まれる。ショートカットを恐れて道を引き離せば、スカスカの密度の低い画像になってしまう。この期間は、まさにこの密度と整合性という、互いに反発し合う二つの力の間で、一歩も前に進めなくなる停滞の時期でした。
当時の私のmdファイルには、部分的な改善は見られるが、全体を統合するルールが見つからないという、書き置きが残されていました。今思えば、このとき私は迷路を木として捉えるという抽象的な視点を持てず、ただ目の前のピクセルと格闘し、場当たり的な修正を繰り返すという、泥沼の戦術に陥っていました。
この時期に費やした膨大な時間と、積み上げられた失敗作の山。それらは一見すると無駄な遠回りに見えます。しかし、一本の正解を先に決め、周囲を枝で埋めるという直感的な手法が、いかに画像の複雑性に対応できないかを骨身に染みて理解したことは、後のブレイクスルーを生むための不可欠な絶望でした。精密に、より精密にという強迫観念に囚われていた私は、このv16の終わりにおいて、自らの手法が限界に達していることをようやく認めざるを得なくなったのです。
検証プログラムの導入と絶望的な近道の発見(v17 - v20)
迷路の複雑さが増すにつれ、自らの目視によるチェックはもはや限界を迎えていました。ディスプレイに映し出された無数の線の中に、道として繋がってはいけない致命的な隙間が隠れていないか。それを人間が一つひとつ確認するのは、砂浜に落ちた一粒の宝石を探すような途方もない作業でした。そこで私は、客観的かつ冷徹に迷路の構造を暴き出すため、グラフ理論における最短経路探索アルゴリズムである幅優先探索、いわゆるBFSを検証プロセスとして導入することに決めました。
この導入の目的は、スタートからゴールまでの正解ルートが、私の設計通りに一本だけ存在しているかを確かめることにありました。もし正解が複数あれば、アルゴリズムがそれを見つけ出し、私に警告を発してくれるはずでした。しかし、初めてこの検証プログラムを実行した瞬間に画面に表示されたのは、想像を絶する、そして目を疑うような冷酷な数字でした。
設計上の正解とは別に、壁のわずかな綻びを縫うようにしてゴールへと繋がるショートカットが、実に59,930箇所も発見されたのです。
この約6万という数字は、私のこれまでの努力が砂上の楼閣であったことを無慈悲に宣告するものでした。自分では完璧に行き止まりを配置し、挑戦者を惑わせる複雑な迷路を構築したつもりでいました。しかし、コンピュータの目から見れば、その迷路は至る所に穴が開いたザルのような代物であり、スタート地点から数歩進むだけで、至る所に隠れたショートカットという名の裏口が口を開けていたのです。
この絶望的な数字は、壁の配置ルールが根本から破綻していることを証明していました。画像から抽出した暗い領域に無理やり通路を詰め込もうとした結果、通路と通路を隔てる壁が限界まで薄くなり、ついには数学的な壁としての機能を失っていたのです。1ピクセルの書き漏らし、あるいはアルゴリズムの論理的な隙間が、これほどまでに巨大な欠陥となって現れる。迷路の体をなしていないという現実に直面し、私は個別の箇所を修正するようなパッチ対応では、この深淵のような課題を解決できないことを痛感しました。構造そのものをゼロから再定義しなければならないという、重い決断を迫られた瞬間でした。
密度と整合性のトレードオフ(v21 - v23)
検証プログラムによって突きつけられた約6万箇所のショートカットという現実に抗うため、バージョン21から23にかけて、私は迷路の密度を極限まで制御する過酷な調整作業に入りました。ショートカットが生まれる最大の原因は、通路が密集しすぎていることにあります。ならば、物理的に道が接触し得ないほどに経路を間引き、壁に十分な厚みを持たせれば、論理的な破綻は防げるはずだ。そう考え、私は迷路の線を極限まで削ぎ落としました。
しかし、その結果待っていたのは、別の意味での絶望でした。
ショートカットを完全に排除した迷路を遠目から眺めてみると、そこにはかつて描こうとした画像の面影はどこにも残っていませんでした。通路を減らしすぎたせいで、絵の陰影や輪郭を構成するための情報が失われ、ただのスカスカで味気ない線画が虚空に浮かんでいるだけだったのです。迷路としての整合性を守ろうとすれば、絵としての美しさが消える。この冷酷な二律背反が、私の前に大きな壁として立ちはだかりました。
逆に、失われた絵のディテールを取り戻そうとして、再び画像の暗い領域に密度を戻していくと、すぐに構造が破綻し始めます。少しでも線を増やせば、網の目のように道が繋がり、検証プログラムは再び無数のショートカットを報告し始めました。右を立てれば左が立たず、左を守れば右が崩れる。この時期の私は、まさに終わりのないシーソーゲームに翻弄されていました。
この泥沼の試行錯誤を通じて、私は一つの決定的な結論に達しました。ランダムに道を生成し、後から不具合を潰していくという場当たり的な手法では、画像の再現とパズルの成立という二つの相反する条件を同時に満たすことは、数学的に不可能であるという事実です。どれほどパラメータを微調整しても、それは根本的な解決にはなり得ません。この段階で、私はこれまでの延長線上にある開発を放棄し、全く異なる論理体系に基づいた新しいアルゴリズムの構築が必要であることを、痛いほどに理解させられました。
数学的な完全性を求めたハミルトン路の挫折(v24 - v26)
場当たり的な修正に限界を感じた私は、迷路の構造を根本から統治するための究極の解答を数学の世界に求めました。そこで浮上したのが、グラフ理論におけるハミルトン路という概念です。これは、与えられたすべての地点を正確に一度だけ通過して一本の道を作り上げるという、究極の一筆書きを意味します。
もしこのハミルトン路を画像全体に敷き詰めることができれば、理想としていた全ての条件が完璧な形で満たされるはずでした。画面の隅々まで道が通ることで絵としての密度は最大化され、かつすべてのマスを一筆書きで繋ぐため、原理的にショートカットが生まれる余地はありません。それは、画像の再現性と迷路の整合性が一点の曇りもなく両立された、まさに聖杯とも呼べる解決策に見えました。
しかし、このあまりにも美しい理論の裏側には、計算機科学における巨大な罠が潜んでいました。
一般的なグリッド上でのハミルトン路探索は、NP完全問題と呼ばれる、現代のコンピュータが最も苦手とする難問の一つだったのです。地点の数が数個や数十個であれば容易に解けますが、絵を描き出すために必要な数万、数十万という膨大なマス目を前にして、アルゴリズムは瞬く間に計算量の爆発に飲み込まれました。
私は、ポーンシュドルフの規則といったヒューリスティクスを導入し、なんとか計算を効率化しようと試行錯誤を繰り返しました。しかし、どれほどコードを最適化しても、計算機が冷酷な沈黙を破ることはありませんでした。膨大な電力を消費し、CPUが悲鳴を上げるような高負荷状態で数時間を費やしても、埋まったのはキャンバス全体のわずか0.4パーセント。画面の片隅に、数ミリにも満たない細かなのたくりのような線が描かれた段階で、プログラムは計算の迷宮で行き止まり、事実上の停止状態に陥りました。
理論上は完璧であっても、現実の計算資源では決して辿り着けない。どれほど正しい数理モデルであっても、実装できなければそれはただの空論に過ぎないという事実を、私はこの痛烈な敗北から学びました。数学の美しさに逃げ込むことで解決を図ろうとした私の試みは、圧倒的な現実の壁の前に、無残にも瓦解したのです。
全域木とオイラーツアーによる最初の突破口(v27 - v34)
数学の理想に敗れ、次なる道を模索していた私が辿り着いたのは、グラフ理論における全域木(スパニングツリー)という概念を基盤とした、より柔軟で堅牢なアプローチでした。ハミルトン路のような厳密すぎる一筆書きに固執するのではなく、網目状に広がる全ピクセルの中から、閉じた輪を一切作らずにすべての地点を連結する、巨大な樹木のような構造を抽出する手法に転換したのです。
この全域木という構造には、極めて重要な数学的性質があります。それは、木の中に存在する任意の二点間を結ぶ経路が、物理的にたった一本しか存在しないという点です。どれほど複雑に枝分かれを繰り返したとしても、道が再び合流してループを形成することがないため、迷路の整合性を脅かしてきた宿敵であるショートカットが、理論上1箇所たりとも発生し得ないのです。
私はこの全域木を、入力画像の色の濃淡に基づいて構築することにしました。暗い領域にはより多くの枝が密集し、明るい領域には最小限の道しか通らないように重み付けを行うことで、木の形状そのものに画像の情報を宿らせたのです。そして、この広大な木の輪郭を、あたかも壁を右手に添えてなぞるように一周するオイラーツアーというアルゴリズムを組み合わせました。
これによって、迷路の生成プロセスに劇的な変化が起きました。オイラーツアーは、木のすべての枝を一度だけ往復して出発点に戻ってくる一筆書きの経路を生成します。この歩みの軌跡こそが、私が追い求めていた正解の道となりました。全域木が全地点を網羅しているため、キャンバスの隅々まで道を行き渡らせるカバレッジが確保され、同時に木構造の制約によってショートカットは完全に封殺されました。
バージョン34に至り、ついに私は暗闇の中で確かな手応えを掴みました。画面には、複雑に入り組みながらも論理的に一分の隙もない迷路が描かれ、それを解き終えた後には、かつてない鮮明さで元の画像が浮かび上がっていたのです。数学的な厳密さと、画像再現という視覚的な欲求。それまで決して相容れることのなかった二つの要素が、全域木という架け橋によって初めて、一つの解として結実した瞬間でした。
全域木とオイラーツアーの組み合わせによって、ついに数学的な勝利を手にしたかに見えました。しかし、画面に映し出されたその正解を凝視したとき、私は言葉を失いました。そこに現れたのは、あまりにも非人間的で、冷徹なまでに緻密すぎる迷路だったからです。
論理的には完璧でした。ショートカットは存在せず、画像の再現度も極めて高い。しかし、1ピクセル単位という極限の細さで構築された道は、もはや人間の肉眼で判別できる限界を超えていました。まるで顕微鏡で覗き込まなければ構造が掴めないほどに道が密集しており、どれほど精巧なプリンターで出力したとしても、隣り合う線同士が混ざり合い、物理的に攻略不可能なノイズの塊へと成り果ててしまったのです。
当時の開発データを見返すと、ノード数は63,025という膨大な数に達していました。これほど巨大なグラフを一枚のキャンバスに押し込めれば、一つひとつの通路の幅はわずか数ピクセル程度にしかなりません。たとえA4サイズに拡大印刷したとしても、密度が高すぎて線が潰れてしまいます。コンピュータが内部処理として解く分には完璧であっても、生身の人間がペンを手に取り、思考を巡らせながら道を辿るという体験を想定したとき、この迷路は完全に失格でした。
ここで私は、根本的な問い直しを迫られました。画像の情報を一滴も漏らさず反映したいという執着から、ピクセル単位の精密さを追求してきましたが、そのアプローチ自体が間違いだったのではないかという疑念です。
冷静に考えれば、人間が快適に迷路を解くために必要な道幅は、入力画像の1ピクセルよりも遥かに大きいはずです。ペン先や指の幅を考慮すれば、紙の上で最低でも3ミリメートルから5ミリメートル程度の余白がなければ、パズルとしての体をなしません。印刷標準である300DPIの解像度で換算すれば、通路幅には35ピクセルから60ピクセル以上のゆとりが求められます。それに対して、私が作り上げたミクロの迷路は、わずか1ピクセルから3ピクセルという絶望的な細さでした。解くどころか、見ることさえ拒絶するような構造になっていたのです。
この38段階に及ぶ長い試行錯誤は、私に痛烈な教訓を刻み込みました。それは、デジタルな計算上の完璧さを盲信して突き進むほど、アナログな人間が肌で感じる楽しさや心地よさから遠ざかってしまうというパラドックスです。
精密さを追求することが、かえって迷路の存在意義を奪う。この矛盾を乗り越えるためには、これまでの執着を捨て、人間が体験するスケールへとアルゴリズムを歩み寄らせる必要がありました。精密さをあえて放棄し、ゆとりある道幅を維持しながらいかに絵としての美しさを保つか。この発想の大転換こそが、次なるブレイクスルーへと至る唯一の道であり、全く新しい別のアプローチが必要となった瞬間でした。
第2章:密度パラダイム — DM-1からDM-8への進化
2.1 発想の転換:ピクセルからセルへ
バージョン34までの私のアプローチは、いわばピクセルという微細な粒子の世界に幽閉されていました。入力画像の輪郭を忠実に追い求め、エッジの一点一点をグラフのノードとして定義する。その結果、63,025もの膨大なノードがひしめき合い、通路の幅がわずか3ピクセルしかない、人間には到底踏み込めないミクロの迷宮が誕生してしまいました。
数学的には正しくとも、人間には解けない。その矛盾を打破するために、私は根本的な思考のパラダイムシフトを決断しました。
ピクセルという最小単位を捨て、セルという集合体で思考する。
画像をピクセル単位でなぞるのをやめ、10×10や14×14といった、ある程度の広さを持った粗いグリッド(セル)へと分割することにしました。各セルの内部に含まれるピクセルの平均的な明るさを計算し、その数値を迷路構築における壁の重みへと変換するのです。単位をセルへと引き上げることで、通路の幅は物理的に担保され、人間がペンを走らせるのに十分な広さを持つ迷路が、初めて現実のものとなりました。
ここで特筆すべきは、解像度を粗くするという選択が、決して精緻さの放棄や妥協ではないという点です。確かにピクセル単位の極小のディテールは失われます。しかし、それと引き換えに、迷路としての本質的な要件である、人間が体験できることという価値が初めて息づきました。精密であっても解くことができない無機質なデータより、粗くとも自分の手でゴールを目指せるパズルの方が、迷路としての生命力に溢れています。
そして、この転換によって、プロジェクトの核心となる思想が明確な形を取り始めました。
暗いセル → 壁としての重みを低く設定 → クラスカル法により早期に接続を確立 → 優先的に通路となる
明るいセル → 壁としての重みを高く設定 → 接続の優先順位を後回しにする → 最終的に壁として残る
画像の輝度そのものが、迷路の構造を決定する設計図となる。
あらかじめ壁を立ててから隙間に経路を通すのではありません。画像の明暗そのものが、どこに道を開き、どこを閉ざすべきかをアルゴリズムに直接指示するのです。画像と迷路は、もはや別々の層として重なっているのではなく、表裏一体の、同一の存在を二つの側面から表現したものへと昇華されました。
これこそが、本プロジェクトの転換点となった密度マッピング(Density Mapping)――DM系列の始まりでした。
2.2 DM-1: 基盤の確立
迷路生成の五段階パイプライン
DM-1の実装コードはわずか220行に過ぎません。しかし、その簡潔なコードの一行一行には、以降のすべての進化を決定づける重要な種子が宿っていました。
迷路が生成されるまでのプロセスは、以下の五つの明確なステージに分けられます。
Stage 1:画像の最適化
入力された画像をグレースケールに変換し、さらにCLAHE(コントラスト制限付き適応波形平坦化)を施すことで、画像全体の明暗のコントラストを最適化し、迷路化に適した下地を作ります。
Stage 2:密度マップの生成
最適化された画像をN×Nの粗いグリッドに分割し、各エリアの平均輝度を算出することで密度マップを構築します。
Stage 3:重みの割り当て
この密度マップを基に、隣接するセル間に存在するすべての壁に対して、個別の重みを割り当てます。
Stage 4:クラスカル法による最小全域木の構築
重みが割り振られた壁のリストをソートし、Union-Findデータ構造を用いて最小全域木を形作ります。
Stage 5:最終出力
構造が完成した迷路に対し、最適な入口と出口を選定。幅優先探索(BFS)によって正解ルートを抽出し、PNGやSVG形式で描き出します。
数学が保証する一意解の信頼性
なぜ、この工程においてクラスカル法(Kruskal's algorithm)による最小全域木の採用が不可欠だったのでしょうか。
グラフ理論において、全域木とはすべてのノードを連結しつつ、閉じた輪(閉路)を一切持たない辺の集合を指します。閉路がないということは、迷路内の任意の二点間を結ぶ経路が、物理的に正確に一本しか存在し得ないことを意味します。つまり、全域木を構築したその瞬間に、迷路の正解が一つであることを数学的に保証できるのです。
この数学的保証という言葉は、単なる理想の表明ではありません。自分の実装が正しいからおそらく一意解だろうと期待するのではなく、グラフ理論の定理として証明されているからこそ絶対に一意解であると断言できるのです。バグの有無に関わらず、全域木の定義に従う限り、迷路としての整合性は揺らぎません。この論理的な盤石さこそが、DM系列の信頼性の根幹となっています。
クラスカル法は、すべての壁(辺)を重みの軽い順に並べ、閉路を作らないものから順番に「除去」していくアルゴリズムです。暗い領域の壁は重みが軽いため優先的に取り除かれ、明るい領域の壁は重いため後回しにされて多くが残ります。
その結果、暗い領域には通路が密集し、明るい領域には壁が密集することになります。完成した迷路を遠目から眺めると、暗い領域が通路の海として浮かび上がり、元の画像のシルエットが鮮やかに再現されるのです。
高速化を支えるUnion-Findの魔術
この複雑なソートと統合のプロセスを瞬時に完了させるために、DM-1ではUnion-Findという非常に洗練されたデータ構造を導入しました。これはどのノードがどのグループ(連結成分)に属しているかを高速に管理するための仕組みです。
クラスカル法とUnion-Findの組み合わせが極めて強力である理由は、その圧倒的な処理速度にあります。512×512ピクセルの画像から迷路を生成する際、10×10のグリッド規模であれば処理時間は1秒もかかりません。理論的な美しさが、そのまま実用的なパフォーマンスへと直結しているのです。
この高速化を実現しているのが、以下の二つの工夫です。
経路圧縮(path compression)
ノードの所属を調べるfind操作の際、通過したすべてのノードを直接グループの代表元につなぎ直します。これにより、二回目以降の検索スピードが劇的に向上します。
ランクによる統合(union by rank)
二つのグループを結合する際、背の低い木を高い木の子にすることで、木が不必要に深くなるのを防ぎ、構造の偏りを抑えます。
この二つの技術を組み合わせることで、n回の操作にかかる合計時間は、数学的に「実質的な定数時間」と見なせるほどに短縮されます。アッカーマン関数の逆関数(α(n))を用いたこの計算量は、宇宙的な規模の計算であっても実用上の負荷がほぼ増えないことを意味します。
壁を一つずつ受け入れるか、拒否するかというクラスカル法の逐次的な判断は、Union-Findが最も得意とする同じグループか判定し、必要なら統合するという操作と完璧な相性を見せました。DM-1で確立されたこの「Kruskal + Union-Find」という黄金の組み合わせは、その完成度の高さゆえに、最終バージョンであるDM-8に至るまで一切変更されることなく、すべての進化を支える不動の基盤として機能し続けたのです。
2.3 DM-2: コントラストの自動調整
DM-1で迷路生成の基礎体力が備わった次なるステップとして、DM-2ではどのような画像が入力されても最適な結果を導き出すための適応能力が実装されました。
写真は撮影された環境によって、その表情を劇的に変えます。薄暗い室内で撮影された写真は全体に沈み込み、逆光の風景は明暗の差が激しく、フラットなイラストは色の変化が乏しいものです。これら性質の異なる画像に対し、一律の処理を施しても理想的な迷路は生まれません。そこでDM-2が導入したのが、画像の統計量を読み取り、自らのパラメータを書き換える自動チューニング機構でした。
コントラスト補正の動的制御
DM-2の核心にあるのは、CLAHE(コントラスト制限付き適応ヒストグラム平均化)という高度な補正技術の最適化です。ここでは、画像の輝度の広がりを示す標準偏差という指標が羅針盤の役割を果たします。
標準偏差の値が小さいということは、画像全体の色の差が乏しく、ぼんやりとしていることを意味します。このような低コントラストな画像に対しては、アルゴリズムは積極的に補正の強度を高め、迷路の道筋を際立たせます。逆に、標準偏差が大きい画像はすでに十分な明暗差を持っているため、過度な加工を控えて自然な陰影を活かすよう振る舞います。
この制御により、どんな条件下で撮られた写真であっても、迷路化に最適な「明暗のメリハリ」が自動的に整えられるようになりました。
輪郭線を守るCannyエッジ検出の統合
密度マップが画像全体の面の情報を伝える役割を担う一方で、DM-2では線の情報を補完するためにCannyエッジ検出が統合されました。これは画像の輪郭を特定し、その場所を優先的に壁として保存する仕組みです。輪郭線が迷路の壁として残ることで、完成したパズルを眺めたときに、元画像の形がより直感的に、鮮明に認識できるようになります。
このエッジ検出においても、固定された数値ではなく標準偏差に基づいた比率による制御が採用されました。エッジ検出の閾値、つまりどれほどの輝度変化を境界線と見なすかという基準を、画像の統計量に連動させたのです。
コントラストが低い画像では、ごくわずかな変化もエッジとして敏感に捉えなければ、大切な輪郭が失われてしまいます。一方で、コントラストが激しい画像で感度を上げすぎると、今度は不要なノイズまで線として拾いすぎてしまいます。標準偏差の比率を基準に据えることで、暗い画像でも明るい画像でも、常にちょうどよい感度で形を切り出すことが可能になりました。
適応値という設計哲学
固定された設定値に頼るのではなく、入力されたデータそのものから最適な数値を導き出す。この設計原則は、DM-2において初めて確立されました。
この哲学は、後に続くマルチスケール合成などの高度な機能においても、一貫して守り抜かれることになります。どのようなカテゴリの画像が来ても柔軟に対応し、安定した品質の迷路を出力し続けるロバスト性。それは、DM-2で植えられた適応という思想が、プロジェクト全体に根を張った結果に他なりません。
2.4 DM-4: 8階調の壁 — 迷路がトーンを帯びる瞬間
これまでのDM-1からDM-2に至るまでの迷路は、壁は黒、通路は白という極めてシンプルな白黒2値の世界でした。この方式は迷路としての視認性には優れていますが、画像の持つ豊かな濃淡情報を表現するには限界があります。明暗の情報を、単に道のある/なしという二択に凝縮せざるを得なかったからです。これは手書きであれば当然の話で、AI開発により初めてぶつかった壁となります。
ただ、どうせやるなら、やれるだけやりたい。
この限界を打ち破るべく、DM-4では壁そのものに8段階のグレースケールを適用するという手法を導入しました。
8段階という絶妙なバランス
DM-4では、各セルの輝度を8段階の階調へと割り当て、壁の色として反映させます。暗い領域の壁は漆黒に近く、明るい領域の壁は白に近いグレーで描かれます。
なぜ、あえて8段階という制約を設けたのでしょうか。2値では情報の圧縮が強すぎ、逆に256階調のフルスケールでは、壁と通路の境界が曖昧になりすぎてパズルとしての視認性が損なわれます。8段階という階調は、画像のディテールを十分に保持しつつ、壁と通路の境界線を明確に保つことができる、人間の知覚にとっての絶妙な中間点だったのです。
知覚に基づいた量子化の設計
DM-4における最大の挑戦は、256階調のグレースケールをいかにして8つの階調へ振り分けるか、という量子化の設計にありました。
単純に等間隔で数値を区切るのではなく、DM-4では視覚的な均等感に配慮した独自の数値を採用しました。人間の目は、明るさの変化を直線的ではなく、対数スケールに近い形で捉える特性があります。そのため、暗い側には細かな階調を割り当て、明るい側にはやや粗い階調を配置することで、人間が目で見た際により自然で、立体感のある仕上がりを実現しました。
さらに、量子化された階調の境界を滑らかにするため、仕上げにガウシアンブラーを適用しました。壁の色がパキッと切り替わるのではなく、じわじわと滲むように変化する平滑化の処理を行うことで、脳が点や線の集合ではなく一つの像として迷路を認識しやすくなったのです。
二つのチャネルが紡ぐ新しい表現
この改革により、迷路は構造とトーンという二つの異なるチャネルで情報を伝えるメディアへと進化を遂げました。
第1チャネル(構造):通路の配置や密度によって、画像の暗部や輪郭を表現する。
第2チャネル(トーン):壁自体の色が輝度情報を補完し、画像の立体感やグラデーションを再現する。
この進化の結果、画像の再現性を測る指標であるSSIM(構造的類似度)は0.45から0.55へと跳ね上がりました。このプラス0.10という数値の変化は、知覚的には劇的です。それまでは何かの模様が見える迷路だったものが、この瞬間、はっきりと画像が見える迷路へと昇華されたのです。
印刷品質に耐えうる緻密なレンダリング
出力の美しさにおいても、DM-4は一切の妥協を排しました。描画時には、あえて実際の出力サイズよりも数倍大きなスケールで内部描画を行い、そこから高品位な手法で縮小を行うアンチエイリアス処理を導入しました。
これにより、デジタル画面上はもちろん、高精細なPDFとして印刷した際にも、壁の境界線がガタつくことなく滑らかに表現されるようになりました。ガウシアンブラーによる平滑化と相まって、量子化特有のノイズや違和感を取り除き、工芸品のような気品を持つ出力が可能になったのです。
2.5 DM-5: 紙の上で解ける迷路
デジタル画面上で鑑賞するだけであれば、解像度やサイズの設定には無限の自由があります。拡大すれば細部が見えるのは当然だからです。しかし、このプロジェクトが目指す究極のゴールは、鑑賞用のアートを作ることではなく、あくまでも人間がペンを手に取り、自らの手で解き明かす迷路を届けることにあります。そのためにDM-5では、デジタルデータの枠を超え、印刷物としての圧倒的な品質を実現するPDF出力機能を実装しました。
印刷専用エンジンと多様な規格への対応
DM-5は、プロフェッショナルな文書生成ライブラリであるreportlabを統合しました。これにより、家庭用プリンターや業務用印刷機で一般的とされる300DPIという高精細な解像度を確保しつつ、A4、A3、レターサイズといった世界標準の用紙規格に最適化された出力が可能になりました。単なる画像の引き伸ばしではなく、各用紙サイズに合わせて迷路の構造を再計算することで、どの紙に印刷しても最適なパズル体験が得られるよう設計されています。
視距離に基づいた壁厚の動的設計
DM-5において最もユニークな機能は、人間の視覚特性と、迷路を解く際の身体的な距離を考慮した壁厚の計算アルゴリズムです。ここでは、迷路と目との距離、すなわち視距離に応じた微細な調整が行われます。
視距離30センチメートルの場合:手に持って解く状況を想定し、壁の厚みを1.5ポイントに設定します。この距離であれば、細い線であっても十分に識別でき、かつ絵としての密度も高く保つことができます。
視距離50センチメートルの場合:テーブルに置いて解く状況を想定し、壁の厚みを2.5ポイントへと太くします。距離が離れると視覚的な感度が低下するため、線を強調することで視認性を確保し、解く際のスムーズさを損なわせない工夫です。
この細やかな設計は、印刷された迷路を手に持って解く場面と、机に広げて解く場面のどちらにおいても、ストレスのない最高のパズル体験を提供するために不可欠なものでした。
なぜ、高度なデジタル技術を駆使しながらも、あえて紙で解けることにこれほどまでに固執したのでしょうか。それは、迷路を解くという行為が、本質的に身体性を伴う体験だからです。
画面をスクロールして一部を切り取って見るのと、一枚の紙の上で全体を俯瞰し、自らの手でペンを走らせるのとでは、その没入感には雲泥の差があります。指先で道を探り、迷い、ペンの跡を辿り、時には間違えて消しゴムで消す。そうした触覚を通じた試行錯誤の果てに、突如として一枚の画像が浮かび上がる瞬間。その感動は、物理的な実体を伴う紙の上での体験において、初めて最大化されます。
デジタル時代の利便性を活用しながらも、その最終的な着地点をアナログな身体的感動に置く。DM-5は、高度なアルゴリズムと人間の手の温もりを繋ぐ、重要な架け橋としての役割を担っています。
2.6 DM-6: ベイズ最適化 — 人間の勘の限界を超える
DM-5に至るまで、迷路の品質を左右するパラメータの調整は、良くも悪くも開発者である私自身の勘と、終わりのない試行錯誤に委ねられていました。グリッドのサイズ、通路の比率、エッジの重み、コントラスト補正の強度、レンダリングのスケール、そして仕上げのぼかしの半径。これら8つ以上の変数は互いに複雑に干渉し合い、一つの数値を動かせば他の数値の最適解も連動して変化します。
この画像にはこの設定が適しているはずだという属人的な直感に頼る開発では、画像カテゴリごとの最適解を導き出すまでに、気が遠くなるほどの時間を費やすことになります。人間が8次元という広大なパラメータ空間を俯瞰し、その相互作用を把握して最適点を見つけ出すことは、実質的に不可能に近い挑戦でした。
Optunaによるベイズ最適化の導入
この限界を突破するため、DM-6ではOptunaという最適化フレームワークを導入し、画像の構造的類似度(SSIM)を目的関数としたベイズ最適化、具体的にはTPE(Tree-structured Parzen Estimator)と呼ばれるアルゴリズムを組み込みました。
これにより、一度コマンドを実行すれば、コンピュータが自動的に100回以上の試行を繰り返し、その画像にとって最もSSIMが高くなるパラメータの組み合わせを自動的に発見してくれるようになりました。しかし、ただ闇雲に探索させるわけではありません。それぞれの画像カテゴリが持つ特性に合わせた制約付き探索空間を定義し、人間のドメイン知識をアルゴリズムの事前分布としてあらかじめ組み込みました。
ポートレート:顔の細部や表情を再現するため、細密なグリッド設定を優先。
風景:広い明暗差を捉えるため、通路比率の許容範囲を広く設定。
ロゴ:形を際立たせるために高コントラストを重視。
アニメ:特徴的な輪郭線を逃さないよう、エッジの重みを固定。
こうした制約を設けることで、ポートレートに対して極端に粗いグリッドを試すような無意味な計算を排除し、効率的かつ知的な探索を実現しました。
写真カテゴリにおける壊滅的失敗と解決
しかし、この高度な探索プロセスの途上で、写真カテゴリのSSIMが0.069という、目を疑うほどに低い数値で停滞する問題が浮き彫りになりました。どれほどベイズ探索を繰り返しても、写真だけは迷路を見ても元の画像が全く判別できないほど崩壊していたのです。
原因は、写真特有の均一な輝度分布にありました。汎用的な自動補正機能が写真に対しては過剰に働き、本来活かすべき繊細なグラデーションを破壊していたのです。探索空間そのものが誤っていれば、いくら最新のアルゴリズムを用いても正解には辿り着けません。
そこで導き出された解決策が、写真専用の特殊設定であるフォト・プリセットの実装でした。自動補正をあえて極限まで抑え、壁の重みの差を最小化し、さらにレンダリングのスケールを4倍に引き上げてから強力なぼかしを加える。この写真の統計的性質に特化したアプローチにより、SSIMは0.069から0.776へと跳ね上がりました。実に1025パーセントという劇的な改善です。
この1025パーセントという数字が意味するのは、元の画像が何であるか全く分からなかった状態から、3メートルほど離れて眺めるだけで、写真のディテールが鮮明に浮かび上がる状態への劇的な進化です。同じ迷路生成アルゴリズムを用いていながら、前処理の設定一つでこれほどまでに結果が変わる事実は、万能なアルゴリズムなど存在しないという真理を私に突きつけました。
ベイズ最適化がもたらした真の価値は、単に最適値を見つけ出したことだけではありません。100回に及ぶ探索の結果を可視化することで、パラメータ空間の地形が明らかになったことにあります。写真カテゴリだけが他のカテゴリとは全く異なる分布を形成していることが一目で分かったからこそ、写真だけは別の論理で処理しなければならないという、本質的な課題の正体に気づくことができたのです。
探索という行為は、答えを見つけるための手段であると同時に、直面している問題がどのような形をしているかを照らし出すためのプロセスでもありました。この観察から得られた知見が、最終的なプリセット設計の確かな指針となったのです。
2.7 DM-7: passage_ratio — 天井を突破する1パラメータ
DM-6で導入したベイズ最適化という強力な武器をもってしても、画像の再現性を図るSSIM(構造的類似度)の数値は0.49付近で無情にも頭打ちとなりました。何百回、何千回とパラメータの組み合わせを試行させても、0.50という壁を超えることができません。アルゴリズムが最適解を求めてもがき、袋小路に迷い込んでいるかのような停滞感がプロジェクトを包みました。
この限界の原因を深く探っていくと、プログラムの深部に潜んでいた通路幅の固定値設定に行き当たりました。当時のコードでは、通路の幅がセルサイズの半分に強制的に固定されていたのです。この単純なルールが、迷路全体の約21パーセントを強制的に白いピクセルで埋め尽くしていました。この消せない白の面積こそが、SSIMの数値を抑え込んでいた天井の正体でした。
強制的な白が招く構造的解離
なぜ、画面の2割強を占める白い通路がSSIMの天井となってしまうのでしょうか。SSIMは画像全体の輝度、コントラスト、そして構造がいかに元画像と一致しているかを精密に測定します。元画像の本来なら暗くあるべき領域にも、21パーセントもの白い通路が一律に入り込んでしまうため、構造的な差異がどうしても生まれてしまいます。
この強制的な白を減らすことができれば、画像の暗い部分はより暗く保たれ、元画像の構造に近づくことができます。そこでDM-7では、通路幅をセルサイズの5パーセントから60パーセントの間で自由に変更できる、通路比率(passage_ratio)という新しいパラメータを導入しました。
数値が語る劇的な改善
このたった一つのパラメータを解放しただけで、迷路の表情は一変しました。
比率0.50(従来の設定):SSIM 0.4884。面積の21パーセントが強制的に白くなる。
比率0.15:SSIM 0.5500。白の占有率が約5.5パーセントまで劇的に減少。
比率0.10:SSIM 0.6149。ついに0.50の天井を突破し、未知の領域へ。
SSIMが0.49から0.61へと跳ね上がったことの意味を具体的に表現するなら、それは見ると何か絵のような模様があるという段階から、見れば、これが誰の顔であるか即座にわかるというレベルへの劇的な進化です。
数理モデルから導く最適なバランス
通路比率の数学的な意味を整理すると、迷路の幾何学的な性質が浮かび上がります。セルサイズに対して通路比率を下げていくと、画面全体に占める通路(白いピクセル)の面積は、計算上、急激に減少していきます。比率を下げれば下げるほど、暗い領域は元画像が持つ本来の暗さを維持できるようになり、これがSSIMの劇的な改善に直結します。
しかし、比率を下げれば通路は必然的に細くなります。もし比率を0.05以下にしてしまえば、印刷した紙の上では通路がわずか1ピクセル程度の細い糸になってしまい、人間が目で追うことさえ困難になります。ここには、画像としての再現度と、迷路としての解きやすさという、避けては通れないトレードオフが存在していました。
迷路の存在意義を守る制約
プロジェクトの優先順位は、当初から要件定義書に明確に刻まれていました。
最優先事項:一意解として物理的に解けること。
同等の優先事項:絵として明確に認識できること。
次優先事項:画像としての再現性を高めること。
見た目の美しさを追求するあまり、一意解という迷路の本質を犠牲にすることは、このプロジェクトでは決して許容しませんでした。そこの美しさは譲れません。
DM-7の役割は、この厳格な制約の中で、ベイズ最適化による探索範囲を通路比率0.05から0.60の間に設定し、人間が解けるという物理的な限界を守りつつ、最高の結果を導き出すことでした。
通路比率というパラメータは、パズルとしての実用性と、アートとしての完成度。その両者の間で理想的な着地点を決める、繊細かつ強力な調節つまみとなったのです。
2.8 DM-8: マルチスケールピラミッド — 3つの解像度で「見る」
DM-7までの密度マップは、画像を単一の解像度だけで捉える「単一スケール」のアプローチに依存していました。画像を一定の格子状に分割し、その一マスごとの明るさを計算する。この手法は、すぐ隣にあるセルとの微細な明暗差を描き出す「局所的な描写」には優れていましたが、一方で大きな欠陥を抱えていました。それは、画像全体が持つ大きなうねりや、広範囲にわたる明暗のグラデーションを捉えきれないという点です。
木を見て森を見ず。まさにこの言葉通り、細部に執着するあまり、画面全体の構造を見失っていたのが単一スケールの限界でした。この課題を解決するため、DM-8ではピラミッド型の「マルチスケール密度マップ」という概念を導入しました。
三つの階層が織りなす情報の統合
DM-8では、画像を以下の三つの異なる解像度で同時に解析します。
L1層(粗視):画像を極めて大きく捉え、左半分が暗く右半分が明るいといった、画面全体の基礎となる明暗構造を把握します。
L2層(中間):大まかな輪郭や、文字情報のブロックがどこにあるかといった、中規模な構造を抽出します。
L3層(原寸):これまで通りのセル単位の輝度を測定し、細密なディテールを保持します。
これら三層の情報を単に混ぜ合わせるのではなく、写真の現像技術などで用いられるアンシャープマスクの原理を応用して合成しました。原寸のデータから中間層のデータを差し引くことで、その境界にある急激な変化――つまり輪郭線や境界線を浮き彫りにし、それを元のデータに加算して強調するのです。この処理により、迷路の密度マップ上でエッジが鮮烈に際立ち、形がよりはっきりと認識できるようになりました。
指標の裏に隠れた真の進化
DM-8がもたらしたSSIM(構造的類似度)の向上は、全カテゴリの平均で見ればわずかな数値の改善に留まっているように見えます。しかし、この地味な数字の裏には、特定の条件下での劇的な進化が隠されていました。
通路の幅が広く、一マスが大きな設定、具体的にはセルサイズが24ピクセルを超えるようなケースにおいては、SSIMの改善幅は平均値の十倍以上に跳ね上がります。これは、グリッドが粗くなればなるほど、マルチスケールによる構造の把握が威力を発揮することを意味しています。
この評価過程を通じて、私は重要な教訓を得ました。全体平均という大まかな指標だけを見ていては、特定の条件下で起きている本質的な進化を見落としてしまう。評価の粒度を、検証したい技術の特性に合わせることの重要性を、DM-8は改めて教えてくれました。
変わらぬ基盤と、進化した表現
DM-8におけるこの革新は、あくまで密度マップの計算方法、つまりどこを道にするかを判断する知能の部分のアップデートです。
プロジェクトの根幹であるクラスカル法による最小全域木の構築や、入口と出口の選定、そして正解ルートの探索アルゴリズムには一切手を加えていません。そのため、数学的に証明された正解が必ず一つであるという一意解の保証は、一分たりとも損なわれることなく維持されています。
不動の数学的基盤の上に、より高度な視覚的表現を積み重ねる。DM-8をもって、密度パラダイムによる進化は一つの完成形へと到達しました。
---
第3部: 壁が先か、道が先か — V1〜V6の哲学的闘争
3.1 6つの設計思想、6つの失敗と成功
迷路生成アルゴリズムの進化は、まさに数学的な正しさと視覚的な意図が衝突し、融け合っていく歴史でした。V1からV6までの軌跡は、一見遠回りに見えますが、その一段一段が人間が解き、かつ絵に見えるという高いハードルを超えるために必要なステップでした。
V1: 壁が先、道は後 — 制御不能な正解
V1は、最も素直で教科書的なアプローチでした。まず画像の輝度に合わせて壁を構築し、その隙間に最短経路(Dijkstra)を通します。
しかし、結果はSSIM 0.32という厳しいものでした。アルゴリズムが最短を求めるほど、道は画像をなぞることをやめ、効率だけを求めて直線的にゴールへ向かってしまいます。経路はあくまで壁構造のおまけに過ぎず、制作者の意図を反映させる自由度が決定的に欠けていたのです。
V2: Greedy Walk — 視覚的成功と論理的破綻
V2では発想を逆転させ、まず経路から設計しました。画像の暗い部分を欲張り(Greedy)に巡回するルートを先に作り、壁を後から配置したのです。
このバージョンは、イメージに最も近いものとなりました。遠目に見れば、経路自体が絵を描き出していたからです。しかし、ここには致命的な欠陥がありました。ルートが自分自身と交差する再訪問が発生し、迷路としての一意解が崩壊していたのです。見えることと解けることは別問題であるという厄介な教訓が、再度噴出したのです。
V3: Trunk + Branch — 直感の裏切り
V3は、最短経路の幹に、行き止まりの枝を生やして絵を表現しようとする折衷案でした。
しかし、どれほど枝を密集させても、解く人が通るのはあくまで最短の幹だけです。解き終えた後に残るのは、画像を無視して対角線を走る一本の細い線だけ。枝を生やせば絵が見えるという直感は、パズル体験としては間違いもいいところだったのです。
V4: V2 + Spanning Tree — 数学に裏切られた設計
V2の絵を描く道を復活させつつ、数学的に正しい全域木で包み込んだのがV4です。一意解は保証されましたが、ここで新たな悩みが生まれます。
設計した道は8,823歩の長い旅路。しかし、全域木の中で最短経路を探すBFS(幅優先探索)が導き出した正解は、わずか927歩でした。アルゴリズムは、私が苦労して描いた絵をなぞる遠回りを無視し、壁の隙間を縫うショートカットを見つけ出してしまったのです。
V5: Pure Path — 失敗の可視化
V5は、あえて装飾を捨ててV4の構造をそのまま描画しました。目的は、起きていた問題を視覚的に確定させること。
赤い線で描かれた正解ルートは、やはり画像とは無関係に対角線を走っていました。この「BFS解 ≠ 設計経路」という問題は、見た目を整える程度では解決できない。構造そのものを根底から変えなければならないことを、このバージョンは教えてくれました。
V6: Anti-Shortcut Spanning Tree — 2行の革命
そしてついに、V6で全てのパズルが組み合わさりました。道を先に設計する思想を継承しつつ、BFSにショートカットを許さない構造を編み出したのです。
その核心は、アンチ・ショートカット・ルールと呼ばれる、わずか2行の条件分岐でした。
Python
if c1 in solution_cells and c2 in solution_cells:
continue # 解経路上のセル同士を、本来のルート以外で繋がない
この処理により、設計した正解ルート以外の裏口が物理的に封鎖されました。解経路のセル同士が余計な辺で結ばれないため、BFSはどんなに効率化を試みても、制作者が意図した絵をなぞる長い道を歩むしかなくなったのです。
ついに「BFS解 = 設計経路」という等式が成立しました。
6つのバージョン、2ヶ月に及ぶ格闘の末に辿り着いた答えは、驚くほどシンプルでした。
道を先に設計し、その道を壊さないように壁を建てる
この一行に集約される真理を理解するために、38の屍と5つの失敗作を積み上げる必要がありました。しかし、その遠回りこそが、数学の正しさとアートの美しさを高い次元で融合させるための、唯一の正解ルートだったのです。
手書きでやっていたことに巡り巡って戻ってくるのは、不思議な因果がありました。
やはり、自分がわかっている分野だと、直観的にこうなりそうという勘は当てになります。
3.2 path_designer.py: 1,350行の設計思想
V6の核となるロジックは、1,350行に及ぶpath_designer.pyというファイルに集約されています。ここには12を超える主要な関数が定義されており、その一つひとつが、これまでの試行錯誤から得られた血の通った知見を体現しています。
V6を支える主要関数の役割
迷路の設計図を描き、それを論理的な構造へと落とし込むために、以下の関数が有機的に連携しています。
_greedy_dark_walk():Warnsdorff(ウォンスドルフ)の規則を独自に拡張したアルゴリズムです。通常は次に移動できる選択肢が最も少ない場所を優先しますが、ここではその対象を暗部セルに限定。周囲に暗部がなければ明部を経由して次の暗部を目指し、かつ全ての行程で一度通った道を二度と通らない再訪問禁止を徹底しています。
_bfs_unvisited_to_dark():上記の探索が袋小路に突き当たった際の救済措置です。まだ誰も足を踏み入れていない未訪問セルだけを繋ぎ合わせ、最短距離で次の暗部へと橋渡しをします。ここで未訪問に限定するのは、既存のルートと接触して閉路(ループ)ができるリスクを数学的に回避するためです。
classify_cells():画像を暗部・中間・明部の3段階に分類します。この分類の閾値自体も、ベイズ最適化によって画像ごとに微調整される変動値となっています。
find_dark_blobs():暗部が固まっている領域(連結成分)を洗い出し、面積の大きな塊から順番に効率よく巡回する計画を立てます。
build_walls_around_path():V6の核心であるアンチ・ショートカット・クラスカル法を実行します。設計した道を最優先で接続し、その後で余計な近道ができないよう厳格な制約の下で壁を立て、最終的に一意解を保証する全域木を完成させます。
削除されなかった失敗と可能性
実は、この1,350行のうちV6のメインロジックで実際に稼働しているのは約半分に過ぎません。残りの半分は、例えば牛の鋤跡のように蛇行しながら領域を埋めるserpentine_fill_blob()など、現時点では採用されなかった代替アルゴリズムで占められています。
一般的なエンジニアリングの原則では、使われていないデッドコードは混乱を招くため削除すべきとされています。しかし、このプロジェクトでは意図的にそれらを残す決断をしました。(エンジニアの方なら決してなさそうですね)
コードの中に残された未使用の関数は、単なるゴミではありません。それは、過去にどのような仮説を立て、なぜそれが主流にならなかったのかという失敗の記録であり、同時に将来やはりこの手法を組み合わせれば精度が上がるのではないかと思い至った際の未来の可能性でもあります。
もしこれらのコードを削除してしまえば、将来新しいアイデアを試そうとしたときに、再びゼロから実装をやり直さなければなりません。コードとして実在していれば、過去の知見を即座に呼び出し、新しいバージョンへの入り口として活用できます。
この判断は、プロジェクトの性質を反映したものです。単に今動くものを作るだけではなく、美しさと正しさの極限を目指して継続的に進化し続けることを目的としています。
未使用のコードを維持するコストよりも、失われたアイデアを再構築するコストの方が高い。開発の系譜をコードベースそのものに刻み込むことで、プロジェクトは過去の自分たちと対話しながら、さらなる高みへと歩みを進めることができるのです。
趣味だからこそ、一度通った道を残しておく選択肢を採用できました。
第4部: V7 Okamoto-Uehara — 17年前の論文が100%を実現する
4.1 57%の壁
V6によって正解の道が、そのまま設計した絵をなぞるという悲願は達成されました。しかし、その中身を詳細に分析すると、新たな課題が浮かび上がりました。画像の暗い部分(暗部)をどれだけ道が埋め尽くしているかを示す暗部カバー率が、57パーセントに留まっていたのです。
暗部を構成する253セルのうち、実際に正解の道が通ったのは145セル。残りの108セルは、道が通ることのない行き止まりや壁の色によって補完されるしかありませんでした。
57パーセントという数値は、遠目から見て何らかの絵が浮かび上がる最低限の閾値は超えています。しかし、それはあくまで壁の濃淡という色の助けを借りた上での妥協の結果でした。本質的なゴールである正解の道筋だけで画像を完璧に描き出すという理想には、まだ半分ほどしか届いていなかったのです。
自らが塞いでしまう退路
なぜ、どれほど緻密に設計しても57パーセントという数字で止まってしまうのでしょうか。その原因は、Greedy Walk(貪欲な探索)という手法の根本的な仕組みにありました。
探索が暗部セルを効率よく巡回しようとする際、離れた場所にある暗部へ移動するために、どうしても通り道として明るい場所(明部セル)を消費します。一度通った場所は訪問済みとなり、二度と通ることはできません。すると、まだ訪れていない暗部セルに到達するための唯一のルートを、自分自身の歩みの軌跡が塞いでしまうという現象が多発したのです。
自分の歩みが、自分の未来を閉ざしていく。探索が進めば進むほど、キャンバスの中にはどこからも辿り着けない孤立した暗部が点在するようになり、カバー率は頭打ちとなりました。
局所最適と全域最適の壁
これは、貪欲法(Greedy Algorithm)が抱える宿命的な限界でもあります。貪欲法は、その瞬間、その場所において最も良さそうな選択を積み重ねていく手法です。
プログラムのどのステップを切り取っても、その瞬間には最善の判断を下しているはずでした。しかし、目先の暗部を追いかける局所的な正しさが、全体を通した時の最適解――すなわち暗部100パーセント網羅――を保証するとは限りません。むしろ、初期の最善の選択が、後の段階での致命的な行き詰まりを招いていたのです。部分最適の末路ですね。
この57パーセントという天井は、既存のアルゴリズムの延長線上では決して突破できないものでした。一歩ずつ最善を探すという思考回路そのものを根本から覆さない限り、完璧な再現への道は開かれない。V6の成功は、同時に次なる巨大な壁の存在を白日の下にさらすことになりました。
4.2 17年前の学術論文
2026年3月、暗部カバー率の限界に頭を悩ませていた私は、調査の過程で運命的な一冊に出会いました。それは2009年に発表された、コンピュータ幾何学の国際会議における一本の論文でした。
> "How to Make a Picturesque Maze"
> Yoshio Okamoto, Ryuhei Uehara
> CCCG (Canadian Conference on Computational Geometry), 2009
2009年。17年前の論文です。その内容は驚くべきものでした:
発想の転換:探索から構造変換へ
その論文が説いていたのは、暗部を網羅するために一歩ずつ道を探すというこれまでの私のやり方とは、根本から異なる次元のアプローチでした。
具体的には、元のグリッドグラフから生成した全域木を、2×2の細かいユニットへと機械的に展開し、その境界線をなぞるように歩いていくという手法です。この幾何学的な操作を行うだけで、元の全域木が網羅していた全ての地点を一度だけ通って戻ってくる道、すなわちハミルトン閉路が、誰がやっても自動的に生成されるというのです。
これは、迷路生成の歴史を変えるほどのパラダイムシフトでした。
構造が約束する100%の成功
ここで最も重要なのは、構造的に得られるという点にあります。
これまでの私のアルゴリズムは、正しい道が見つかるまで何度も試行錯誤を繰り返す、いわば探索の旅でした。しかし、この論文が示したのは、決められた手順に従って形を変換しさえすれば、計算が終わった瞬間に、暗部セルを100%カバーする一意解が必ず手に入るという幾何学的な必然性です。
本来、グラフの全ての点を一度だけ通るルートを見つける問題は、コンピュータにとって非常に計算負荷の高い難問として知られています。しかし、問題をグリッドグラフと全域木の展開という形に置き換えることで、その難問を極めて短時間で、しかも数学的な保証付きで解けるようにしたのです。
ついに手に入れた究極の地図。
17年前に既に示されていたこの知見は、私が57%という天井に絶望していた暗闇を、一筋の光で照らし出しました。
探索して見つかるかどうかを祈るのではなく、最初から正解が約束された構造を組み立てる。この幾何学的な魔法を手にしたことで、迷路はついに、画像としての再現性とパズルとしての正しさを100%両立させる最終段階へと突入することになります。
かつての先駆者たちが残した知恵の重みを感じながら、私はこの理論を自らのコードへと組み込む準備を始めました。
4.3 2×2展開の数理
Okamoto-Ueharaの手法の核心は辺変換ルールにあります。元の迷路セル(r,c)を2×2の4ピクセルに展開します:
```
元セル (r,c):
TL = (2r, 2c) TR = (2r, 2c+1)
BL = (2r+1, 2c) BR = (2r+1, 2c+1)
```
全域木の辺に応じて、展開グリッドの接続規則を決めます:
```
辺変換ルール:
tree辺がある方向(例: 右に隣接セルと接続):
→ 2本の並行辺を張る
→ TR—(2r, 2c+2) と BR—(2r+1, 2c+2)
→ 「幅2の廊下」が隣接ブロックに伸びる
tree辺がない方向(例: 右に壁):
→ U-turn辺を張る
→ TR—BR
→ ブロック内で折り返す
```
Okamoto-Ueharaの手法がこれほどまでに鮮烈だった理由は、本来であればコンピュータが途方もない時間をかけて探索しなければならない正解を、まるで折り紙を折るような単純な手順の積み重ねで、確実に出現させてしまう点にありました。その魔法の正体は、辺変換ルールと呼ばれる美しい幾何学的な規則に隠されています。
2×2の細胞分裂
まず、元の迷路の一つのセルを、縦横2マスずつの合計4つのピクセルへと細かく分割します。一つの部屋を4つの小さな区画に分けるようなイメージです。
ここからがこの手法の真骨頂です。元の全域木で道がつながっていた方向と、壁だった方向に分けて、新しくできた4つのピクセルの繋ぎ方を決めていきます。
道と壁が生み出す必然の形
もし元のセルが隣のセルと道でつながっていたなら、新しく展開されたピクセル同士も、二本の並行した道で隣の区画へと手を伸ばします。これにより、幅2のゆったりとした廊下が隣接するブロックへと伸びていくことになります。
一方で、元のセルが壁で行き止まりだった方向については、区画の中で道をくるりと折り返させます。自分のブロック内にある上下、あるいは左右のピクセル同士を繋ぎ、Uターンさせるのです。
このルールを全てのセルに適用すると、驚くべき現象が起こります。
数学が導き出す唯一の輪
この変換を終えたとき、新しく生まれた全てのピクセルは、例外なく正確に二本の道とだけ接続されることになります。隣のブロックへ伸びる道か、自分のブロック内で折り返す道か、そのどちらかによって、全ての点がちょうど二つの隣人と結ばれるのです。
グラフ理論の世界において、全ての点が二つの枝を持つ連結したグラフは、必ず一本の大きな輪になります。元となる全域木が全てのエリアを網羅しているため、そこから生まれたこの輪もまた、全てのピクセルを漏れなく、そして一度だけ通過する巨大な道——すなわちハミルトン閉路——として完成するのです。
難問の解体と再構築
本来、全ての地点を一度だけ通るルートを探し出すハミルトン閉路の問題は、コンピュータ科学において最も難しい部類に属します。力任せに探そうとすれば、宇宙の寿命をかけても終わらないほどの時間がかかることも珍しくありません。
しかし、Okamoto-Ueharaの手法は、探索という行為そのものを放棄しました。問題を幾何学的な構造変換へと置き換えることで、まるで設計図通りに部品を組み立てるかのような速さで、完璧なルートを導き出すことに成功したのです。
構造によって正解を約束する。このエレガントな解決策を手にしたことで、暗部を100%網羅するという究極の目標は、もはや手の届く現実となりました。
4.4 なぜNP困難を回避できるのか
一般的なグリッドグラフの中から、全ての地点を一筆書きで巡るハミルトン路を見つけ出すという行為は、コンピュータ科学の世界ではNP完全と呼ばれる、解決に膨大な時間を要する難問として知られています。かつて私がバージョン25で、どれほど工夫を凝らした探索を試みてもカバレッジがわずか0.4%という惨敗に終わったのは、まさにこの巨大な理論の壁に正面からぶつかっていたからでした。
しかし、Okamoto-Ueharaの手法は、この壁を力ずくで突き破るのではなく、鮮やかに迂回するという道を選びました。
難問を解くのではなく、問題の形を変える
この手法の最もエレガントな点は、一般のグラフという広大な迷宮の中で正解を探し回るのをやめたことにあります。代わりに、元の全域木を2×2に展開するという特殊な構造を自ら作り出しました。
この特殊な構造の中では、数学の定理によって全ての地点が正確に二つの道を持つことが約束されています。つまり、正解のルートは、暗闇の中から宝探しをするように見つけ出すものではなく、構造を変換した瞬間に、まるで最初からそこにあったかのように自然と浮かび上がってくるものになったのです。
難しい問題をそのまま解くのではなく、解けることが保証された形へと問題を書き換える。これこそが、数学的な美しさの本質と言えるでしょう。
迷路を歩くだけで辿り着く正解
こうして構築されたルートは、特別な計算も、高度な予測も必要としません。極めて原始的な右手法則、つまり右側の壁に手を触れたまま一歩ずつ進むというルールに従うだけで、迷路全体の全ての地点を漏れなく、重複なく訪問する一本の巨大な閉路が完成します。
たとえ何万という部屋がある巨大な迷宮であっても、元の全域木を往復するように進むだけで、誰でも確実に、そして機械的に正解へと導かれます。
圧倒的な速さ、圧倒的な確信
この手法による計算量は、セルの数に比例するだけの極めて小さなものです。一千万個のセルがあっても、コンピュータにとっては瞬きをするほどの時間で処理が完了します。
かつては絶望的な計算時間の前に立ち尽くしていた難問が、発想を一つ変えるだけで、これほどまでに軽やかで、かつ絶対的な確信を伴う解決策へと変貌を遂げたのです。この幾何学的な確信こそが、迷路生成における「完璧」への扉をこじ開けることになりました。
4.5 V7パイプラインの実装
V7の核心を担うv7_generator.pyは、約600行という凝縮されたコードの中に、数学的理論を実用的な芸術へと変換する5つのフェーズを収めています。
フェーズ1:前景抽出 — 本質の切り出し
まずは、迷路で表現すべき主要な像を特定することから始まります。画像全体の密度マップを分析し、暗い領域を二値化して抽出。さらに、その中から最も大きくつながっている塊を特定します。
これは、顔の影の中に偶然混じった小さな点やノイズのような孤立したピクセルを除去し、表現すべきメインの対象だけを純粋に取り出すための作業です。この段階を経ることで、迷路の道筋がバラバラに散らばることなく、一貫した形を描けるようになります。
フェーズ2:重み付き全域木 — 像をなぞる骨組み
抽出した前景の範囲内で、迷路の背骨となる全域木を生成します。V7ではここに、画像の暗さに応じた重み付けを導入しました。
より暗い領域のセルが優先的に選ばれ、木の中心に近い主要なルートに配置されるように調整されています。この工夫により、後に生成される道が画像の暗部をより濃密に、かつ連続的に通過するようになり、完成した迷路が元の画像の表情をより強く、鮮明に反映するようになります。
フェーズ3:幾何学的な展開と接続の魔法
ここでは、生成された全域木を2×2のピクセル単位へと細分化し、あらかじめ定義された規則に従って繋ぎ合わせます。
道がある方向には並行する二本の廊下を通し、道がない方向、つまり壁の部分ではくるりとUターンさせる。この機械的な置き換えを行うだけで、全ての点が正確に二つの隣人と結ばれるという、完璧な調和が保たれた構造が生まれます。
フェーズ3.5:境界処理 — 閉ざされた輪を保つ
この幾何学的展開において、最も緻密な設計を要したのが画像の端にあたる境界部分の処理です。通常であれば隣接するセルが存在しない場所では、道が途切れてしまいがちです。
もしここで処理を誤り、一本しか繋がっていない点が生じると、せっかくのルートが行き止まりになってしまいます。境界の外側に向かうはずだった道を自ブロック内の隣接ノードへと正しく折り返させることで、画面の端であっても例外なく全ての点が二つの繋がりを持ち続ける、完全な閉路が維持されます。
フェーズ4:ハミルトン閉路走査 — 探索のいらない旅
構造が完成すれば、あとは任意の点から順番に辿っていくだけです。ここには複雑な探索アルゴリズムは必要ありません。全ての点が二つの道しか持っていないため、一方から来れば、次に進むべき道は未訪問の唯一の隣接ノードとして自動的に決まっています。
プログラミング的には、ただ隣を順番に選んでいるだけなのに、気づけば画面上の全ての地点を漏れなく巡り、元の場所へと戻ってくる。構造が正解を保証しているからこそ可能な、淀みのない生成プロセスです。
フェーズ5:閉路切断と迷路への仕上げ
最後に、完成した巨大な一本の輪を一箇所だけ切断し、入り口と出口を設定します。これで、全ての暗部を100%網羅する一筆書きの正解ルートが完成します。
さらに、背景にあたる白い領域からは枝分かれする袋小路を伸ばし、迷路としての複雑さと奥行きを付け加えます。これらの枝道は本筋とは決して繋がらない木構造になっているため、入り口から出口へと続く唯一の正解ルートは、数学的に揺らぐことなく守られ続けます。
4.6 成果
`V6からV7への進化は、単なる数値の向上という言葉では片付けられない、迷路生成における歴史的な転換点となりました。
圧倒的な数値が示す、描画力の差
データを比較すれば、その差は一目瞭然です。暗部カバー率は21%から一気に100%へと到達し、画像の再現性を示すSSIMも0.48から0.78へと、60%以上も跳ね上がりました。
V6までの世界では、正解の道筋は画像の暗い部分の約半分しか通ることができず、足りない部分は壁の色を暗くすることで何とか補っていました。いわば、薄い下書きの上に色を乗せて誤魔化していたような状態です。
しかし、V7では正解の道が、暗い部分のセルを一つ残らず踏破します。これによって、ペンで迷路を解き進めるという行為そのものが、一点の曇りもない画像をキャンバスに描き出す作業へと昇華されました。
質的に変化した驚きの正体
この数値の変化が、解く人の体験にどのような違いをもたらすのかを想像してみてください。
V6の迷路を解いたとき、そこに現れるのは人物の大まかなシルエットです。目や鼻の場所がなんとなく分かる程度で、受け取った人は、顔のように見える何かだと認識するでしょう。
対してV7の迷路を解き終えたとき、そこには目の周りの繊細な陰影、鼻筋の通ったライン、唇の柔らかな曲線までが、太い一筋の道によって完全に塗りつぶされています。3メートル離れて眺めれば、たった今自分が解いたはずのパズルが、元の写真と見紛うほど鮮明に浮かび上がってくるのです。これ本当に迷路を解いただけなのか、という純粋な驚き。SSIMが0.5前後から0.7台後半へ移行するということは、このように体験の質が根本から変わることを意味しています。
17年の時を超えた、知の開花
2009年に発表された幾何学の論文が、2026年の現代において、これほどまでに豊かな体験を生み出すプロダクトとして結実しました。
一見すると難解な数式や理論も、それを迷路という身体的なパズルに落とし込むことで、言葉を超えた感動へと変わります。かつての先駆者が示した数学的なエレガンスが、今、解く人の手元で一枚の鮮やかな肖像画として花開いたのです。
第5部: 品質を守る仕組み
5.1 SSIMという目
迷路生成のプロジェクトが、主観的な美学から客観的な工学へと脱皮した瞬間。それが、SSIM(構造的類似度)という、画像がどれだけ元の姿を保っているかを測る指標を導入したときでした。
「迷路を解くと絵が出る」というプロジェクトの核心にある要件は、個人の主観だけで判断していると、どうしても限界が訪れます。ある人は見えると言い、ある人は見えないと言う。そんな曖昧な境界線の上では、技術の着実な進歩は望めません。そこで私は、人間の視覚に近い判断を下してくれるこの数値を、プロジェクトの羅針盤に据えることにしました。
なぜ、単純な差分ではいけなかったのか
画像を比較する最も単純な方法は、点と点の色を比べる平均二乗誤差(MSE)です。しかし、迷路という特殊な画像において、この方法は全く機能しませんでした。
迷路には無数の壁の線があり、道は白く抜かれています。元の写真と比べれば、ピクセル単位ではほとんどの場所が異なっています。単純な比較では、これらはすべてエラーとして加算され、どんなに素晴らしい迷路でも、数値上は「ひどく壊れた画像」と判定されてしまうのです。
一方で、今回採用したSSIMは、人間が画像の特徴を捉えるときと同じように、明るさ、コントラスト、そして全体の形という三つの要素を分析します。細かい線が走っていても、画像全体が持つ構造が保たれていれば、それを正しく評価してくれます。人間がこれは元の絵だと感じる感覚を、コンピュータが理解できる言葉である数値に翻訳してくれる(私が思い付けた)唯一の方法でした。
開発を支えた揺るぎないものさし
この指標を徹底的に使い倒すことで、開発の風景は一変しました。
まず、新しいアイデアが本当に正しいのか、客観的に証明できるようになりました。通路を細くする改良を加えた際、以前ならなんとなく良くなった気がするで終わっていた議論が、SSIMが26パーセント向上したという明確な事実になりました。この揺るぎない根拠があったからこそ、自信を持って技術を積み上げることができたのです。
また、コンピュータが自動で最適な設定を探し出す際にも、この数値が唯一のゴールとなりました。何を基準に調整すればいいかが明確になったことで、コンピュータは迷うことなく、最も画像が美しく見える設定へと辿り着けるようになったのです。
数字と感覚のバランス
もちろん、数字だけがすべてではありません。この指標にも弱点はあります。画像の一部だけが大きく歪んでいても、全体で見れば数値が高く出てしまうことがあったり、迷路である以上、理論上の満点には決して到達できなかったりします。
そのため、数字に支配されるのではなく、数字を使いこなすことを大切にしました。機械的に算出されたデータを確認しつつ、最後には自分の足で3メートル離れ、自分の目でその迷路を眺める。数値が良くなったとしても、自分の目が美しくないと判断すれば、その技術は不採用としました。
客観的なデータによって進むべき方向を定め、人間の感性によって最後の仕上げを行う。この数値という名の強力な道具を手にしたことで、迷路は単なるパズルの域を超え、緻密に計算された模様へと進化することができたのです。
5.2 テストは何を守っているのか
```
tests/
├── test_dm1_foundation.py # 全域木の連結性、壁の整合性
├── test_dm2.py # CLAHEの自動チューニング
├── test_dm4.py # 8階調壁の量子化精度
├── test_dm6.py # 難易度パラメータの変換
├── test_dm7_passage_ratio_ssim.py # passage_ratioとSSIMの相関
├── test_dm8.py # マルチスケール密度マップ
├── test_dm8_edgecases_704k.py # 極小グリッド、均一画像
├── test_dm8_gridsearch_wall_color.py # パラメータ空間探索(87テスト)
├── test_ssim_benchmark.py # SSIMベンチマーク
├── test_v7_*.py # V7 Okamoto-Ueharaパイプライン
├── test_path_first_masterpiece.py # V6コア(33テスト)
├── test_solver_paths.py # 一意解検証
└── ...(30+テストファイル、計961テスト)
```
開発において、最も強固な土台となったのは、4ヶ月という短期間で13倍にも膨れ上がった膨大なテスト群でした。当初はわずか73項目だったテストは、最終的に961項目にまで達しました。この数字は、単に作業量が増えたことを示しているわけではありません。新しく生み出された数々のアルゴリズムが正しく動いているか、そして過去に苦労して修正した不具合が再発していないかを、機械が休まず監視し続けてきた証です。
五つの層で守る品質
プロジェクトの安全を守るために、テストは役割ごとに五つの層に分けて設計されました。
基礎となる一段目では、数値の変換といった小さな部品の正確さを確認し、二段目では迷路が途切れていないか、ループしていないかといったアルゴリズムの正しさを検証します。三段目で画像が入力されてから迷路が出力されるまでの全行程を繋いでテストし、四段目では再現性の指標であるSSIMが過去の記録を下回っていないかを厳しくチェックします。そして最上階の五段目では、あらゆる設定の組み合わせを網羅的に試し、最適な設定が常に選ばれることを確認しています。
信頼の根拠:二重の鍵
テスト設計において最も心血を注いだのは、迷路の正解が必ず一つであるという一意解の保証です。
数学の理論上、全域木という構造を使えば正解は一つになります。しかし、その理論を形にするプログラミングコードが、一文字も間違っていないという保証はどこにもありません。そこで、出来上がった迷路をコンピュータに実際に解かせてみるテストを導入しました。数学的な正しさと、実際に解いてみた結果。この二重の確認を行うことで、誰がどんな画像を読み込ませても、決して解けない迷路が生まれない環境を整えました。
爆発的な増加と進化のスピード
開発が終盤に差し掛かった時期、テストの数は583から961へと爆発的に増加しました。これは、全く新しい仕組みであるV6やV7を導入した時期と重なっています。
新しい道筋の作り方を一箇所変えるだけで、それまでのすべての機能に影響が出る可能性がある。そんな緊張感のある開発の中で、961ものテスト項目は、暗闇を照らす街灯のような役割を果たしました。実装してはテストを走らせ、どこにも異常がないことを数分で確認する。このサイクルを繰り返せたからこそ、複雑な新機能を驚異的なスピードで、しかも安全に組み込むことができたのです。
必要なものだけに集中する
これほど多くのテストを維持できたのは、何をテストしないかという決断があったからです。画像処理に使っている既存の有名なライブラリ自体の動作確認は、その開発元に任せました。
961個のテストは、単なるコードの集まりではありません。それは、これまでの開発の歴史で直面した困難や発見をすべて記録した、プロジェクトの記憶そのものです。この分厚い安全網があったからこそ、迷路に迷いながらも、究極の迷路という未踏の領域へ足を踏み入れることができたのです。
5.3 一意解の検証: 防御的プログラミング
迷路の正解が必ず一つになるという全域木の構造は、動かしようのない数学の事実です。しかし、どれほど理論が完璧であっても、それをプログラムとして記述する人間が、一文字も打ち間違えないという保証はありません。理論上は正しいはずだという信念と、実際に正しく動いているという事実は、明確に区別しなければならないのです。
この二つの間にある溝を埋めるために設計されたのが、防御的検証モジュールとしての機能です。
理論を疑い、事実を確認する
開発の根幹を支えるこのモジュールは、数学の正しさを鵜呑みにせず、出来上がった迷路を厳しく検査します。
入り口から出口までたどり着ける道が本当にあるか。そして、その道が余計に存在していないか。プログラムは完成した迷路の中をくまなく探索し、正解の数を数え上げます。もし万が一、プログラムのミスで余分な道が一本でも混じってしまったら、即座にそれを検出し、修正をかける仕組みになっています。
三重の安全網で守る品質
迷路の品質を守るために、三つの異なる視点からの安全網を敷きました。
一つ目は、絶対に揺るがない数学の理論。二つ目は、その理論を正しく反映できているかを確認し続ける膨大なテスト。そして三つ目が、出来上がった迷路を最後の一マスまで調べ上げる、この防御的検証です。
数学という設計図が正しいことを信頼しながらも、実際に組み上がった建物に綻びがないかを、現場で何度も確認するような作業です。この慎重な姿勢こそが、単なるプログラムの実験作ではなく、誰がいつ手に取っても完璧に遊べる製品としての品質を支えています。
誠実な開発姿勢の象徴
理論を形にする過程で、自分たちの実装が数学に対して忠実であるかを問い続けること。この地道な検証の積み重ねが、迷路生成の精度を極限まで高めました。
数学的な美しさを追求する情熱と、わずかなミスも許さない冷徹な検証。この両輪が揃うことで、迷路を解く人が味わう一瞬の感動を、数学の裏付けがある本物の体験として届けることができるようになったのです。
第6部: 技術的な判断
6.1 なぜPrimではなく、Kruskalなのか
迷路生成における技術選択は、単に効率を求めるだけでなく、設計者の意図がいかに正確にアルゴリズムに反映されるかという観点で行われました。全域木を作るための二つの有名な手法、Kruskal法とPrim法の選択は、その最たる例です。
画像の明暗に合わせて迷路の密度を制御するためには、どの壁を取り除いて道にするかという、辺単位での判断が求められます。Kruskal法は、グラフ上のすべての辺を重み順に並べてから処理する性質を持っているため、この目的に完璧に合致しました。
暗い領域の壁を優先的に除去して道にするという方針は、プログラム上で辺を輝度順に並び替えるという、極めて直感的な一行の処理で完結します。アルゴリズムの構造そのものが、画像から迷路を生成するという設計思想を直接的に体現しているのです。
Kruskal法のもう一つの利点は、処理の結果が入力データに対して一意に決まる点です。
すべての辺をあらかじめソートしてから処理を開始するため、同じ画像と同じ設定値を用いれば、何度実行しても必ず同じ迷路が生成されます。これは、開発過程での不具合の検証や、品質を一定に保つためのテストにおいて、欠かすことのできない重要な特性となりました。
対照的に、Prim法は一つの点から周囲へと探索範囲を広げながら木を成長させていくアプローチをとります。
この手法で暗い場所を優先しようとすると、次にどの点を取り込むかという判断ロジックの中に、輝度の情報を間接的に組み込む必要が生じます。また、最初にどの点から成長を開始するかによって結果が左右されやすく、同じ画像であっても生成される迷路にばらつきが出やすいという課題がありました。
意図を反映する最短距離の選択
技術の選定基準は、単なる計算速度だけではありません。作り手の狙いが、いかに素直に、そして透明性の高いコードとして記述できるかが重視されました。
Kruskal法の採用により、暗部を道にするという意図は、複雑な条件分岐に隠されることなく、シンプルなソート処理としてコードに宿ることになりました。このロジックの明快さが、迷路としての正しさと画像としての美しさを高次元で両立させるための、確かな土台となっています。
6.2 なぜSSIMか(MSEやPSNRではなく)
迷路の画像と元の写真は、細かく一画素ずつ比較していくと、実は全くの別物に見えてしまいます。迷路には黒い壁の線が網の目のように走り、道となる部分は白く抜けています。この一画素ごとの色の違いを単純に引き算して評価する手法(MSE)では、コンピュータは画面上のすべての場所が間違っていると判断し、最低の評価を下してしまいます。
しかし、人間がその迷路を少し離れて眺めたときには、不思議と元の絵が浮かび上がって見えます。この、人間が直感的に感じる「似ている」という感覚を正しく数値化してくれるのが、SSIMという指標です。
SSIMは、単純な色の違いではなく、次の三つの視点から画像を評価します。
まず一つ目は、画像全体の明るさが調和しているかという輝度の視点。二つ目は、明るい場所と暗い場所のメリハリが保たれているかというコントラストの視点。そして三つ目が、最も重要なパターンの配置が似ているかという構造の視点です。
たとえ画面の中に壁の線が無数にあったとしても、暗い部分が正しい位置に集まり、画像全体の形が維持されていれば、SSIMは構造が一致しているとして高いスコアを与えます。これは、人間が細部を無視して全体の雰囲気や形を捉える仕組みに非常によく似ています。
もし、単純なピクセル単位の差(MSE)だけで迷路を最適化しようとすると、おかしなことが起こります。コンピュータは、壁や道をはっきり描くよりも、画面全体をぼかした灰色の画像にした方が「平均的な色の差が少ない」と判断し、それを正解だと思い込んでしまうのです。これでは、迷路としての形を保ちながら絵を表現することはできません。
SSIMを評価の軸に据えることで、迷路というパズルの構造を壊すことなく、元の画像の魅力を最大限に引き出すための、極めて精度の高いチューニングが可能になりました。数値が人間の感性を代弁してくれるようになったことで、迷路生成は工学的な正確さと芸術的な美しさを同時に手にすることができたのです。
6.3 なぜ8階調か
迷路の色使いに関する設計は、当初は白と黒の二色のみで構成する予定でしたが、AIを取り入れたことで、その可能性が大きく広がった領域です。
画像としての美しさと、パズルとしての遊びやすさを両立させるために、壁に持たせる色の情報をどのように扱うべきか。その試行錯誤の末にたどり着いたのが、8階調という絶妙なバランスでした。
二値による表現の限界
最もシンプルな方法は、壁を完全な黒、通路を完全な白とする二値化です。しかし、この方法では元の画像が持っていた繊細な光の階調がすべて削ぎ落とされてしまいます。情報の欠落が激しいため、どれだけ工夫しても画像の再現性を示すスコアを一定以上に高めることはできず、表現としてはどうしても単調なものに留まっていました。
階調が多すぎることによる弊害
一方で、256階調というフルスケールのグレーを壁に持たせれば、理論上は元の画像のトーンを完璧に写し取ることができます。しかし、実際にこれを迷路に適用すると、深刻な問題が発生しました。
隣り合う壁の色が滑らかに変化しすぎるため、どこまでが壁でどこからが通路なのかという境界が曖昧になり、パズルとして解くことが困難になってしまったのです。画面全体がぼやけた印象になり、迷路の命である視認性が大きく損なわれるという、本末転倒な結果となりました。
八階調という最適の着地点
これらの失敗を踏まえて導き出されたのが、壁の色を8段階のグレーに分けるという手法です。
この設定の優れた点は、壁の色に変化を持たせることで画像の明暗を豊かに表現しながらも、色と色の間に明確な段差があるため、壁の存在感をしっかりと維持できることです。迷路としての解きやすさを守りつつ、離れて見たときには絵として鮮明に浮かび上がる。まさに、実用性と芸術性の交差点とも言える数値でした。
この8という数字は、数多くの実験を重ねる中で経験的に見出されたものですが、その後の検証においても、これより多くても少なくてもバランスが崩れてしまうことが確認されています。迷路の壁一枚一枚が、画像を構成する大切な一欠片としての役割を果たしながら、同時に迷宮を形作る確かな境界線としても機能する。この細やかな階調の制御が、迷路アートに深い奥行きを与えることになったのです。
6.4 なぜGrid SearchやRandom Searchではなく、Optunaなのか
迷路の完成度を高めるためには、解像度や壁の太さ、明暗の調整など、多くの設定値を最適に組み合わせる必要があります。しかし、調整すべき要素が5つ、6つと増えていくにつれ、力任せに正解を探すやり方では、すぐに限界が訪れます。
網羅的な探索が直面する時間の壁
もし、すべての設定の組み合わせを順番に試していく網羅的な探索(グリッドサーチ)を行おうとすると、計算量は爆発的に膨れ上がります。たとえ一つの要素を10段階で刻んだとしても、5つの要素があれば組み合わせは10万通りに達します。一回の計算にわずか2秒しかかからないとしても、すべてを終えるのに50時間以上を費やす計算になり、現実的な開発のペースには到底追いつけません。
効率と精度のジレンマ
一方で、設定をランダムに選んで試す手法(ランダムサーチ)は、時間の問題こそ解決しますが、運任せの側面が強くなります。可能性の低い領域も、有望そうな領域も同じ頻度で調べてしまうため、限られた試行回数の中では、本当の最適解にたどり着く精度はどうしても低くなってしまいます。
過去の経験から学ぶ賢い探索
こうした課題を解決するために導入されたのが、ベイズ最適化という仕組みを活用したOptunaという道具です。
この手法の最大の特徴は、過去に行った試行の結果から学習し、次に試すべき有望な設定を賢く推測する点にあります。これまでの実験データに基づいて、どのあたりの数値がより良い結果を生みそうかという分布を常に更新し、成功の可能性が高い領域へと探索を集中させます。これにより、わずか100回程度の試行であっても、膨大な時間をかけた網羅的な探索に匹敵する、あるいはそれを超えるような優れた設定を見つけ出すことが可能になりました。
無駄を省くための知識の活用
さらに、この仕組みの優れた点は、事前の知識をルールとして組み込めることにあります。例えば、人物の肖像画を迷路にするなら極端に粗い解像度は試さない、といったカテゴリごとの制約をあらかじめ定義できます。これにより、明らかに失敗すると分かっている無意味な領域に貴重な計算リソースを割くことなく、本質的な改善に集中できるようになりました。
過去の知識を蓄積し、それを次の挑戦へと役立てる。この洗練された探索のプロセスこそが、複雑なパラメータの迷宮を最短距離で駆け抜け、迷路としての品質を極限まで引き上げる原動力となったのです。
おわりに
残念ながら、迷路生成の技術を極限まで磨き上げたとしても、すべての画像が同じように美しい迷路に変わるわけではありません。実験を通じて得られたSSIM(構造的類似度)の数値は、この手法が持つ得意分野と、どうしても避けられない限界を正直に示しています。
得意な画像と苦手な画像
採用した格子ベースの密度マッピングという手法は、広い範囲で色が滑らかに変化するグラデーションや、はっきりとした形を持つロゴ、人物の顔写真などにおいて、その真価を発揮します。これらの画像では、どこを道にしてどこを壁にするかという判断が色の濃淡とよく一致するため、元の絵の雰囲気を色濃く残した迷路を作ることができます。
一方で、細い線が密集する幾何学的なパターンや、非常に細かい繰り返し模様などに対しては、この手法は苦戦を強いられます。これは設計上のミスではなく、格子状に世界を区切って迷路を作るという手法そのものが抱える、構造的な性質からくるものです。
テキストが表現できない理由
例えば、白い背景に黒い文字が書かれた画像の場合、評価数値は極めて低くなってしまいます。文字を構成する線は画像全体に対して非常に細く、小さな領域しか占めていません。これを格子状に分割すると、文字の線が通っているマス目よりも、何もない真っ白なマス目の方が圧倒的に多くなります。
その結果、迷路を作るプログラムにとっては、画面のほとんどが「平坦な白い場所」に見えてしまいます。どこに重点を置いて道を作るべきかの手がかりが失われ、完成した迷路からは、元の文字の面影が消えてしまうのです。
円形や斜め線の限界
同心円のような放射状の模様も、苦手とする対象の一つです。迷路の格子は上下左右に規則正しく並んでいますが、円や斜めの線はこの格子の並びを無視して自由に走っています。四角いマス目の集まりで滑らかなカーブを表現しようとすると、どうしても階段のようなガタガタした形になってしまい、元のしなやかな構造を再現することが難しくなります。
格子の密度を極限まで上げれば解決に近づくかもしれませんが、そうなると迷路の道が細すぎて、人間が遊ぶパズルとしての楽しさが失われてしまいます。
誠実さとしての限界の明示
これらの限界を明らかにすることは、決して技術の敗北を認めることではありません。むしろ、どの場面で最高のパフォーマンスを発揮できるかを定義する、品質に対する誠実さの表れです。
「どんな画像でも魔法のように迷路にできる」と語るのではなく、今の技術でできることとできないことを正しく伝える。この境界線を明確にすることで、利用者は迷路に込めた表現を最大限に引き出すことができるようになります。
この挑戦は、この手法が最も輝く領域を広げ、磨き上げることにあります。できないことを知ることは、次に進むべき道、あるいは新しい手法を模索するための確かな出発点となるのです。
はじまりは、バケットリストに載った、たった一つの素朴な問いでした。
しかし、その問いを追い求める旅は、いつの間にかグラフ理論や画像処理、ベイズ最適化といった広大な技術の海を横断するプロジェクトへと進化していました。積み上げられた膨大なテストとコミットの痕跡は、解いた軌跡が絵になる迷路というシンプルな理想にたどり着くための、長く険しい道のりを物語っています。
自分でもver38までやったのは正直笑いましたが、それらは決して恥ずべきものではありまません。
ある手法を試してもうまくいかなかったとき、それはその仮説が正しくなかったという貴重な発見でした。力任せの探索では一筆書きの道が見つからないと知ったからこそ、構造そのものを変える画期的な手法へと舵を切ることができました。設計した道とは別の場所を正解のルートが通ってしまう問題に直面したからこそ、絶対にショートカットを許さない強固なルールが生まれました。
もし最初から近道を知っていたら、これほどまでに堅牢で、洗練されたアーキテクチャを築くことはできなかったでしょう。遠回りに見えた一歩一歩が、結果として最も揺るぎない土台を作り上げたのです。
また、開発のあらゆる局面で立ち返ったのは、プロジェクトの第1条に掲げた三つの要件でした。
離れて見れば絵に見え、近づけば迷路として楽しめ、解き終えればその軌跡が鮮やかな像を描き出す。この三行の理想こそが、すべてのアルゴリズムを生む動機であり、迷ったときの唯一の判断基準でした。
「一意解が絵になる」という言葉は、口にするのは簡単ですが、それを数学的に保証し、かつ人間が実際に解けるパズルとして成立させるのは至難の業です。その難しさに正面から向き合い、一つひとつ問いを解いていった結果が、今の形になりました。
当初、この形になるとは私自身全く想像できていませんでした。
学びの整理:旅が教えてくれたこと
この長い旅を通じて得られた教訓は、これからの開発のあり方を照らす光となります。
失敗の価値を知る: うまくいかなかった原因を分解し、何が間違っていたかを突き止めることが、次の一手を決める最も確実な材料になります。
先人の知恵と独自の工夫: 過去の優れた研究は大きな助けとなりますが、自ら遠回りして生み出した独自の解決策もまた、システムを支える強力な武器になります。
指標を使いこなす: 数値はあくまで現実を映す鏡です。データに盲従するのではなく、人間の感性と照らし合わせながら、道具として賢く扱うことが大切です。
実用性を重んじる: 数学的な美しさも重要ですが、最終的に使う人が満足できる製品であることを優先する決断が、価値あるものづくりには欠かせません。
テストは未来への投資: 膨大なテストは、単なる正しさの証明ではありません。将来、安心して新しい挑戦をするための、最も安上がりで強力な安全網です。
変更に耐える設計: 基礎となる部分が最後まで揺るがなかったことは、最初の設計選択が正しかったことの何よりの証明です。
理論を形にする喜び: 論文の中に眠っていた素晴らしい知恵を、実際に動くソフトウェアとする。それこそが、開発者としての大きな喜びの一つです。
旅は、まだ終わりません。私の探求はまだまだ続きます。
おまけ
バナー画像の迷路です。挑戦者募集中です。
別の迷路その2



