(57)【要約】【課題】最短経路の探索時間を短縮することを課題とする。【解決手段】探索装置は、グラフデータが有する複数のノードの中から始点および終点を特定する。探索装置は、始点と終点とを繋ぐ経路のうち距離の短い上位所定数の最短経路を探索する場合に、所定数より小さい値が設定される制限値を用いて、始点および終点の双方向から、始点からの経路と終点からの経路とが結合する結合点を特定する。探索装置は、結合点を含む複数のノードそれぞれに対応付けて保持する経路の数を制限値以下に制限して、各ノードに到達する経路のうち距離が短い経路を保持し、各ノードに対応付けた保持される経路を用いて、結合点に至る経路から上位所定数の最短経路を探索し、探索された上位所定数の経路を出力する。【選択図】図４
2020135207.tif 000002
【特許請求の範囲】
【請求項１】
コンピュータが、
グラフデータが有する複数のノードの中から始点および終点を特定し、
前記始点と前記終点とを繋ぐ経路のうち距離の短い上位所定数の最短経路を探索する場合に、前記所定数より小さい値が設定される制限値を用いて、前記始点および前記終点の双方向から、前記始点からの経路と前記終点からの経路とが結合する結合点を特定し、
前記結合点を含む前記複数のノードそれぞれに対応付けて保持する経路の数を前記制限値以下に制限して、各ノードに到達する経路のうち距離が短い経路を保持し、
前記各ノードに対応付けた保持される前記経路を用いて、前記結合点に至る経路から前記上位所定数の最短経路を探索し、
探索された前記上位所定数の経路を出力する、
処理を実行することを特徴とする経路探索方法。
【請求項２】
前記保持する処理は、前記各ノードに到達する経路を、優先度キューを用いて保持し、
前記探索する処理は、出発点から頂点までの長さと相手側の出発点から当該頂点までの最短経路長あるいは前記優先度キューの先頭の経路の長さの和が、既に求まっている前記上位所定数番目の最短経路の長さ以上の場合は、当該頂点から先へ探索範囲を延長しないことを特徴とする請求項１に記載の経路探索方法。
【請求項３】
前記探索する処理は、前記始点から前記結合点までの各経路と、前記終点から前記結合点までの各経路とを組み合わせた複数の経路を生成し、前記複数の経路のうち距離が短い経路を順次特定して、前記上位所定数の最短経路を探索することを特徴とする請求項１に記載の経路探索方法。
【請求項４】
前記保持する処理は、前記結合点を含む前記複数のノードそれぞれに対応付けて保持する経路の数を、前記制限値の平方根以下に制限することを特徴とする請求項１に記載の経路探索方法。
【請求項５】
前記保持する処理は、前記結合点を含む前記複数のノードそれぞれに対応付けて保持する経路の数を、前記制限値の平方根に定数パラメータを乗算した乗算値以下に制限することを特徴とする請求項４に記載の経路探索方法。
【請求項６】
前記パラメータは、経路探索の出発点から結合点までの部分的な最短経路の数である最大経路数を１から前記制限値まで増やして経路探索のシミュレーションを行った場合に、ユーザが指定する精度を満たす最大の値であることを特徴とする請求項５に記載の経路探索方法。
【請求項７】
コンピュータに、
グラフデータが有する複数のノードの中から始点および終点を特定し、
前記始点と前記終点とを繋ぐ経路のうち距離の短い上位所定数の最短経路を探索する場合に、前記所定数より小さい値が設定される制限値を用いて、前記始点および前記終点の双方向から、前記始点からの経路と前記終点からの経路とが結合する結合点を特定し、
前記結合点を含む前記複数のノードそれぞれに対応付けて保持する経路の数を前記制限値以下に制限して、各ノードに到達する経路のうち距離が短い経路を保持し、
前記各ノードに対応付けた保持される前記経路を用いて、前記結合点に至る経路から前記上位所定数の最短経路を探索し、
探索された前記上位所定数の経路を出力する、
処理を実行させることを特徴とする経路探索プログラム。
【請求項８】
グラフデータが有する複数のノードの中から始点および終点を特定する特定部と、
前記始点と前記終点とを繋ぐ経路のうち距離の短い上位所定数の最短経路を探索する場合に、前記所定数より小さい値が設定される制限値を用いて、前記始点および前記終点の双方向から、前記始点からの経路と前記終点からの経路とが結合する結合点を特定する特定部と、
前記結合点を含む前記複数のノードそれぞれに対応付けて保持する経路の数を前記制限値以下に制限して、各ノードに到達する経路のうち距離が短い経路を保持する保持部と、
前記各ノードに対応付けた保持される前記経路を用いて、前記結合点に至る経路から前記上位所定数の最短経路を探索する探索部と、
探索された前記上位所定数の経路を出力する出力部と
を有することを特徴とする経路探索装置。
【請求項９】
複数のノードを有するグラフデータを含む経路探索のデータ構造であって、コンピュータが、
グラフデータが有する複数のノードの中から始点および終点を特定し、
前記始点と前記終点とを繋ぐ経路のうち距離の短い上位所定数の最短経路を探索する場合に、前記所定数より小さい値が設定される制限値を用いて、前記始点および前記終点の双方向から、前記始点からの経路と前記終点からの経路とが結合する結合点を特定し、
前記結合点を含む前記複数のノードそれぞれに対応付けて保持する経路の数を前記制限値以下に制限して、各ノードに到達する経路のうち距離が短い経路を保持し、
前記各ノードに対応付けた保持される前記経路を用いて、前記結合点に至る経路から前記上位所定数の最短経路を探索し、
検索された前記上位所定数の経路を出力する、
経路探索のデータ構造。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、経路探索方法、経路探索プログラム、経路探索装置および経路探索のデータ構造に関する。
【背景技術】
【０００２】
ＳＮＳ（Social  Networking  Service）、顧客関係管理、ネットワーク管理、バイオエンジニアリング、輸送など様々な分野で、ネットワーク的なデータを活用するアプリケーションが増えている。ネットワーク的データとしては、インターネット、Ｗｅｂ、交通網などのいわゆるネットワークや、人間関係や分子間の関係などがある。ネットワーク的データは、頂点と、頂点と頂点間を結ぶ辺とによって構成され、人間関係で言えば、人間が頂点、人間同士の関係がその間の辺としてモデル化される。
【０００３】
こうしたネットワーク的データは数学的にはグラフもしくはグラフデータと呼ばれ、グラフデータを分析して、ビジネス、経営、研究などに重要な情報を抽出することが行われている。グラフデータの分析としては、例えば幅優先探索法、Dijkstra法、双方向探索法などのように、２点間の最短経路を探索する手法が広く利用されている。
【０００４】
図３５は、幅優先探索法を説明する図である。幅優先探索法は、重みなしグラフの最短経路を探索する手法である。図３５に示すように、幅優先探索法は、始点につながる頂点を、始点を中心とした同心円状に探索し、その同心円上に終点が現れた時点で処理を終了する。
【０００５】
図３６は、Dijkstra法を説明する図である。Dijkstra法は、重み付きグラフの最短経路を探索する手法である。図３６に示すように、Dijkstra法は、始点から隣接する頂点を順に優先度キューに入れて、重みの小さな頂点を順次取り出し、すべての頂点を取り出した時点で終了する。
【０００６】
例えば、Dijkstra法は、頂点０を始点として、それに隣接する全ての頂点への経路を優先度キュー（もしくは優先度付きキュー）に入れる。続いて、Dijkstra法は、優先度キューの先頭にある経路を取り出す。ここで取り出された取り出した経路［０，１］は、頂点０から頂点１までの最短経路になっている。次に、頂点０で行った処理と同様に、Dijkstra法は、取り出された経路の最後の頂点である頂点１に隣接する全ての頂点への経路を優先度キューに入れる。ただし、既に辿った頂点０は除く。その後、Dijkstra法は、優先度キューの先頭にある経路［０，２］を取り出す。ここで取り出された取り出した経路［０，２］は、頂点０から頂点２までの最短経路になっている。Dijkstra法は、上記処理を終点が優先度キューから取り出されるまで実行することで、始点から終点までの最短経路を探索する。
【０００７】
図３７は、双方向探索法を説明する図である。図３７に示すように、双方向探索法は、幅優先探索を始点と終点の双方から同時に行い、双方が衝突した時点で、双方の経路を合成する。そして、双方向探索法は、双方の探索において用いられるキューの先頭にあるパスの長さの和が今までに探索された最短な経路より長くなった時点で終了する。
【０００８】
近年では、交通網やコンピュータネットワーク通信の迂回路探索などの探索として、２点間の経路のうち最短経路からｋ番目までのｋ本の経路（以降では、ｋ−最短経路と記載する場合がある）を探索することも行われている。例えば、始点と終点との間の最短経路を求め、その最短経路を構成する辺がｐ個あれば、各辺を取り除いたｐ通りのグラフを考え、それぞれのグラフで求めたｐ通りの最短経路の中で最短なものを２番目の最短経路とし、３番目以降の最短経路もこれに類似した方法で求める。
【先行技術文献】
【特許文献】
【０００９】
【特許文献１】特開２０１７−０９８５９３号公報
【特許文献２】特開２０１０−２８６９７８号公報
【特許文献３】特開２０１６−１９４９０８号公報
【非特許文献】
【００１０】
【非特許文献１】E.Filtz，et  al、“On  finding  the  k  shortest  paths  in  RDF  data”，IESD（Intelligent  Exploration  of  Semantic  Data），2016
【発明の概要】
【発明が解決しようとする課題】
【００１１】
ところで、頂点が多い複雑なグラフデータでは、ある頂点（ノード）を始点とする経路の数が膨大になる。このため、複雑なグラフデータのｋ−最短経路を探索する場合、各頂点を通過する膨大な経路の数それぞれについて最短経路を探索することになり、計算量が多く、探索時間も長くなる。
【００１２】
また、最短経路を求めるDijkstra法を拡張した方式（以降では、拡張Dijkstra法と記載する場合がある）も考えられる。例えば、拡張Dijkstra法では、始点から出発して、幅優先探索のようにおおよそ同心円状に終点に辿りつく経路を探索していくが、その探索の途中で通る頂点において最短経路だけでなく、探索された２番目以降の最短経路も保持する。このようにして、拡張Dijkstra法は、ｋ−最短経路の探索を実行する。ところが、この拡張Dijkstra法では、頂点の数が多いほど各頂点で探索する経路が膨大となるので、計算量が多くなり、探索処理の時間その分要する。
【００１３】
一つの側面では、最短経路の探索時間を短縮することができる経路探索方法、経路探索プログラム、経路探索装置および経路探索のデータ構造を提供することを目的とする。
【課題を解決するための手段】
【００１４】
第１の案では、経路探索方法は、コンピュータが、グラフデータが有する複数のノードの中から始点および終点を特定する処理を実行する。経路探索方法は、コンピュータが、前記始点と前記終点とを繋ぐ経路のうち距離の短い上位所定数の最短経路を探索する場合に、前記所定数より小さい値が設定される制限値を用いて、前記始点および前記終点の双方向から、前記始点からの経路と前記終点からの経路とが結合する結合点を特定する処理を実行する。経路探索方法は、コンピュータが、前記結合点を含む前記複数のノードそれぞれに対応付けて保持する経路の数を前記制限値以下に制限して、各ノードに到達する経路のうち距離が短い経路を保持する処理を実行する。経路探索方法は、コンピュータが、前記各ノードに対応付けた保持される前記経路を用いて、前記結合点に至る経路から前記上位所定数の最短経路を探索し、探索された前記上位所定数の経路を出力する処理を実行する。
【発明の効果】
【００１５】
一実施形態によれば、最短経路の探索時間を短縮することができる。
【図面の簡単な説明】
【００１６】
【図１】図１は、実施例１にかかる探索装置を説明する図である。
【図２】図２は、実施例１にかかる探索装置の機能構成を示す機能ブロック図である。
【図３】図３は、グラフデータＤＢに記憶されるグラフデータの例を示す図である。
【図４】図４は、入力されるグラフデータから出力結果までの一例を示す図である。
【図５】図５は、実施例１にかかる処理の流れを示すフローチャートである。
【図６】図６は、頂点ｖと始点、頂点ｖと終点の関係を説明する図である。
【図７】図７は、実施例２にかかるグラフのデータ構造例を示す図である。
【図８】図８は、実施例２にかかるｋ−最短経路探索処理の流れを示すフローチャートである。
【図９】図９は、実施例２にかかるｖの延長処理の流れを示すフローチャートである。
【図１０】図１０は、実施例２にかかるｖの隣接頂点処理の流れを示すフローチャートである。
【図１１】図１１は、実施例２にかかる延長判定処理を行う関数であるis_extended（x，i，path_length，is_v）の流れを示すフローチャートである。
【図１２】図１２は、実施例２にかかる具体例のキュー状況および初期化状態を説明する図である。
【図１３】図１３は、始点および終点における隣接頂点処理を説明する図である。
【図１４】図１４は、始点および終点における隣接頂点処理後のデータ構造を説明する図である。
【図１５】図１５は、頂点１および頂点５における隣接頂点処理を説明する図である。
【図１６】図１６は、頂点１および頂点５における隣接頂点処理後のデータ構造を説明する図である。
【図１７】図１７は、頂点３および頂点７における隣接頂点処理を説明する図である。
【図１８】図１８は、頂点３および頂点７における隣接頂点処理後のデータ構造を説明する図である。
【図１９】図１９は、頂点２における隣接頂点処理を説明する図である。
【図２０】図２０は、頂点２における隣接頂点処理後のデータ構造を説明する図である。
【図２１】図２１は、頂点４における隣接頂点処理を説明する図である。
【図２２】図２２は、頂点４における隣接頂点処理後のデータ構造を説明する図である。
【図２３】図２３は、頂点５および頂点６における隣接頂点処理を説明する図である。
【図２４】図２４は、頂点５および頂点６における隣接頂点処理後のデータ構造を説明する図である。
【図２５】図２５は、頂点６および頂点１における隣接頂点処理を説明する図である。
【図２６】図２６は、頂点６および頂点１における隣接頂点処理後のデータ構造を説明する図である。
【図２７】図２７は、対角線上の結合点における部分的最短経路を説明する図である。
【図２８】図２８は、実施例３にかかるパラメータαの最適化処理の流れを示すフローチャートである。
【図２９】図２９は、パラメータαの最適化の測定結果を示す図である。
【図３０】図３０は、ｐｍａｘ（横軸）と、最大時間比または精度（縦軸）の関係を示す図である。
【図３１】図３１は、近似の有無による比較結果を説明する図である。
【図３２】図３２は、ｍａｘによる削減効果を説明する図である。
【図３３】図３３は、拡張Dijkstraとの比較を説明する図である。
【図３４】図３４は、ハードウェア構成例を説明する図である。
【図３５】図３５は、幅優先探索法を説明する図である。
【図３６】図３６は、Dijkstra法を説明する図である。
【図３７】図３７は、双方向探索法を説明する図である。
【発明を実施するための形態】
【００１７】
以下に、本願の開示する経路探索方法、経路探索プログラム、経路探索装置および経路探索のデータ構造の実施例を図面に基づいて詳細に説明する。なお、この実施例によりこの発明が限定されるものではない。また、各実施例は、矛盾のない範囲内で適宜組み合わせることができる。
【実施例１】
【００１８】
［探索装置の説明］
図１は、実施例１にかかる探索装置１０を説明する図である。図１に示す探索装置１０は、始点から終点までのｋ−最短経路を探索するコンピュータ装置の一例である。例えば、探索装置１０は、入力データとして、各辺に重みが設定された重み付きグラフであり、辺に向きがない無向グラフである、グラフデータを受け付ける。そして、探索装置１０は、グラフデータにおける各頂点のうち始点と終点を設定する。
【００１９】
続いて、探索装置１０は、始点および終点を繋ぐ経路のうちユーザが所望する探索数を取得し、取得した探索数より小さい値と、取得したグラフデータに対して設定される中間点の数に関する値とを用いて、グラフデータのノードのうち始点および終点の双方向から合流点に至るまでの経路の数を特定する。その後、探索装置１０は、特定された経路の数を基にして、特定した始点および終点を繋ぐ経路を検索し、検索された経路を出力する。
【００２０】
例えば、探索装置１０は、Dijkstra法を最短経路探索に拡張した拡張Dikstra法を、さらに双方向探索するようにした方式を用いて、結合点を含む中間点において保持する最短経路の数をｋ以下に制限することで、高速化を図る。図１の例では、探索装置１０は、始点から終点までの経路のうち、最短である１番目の経路、２番目の経路、３番目の経路の３経路を探索する。
【００２１】
［探索装置１０の機能構成］
図２は、実施例１にかかる探索装置１０の機能構成を示す機能ブロック図である。図２に示すように、探索装置１０は、通信部１１、記憶部１２、制御部２０を有する。
【００２２】
通信部１１は、他の装置の間の通信を制御する処理部であり、例えば通信インタフェースなどである。例えば、通信部１１は、管理者の端末から、グラフデータを受信したり、ｋ−最短経路の探索指示を受信したりする。また、通信部１１は、探索結果を指定端末に送信したり、探索結果を表示する画面を指定端末に送信したりする。
【００２３】
記憶部１２は、プログラムやデータを記憶する記憶装置の一例であり、例えばメモリやハードディスクなどである。この記憶部１２は、グラフデータＤＢ１３を記憶する。
【００２４】
グラフデータＤＢ１３は、探索対象であるグラフデータを記憶するデータベースである。図３は、グラフデータＤＢ１３に記憶されるグラフデータの例を示す図である。図３に示すように、探索対象のグラフデータは、０から８までの９個の頂点と、各辺に重みが設定された重み付きの無向グラフである。重みは、言い換えると辺の長さである。
【００２５】
具体的には、頂点０と頂点１との間の辺、頂点１と頂点２との間の辺、頂点２と頂点５との間の辺、頂点３と頂点４との間の辺、頂点４と頂点５との間の辺、頂点５と頂点８との間の辺、頂点６と頂点７との間の辺、頂点７と頂点８との間の辺に対しては、重み「１．０」が設定されている。また、頂点０と頂点３との間の辺、頂点３と頂点６との間の辺、頂点１と頂点４との間の辺、頂点４と頂点７との間の辺に対しては、重み「２．０」が設定されている。なお、以降では、グラフデータについて、重みが「１．０」の辺を点線で図示し、重みが「２．０」の辺を実線で図示する。
【００２６】
制御部２０は、探索装置１０全体を司る処理部であり、例えばプロセッサなどである。制御部２０は、初期設定部２１、探索部２２、出力制御部２３を有する。なお、初期設定部２１、探索部２２、出力制御部２３は、プロセッサが有する電子回路の一例やプロセッサが実行するプロセスの一例などである。
【００２７】
初期設定部２１は、管理者などのユーザから各種設定を受け付けて各種設定を行う処理部である。例えば、初期設定部２１は、ｋ−最短経路の始点と終点、探索数（ｋの値）などを設定する。
【００２８】
探索部２２は、頂点処理部２２ａ、結合点処理部２２ｂ、経路生成部２２ｃを有する。この探索部２２は、優先度キューなどのデータ構造に探索処理の途中結果を格納して保持しつつ、グラフデータＤＢ１３に記憶されるグラフデータに対して、初期設定部２１により設定された値を用いてｋ−最短経路の探索を実行する処理部である。
【００２９】
頂点処理部２２ａは、始点からと終点からの両方向で、各頂点に至るまでの最短経路の候補を特定する処理部である。具体的には、頂点処理部２２ａは、双方向探索を実行しつつ、各頂点に至る複数の経路のうち、長さが短い順に指定数（ｋ本）以下だけ保持する。例えば、ｋとして２が設定された場合、保持する経路数を１などと設定する。なお、以降では、長さがＬである頂点Ａから頂点Ｂへの経路を、Ｌ［頂点Ｂ，頂点Ａ］と記載する。頂点Ａから頂点Ｂへの間に他の頂点がある場合は、それを順に並べるものとする。たとえば、頂点Ａから、頂点Ｂまでの間に、順に頂点Ｃ，頂点Ｄがある場合、Ｌ［頂点Ｂ，頂点Ｄ、頂点Ｃ、頂点Ａ］と書くことにする。
【００３０】
ここで、図３を例に、ｋ−最短経路として２（＝ｋ）を設定し、保持する経路数の閾値を１として具体的に説明する。頂点処理部２２ａは、始点の頂点０に隣接する頂点１について、頂点０から頂点１への経路として１．０［１，０］を特定する。ここで、頂点処理部２２ａは、頂点１への経路の保持数が０であり閾値（１）以下であることから、頂点１の経路として１．０［１，０］を保持する。同様に、頂点処理部２２ａは、始点の頂点０に隣接する頂点３についても、頂点０から頂点３への経路として２．０［３，０］を保持する。
【００３１】
また、頂点処理部２２ａは、終点の頂点８に隣接する頂点５について、頂点８から頂点５への経路として１．０［５，８］を特定し、頂点５への経路の保持数が０であり閾値（１）以下であることから、頂点５の経路として１．０［５，８］を保持する。同様に、頂点処理部２２ａは、終点の頂点８に隣接する頂点７についても、頂点８から頂点７への経路として１．０［７，８］を保持する。
【００３２】
続いて、頂点処理部２２ａは、探索済みの頂点１に隣接する頂点２について、頂点０から頂点２への経路として２．０［２，１，０］を特定し、頂点２への経路の保持数が閾値（１）以下であることから、頂点２までの経路として２．０［２，１，０］を保持する。同様に、頂点処理部２２ａは、探索済みの頂点１に隣接する頂点４について、頂点０から頂点４への経路として３．０［４，１，０］を特定し、頂点４への経路の保持数が閾値（１）以下であることから、頂点４までの経路として３．０［４，１，０］を保持する。
【００３３】
また、頂点処理部２２ａは、探索済みの頂点３に隣接する頂点４について、頂点０から頂点４への経路として３．０［４，３，０］を特定する。しかし、頂点処理部２２ａは、この経路を保持すると、頂点３への経路の保持数が閾値（１）を超えることとなり、さらに、すでに保持されている頂点４への経路「３．０［４，１，０］」の長さが現在の保持対象「３．０［４，３，０］」と同じであることから、現在の保持対象「３．０［４，３，０］」を破棄する。同様に、頂点処理部２２ａは、探索済みの頂点３と隣接する頂点６について、頂点０から頂点６への経路として４．０［６，３，０］を特定し、頂点６への経路の保持数が閾値（１）以下であることから、頂点６までの経路として４．０［６，３，０］を保持する。
【００３４】
このように、頂点処理部２２ａは、優先度キューなどのデータ構造を用いて、各頂点までの経路探索において頂点毎の経路保持数を制限することで、処理量の削減を図る。また、頂点処理部２２ａは、始点と終点の双方向から上記処理を実行し、全頂点または所望の最短経路が探索されるまで実行する。
【００３５】
結合点処理部２２ｂは、頂点処理部２２ａによって探索された各頂点までの経路を用いて、始点側からの探索と終点側からの探索とが結合する結合点を特定する処理部である。具体的には、結合点処理部２２ｂは、終点側から経路が探索されたある頂点について、その頂点への経路が始点側からの探索済みである場合に、その頂点を結合点と特定する。そして、結合点処理部２２ｂは、結合点に関する情報を経路生成部２２ｃに通知する。
【００３６】
例えば、結合点処理部２２ｂは、頂点処理部２２ａによって終点から頂点２までの経路「２．０［２，５，８］」が探索され保持されたときに、始点から探索された頂点２までの経路「２．０［２，１，０］」が探索済みであれば、頂点２を結合点と特定する。一方、結合点処理部２２ｂは、頂点処理部２２ａによって終点から頂点２までの経路「２．０［２，５，８］」が探索された保持されたときに、始点から探索された頂点２までの経路が未探索であれば、頂点２を結合点と特定しない。
【００３７】
経路生成部２２ｃは、頂点処理部２２ａの探索結果と結合点処理部２２ｂの特定結果とを用いて、ｋ−最短経路を生成する処理部である。経路生成部２２ｃは、結合点が特定されると、始点から結合点までの経路と終点から結合点までの経路とを組み合わせて経路を生成する。そして、経路生成部２２ｃは、生成した経路を最大ｋ本保持する。このため、経路生成部２２ｃは、生成した経路を保持する際に、重みが大きい（経路長が長い）経路を削除することで、最大ｋ本の制限を遵守する。
【００３８】
上記例で説明すると、経路生成部２２ｃは、頂点２が結合点として特定された場合、始点から結合点（頂点２）の経路「２．０［２，１，０］」と、終点から結合点（頂点２）の経路「２．０［２，５，８］」とを組み合わせて、始点から終点までの経路「４．０［０，１，２，５，８］」を生成する。そして、経路生成部２２ｃは、現時点での保持数が２本（ｋ＝２）未満であれば、この経路「４．０［０，１，２，５，８］」をそのまま保持する。
【００３９】
また、経路生成部２２ｃは、現時点での保持数が２本（ｋ＝２）であり、経路長が４．０より大きい他経路がある場合には、他経路の中で最長のものを削除してこの経路「４．０［０，１，２，５，８］」を保持する。また、経路生成部２２ｃは、現時点での保持数が２本（ｋ＝２）であり、経路長が４．０以上の他経路が保持されていない場合には、この経路「４．０［０，１，２，５，８］」を破棄する。このように、経路生成部２２ｃは、結合点が特定されるたびに、ｋ本以下の制限を遵守しつつ、ｋ−最短経路の保持を行う。
【００４０】
出力制御部２３は、探索部２２によって生成されたｋ−最短経路の出力を実行する処理部である。具体的には、出力制御部２３は、探索部２２によって各頂点に対する上記処理の実行が完了した時点で、経路生成部２２ｃにより生成されて保持されるｋ本の経路を、記憶部１２等に格納する。そして、出力制御部２３は、ｋ本の経路を、ｋ−最短経路の探索結果として、管理者の端末に送信したり、ディスプレイ等の表示部に出力したりする。
【００４１】
ここで、ｋ−最短経路の探索の具体例を説明する。図４は、入力されるグラフデータから出力結果までの一例を示す図である。図４のグラフデータは、会社や会社の経営者を頂点とする重みなしのグラフであり、黒い頂点は経営者を表し、黒い点を白い円で囲った頂点は会社を表すものとする。そして、関係の深い会社や人間の間を辺で結んだものである。たとえば、会社間の関係であれば、関係会社あるいは大量株所有といった関係である。人間と会社の関係ではその会社の経営者や大株主といった関係である。
【００４２】
この時、もしある二人の人物が不正に関わった可能性があるとされた際、二人の人物の間の最短経路を調べることによって、二人がどういう経路で知り合ったか、あるいはその不正に関わった他の人物や会社を調べることが容易になる。ただし、最短経路以外の経路で関わった可能性も高い。こういう場合、ｋ−最短経路探索で複数の経路を調べて、探索結果のｋ−最短経路の結果を画面に表示したりすることにより、より確度の高い捜索が可能となる。
【００４３】
図４の例では、ａ氏とｂ氏とが不正に関わった場合に、ａ氏を起点、ｂ氏を終点として、３つの最短経路探索（ｋ＝３）を実行した例である。ここでは、探索部２２は、最短の経路である経路Ｎｏ．１と、２番目の経路である経路Ｎｏ．２と、３番目の経路である経路Ｎｏ．３とを探索したとする。この場合、出力制御部２３は、最短経路「起点（ａ氏）、中間点（Ａ社、ｃ氏、Ｂ社）、終点（ｂ氏）」、２番目の経路「起点（ａ氏）、中間点（Ａ社、Ｄ社、Ｂ社）、終点（ｂ氏）」、３番目の経路「起点（ａ氏）、中間点（Ａ社、ｃ氏、Ｃ社、Ｂ社）、終点（ｂ氏）」を含む一覧表を生成して表示することができる。
【００４４】
［処理の流れ］
次に、上述した処理を、優先度キューなどを用いて具体的に実行する例を説明する。図５は、実施例１にかかる処理の流れを示すフローチャートである。図１５に示す処理は、始点側Q[0]からと終点側Q[1]からの交互に実行され、いずれかのQが空になると、他方のQについて処理が実行され、両方のQが空になると、探索された経路が出力される。
【００４５】
図５に示すように、初期設定部２１は、処理開始が指示されると、初期化処理を実行する（Ｓ１０１）。具体的には、初期設定部２１は、グラフデータを取得し、始点、終点の設定、探索数（ｋ）と最大経路数pmaxを設定する。また、初期設定部２１は、求めるべき最短経路を入れる優先度キューtotalQと始点側および終点側の優先度付キューQ[0]、Q[1]を初期化する。なお、totalQは、小さい方からｋ番目までの経路を入れ、それをｋ＋１番目以上のものは廃棄する。また、初期設定部２１は、頂点ごとに始点側、および終点側の経路を保持するためのP[0]とP[1]を初期化する。ｊ番目の頂点に関する経路リストはリストP[i][j]に保持する。
【００４６】
続いて、探索部２２は、Q[0]またはQ[1]が空ではない場合（Ｓ１０２：Ｙｅｓ）、ｉに０を代入して初期化し（Ｓ１０３）、現在のｉが１以下であるか否かを判定する（Ｓ１０４）。
【００４７】
そして、探索部２２は、ｉが１以下であり（Ｓ１０４：Ｙｅｓ）、Q[i]が空ではない場合（Ｓ１０５：Ｙｅｓ）、Q[1]から、始点から頂点ｖまでの経路path_vを取り出す（Ｓ１０６）。例えば、探索部２２は、経路path_vをP[i][v.id()]に保持する。なお、v.id()は頂点vの番号である。
【００４８】
続いて、探索部２２は、保持している経路数がp_maxより小さいか否かを判定する（Ｓ１０７）。そして、探索部２２は、保持している経路数がp_maxより小さい場合（Ｓ１０７：Ｙｅｓ）、経路path_vの結合処理を実行する（Ｓ１０９）。例えば、探索部２２は、点vが結合点である場合、path_vとP[opp(i)][v.id()]の経路とを結合し、totalQに入れる。opp(i)は、iの逆側の番号、すなわち、i=0であれば１、i＝1であれば０を返す関数である。
【００４９】
その後、探索部２２は、頂点vの結合処理を実行し（Ｓ１１０）、ｉをインクリメントし（Ｓ１１１）、Ｓ１０４を実行する。例えば、探索部２２は、頂点vに隣接する頂点wに対し、経路path_w＝[w，path_v]を作り、Q[i]に入れる。
【００５０】
なお、Ｓ１０７において、探索部２２は、保持している経路数がp_max以上である場合（Ｓ１０７：Ｎｏ）、Ｓ１１１以降を実行する。また、Ｓ１０５において、探索部２２は、Q[i]が空である場合（Ｓ１０５：Ｎｏ）、Ｓ１１１以降を実行する。
【００５１】
また、Ｓ１０４において、探索部２２は、ｉが１より大きい場合（Ｓ１０４：Ｎｏ）、Ｓ１０２以降を実行する。また、Ｓ１０２において、探索部２２は、Q[0]およびQ[1]が空である場合（Ｓ１０２：Ｎｏ）、探索された経路群を結果として出力する（Ｓ１１２）。
【００５２】
［効果］
上述したように、探索装置１０は、ユーザが所望する本数の最短経路を、拡張Ｄｉｋｓｔｒａ法を用いた双方向探索で探索する際に、探索途中で保持する経路の情報を制限する。このことにより、探索装置１０は、頂点の数が膨大であったとしても、ユーザの所望する経路を精度良く探索しつつ、計算量を削減することができる。
【実施例２】
【００５３】
次に、上述した実施例１に係る探索装置１０が実行する探索処理の詳細なアルゴリズムについて説明する。まず、実施例で用いる用語を説明し、その後にアルゴリズムについて説明する。
【００５４】
［用語の説明］
グラフではその点のことを「頂点」（vertex）、線のことを「辺」（edge）と記載する。グラフの頂点の集合をＶ、辺の集合をＥと表す。このグラフにＧと名前を付けた場合、Ｇ＝（Ｖ，Ｅ）と表す。すなわち、グラフＧは頂点の集合Ｖと辺の集合Ｅからなるグラフであるという意味である。
【００５５】
また、辺に向きがないグラフを「無向グラフ」と記載し、向きがあるグラフを「有向グラフ」と記載する。例えば、道路が全て両方向であれば、道路網を無向グラフで表現できる。しかし、一方通行を含む場合は、有向グラフでないと表現できない。
【００５６】
また、各辺に重みがついているグラフを「重み付きグラフ」と記載し、重みがついていないグラフを「重みなしグラフ」と記載する。例えば、鉄道網は頂点を駅、駅間の距離あるいは所要時間を対応する頂点間の辺に付与することで、重み付きグラフとして表現できる。一方、人間関係を友人関係のみに着目し、関係の親密さは問わない場合、友人関係は重みなしグラフで表現できる。
【００５７】
２つの頂点が１つの辺で結ばれている場合、２つの頂点は隣接している（adjacent）という。また、ある頂点ｖに隣接する頂点からなるリストを頂点ｖの隣接頂点リストと記載する。重みありグラフの場合は、隣接頂点とその頂点への辺の長さのペアをリストとして持つ。
【００５８】
また、「経路（パス）」について、頂点の列「ｖ０，ｖ１，・・・，ｖｎ」において任意のｉ（１≦ｉ≦ｎ）に対して、ｖｉ−１，ｖｉが隣接している場合、この頂点の列を経路（パス）と呼ぶ。有向グラフでは、ｖｉ−１からｖｉへの辺がＥに含まれていることが必要である。なお、ｖ０を経路の「始点」、ｖｎを「終点」と呼ぶ。本実施例では、頂点は経路上に重複して現れないものとする。
【００５９】
また、「経路の長さ」について、重みなしグラフの場合は、各辺に重み１がついているものと考え、経路上の辺の重みの合計をその「経路の長さ」、あるいは「経路長」と記載する。通常は、２頂点間の経路のうち長さが最も短い経路を「最短経路」と記載する。一般に複数存在する可能性がある。本実施例では、通常の意味での最短経路だけではなく、何番目までかの準最短経路と呼んでもよい経路も単に最短経路と呼ぶことにする。
【００６０】
また、１≦ｋとして、ある頂点ｖｓからある頂点ｖｔまでの最も短いものからｋ番目までのｋ本の最短経路を「ｋ−最短経路」、それを求める処理を「ｋ−最短経路探索」と記載する。ｖｓやｖｔはそれぞれ始点、終点と記載する。また、後述のように双方向探索では、始点、終点の双方から探索を行う。この意味で両者をそれぞれ「出発点」とも呼ぶ。また、始点と終点が一致した経路を閉路と記載する。また、ｋ−最短経路探索における始点と終点の間での探索中に辿られる点を「中間点」と記載する。中間点の一種であるが、始点からの経路と終点からの経路がぶつかる点を「結合点」と記載する。
【００６１】
［アルゴリズムの説明］
最短経路を求めるために、頂点から辺を「辿る」という処理が行われる。この処理をいかに早く打ち切るかが高速化にとって重要である。本実施例では、探索処理の高速化を、「近似的手法による削減」と「ｍａｘによる削減（解の候補として求まったｋ番目の最短経路の長さを利用して無駄な辿りを減らす）」とによって実現する。
【００６２】
例えば、ｋ−最短経路を求める際、その解が必ずしも厳密な解ではなく、近似で十分な場合も多い。交通路、通信路の迂回路や、人間関係のデータ分析などの場合は最適解に十分近ければ、多少厳密性を犠牲にしてもより高速なものが望まれることが考えられる。交通路で言えば、厳密解を求めるのに１分かかる方式よりも、多少精度は落ちても３秒で求まる方式の方が好まれる。また、今日のビッグデータの時代では、データを分析することが要求され、その際に最短経路やｋ番目までの最短経路を多くの二頂点間で計算することが求められている。その際、大規模データでは膨大な時間がかかることが予想され、その場合は正確さよりも速度が優先される場合が多いと考えられる。
【００６３】
また、「近似的手法による削減」ではパラメータの調節が発生するので、このパラメータの最適化を自動化する。また、グラフには、無向／有向グラフ、重み付き／重みなしグラフがあり、それらの組み合わせで４種類（＝２×２）のグラフが考えられるが、本実施例ではその全種類に適用可能である。なお、本実施例では、重み付き無向グラフを前提として説明する。
【００６４】
［近似的手法による削減］
本実施例と一般手法との違いの１つは、結合点を含めた中間点において求める始点あるいは終点からの経路の個数をｋ本以下に制限することである。なお、ユーザが許容できるとして設定した精度をＰｍｉｎとする。これは、ユーザにより任意に設定変更することができる。
【００６５】
本実施例は、出発点から中間点までの部分的最短経路の求める数をｋ本以下にすることにより、探索処理を減らすことで高速化を実現する。この制限された部分的な最短経路の数を「最大経路数」と呼び、以降ｐｍａｘで表す。ｐｍａｘを無作為に減らすと高速化は果たせるが、精度が損なわれる可能性がある。そこで、精度と速度の観点から、αをパラメータとして、式（１）で示される程度に制限する。このように制限することで、結合点では、始点からのｋｓ（≦ｐｍａｘ）本の部分的な最短経路と、終点からのｋｔ（≦ｐｍａｘ）本の部分的な最短経路が求められる。そして、始点およぶ終点からの最短経路同士を組み合わせることで、ｋｓ×ｋｔ本の始点から終点までの最短経路の候補が得られる。このように各結合点で得られた最短経路の候補から、小さい順にｋ番目までの最短経路を求めることで最終結果を得る。
【００６６】
【数１】
2020135207.tif 000003
【００６７】
式（１）が妥当である理由を述べる。式（１）が成立したと仮定し、各結合点で式（１）の右辺で示される本数の部分的な最短経路が始点側および終点側で求まったと仮定すると、結合点では組み合わせることになり、式（２）で示される本数の最短経路の候補が求まる。
【００６８】
【数２】
2020135207.tif 000004
【００６９】
一般に、結合点は多く存在するが、その数をｃとすると合計で「ｃ×式（２）」の最短経路が求まる。この値は少なくともｋを越えている必要があるが、求めたものの中に重複もありうるし、また、数が少なければユーザの精度Ｐｍｉｎ以上の要求に応えられないので、ｋの何倍かは求める必要がある。その数をβとすると、ｃα２ｋ＝βｋ、すなわち式（３）となる。
【００７０】
【数３】
2020135207.tif 000005
【００７１】
逆にαの値をこのような値に設定すれば、おおよそユーザの精度の要求に応えられると考えられる。ただし、ここでは、βやｃを定数のように扱ったが、実際には、これらの値はｋや始点、終点の位置に影響を受ける可能性があり、それに伴い、αも変動する可能性がある。ｋをユーザが使う範囲で変え、また始点や終点を変えて、その中のαの最大値あるいは平均値を取るというような統計的処理を行うことが考えられる。精度に対する要請が厳しい場合は、最大値を取ることが考えられ、それほど厳しくないのであれば平均値を取ることも考えられる。また、ｋの値をいくつかの範囲に分け、その範囲ごとにαを決めることも考えられる。パラメータαの最適化については後述する。
【００７２】
［ｍａｘによる削減］
ｍａｘによる削減では、ｋ番目の最短経路の候補（真にｋ番目かはわからないが、今までに求まっている中でｋ番目に短いもの）が求まっていることが前提である。その長さをｍａｘとする。この手法は、出発点から頂点ｖまで辿ってきた経路とその長さを優先度キューで管理し、入れて取り出す。図６は、頂点ｖと始点、頂点ｖと終点の関係を説明する図である。
【００７３】
図６に示すように、一方の出発点をｓ、もう一方の出発点をｏ、キューから取り出された頂点をｖ、出発点からｖまでの経路の長さをｌｓｖとする。なお、本実施例では、双方向の探索を行い、２つのキュー、すなわち一方の出発点ｓ側のキューＱｓともう一方の出発点ｏ側のキューＱｏを利用する。以降、このように文脈から経路が明確な場合、頂点ｘ、ｙ間の経路の長さをｌｘｙで表すことにする。
【００７４】
図６の点線は、始点あるいは終点からの経路を表している。このとき、２つの事象が問題となる。具体的には、（１）ｖからさらに先を探索するべきか、（２）ｖからさらに先を探索すべきことになった場合、ｖに隣接する頂点をｗとして、ｗより先を探索すべきか、すなわち出発点からｗまでの経路と長さをＱｓに入れるべきかである。
【００７５】
（１）について考える場合、相手側からも頂点ｖに到達している図６の（ａ）と、相手側からは頂点ｖに未到達である（ｂ）に示す場合が考えられる。具体的には、図６の（ａ）は、頂点ｖまで頂点ｏから既に到達しており、その最短経路の長さをｍｉｎとする。また、図６の（ｂ）は、頂点ｖまで頂点ｏから未だ到達しておらず、キューＱｏに入れられた最短経路の最小値をｍｉｎとする。図６の（ｂ）では、キューＱｏの先頭、すなわち長さがｍｉｎの最短経路の先端が頂点ｘであることを示している。
【００７６】
いずれの場合も「ｍａｘ≦ｌｓｖ＋ｍｉｎ」（この不等式を簡単に「ｍａｘによる判定式」と呼ぶことにする）が成り立っているのであれば、これ以上、頂点ｖから延長してもｍａｘより短い最短経路を求めることはできない。すなわち、このことは、頂点ｖから延長する必要がなく、探索を打ち切ってよいことを示し、これは次のことから言える。
【００７７】
例えば、頂点ｖよりもさらに先を辿って到達した頂点ｙで相手側からの最短経路と合成することでｍａｘより短い最短経路ができたと仮定する。その時、図６の（ｃ）に示すように、ｌｖｏ＝ｌｖｙ＋ｌｙｏであり、ｍｉｎ≦ｌｖｏでなければならない。このことを２つに分けて考える。（ａ）の場合であれば、既に到達した経路は頂点ｏからｖまでの最短経路であり、最短経路の定義そのものから、今求めたｙを経由した経路の長さもｍｉｎ以上でなければならないからである。
【００７８】
また、（ｂ）の場合、頂点ｖに頂点ｓ側から到達した時点では、まだ頂点ｏからは未到達だったので、ｍｉｎ≦ｌｖｏでなければならない。なぜなら、ｌｖｏ＜ｍｉｎであれば、キューが優先度キューであることから、求めたｙを経由した経路は既にキューから取り出されているはずであり、未到達という仮定に反するためである。
【００７９】
以上のことは、今後、キューＱｓから取り出された頂点がｖであった場合に常に成り立つ。これ以降に取り出される頂点ｖまでの経路の長さは、キューが優先度キューであることから、今取り出された頂点ｖまでの経路の長さ以上であるはずだからである。このことから、今後は、キューＱｓから取り出された経路の先端が頂点ｖである場合は、その経路の長さによらず、延長する必要がないと言える。なお、ここで注意すべきは、延長の必要がないのは、頂点ｖにおける頂点ｓ側からの延長に関してであり、頂点ｖにおける頂点ｏ側からの延長が必要ないとは言えないことである。
【００８０】
（２）について考える、すなわち頂点ｖから先に延長できることになった場合である。この場合、頂点ｖに隣接する頂点ｗを調べる。そして、頂点ｗから先を探索すべきかどうか、すなわち頂点ｗまでの経路をキューＱｓに入れるかどうかが問題になる。この場合も、頂点ｖの場合と全く同様の理由から、ｍａｘ≦ｌｓｗ＋ｍｉｎが成り立てば、頂点ｗより先を延長する必要がなく、したがってキューＱｓに入れる必要がないと言える。なお、ｌｓｗは、ｌｓｗ＝ｌｓｖ＋ｌｖｗによって計算でき、ｌｖｗは、頂点ｖ、ｗ間の辺の長さである。
【００８１】
ただし、頂点ｖの場合と違って、今後キューＱｓから取り出された経路の先端が頂点ｗであった場合に、頂点ｗまでの経路の長さに依らず、頂点ｗから延長する必要がないとは言えない。これは、頂点ｗはキューＱｓから取り出された経路の先端ではなく、ｌｓｗよりも短い経路が今後キューＱｓから取り出される可能性があるためである。すなわち、言えることは、lｓｗとｓからｖまでの経路にｗを加えたｗまでの経路を入れる必要はないということである。
【００８２】
以上より、（１）の場合は頂点ｖでの出発点側からの延長を停止することが可能となり、（２）の場合は、頂点ｖを経由した頂点ｗまでの経路をキューＱｓに入れることが不要となり、その分高速化につながる。実際、後述の実施例４ではおおよそ１０倍の高速化をもたらした。ここで説明したｍａｘによる判定式を中心とした無駄な辿りの削減を簡単に「ｍａｘによる削減」と記載することとする。
【００８３】
［近似によるｋ−最短経路探索処理］
次に、近似によるｋ−最短経路探索処理に具体的に説明するが、ここでは、グラフの構造やキューの構造などを説明してから、処理の具体的な流れについて説明する。
【００８４】
（１．グラフのデータ構造）
図７は、実施例２にかかるグラフのデータ構造例を示す図である。図７に示すように、グラフは頂点と辺をデータ構造で表現することで表される。図７の（ａ）は、頂点と辺を表すデータ構造を示す。頂点のデータ構造は、頂点識別子（id）と隣接する頂点への辺のリスト（adj_edge_list）へのポインタ）を含み、リストは配列と同義である。辺のデータ構造は、その辺がつなぐ隣接する頂点（adj_vertex）へのポインタとその辺の長さ（length）を含む。
【００８５】
図７の（ｂ）は、図３６に示したグラフを例としたグラフのデータ構造を示す。頂点（id）ごとに、隣接する頂点への辺のリスト「adj_edge_list」を示している。図７の（ｂ）の例では、頂点ｉｄが０である頂点０には、重みが１．０である頂点１への辺、重みが２．０である頂点２への辺、重みが３．０である頂点３への辺、重みが４．０である頂点４への辺が接続されていることを示している。
【００８６】
（２．最大経路数）
上述したように、最大経路数ｐｍａｘは、「ceil（式（１））」とする。ここで、「ceil（ｘ）」は、浮動小数点数ｘを整数に切り上げる関数である。
【００８７】
（３．優先度キュー）
最短経路探索で用いられる優先度キューには次の三種類がある。優先度キューには、最短経路の長さを「path_length」、経路を「path」とした際、それらのペア［path_length，path］、あるいは「path_length」のみが入れられる。
【００８８】
（３．１全体キュー）
全体キューを「totalQ」で表す。「totalQ」には、始点から終点までの最も短いものからｋ番目までの最短経路について各最短経路の長さを「path_length」、経路と「path」とした場合、そのペアである［path_length，path］を入れる。「totalQ」には、最大ｋ個までデータを格納することができ、超過する場合は「path_length」が大きい経路から削除される。「totalQ」の最大値とは、入れられた経路の中で最大の長さをいい、「total.max()」で参照できるものとする。例えば、すでにｋ個の経路が格納されている「totalQ」に新たに経路を格納する場合、この最大値以上のときは格納されない。「totalQ」の初期状態は空であり、「totalQ」に格納される最短経路の個数は「totalQ.len()」で参照できるものとする。len()は、totalQだけでなく、一般のリストの要素を返す関数で、以下の他のリストでも使われる。なお、本実施例では、上記のようにtotalQ.len（）というような書き方もしているが、これはtotalQがlen（）という関数の第一引数であることを意味していて、len（totalQ）と同じ意味である。一般に、x.f()はf(x)と同じ意味である。
【００８９】
（３．２始点キュー・終点キュー）
始点側の優先度キューを「Q[0]」、終点側の優先度キューを「Q[1]」と表す。本実施例は、双方向探索であることから、２つのキューを用意する。なお、本実施例では、始点側を０、終点側を１で表すこととする。
【００９０】
例えば、ある頂点までの部分的な最短経路の経路長を「path_length」、経路を「path」とした場合、優先度キューにはこれらのペアである［path_length，path］が格納される。Dijkstra法では経路は一般には格納されないが、最短経路探索では複数の経路を覚えておく必要があるためである。「Q[0]」の初期状態は、始点をｖｓとすると[0.0,[vs]]が格納され、「Q[1]」の初期状態は、終点をｖｔとすると［0.0,[vt]］が格納される。なお、Q[i]（i＝0,1）に格納されている経路の中で最短の経路、すなわち先頭に格納されている経路の「path_length」は、「Q[i].min（）」で参照できるものとする。
【００９１】
（３．３各頂点キュー）
各頂点には、２つの優先度キュー「q0」と「q1」を用意し、始点および終点から頂点ｖまでの部分的な最短経路の長さをそれぞれ「q0」と「q1」に格納する。「q0」、「q1」には、最大ｐｍａｘ個までの最短経路長「path_length」だけが格納される。すでにｐｍａｘ個が格納されている場合、「path_length」がそれらの最大値以上であれば格納されない。
【００９２】
「q0」、「q1」は、実際に格納された場合、すなわち格納されている個数がｐｍａｘ未満か最大値未満の場合は「真」を返し、逆に格納されなかった場合は「偽」を返す。そして、リストqのq[v.id()]に[q0，q1]を格納し、q0はq[v.id()][0]、q1はq[v.id()][1]によって参照されるものとする。ここで、「v.id()」は、ｖの識別子（頂点の数をｎとした時、各頂点に付けられた０からｎ−１までの番号）を返す関数である。
【００９３】
なお、「q0」あるいは「q1」に長さだけ格納するのは、長さがｐｍａｘ番目以内であれば、経路はQ[0]あるいはQ[1]に格納され、ｐｍａｘ番目より大きければ、本実施例の方針からその経路は破棄することにしており、どちらの場合も、「q0」あるいは「q1」経路を記憶する必要がないためである。［q］の初期状態は、始点、終点の頂点識別子をそれぞれs、tとして、q[s][0]、q[t][1]の値だけ[0.0]であり、それ以外の要素はすべて空のリスト［］である。
【００９４】
（３．４部分的な最短経路リスト）
頂点ｖごとに始点側および終点側から到達した部分的な最短経路を管理するリストをPとし、P[v.id()][i]がi（i＝0、１）側で、頂点ｖに到達した一般に複数の最短経路のリストを表すものとする。すなわち、ｉ＝０の場合は始点から頂点ｖに到達した経路のリストを表し、ｉ＝１の場合は終点からの経路のリストを表す。ｋ番目の最短経路は、P[v.id()][i][k-1]で表されることになる。また、各最短経路は、全体キューや始点キュー・終点キューと同様、［path_length,path］で表されるものとする。ｋ番目の最短経路の「path_length」や「path」はそれぞれ「P[v.id()][i][k-1].path_length」、「P[v.id()][i][k-1].path」で参照できるものとする。なお、Pの初期状態は、すべての要素が空のリスト[]である。
【００９５】
（３．５結合点を管理するリスト）
リスト「is_joint」の「is_joint[v.id()]によって頂点ｖが結合点であるかどうかを表す。すなわち、その値が真であれば頂点ｖが結合点であることを示す。なお、リスト「is_joint」の初期状態は、すべての要素がFalseである。
【００９６】
（３．６延長可能性を示すリスト）
リスト「is_extended_list」の「is_extended_list[v.id()][i]」によって頂点ｖから延長されるかどうかを表す。例えば、ｉ＝０の場合は始点から頂点ｖに到達した場合について表し、ｉ＝１の場合は終点から頂点ｖに到達した場合について表す。すなわち、その値が真であれば頂点ｖから先を延長する（探索する）必要があることを示す。なお、「is_extended_list」の初期状態は、すべての要素がTrueである。
【００９７】
（４．ｋ−最短距離探索処理のフローチャート）
図８は、実施例２にかかるｋ−最短経路探索処理の流れを示すフローチャートである。図８に示すように、探索装置１０の探索部２２は、「0＜Q[0].len()、または、0＜Q[1].len()」を満たす場合（Ｓ１１：Ｙｅｓ）、ｉに０を代入して（Ｓ１３）、「i≦1」を満たすか否かを判定する（Ｓ１４）。
【００９８】
そして、探索部２２は、「i≦1」を満たす場合（Ｓ１４：Ｙｅｓ）、「Q[i].len()＝0」を満たすかどうかを判定し（Ｓ１５）、これを満たす場合（Ｓ１５：Ｙｅｓ）、ｉをインクリメントして（Ｓ１６）、Ｓ１４以降を繰り返す。
【００９９】
一方、探索部２２は、「Q[i].len()＝0」を満たさない場合（Ｓ１５：Ｎｏ）、Q[i]の先頭を取り出し、その長さをpath_length_vに、経路をpath_vに設定し、vにpath_vの0番目の要素を設定する（Ｓ１７）。Q[i].deque()は、キューの先頭を取り出す関数であり、Q[i].deque()の値は経路長l、経路pのペアからなるリスト[l,p]である。キューには、経路の長さと、経路の組が、経路長が短い順に並んでいるので、その最短のものを取り出すことになる。なお、一般に[a,b]＝[c,ｄ]は、aにcを、bにdを設定することを意味する。その後、探索部２２は、リスト「is_extended(v,i,path_length，True)」が「True」か否かを判定し（Ｓ１８）、「True」である場合は（Ｓ１８：Ｙｅｓ）、頂点vの延長処理を実行する（Ｓ１９）。なお、延長処理後は、Ｓ１６以降が繰り返される。
【０１００】
また、探索部２２は、リスト「is_extended(v,i,path_length)」が「True」ではない場合（Ｓ１８：Ｎｏ）、Ｓ１６以降を繰り返す。また、Ｓ１４において、探索部２２は、「i≦1」を満たさない場合（Ｓ１４：Ｎｏ）、Ｓ１１に戻って以降の処理を繰り返す。また、Ｓ１１において、探索部２２は、「0＜Q[0].len()、または、0＜Q[1].len()」を満たさない場合（Ｓ１１：Ｎｏ）、「totalQ.sorted_list()」が返す値を変数lp_listに代入し（Ｓ１２）、処理を終了する。
【０１０１】
上述した処理を具体的に説明すると、全体の処理は、条件「0＜Q[0].len()、または、0＜Q[1].len()」が示すように、優先度キューQ[0]あるいはQ[1]のどちらかが空である限り続けられる。そして、その空でないQ[0]やQ[1]から取り出された[path_length_v,path_v]に対して、「v＝path_v[0]」によって、出発点からの部分的な最短経路における最後の頂点ｖが取り出される。
【０１０２】
なお、「len()」は、優先度キューに格納された要素数など、リストに格納された要素の数を返す関数（メソッド）である。また、「sorted_list()」は、「totalQ」に格納された経路長lと経路pの組[l，p]をlの小さい順にソートしたリスト、すなわち、このアルゴリズムが求めるべきｋ個の最短経路の長さと経路のペアのリストを返す関数である。
【０１０３】
（５．延長処理のフローチャート）
図９は、実施例２にかかるｖの延長処理の流れを示すフローチャートである。図９に示すように、探索装置１０の探索部２２は、「is_joint[v.id()]＝False  and  0＜P[v.id()][opp(i)].len()」を満たす場合（Ｓ２１：Ｙｅｓ）、「is_joint[v.id()]」に「True」を代入する（Ｓ２２）。
【０１０４】
続いて、探索部２２は、「P[v.id()].append([path_length，path_v])」により、P[vid][i]に[path_length，path_v]を追加する（Ｓ２３）。そして、探索部２２は、「is_joint[v.id()]」が「True」であるか否かを判定する（Ｓ２４）。
【０１０５】
そして、探索部２２は、「is_joint[v.id()]」が「True」である場合（Ｓ２４：Ｙｅｓ）、Ｓ２５を実行する。具体的には、探索部２２は、「path_v」と「P[v.id()][opp(i)]」の経路群を合成する。そして、探索部２２は、合成した経路のうち、ループを含まず、totalQに含まれず、かつ、totalQの最大値より小さい長さの経路をtotalQに格納する。
【０１０６】
その後、探索部２２は、頂点ｖの隣接頂点処理を実行する（Ｓ２６）。なお、Ｓ２４において、探索部２２は、「is_joint[v.id()]」が「True」ではない場合（Ｓ２４：Ｎｏ）、Ｓ２５を実行することなくＳ２６を実行する。また、Ｓ２１において、探索部２２は、「is_joint[v.id()]＝False  and  0＜P[v.id()][opp(i)].len()」を満たさない場合（Ｓ２１：Ｎｏ）、Ｓ２２を実行することなくＳ２３を実行する。
【０１０７】
上述した処理を具体的に説明すると、条件「is_joint[v.id()]＝False」は、頂点ｖが結合点でないこと、条件「0＜P[v.id()][opp(i)].len()」は、相手側の出発点から頂点ｖへの部分的な最短経路の個数が０より大きいこと、すなわち相手側の出発点から頂点ｖへ既に到達していて、頂点ｖがこの時点で結合点になったことを示している。そこで、「is_joint[v.id()]＝True」とする。ここで、opp(i)は、iの相手を返す関数である。すなわち、ｉ＝０の場合は１を返し、ｉ＝１の場合は０を返す。また、「P[v.id()].append([path_length，path_v])」により、P[vid][i]に[path_length，path_v]が追加される。
【０１０８】
そして、「is_joint_list[v.id()]＝True」により結合点であるか否かが判定され、結合点である場合、「path_v」と「P[v.id()][opp(i)]」の経路群が合成される。すなわち、[path_length，path_v]とP[vid][opp(i)]とに格納されている部分的な最短経路を組み合わせることで、始点から終点までの最短経路が合成される。そして、合成された最短経路にループがなく、totalQに格納されている最短経路と異なり、totalQの最大値より小さいという３つの条件を満たした場合に、合成された最短経路がtotalQに格納される。
【０１０９】
ここで、経路の合成についてより具体的に説明する。「P[v.id()][opp(i)]」には、[[l1，p1]，[l2，p2]，・・・[lk，pk]]が格納されているものとする。「li」は経路長の長さであり、「pi」は経路である。そして、[path_length_v，path_v]とこれらの経路群を合成する。すなわち、[path_len＋li，path_v＋pi]（i＝1,2・・・k）が作られる。最後に頂点ｖからの経路を延長するために、頂点ｖに隣接する頂点に関する処理が行われる。
【０１１０】
（６．隣接頂点処理のフローチャート）
図１０は、実施例２にかかるｖの隣接頂点処理の流れを示すフローチャートである。図１０に示すように、探索装置１０の探索部２２は、「v.adj_edge_list()」に未処理の[w，edge_length]が残っている場合（Ｓ３１：Ｙｅｓ）、「w」が「path_v」に含まれていないかどうかを判定する（Ｓ３２）。
【０１１１】
そして、探索部２２は、「w」が「path_v」に含まれていない場合（Ｓ３２：Ｙｅｓ）、「path_length_w」に「（path_length_v）＋（edge_length）」を代入する（Ｓ３３）。
【０１１２】
そして、「is_extended（w，i，path_length_w，False）」が「True」か否かを判定し（Ｓ３４）、「True」である場合に、Ｓ３５が実行される。
【０１１３】
そして、探索部２２は、「q[v.id][i].enque(path_length_w)」が「True」である場合（Ｓ３５：Ｙｅｓ）、「path_w＝[w，path_v]」によって「w」までの経路を生成し、Q[i]に「path_length_w，path_w」を格納する（Ｓ３６）。その後は、Ｓ３１以降が繰り返される。
【０１１４】
なお、探索部２２は、Ｓ３５において「q[v.id][i].enque(path_length_w)」が「True」ではない場合（Ｓ３５：Ｎｏ）、Ｓ３２において「w」が「path_v」に含まれている場合（Ｓ３２：Ｎｏ）、Ｓ３４において「is_extended(w，i，path_length_w，False)」が「True」ではない場合（Ｓ３４：Ｎｏ）、Ｓ３１以降を繰り返す。
【０１１５】
また、探索部２２は、Ｓ３１において、「v.adj_edge_list()」に未処理の[w，edge_length]が残っていない場合（Ｓ３１：Ｎｏ）、処理を終了する。
【０１１６】
上述した処理を具体的に説明すると、「v.adj_edge_list()」は、頂点ｖに隣接する頂点ｗと、頂点ｖと頂点ｗの間の辺の長さ「edge_length」のペア「w，edge_length」のリスト（これを隣接頂点リストと呼ぶ）を返す関数である。ここに、未処理の「w，edge_length」が残っている間、処理が継続して実行される。
【０１１７】
次に、頂点ｗが頂点ｖまでの経路「path_v」に含まれていないことを確認する。頂点ｗが既にあればループがあることになるからである。
【０１１８】
次に、「path_length_w＝path_length＿v＋edge_length」により、出発点から頂点ｗまでの最短経路の長さを求める。そして、「is_extended(w，i，path_length_w，False)」が「True」か否かを判定し、「True」である場合に、q_list[w.id()][i].enque（path_length_w）の値で優先度キューにpath_length_wが格納されるかを判定する。ここで、格納できるのであれば、path_length_wが頂点ｗに今まで到達した経路の中でｐｍａｘ番目以内に入っていることになる。すなわち、頂点ｗ以降に延長できる可能性があることになる。ここで可能性があると言っているのは、これ以降、頂点wにこの経路より短い最短経路が到達して、この経路がｐｍａｘ以内に入らない可能性もあるためである。
【０１１９】
そこで、path_w＝[w，path_v]によって頂点ｗまでの経路を生成し、Q[i].enque（[path_length_w，path_w]）により、Q[i]に「path_length_w，path_w」が格納される。なお、path_w＝[w，path_v]と頂点vまでの経路path_vを利用して、path_wを効率的に定義することができる。
【０１２０】
（７．延長判定処理のフローチャート）
図１１は、実施例２にかかる延長判定処理を行う関数であるis_extended（x，i，path_length，is_v）の流れを示すフローチャートである。xは頂点である。iは始点側の場合０、終点側の場合１を取る整数である。path_lengthは、頂点xまでの始点からの距離である。is_vは、Trueであれば頂点ｘがｖであること、すなわち図８のｋ−最短経路探索処理で呼ばれることを示し、Falseであればｗであること、すなわち図１０の隣接頂点処理で呼ばれることを示す。パラメータ以外の他のデータ構造は今までに説明したものであり、この関数の中から参照できるものとする。図１１に示すように、探索装置１０の探索部２２は、rにTrueを代入し（Ｓ３１１）、「is_extended_list[x.id()][i]」がTrueか否かを判定する（Ｓ３１２）。
【０１２１】
続いて、探索部２２は、「is_extended_list[x.id()][i]」がTrueである場合（Ｓ３１２：Ｙｅｓ）、P[x.id()][i].len()がｐｍａｘより小さいか否かを判定する（Ｓ３１３）。
【０１２２】
そして、探索部２２は、P[x.id()][i].len()がｐｍａｘより小さい場合（Ｓ３１３：Ｙｅｓ）、ｋ番目の最短経路が求まっていて、その経路長ｍａｘが求まっているか否かを判定する（Ｓ３１４）。
【０１２３】
ここで、探索部２２は、ｋ番目の最短経路およびその経路長ｍａｘが求まっている場合（Ｓ３１４：Ｙｅｓ）、P[x.id()][opp(i)].len()が０より大きいか否かを判定する（Ｓ３１５）。そして、探索部２２は、P[x.id()][opp(i)].len()が０に等しく（Ｓ３１５：Ｎｏ）、Q[opp(i)].len()が０に等しい場合（Ｓ３１６：Ｎｏ）、is_extended_list[x.id()][i]にFalseを代入する（Ｓ３１７）。
【０１２４】
一方、探索部２２は、P[x.id()][opp(i)].len()が０より大きい場合（Ｓ３１５：Ｙｅｓ）、P[x.id()][opp(i)][0].path.lengthを「min」に代入する（Ｓ３１８）。また、探索部２２は、Q[opp(i)].len()が０より大きい場合（Ｓ３１６：Ｙｅｓ）、Q[opp(i)].min()を「min」に代入する（Ｓ３１９）。また、探索部２２は、Ｓ３１７を実行後、「r＝False」として（Ｓ３２２）、値rを返し、処理を終了する。
【０１２５】
また、探索部２２は、Ｓ３１８またはＳ３１９を実行後、「path_length＋min」がmaxより小さいか否かを判定する（Ｓ３２０）。そして、探索部２２は、「path_length＋min」がmaxより小さい場合（Ｓ３２０：Ｙｅｓ）、「r＝True」のままでとして、値rを返して、処理を終了する。
【０１２６】
また、探索部２２は、「path_length＋min」がmax以上である場合（Ｓ３２０：Ｎｏ）、is_vが「True」であるかを判定し（Ｓ３２１）、そうであればＳ３１７を実行し、そうでなければＳ３２２を実行する。なお、Ｓ３１４において、探索部２２は、ｋ番目の最短経路の経路長がまだ求まっていない場合（Ｓ３１４：Ｎｏ）、値rを返して、処理を終了する。
【０１２７】
上述した処理を具体的に説明する。図１１は、頂点ｖや頂点ｗが延長されるか判定する関数is_extended()のフローチャートである。
【０１２８】
Ｓ３１２で「is_extended_list[x.id()][i]」がFalseであれば、頂点ｘから先に延長する必要がないことを意味するので、Ｓ３２２で「r＝False」として、値rを返して、処理を終了する。また、Ｓ３１３で、P[x.id()][i].len()がｐｍａｘに達していれば、この頂点までの部分的最短経路をこれ以上求める必要がないので、Ｓ３１７で「is_extended_list[x.id()][i]」をFalseとしている。したがって、次の処理タイミングからは、Ｓ３１２で「r＝False」と即時に判定されることになる。この条件により、探索処理の削減が実現される。
【０１２９】
また、Ｓ３１４において、「ｋ番目の最短経路が求まっている」とは、全体キュー「totalQ」にすでにｋ個の最短経路が格納されていて（このことは、totalQ.len()の値がｋに等しいか判定することでわかる）、「その経路長がｍａｘ」とは、totaQ.max()の値をmaxとすることを意味している。この場合に、Ｓ３１５以降において、maxによる削減が可能かどうかの判定を行うことにより、高速化を実現できる。
【０１３０】
また、Ｓ３１８やＳ３１９で求めているｍｉｎは、Ｓ３１５の条件が成り立つ場合はＳ３１８により値が設定され、成り立たずにＳ３１６が成り立つ場合は、Ｓ３１９により値が設定される。そして、Ｓ３２０のｍａｘによる判定式が成り立つ場合は、ｍａｘより短い始点から終点までの最短経路が求まる可能性があるので、頂点xでの延長は停止しないと判定される。しかし、そうでない場合は、Ｓ３２１で頂点ｘが頂点ｖか頂点ｗかによって分かれ、頂点ｖの場合は、Ｓ３１７によって頂点ｘでの出発点側からの延長処理を停止するように設定される。すなわち、無駄な延長処理を妨げることができ、処理の高速化につながる。一方、頂点ｗの場合は、Ｓ３２２によって単に頂点ｗまでの経路の延長は行わない。すなわちその経路をキューには入れないと判定される。このことも、頂点ｖの場合のように、頂点ｗでの延長を行わないとは言えないまでも、キューに入れることを妨げることで高速化に寄与する。
【０１３１】
［動作の具体例］
次に、図１２から図２７を用いて、上述した処理の具体例を説明する。図１２は、実施例２にかかる具体例のキュー状況および初期化状態を説明する図である。図１２の（ａ）に示すように、ここでは、二次元格子状のグラフを用いて説明する。このグラフは、９個の頂点と１２本の辺からなり、各頂点には０から８までの識別子がつけられている。また、各辺には、１．０か２．０の重みが付けられている。距離的には同じであるが、たとえば頂点間に要する時間などが異なる。なお、この具体例では、重みを区別しやすいように、重みが２．０の辺を実線で示し、重みが１．０の辺を破線で示す。このことを利用して、以降の図では辺の重みの記載を省くことにする。そして、頂点０を始点、頂点８を終点とする。なお、最短経路を２番目まで求める、すなわち、ｋ＝２とする。また、最大経路数ｐｍａｘは１とする。
【０１３２】
（初期状態）
図１２の（ｂ）は、各キューの初期状態を示す図である。キューQの0、１の列がそれぞれQ[0]、Q[1]を示している。また、i＝0，1，・・・，8として、q[i]、P[i]、is_extended_list[i]の0、１の列が、それぞれq[i][0]、q[i][1]、P[i][0]、P[i][1]、is_extended_list[i][0]、is_extended_list[i][1]を表している。is_extended_listは図中では、図を簡略化するためis_extと略されている。また、初期値のTrueも略し、今後Falseとなる場合だけを図示する。
【０１３３】
なお、図をさらに簡略化するため以下のようにする。リストを表す括弧（[、]）は省略し、頂点はｖｉと表すべきところ、単に整数ｉで表す。また、経路も再帰的な構造を簡略化し、平坦なリストの形で記載する。たとえば、[3,[2,[1]]]と記載すべきところを[3,2,1]と記載する。また、is_joint_listは図中には表示せず、代わりにP[i]を太字で記載することで、is_joint_list[i]がTrueであることを示すことにする。
【０１３４】
（始点・終点における処理）
図１３は、始点および終点における隣接頂点処理を説明する図である。図１４は、始点および終点における隣接頂点処理後のデータ構造を説明する図である。ここでは、頂点０や頂点８、それらに隣接する頂点１、３、５、７に関する処理である。図１３に示すように、探索部２２は、始点側については頂点０に隣接する頂点１と頂点３、および、終点側については頂点８に隣接する頂点５と頂点７に対して、経路の探索を実行し、その結果を図１４に示す各データ構造に格納する。
【０１３５】
まず、始点側について探索処理が実行される。図１３に示すように、探索部２２は、始点である頂点０と隣接する頂点１と頂点３のうち、頂点１について処理を実行する。なお、頂点３を先に処理しても構わないが、基本的にリスト「v.adj_edge_list()」に格納されている順番に処理する。そして、以下では頂点番号の順にリストに格納されているものとして説明する。具体的には、探索部２２は、始点側の優先度キューを「Q[0]」から［0.0,[0]］を取り出して、P[0][0]に格納する。続いて、探索部２２は、頂点０から頂点１への長さ「1.0」を特定し、頂点１のq[1][0]の格納数がｐｍａｘ（＝１）未満であることから、q[1][0]に「1.0」を格納する。そして、探索部２２は、始点側の優先度キューQ[0]に、始点から頂点１への経路情報[長さ，経路＝[頂点，頂点]]として[1.0,[1,0]]を格納する。
【０１３６】
同様に、探索部２２は、頂点０から頂点３への長さ「2.0」を特定し、頂点３のq[3][0]の格納数がｐｍａｘ（＝１）未満であることから、q[3][0]に「2.0」を格納する。そして、探索部２２は、始点側の優先度キューQ[0]に、始点から頂点３への経路情報[長さ，経路＝[頂点，頂点]]として[2.0,[3,0]]を格納する。
【０１３７】
次に、終点側について探索処理が実行される。図１３に示すように、探索部２２は、終点である頂点８に対しても、頂点０と同様の処理を実行することで、終点側の優先度キューを「Q[1]」から［0.0,[8]］を取り出して、処理対象である頂点８に対応するリストP[8][1]に［0.0,[8]］を格納する。また、探索部２２は、頂点８に隣接する頂点５のリストq[5][1]に[1.0]を格納し、頂点８に隣接する頂点７のリストq[7][1]に[1.0]を格納する。また、探索部２２は、終点側の優先度キューQ[1]に、終点から頂点５への経路情報[1.0,[5,8]]と、終点から頂点７への経路情報[1.0,[7,8]]を格納する。
【０１３８】
上記処理をより詳細に説明する。まず、探索部２２は、Q[0]やQ[1]が空ではないことから、図８のＳ１１の条件が成り立つので、Ｓ１３の「i＝0」を実行する。続いて、探索部２２は、Ｓ１４が成り立つことから、Q[0]が空でないのでＳ１７を実行し、Q[0]から[path_length_v，path_v]＝[0,0,[0]]を取り出す。すなわち、path_length_v＝0,0，path_v＝[0]が設定される。なお、ここでは、頂点識別子がiである頂点をviと書くことにすると、path_v＝［v0］と書くべきところを簡略化している。そして、v＝path_v[0]により、v＝0が設定される。
【０１３９】
続いて、探索部２２は、Ｓ１８でＳ１９以下のvの延長処理を行うか否かを判定する関数is_extended()を呼び出す。そして、探索部２２は、図１１のＳ３１２やＳ３１３が少なくとも初期状態では成り立つので、Ｓ３１４を実行する。しかし、探索部２２は、最短経路が１本も見つかっていないので、Ｓ３１１３において、Ｓ３１１で設定されたままのr＝Trueで処理を戻す。すなわち、探索部２２は、延長処理を行うと判定し、図８のＳ１９を実行する。
【０１４０】
その後、探索部２２は、図９のＳ２１の頂点ｖが結合点になるかどうかを判定する条件が未成立と判定してＳ２３を実行し、P[0][0]に[0,0,[0]]を追加する。ここで、頂点ｖは結合点ではないので、Ｓ２４の式が成り立たず、Ｓ２６の頂点隣接処理が実行される。
【０１４１】
そして、探索部２２は、Ｓ３１で未処理のものとして[1,1.0]と[3,2.0]が残っているので、まず[w，edge_length]として[1,1.0]が選ばれるものとして、Ｓ３２を実行する。続いて、探索部２２は、Ｓ３２の条件が成り立つと判定し、w＝1がpath_v＝[0]に含まれないので、Ｓ３４を実行し、path_length_v＝0.0、edge_length＝1.0であることから、頂点ｗまでの経路長path_length_wを「1.0」と計算する。その後、探索部２２は、Ｓ３５でリストq[0][0]にpath_length_wを格納するが、まだリストが空なので、Ｓ３５の条件が成立してＳ３６を実行し、path_w＝[w，path_v]としてQ[0]に[path_length_w，path_w]、すなわち[1.0,[1,0]]を格納する。
【０１４２】
また、探索部２２は、未処理の[3,2.0]についても同様の計算を実行し、Q[0]に[2.0,[3,0]]を格納する。この処理が終わった段階で、図１４に示すように、Q、q[1]、q[3]、P[0]の各0の列に値が設定されるが、is_extended_listについては延長停止になった頂点がないので初期状態からの変化はない。
【０１４３】
これでvの隣接頂点処理が終了し、vの延長処理が終了して、図８のＳ１６に戻り、i＝1となるので、今度はＳ１４以降の終点側の処理が同様に実行される。その結果、図１４に示すように、Q、q[1]、q[3]、P[0]の各1の列に値が設定される。すなわち、Q[1]には[1.0,[5,8]]と[1.0,[7,8]]が格納され、q[5][1]とq[7][1]にはそれぞれ1.0が格納され、P[8][1]には[0.0,[8]]が格納される。
【０１４４】
なお、図１４はあくまで始点側と終点側でのすべての隣接頂点処理が終わった時点でのデータ構造の様子を示したものであり、上記の処理を行なっている時点のものではない。たとえば、始点側の処理が終わった時点では、図１４のようには終点側の設定はされていない。以降の図も同様である。また、図１４において薄い文字で示された部分は、削除されたことを示し、太文字で示された部分は新たに設定された部分を示す。キューは優先度キューなので、キューの中では長さの小さい順にソートされる。
【０１４５】
（隣接頂点処理：その１）
図１５は、頂点１および頂点５における隣接頂点処理を説明する図である。図１６は、頂点１および頂点５における隣接頂点処理後のデータ構造を説明する図である。ここでは、Q[0]から先頭に格納される情報として、頂点１に関する経路情報[1.0,[1,0]]が取り出され、Q[1]から先頭に格納される情報として、頂点５に関する経路情報[1.0,[5,8]]が取り出されることから、始点側からは頂点１が処理対象となり、終点側からは頂点５が処理対象となる。
【０１４６】
具体的には、図１５に示すように、探索部２２は、探索された始点側の頂点１に隣接する頂点２と頂点４、および、探索された終点側である頂点５に隣接する頂点２と頂点４とについて、経路の探索を実行し、その結果を図１６に示す各データ構造に格納する。なお、探索部２２は、頂点１から頂点０についても同様の処理を行うが、頂点０はすでに通過した頂点であることから、格納対象外と判断する。頂点８についても同様である。
【０１４７】
まず、始点側について探索処理が実行される。図１５に示すように、探索部２２は、処理対象の頂点１と隣接する頂点２と頂点４のうち、頂点２について処理を実行する。具体的には、図１６に示すように、探索部２２は、始点側の優先度キューを「Q[0]」から［1.0,[1,0]］を取り出して、処理対象である頂点１に対応するP[1][0]に格納する。続いて、探索部２２は、始点から頂点２への経路（長さ）として、頂点０から頂点１への長さ「1.0」と頂点１から頂点２への長さ「1.0」とを加算した長さ「2.0」を算出する。そして、探索部２２は、頂点２のq[2][0]の格納数がｐｍａｘ（＝１）未満であることから、q[2][0]に「2.0」を格納する。そして、探索部２２は、始点側の優先度キューQ[0]に、頂点２への経路情報[長さ，経路]として[2.0,[2,1,0]]を格納する。
【０１４８】
同様に、図１５に示すように、探索部２２は、始点である頂点０から頂点４への長さ「3.0」を特定し、頂点４のq[4][0]の格納数がｐｍａｘ（＝１）未満であることから、図１６に示すように、q[4][0]に「3.0」を格納する。そして、探索部２２は、始点側の優先度キューQ[0]に、頂点４への経路情報[長さ，経路]として[3.0,[4,1,0]]を格納する。
【０１４９】
次に、終点側について探索処理が実行される。図１５に示すように、探索部２２は、終点側である頂点５に対しても、頂点１と同様の処理を実行することで、終点側の優先度キューを「Q[1]」から［1.0,[5,8]］を取り出して、処理対象である頂点５に対応するP[5][1]に［1.0,[5,8]］を格納する。また、探索部２２は、終点である頂点８から頂点２への長さ「1.0＋1.0＝2.0」を算出してq[2][1]に[2.0]を格納する。また、探索部２２は、終点である頂点８から頂点４への長さ「1.0＋1.0＝2.0」を算出してq[4][1]に[2.0]を格納する。また、探索部２２は、終点側の優先度キューQ[1]に、終点８から頂点２への経路情報[2.0,[2,5,8]]と、終点８から頂点４への経路情報[2.0,[4,5,8]]を格納する。
【０１５０】
上記処理をより詳細に説明する。まず、探索部２２は、Q[0]の先頭の[1.0,[1,0]]やQ[1]の[1.0,[5,8]]を取り出して、図１３や図１４と同様の処理を実行する。ここで、探索部２２は、頂点０について、［w，edge_length］として[0,1.0]、すなわちw＝0、edge_length＝1.0も残っていることから処理を実行する。しかし、探索部２２は、ただし、w＝0は始点であり、既に通ってきている頂点であるため、path_v＝[1,0]に含まれているので、処理対象外とする。頂点８は同様に処理対象外となる。このような頂点は、図１５では省略しており、以降の図においても省略する。
【０１５１】
また、始点と終点の双方から頂点２および頂点４に到達しているので、結合することによって、始点から終点までの最短経路が形成されそうに見えるが、そうではない。確かに、始点、終点から頂点２および頂点４までの経路は最短経路の候補としてキューQ[0]およびQ[1]には格納されたが、あくまで候補であり、キューから取り出された時点で初めて、未だ取り出されていない（キューにまだ入っていないものも含めた）すべての候補の中で、始点あるいは終点からその頂点までの部分的な最短な経路であることが確定するためである。すなわち、もしその頂点までの最短経路が取り出されていないのであれば、取り出された経路が始点あるいは終点からその頂点までの最短経路であることが保証される。また、すでにｉ本の経路が到着しているのであれば、ｉ＋１番目の最短経路であることが保証される。逆に、キューQ[0]およびQ[1]に格納された候補同士をつなぎ合わせても、何番目のもの同士を結び付けたかさえはっきりしない。
【０１５２】
（隣接頂点処理：その２）
図１７は、頂点３および頂点７における隣接頂点処理を説明する図である。図１８は、頂点３および頂点７における隣接頂点処理後のデータ構造を説明する図である。ここでは、Q[0]から先頭に格納される情報として、頂点３に関する経路情報[2.0,[3,0]]が取り出され、Q[1]から先頭に格納される情報として、頂点７に関する経路情報[1.0,[7,8]]が取り出されることから、始点側から頂点３が処理対象となり、終点側からは頂点７が処理対象となる。
【０１５３】
具体的には、図１７に示すように、探索部２２は、探索された始点側の頂点３に隣接する頂点４と頂点６、および、探索された終点側である頂点７に隣接する頂点４と頂点６について、経路の探索を実行し、その結果を図１６に示す各データ構造に格納する。なお、探索部２２は、頂点０や頂点８についてはすでに通過した頂点であるとから、処理対象外と判断する。
【０１５４】
まず、始点側について探索処理が実行される。図１７に示すように、探索部２２は、処理対象の頂点３と隣接する頂点４と頂点６のうち、頂点４について処理を実行する。具体的には、図１６に示すように、探索部２２は、始点側の優先度キューを「Q[0]」から先頭に格納される［2.0,[3,0]］を取り出して、処理対象である頂点３に対応するP[3][0]に格納する。続いて、探索部２２は、始点から頂点４への経路（長さ）として、頂点０から頂点３への長さ「2.0」と頂点３から頂点４への長さ「1.0」とを加算した長さの合計「3.0」を算出する。そして、探索部２２は、この長さの合計「3.0」を頂点４のq[4][0]に格納を試みるが、すでにq[4][0]には「3.0」が格納されており、格納数がｐｍａｘ未満の条件を満たさず、かつ、格納済みの長さが算出された長さ以下であることから、格納せずに破棄する。この結果、探索部２２は、頂点４への経路情報[3.0,[4,3,0]]についても、始点側の優先度キューQ[0]に格納しない。
【０１５５】
同様に、図１７に示すように、探索部２２は、始点である頂点０から頂点６への長さ「4.0」を特定し、頂点６のq[6][0]の格納数がｐｍａｘ（＝１）未満であることから、図１７に示すように、q[6][0]に「4.0」を格納する。そして、探索部２２は、始点側の優先度キューQ[0]に、経路情報[長さ，経路]として[4.0,[6,3,0]]を格納する。
【０１５６】
次に、終点側について探索処理が実行される。図１７に示すように、探索部２２は、終点側である頂点７に対しても、頂点３と同様の処理を実行することで、終点側の優先度キューを「Q[1]」から先頭の［1.0,[7,8]］を取り出して、処理対象である頂点７に対応するP[7][1]に［1.0,[7,8]］を格納する。また、探索部２２は、終点から頂点７に隣接する頂点６への経路（長さ）として、頂点８から頂点７への長さ「1.0」と頂点７から頂点６への長さ「1.0」とを加算した長さの合計「2.0」を算出する。そして、探索部２２は、頂点６のq[6][1]の格納数がｐｍａｘ（＝１）未満であることから、q[6][1]に「2.0」を格納する。また、探索部２２は、始点側の優先度キューQ[0]に、頂点６への経路情報[長さ、経路]として[2.0,[6,7,8]]を格納する。
【０１５７】
さらに、探索部２２は、頂点７に隣接する頂点４についても同様に、終点から頂点４への経路（長さ）として、頂点８から頂点７への長さ「1.0」と頂点７から頂点４への長さ「2.0」とを加算した長さの合計「3.0」を算出する。そして、探索部２２は、この長さの合計「3.0」を頂点４のq[4][1]に格納を試みるが、すでにq[4][1]には「2.0」が格納されており、格納数がｐｍａｘ未満の条件を満たさず、かつ、格納済みの長さが算出された長さ以下であることから、格納せずに破棄する。この結果、探索部２２は、頂点４への経路情報[3.0,[4,7,8]]についても、始点側の優先度キューQ[1]に格納しない。
【０１５８】
上記処理をより詳細に説明する。ここでは、頂点３および頂点７に対して隣接接点処理が行われることで、図１８のデータ構造を得ることができる。この処理においては、頂点３から頂点４への隣接頂点処理において、[w，edge_length]＝[4,1.0]が図１０のＳ３１で処理されるが、Ｓ３４でpath_length＝3.0と計算され、q[4][0]には既に3.0が格納済みであり、かつｐｍａｘ＝１であるため、Ｓ３５でqに入れようとしても弾かれる。その場合、「q[v.id()][i].enque(path_length_w)」の値は「False」であるので、Ｓ３６でキューQに格納されずに済むことになる。ここが、qによる不要な候補の削減効果である。図１８において、q[4][0]の3.0が丸括弧で囲まれているのは、このように入れようとして弾かれたことを意味している。また、Q[0]やQ[1]に丸括弧で囲まれた「3.0,[4,3,0]」や「3.0,[4,7,8]」は、入れようとして弾かれたわけではないが、qによる削減効果がなければ、入れられていたことを意味している。以降、他のデータ構造でもこの記法を用いることにする。なお、終点側での頂点７から頂点４への隣接頂点処理についても同様である。
【０１５９】
（隣接頂点処理：その３）
図１９は、頂点２における隣接頂点処理を説明する図である。図２０は、頂点２における隣接頂点処理後のデータ構造を説明する図である。ここでは、Q[0]から先頭に格納される情報として、頂点２に関する経路情報[2.0,[2,1,0]]が取り出され、Q[1]から先頭に格納される情報として、頂点２に関する経路情報[2.0,[2,5,8]]が取り出されることから、両側共通として頂点２が処理対象となる。具体的には、図１９に示すように、探索部２２は、探索された頂点２に隣接する始点側からの頂点１と終点側からの頂点５について、経路の探索を実行し、その結果を図２０に示す各データ構造に格納する。なお、始点側からの頂点１と終点側からの頂点５は、すでに探索済みであることから、処理対象となる。
【０１６０】
まず、図１９に示すように、探索部２２は、処理対象の頂点２と隣接する頂点５について処理を実行する。具体的には、図２０に示すように、探索部２２は、始点側の優先度キューを「Q[0]」から先頭に格納される［2.0,[2,1,0]］を取り出して、処理対象である頂点２に対応するP[2][0]に格納する。続いて、探索部２２は、始点から頂点５への経路として、頂点０から頂点１への長さ「1.0」と頂点１から頂点２への長さ「1.0」と頂点２から頂点５への長さ「1.0」とを加算した長さの合計「3.0」を算出する。そして、探索部２２は、頂点５のq[5][0]の格納数がｐｍａｘ（＝１）未満であることから、q[5][0]に「3.0」を格納する。そして、探索部２２は、始点側の優先度キューQ[0]に、頂点５への経路情報として[3.0,[5,2,1,0]]を格納する。なお、優先度キューQ[0]には、長さが小さい順になるように挿入される。
【０１６１】
また、探索部２２は、処理対象の頂点２と隣接する頂点１についても同様の処理を実行することで、終点側の優先度キューを「Q[1]」から先頭に格納される［2.0,[2,5,8]］を取り出して、処理対象である頂点２に対応するP[2][1]に［2.0,[2,5,8]］を格納する。また、探索部２２は、終点である頂点８から頂点１への長さ「1.0＋1.0＋1.0＝3.0」を算出してq[1][1]に[3.0]を格納する。また、探索部２２は、終点側の優先度キューQ[1]に、終点８から頂点１への経路情報[3.0,[1,2,5,8]]を格納する。
【０１６２】
ここで、探索部２２は、P[2][0]およびP[2][1]に値が格納されていることから、頂点２を結合点と判定する。そして、探索部２２は、始点から頂点２までの経路［2,1,0］と、終点から頂点２までの経路［2,5,8］とを組み合わせ経路［0,1,2,5,8］を生成する。また、探索部２２は、始点から頂点２までの経路の長さ「2.0」と終点から頂点２までの経路の長さ「2.0」とを組み合わせて、経路［0,1,2,5,8］の長さを「4.0」と算出する。そして、探索部２２は、totalQにデータが格納されていないことから、経路情報「4.0,[0,1,2,5,8]を最短経路としてtotalQに格納する。
【０１６３】
上記処理をより詳細に説明する。Q[0]から[2.0,[2,1,0]]が取り出され、Q[1]からは[2.0,[2,5,8]]が取り出されるので、ここで初めて、始点からの最短経路と終点からの最短経路が頂点２で結合することになる。すなわち、頂点２が結合点となる。図８でi＝1、すなわち、終点側の処理を行っている際に、図９のＳ２１でis_joint[2]で、P[2][0]には既に[2.0,[2,1,0]]が格納されていて、「0＜P[v.id][opp(i)].len()」が成り立つので、頂点２が結合点であることを示すＳ２２が実行される。したがって、Ｓ２３が実行された後、Ｓ２４も成り立つので、Ｓ２５が実行され、始点から頂点２まで既にP[2][0]として求まっている部分的最短経路[2,1,0]とpath_v＝[2,5,8]が合成され、[0,1,2,5,8]という始点から終点までの長さ4.0の経路が合成される。そして、この求めた経路にループが含まれず、totalQはこの時点では空で、totalQは当然同じものは含まれておらず、totalQは空で入れることができるので、[4.0,[0,1,2,5,8]]がtotalQに格納される。このように、始点から終点までの（一番の）最短経路がtotalQに格納されたことになる。上述したように、図２０でP[2]を太文字にすることで、頂点２が結合点であることを示している。
【０１６４】
（隣接頂点処理：その４）
図２１は、頂点４における隣接頂点処理を説明する図である。図２２は、頂点４における隣接頂点処理後のデータ構造を説明する図である。ここでは、Q[0]から先頭に格納される情報として、頂点４に関する経路情報[3.0,[4,1,0]]が取り出され、Q[1]から先頭に格納される情報として、頂点４に関する経路情報[2.0,[4,5,8]]が取り出されることから、両側共通として頂点４が処理対象となる。具体的には、図２１に示すように、探索部２２は、探索された頂点４に隣接する頂点５、頂点７、頂点１、頂点３のそれぞれについて、経路の探索を実行し、その結果を図２１に示す各データ構造に格納する。
【０１６５】
まず、始点側について探索処理が実行される。図２１に示すように、探索部２２は、処理対象の頂点４と隣接する頂点５と頂点７のうち、頂点５について処理を実行する。具体的には、図２２に示すように、探索部２２は、始点側の優先度キューを「Q[0]」から先頭の［3.0,[4,1,0]］を取り出して、処理対象である頂点４に対応するP[4][0]に格納する。続いて、探索部２２は、始点から頂点５への経路として、頂点０、頂点１、頂点４、頂点５の経路の長さの合計「4.0」を算出する。そして、探索部２２は、この長さ「4.0」を頂点５のq[5][0]に格納を試みるが、すでにq[5][0]には「3.0」が格納されており、格納数がｐｍａｘ未満の条件を満たさず、かつ、格納済みの長さが算出された長さ以下であることから、格納せずに破棄する。この結果、探索部２２は、頂点５への経路情報[4.0,[5,4,1,0]]についても、始点側の優先度キューQ[0]に格納しない。
【０１６６】
同様に、図２１に示すように、探索部２２は、始点である頂点０から頂点７への長さ「5.0」を特定し、頂点７のq[7][0]の格納数がｐｍａｘ（＝１）未満であることから、図２２に示すように、q[7][0]に「5.0」を格納する。そして、探索部２２は、始点側の優先度キューQ[0]に、経路情報として[5.0,[7,4,1,0]]を格納する。
【０１６７】
次に、終点側について探索処理が実行される。図２１に示すように、探索部２２は、終点側である頂点１に対しても、同様の処理を実行することで、終点側の優先度キューを「Q[1]」から［2.0,[4,5,8]］を取り出して、処理対象である頂点４に対応するP[4][1]に［2.0,[4,5,8]］を格納する。そして、探索部２２は、終点である頂点８から頂点３への長さ「3.0」を特定し、頂点３のq[3][1]の格納数がｐｍａｘ（＝１）未満であることから、図２２に示すように、q[3][1]に「3.0」を格納する。そして、探索部２２は、始点側の優先度キューQ[1]に、経路情報として[3.0,[3,4,5,8]]を格納する。
【０１６８】
また、探索部２２は、終点側である頂点１に対しても同様の処理を実行し、終点から頂点１への経路（長さ）として、頂点８、頂点５、頂点４、頂点１を経由する経路の長さの合計「4.0」を算出する。そして、探索部２２は、この長さ「4.0」を頂点１のq[1][1]に格納する際、すでにq[1][1]には「3.0」が格納されており、格納数がｐｍａｘ未満の条件を満たさず、かつ、格納済みの長さが算出された長さ以下であることから、格納せずに破棄する。この結果、探索部２２は、頂点１への経路情報[4.0,[1,4,5,8]]についても、始点側の優先度キューQ[1]に格納しない。
【０１６９】
ここで、探索部２２は、P[4][0]およびP[4][1]に値が格納されていることから、頂点４を結合点と判定する。そして、探索部２２は、始点から頂点４までの経路［4,1,0］と、終点から頂点４までの経路［4,5,8］とを組み合わせ経路［0,1,4,5,8］を生成する。また、探索部２２は、始点から頂点４までの経路の長さ「3.0」と終点から頂点４までの経路の長さ「2.0」とを組み合わせて、経路［0,1,4,5,8］の長さを「5.0」と算出する。そして、探索部２２は、totalQに格納されるデータが２（＝ｋ）未満であることから、経路情報「5.0,[0,1,4,5,8]を最短経路としてtotalQに格納する。
【０１７０】
上記処理を実行することで、頂点４において図２１に示す隣接頂点処理が行われ、図２２に示すデータ構造になる。ここで注目すべき点は、totalQが一杯になったことである。以降では、このことによる図１１のＳ３１４4以降の処理による削減効果も期待できるようになる。また、ここでも、qによる削減効果が現れている。
【０１７１】
（隣接頂点処理：その５）
図２３は、頂点５および頂点６における隣接頂点処理を説明する図である。図２４は、頂点５および頂点６における隣接頂点処理後のデータ構造を説明する図である。ここでは、Q[0]から先頭に格納される情報として、頂点５に関する経路情報[3.0,[5,2,1,0]]が取り出され、Q[1]から先頭に格納される情報として、頂点６に関する経路情報[2.0,[6,7,8]]が取り出されることから、頂点５および頂点６が処理対象となる。
【０１７２】
具体的には、図２３に示すように、探索部２２は、探索された頂点５に隣接する頂点４および頂点８と、探索された頂点６と隣接する頂点３のそれぞれについて、経路の探索を実行し、その結果を図２４に示す各データ構造に格納する。なお、頂点７については、終点である頂点８からの探索ですでに探索済みであることから、処理対象外となる。
【０１７３】
まず、始点側について探索処理が実行される。図２３に示すように、探索部２２は、処理対象の頂点５と隣接する頂点４と頂点８のうち、頂点４について処理を実行する。具体的には、図２４に示すように、探索部２２は、始点側の優先度キューを「Q[0]」から先頭の［3.0,[5,2,1,0]］を取り出して、処理対象である頂点５に対応するP[5][0]に格納する。続いて、探索部２２は、始点から頂点４への経路として、頂点０、頂点１、頂点２、頂点５、頂点４の経路の長さの合計「4.0」を算出する。そして、探索部２２は、この長さ「4.0」を頂点４のq[4][0]に格納する際、すでにq[4][0]には「3.0」が格納されており、格納数がｐｍａｘ未満の条件を満たさず、かつ、格納済みの長さが算出された長さ以下であることから、格納せずに破棄する。この結果、探索部２２は、頂点４への経路情報[4.0,[4,5,2,1,0]]についても、始点側の優先度キューQ[0]に格納しない。
【０１７４】
同様に、図２３に示すように、探索部２２は、頂点８についても同様に実行する。具体的には、探索部２２は、始点である頂点０から頂点８への長さ「4.0」を特定し、頂点８のq[8][0]の格納数がｐｍａｘ（＝１）未満であることから、図２４に示すように、q[8][0]に「4.0」を格納する。そして、探索部２２は、始点側の優先度キューQ[0]に、経路情報として[4.0,[8,5,2,1,0]]を格納する。
【０１７５】
次に、終点側について探索処理が実行される。図２３に示すように、探索部２２は、今までであれば、終点側である頂点６に隣接する頂点３に対しても、同様の処理を実行する。しかし、以下で詳述するように、図１１の延長判定処理においてmaxによる削減の効果で、延長しないと判定されるため、処理は行わずに済む。
【０１７６】
ここで、探索部２２は、P[5][0]およびP[5][1]に値が格納されていることから、頂点５を結合点と判定する。そして、探索部２２は、始点から頂点５までの経路［5,2,1,0］と、終点から頂点５までの経路［5,8］とを組み合わせ経路［0,1,2,5,8］を生成する。また、探索部２２は、始点から頂点５までの経路の長さ「3.0」と終点から頂点５までの経路の長さ「1.0」とを組み合わせて、経路［0,1,2,5,8］の長さを「4.0」と算出する。そして、探索部２２は、この経路情報[4.0,［0,1,2,5,8］]をtotalQに格納することを試みるが、すでに格納済みであることから破棄する。
【０１７７】
上記処理をより詳細に説明する。頂点５、頂点６において今まで同様に隣接頂点処理を実行する際、頂点６では隣接頂点処理は行われず、図２４に示すデータ構造になる。これは、上述した削減効果によるためである。具体的には、頂点６の延長処理を行なうか、図１１のフローチャートで判定する際、Ｓ３１４の条件が成り立つために、Ｓ３１５が実行され、この条件が成り立たないために、Ｓ３１６が実行される。そして、この条件が成り立つために、Ｓ３１９でmin＝4.0と設定される。この結果、Ｓ３２０でpath_length＋min＝2.0＋4.0となり、一方でmax＝5.0よりこの条件が成り立たない。このため、Ｓ３２１が実行され、is_vはTrueであるので、Ｓ３１７によりここで今までで初めてis_extended_list[x.id()][i]に、具体的には、is_extended_list[6][1]にFalseが設定される。そして、r＝FalseとＳ３２２で設定され、r＝Falseが戻り値となる。すなわち、vの延長処理は行われない。
【０１７８】
（隣接頂点処理：その６）
図２５は、頂点６および頂点１における隣接頂点処理を説明する図である。図２６は、頂点６および頂点１における隣接頂点処理後のデータ構造を説明する図である。ここでは、Q[0]から先頭に格納される情報として、頂点６に関する経路情報[4.0,[6,3,0]]が取り出され、Q[1]から先頭に格納される情報として、頂点１に関する経路情報[3.0,[1,2,5,8]]が取り出されることから、始点側では頂点６が処理対象となり、終点側では頂点１が処理対象となる。
【０１７９】
具体的には、図２５に示すように、探索部２２は、探索された頂点６に隣接する頂点７と、探索された頂点１と隣接する頂点０および頂点４のそれぞれについて、経路の探索を実行し、その結果を図２６に示す各データ構造に格納する。なお、始点側からの頂点３と終点側からの頂点２については、すでに探索済みであることから、処理対象外となる。
【０１８０】
まず、始点側について探索処理が実行される。図２５に示すように、探索部２２は、処理対象の頂点６と隣接する頂点７について処理を実行するところである。しかし、前回と同様、以下で詳述するように、図１１の延長判定処理においてmaxによる削減の効果で、延長しないと判定されるため、処理は行わずに済む。
【０１８１】
次に、終点側について探索処理が実行される。図２５に示すように、探索部２２は、終点側である頂点１に隣接する頂点０に対しても、同様の処理を実行する。具体的には、探索部２２は、終点側の優先度キューを「Q[1]」から［3.0,[1,2,5,8]］を取り出して、処理対象である頂点１に対応するP[1][1]に［3.0,[1,2,5,8]］を格納する。また、探索部２２は、終点から頂点０への経路（長さ）として、頂点８、頂点５、頂点２、頂点１、頂点０を経由する経路の長さの合計「4.0」を算出する。そして、探索部２２は、この長さ「4.0」を頂点１のq[0][1]に格納する。また、探索部２２は、頂点０への経路情報[4.0,[0,1,2,5,8]]についても、終点側の優先度キューQ[1]に格納する。
【０１８２】
頂点１に隣接する頂点４に対しては、終点から頂点４へは既に長さ２の経路が到達していること（q[4][1]＝[2.0]）から、処理は打ち切られる。
【０１８３】
上記処理を実行することで、ここでは、頂点６、頂点１において隣接頂点処理が行われ、頂点１では今までと変わらないが、頂点６では隣接頂点処理は行われず、図２６に示すデータ構造になる。具体的には、頂点６の延長処理を行なうかを図１１のフローチャートで判定する際、Ｓ３１４の条件が成り立つので、Ｓ３１５が実行される。しかし、この条件は成り立たないことから、Ｓ３１６が実行されて、Ｓ３１６が成り立つのでＳ３１９が実行されて、min＝3.0と設定される。この結果、Ｓ３２０において、path_length＋min＝4.0＋3.0＝7.0となり、一方でmax＝5.0より、条件が成り立たないので、Ｓ３２１が実行される。そして、is_vはTrueであるので、Ｓ３１７が実行されて、is_extended_list[6][0]にFalseが設定される。そして、r＝FalseとＳ３２２で設定され、r＝Falseが戻り値となる。頂点１が新たに結合点になっているが、結合されて生成される経路「4.0，[0,1,2,5,8]」が既にtotalQに入っているため、図９のＳ２５の働きによりtotalQに入らない。
【０１８４】
これ以降も処理が続くが、このように、Q[0]およびQ[1]に入れられることが妨げられるようになりQ[0]およびQ[1]は両方ともいずれ空になるので、その時点で図８のＳ１１の条件から処理が終了する。そして、その時点でtotalQに残っているものが、求めるべきｋ−最短経路となる。
【０１８５】
なお、以上の説明を踏まえ、結合点における部分的最短経路の合成によって最短経路を求めている全体像を、図２７を用いて説明する。図２７は、対角線上の結合点における部分的最短経路を説明する図である。図２７は、始点・終点を結ぶ対角線とは別の対角線上の（結合点になりそうな）頂点で求まる最終的な部分的最短路を表したものである。各頂点で始点側(0)と終点側(1）の部分的最短路を合成することで、図１２の（ａ）に示すすべての経路が求まることがわかる。たとえば、頂点４では始点側と終点側のそれぞれ２つずつの部分的最短路を組み合わせることで、頂点４を通るすべての最短経路が求まる。ただし、以上のことはこの例ではであり、一般には始点から終点までのすべての経路を求めるわけではない、求めていては非常に時間がかかってしまうので、図８Ｓ１１の条件により途中で打ち切っている。
【実施例３】
【０１８６】
次に、パラメータαの最適化について説明する。パラメータαの最適化は、ユーザが許容できる精度Ｐｍｉｎ以上の範囲内で最適なものをｐｍａｘの値を１からｋまでの範囲で変動させることで探すということを示す。ｋを含めることで、Ｐｍｉｎ＝１．０を指定されても精度が１．０のものは見つかることが保証される。ただし、ｐｍａｘの値を１からｋまでの範囲で変動させると、特にｐｍａｘの値がｋに近い値の場合には多大な時間がかかる可能性がある。このことを次のように回避する。一般にｐｍａｘの値が小さいほど、探索時間は短い。一方、後述する実験等によれば、ｐｍａｘの値が小さくても精度１．０という結果が得られている。以上を考慮して、ｐｍａｘを１から始めて、精度がＰｍｉｎを超えた時点で処理を打ち切る。このことで、最適化を高速に行うことが期待できる。
【０１８７】
（フローチャート）
図２８は、実施例３にかかるパラメータαの最適化処理の流れを示すフローチャートである。INFITEはどの数値よりも大きい数値を表す。厳密解と一致することを望む場合は、Ｐｍｉｎ＝１．０を指定する。
【０１８８】
図２８に示すように、Ｓ４１では、find_acc(v_list,source_vid,target_vid,k)は、正確なｋ−最短距離探索を行う関数であり、それを実行する。この関数find_accは、頂点のリストv_list、始点の頂点識別子source_vid、終点の頂点識別子target_vid、および何番目までの最短経路を求めるかを示すｋをパラメータとして、最短経路の長さと最短経路を構成する始点から終点までの頂点列のペアのリストであるspl_accを返す。なお、accは厳密であることを意味するaccurateの略である。spl_accは、最短経路の長さが短い順にソートされている。このリストを「最短経路リスト」と呼ぶことにする。以前に部分的な最短経路リストという言葉が出てきたが、こちらは全体的な最短経路リストである。
【０１８９】
次に、p_maxに１を代入して（Ｓ４２）、p_maxがｋ以下であれば（Ｓ４３：Ｙｅｓ）、Ｓ４４において関数find_appを実行する。具体的には、find_app(v_list,source_vid,target_vid,k,p_max)は、近似によるｋ−最短経路探索を行う関数であり、パラメータや関数の返り値はfind_accと類似するが、パラメータに最大経路数であるp_maxが追加されている点が異なる。spl_appは、spl_accと同様のリストであり、うまく行けば全く一致する可能性もあるが、近似的に求めたものであるため、spl_accに含まれているものが全て含まれているとは限らない。このリストは図８のＳ１２で返されるものそのものであり、やはり「最短経路リスト」と呼ぶことにする。なお、appは近似であることを意味するapproximateの略である。diff(spl_acc，spl_app)は、２つの最短経路リストspl_acc、spl_appで異なる最短経路の個数を計算する関数である。全く一致する場合は０を返し、ｄ個違えばｄを返す。
【０１９０】
その後、Ｓ４４で得られるprecisionがＰｍｉｎ未満であれば（Ｓ４５：Ｎｏ）、p_maxをインクリメントして（Ｓ４７）、Ｓ４３以降が実行される。一方、Ｓ４４で得られるprecisionがＰｍｉｎ以上であれば（Ｓ４５：Ｙｅｓ）、Ｓ４６を実行して処理を終了する。このように、p_max＝ｋまで調べれば、Ｐｍｉｎ＝１．０が指定されても厳密解が必ず求まる。したがって、p_max＝ｋまで調べてもαが求まらない場合は、エラーすなわち異常終了としている。
【０１９１】
（パラメータαの最適結果）
図２９は、パラメータαの最適化の測定結果を示す図である。図３０は、ｐｍａｘ（横軸）と、最大時間比または精度（縦軸）の関係を示す図である。縦横それぞれ６４、すなわち頂点数ｎ＝４０９６（６４×６４）の二次元格子グラフで、ｋの値が１６、３２、６４の場合に最適化した結果を図２９に示す。ここでは、近似の測定ではＰｍｉｎ＝１．０とし、最小の時間、すなわちｐｍａｘの値を１、２、３・・・と順に増加させ、精度がＰｍｉｎ＝１．０になった時点での処理時間を求めた。処理時間はＣＰＵ時間である。
【０１９２】
図３０は３つのうちのｋ＝６４の場合の処理時間と精度の関係を示すものである。両者のスケールを合わせるため、最大（すなわちｐｍａｘ＝４）の処理時間に対するそれぞれの処理時間の比を最大時間比として示している。たとえば、ｐｍａｘ＝１の場合は、精度が１．０のｐｍａｘ＝４の場合よりも約半分の処理時間で済むものの、精度は０．３程度であることを示している。
【０１９３】
この例では、ｐｍａｘがかなり小さいうちに精度が１．０になったので、処理が打ち切られている。求めるαの値は、処理が打ち切られた際のｐｍａｘの値を用いて計算したものであり、ｋの値１６、３２、６４に対して、それぞれ０．７５、０．７０７、０．５とお互いに近い値を示している。これらの値の最大値であるα＝０．７５を最終的なαの値として採用すれば、ｋの値によらずに精度が１．０あるいはそれに近いことが期待できる。また、精度への要求がそれほど厳密でないのであれば、たとえばこれらの値の平均である０．６５を用いることもできる。逆に精度への要請がより厳しい場合は、αの値をマージンをとって大きくしておくこともできる。なお、上の測定では説明を簡易にするためもあって、始点、終点は一組だけで、測定も一度しか行っていないが、実際にαを決定する際には、ｋをそれが使われる範囲でいろいろ変え、また始点、終点をいろいろに変え、αの最大値あるいは平均値を取るというような統計的処理を行うのが有効である。
【実施例４】
【０１９４】
次に、実施例１−３で説明した手法による効果を説明する。ここでは、近似の有無による効果と、ｍａｘによる削減効果、拡張Dijkstraとの比較とについて説明する。
【０１９５】
（近似の有無の比較）
図３１は、近似の有無による比較結果を説明する図である。ここでは、上記実施例で近似を用いた場合すなわちｐｍａｘ＜ｋの場合と、近似を用いない厳密解の場合すなわちｐｍａｘ＝ｋの場合の処理時間を比較する。近似では、図３０で示す最適化でＰｍｉｎ＝１．０とした結果を用いた。すなわち、近似ではあるが、精度は１．０であるようにした。そして、最小の時間、すなわち図３１で示したように、ｐｍａｘの値を１、２、３、・・・と順に増加させ、精度がＰｍｉｎ＝１．０になった時点での処理時間を求めた。このようにしたのは近似における測定値の意味づけをはっきりするためである。したがって、精度は１．０でないものの、より短い時間で処理することも可能である。
【０１９６】
以上による測定結果をまとめたのを図３１に示す。性能比は、近似の処理時間に対する近似を用いなかった場合の処理時間の比、すなわち近似を用いることで何倍速くなるかを示している。図３１に示す結果から、近似を用いることで、２．８から１４．８倍速くなり、また頂点数が増えるにつれて性能比が大きくなっていることがわかる。
【０１９７】
（ｍａｘによる削減効果）
図３２は、ｍａｘによる削減効果を説明する図である。ここでは、上記実施例においてｍａｘによる削減を用いた場合、すなわち図１１のＳ３１４以下を用いた場合と、用いなかった場合の処理時間を比較する。測定にあたっては、図３２の（ａ）に示す近似を用いた場合と、図３２の（ｂ）に示す近似を用いなかった場合のそれぞれについて測定した。
【０１９８】
性能比は、maxによる削減を適用した場合の処理時間に対して適用しなかった場合の処理時間の比、すなわちmaxによる削減を適用すると何倍速くなるかを示す。近似を用いた場合は３．４から９．５倍速くなり、また頂点数が増えるにつれて性能比が大きくなることを示している。近似を用いなかった場合は８．０から１２．２倍速くなり、減少している部分もあるものの、概ね頂点数が増えるにつれて性能比が大きくなる傾向にあることを示している。
【０１９９】
（拡張Ｄｉｊｋｓｔｒａとの比較）
図３３は、拡張Dijkstraとの比較を説明する図である。ここでは、近似による上記実施例の方式と拡張Dijkstra法の処理時間の比較を行う。測定に用いた拡張Dijkstra法には、中間点で求める最短経路をｋ本までに限定するという改良を施している。測定結果をまとめたのを図３３に示す。性能比は、実施例の方式が拡張Dijkstra法より何倍速いかを示す値である。図３３に示す結果から、近似による実施例の方式は、拡張Dijkstra法より４．８から３２．５倍速いこと、そして頂点数が増えるにつれて性能比が増えていることがわかる。
【０２００】
（実施例の方式による比較）
図２９に示すように、パラメータαをユーザが要求した精度以上の範囲で、なるべく高速になるよう自動的に最適化でき、ユーザによるパラメータの調節を省略することができる。また、図３１に示すように、近似を使うことにより精度１．０を保ちながら約３〜１５倍と高速化を実現することができる。さらに、高速化は、頂点数が増えるにつれて、より効果的である。
【０２０１】
図３２に示すように、maxによる削減により、近似を用いた場合は約３〜１０倍、近似を用いない場合は約８〜１２倍と高速化を実現できる。また、その効果は概ね頂点数が増えるにつれてより効果的である。図３３に示すように、実施例の方式は、拡張Dijkstra法よりおよそ５倍から３３倍程度の高速化を実現でき、その効果は頂点数が増えるにつれてより効果的である。
【実施例５】
【０２０２】
さて、これまで本発明の実施例について説明したが、本発明は上述した実施例以外にも、種々の異なる形態にて実施されてよいものである。
【０２０３】
［適用グラフ］
例えば、重みなしグラフの最短経路は、よく知られているように幅優先探索を用いることで高速に求めることができる。それは、優先度付きキューの代わりに、「first−in，first−out」の通常のキューを用いることで容易に実現できる。実施例で説明した方式でも、優先度付きキューを通常のキューに置き換えることで、容易に重みなしグラフに対応することが可能である。なお、重みをすべて１．０として本実施例の方式を用いることで対応することも可能であるが、幅優先探索を用いた方がより高速である。
【０２０４】
また、Dijkstra法は有向グラフに対して対応可能である。したがって、実施例の方式を、有向グラフに対応するよう改良することは容易である。具体的には、頂点ｖ，ｗが隣接している場合、無向グラフでは、ｖとｗのadj_edge_listの双方に辺を表すデータ構造を入れていたが、有向グラフでは、ｖからｗへの向きの辺がある場合に限って、ｖのadj_edge_listに辺を加える。両方向にある場合は、ｗのadj_edge_listにも加えられる。この変更を加えるだけで、有向グラフには対応可能である。
【０２０５】
［システム］
上記文書中や図面中で示した処理手順、制御手順、具体的名称、各種のデータやパラメータを含む情報については、特記する場合を除いて任意に変更することができる。また、実施例で説明した具体例、分布、数値などは、あくまで一例であり、任意に変更することができる。
【０２０６】
また、図示した各装置の各構成要素は機能概念的なものであり、必ずしも物理的に図示の如く構成されていることを要しない。すなわち、各装置の分散や統合の具体的形態は図示のものに限られない。つまり、その全部または一部を、各種の負荷や使用状況などに応じて、任意の単位で機能的または物理的に分散・統合して構成することができる。さらに、各装置にて行なわれる各処理機能は、その全部または任意の一部が、ＣＰＵおよび当該ＣＰＵにて解析実行されるプログラムにて実現され、あるいは、ワイヤードロジックによるハードウェアとして実現され得る。
【０２０７】
［ハードウェア］
図３４は、ハードウェア構成例を説明する図である。図３４に示すように、探索装置１０は、通信装置１０ａ、ＨＤＤ（Hard  Disk  Drive）１０ｂ、メモリ１０ｃ、プロセッサ１０ｄを有する。また、図１０に示した各部は、バス等で相互に接続される。
【０２０８】
通信装置１０ａは、ネットワークインタフェースカードなどであり、他のサーバとの通信を行う。ＨＤＤ１０ｂは、図２に示した機能を動作させるプログラムやＤＢを記憶する。
【０２０９】
プロセッサ１０ｄは、図２に示した各処理部と同様の処理を実行するプログラムをＨＤＤ１０ｂ等から読み出してメモリ１０ｃに展開することで、図２等で説明した各機能を実行するプロセスを動作させる。すなわち、このプロセスは、探索装置１０が有する各処理部と同様の機能を実行する。具体的には、プロセッサ１０ｄは、初期設定部２１、探索部２２、出力制御部２３等と同様の機能を有するプログラムをＨＤＤ１０ｂ等から読み出す。そして、プロセッサ１０ｄは、初期設定部２１、探索部２２、出力制御部２３等と同様の処理を実行するプロセスを実行する。
【０２１０】
このように探索装置１０は、プログラムを読み出して実行することで探索方法を実行する情報処理装置として動作する。また、探索装置１０は、媒体読取装置によって記録媒体から上記プログラムを読み出し、読み出された上記プログラムを実行することで上記した実施例と同様の機能を実現することもできる。なお、この他の実施例でいうプログラムは、探索装置１０によって実行されることに限定されるものではない。例えば、他のコンピュータまたはサーバがプログラムを実行する場合や、これらが協働してプログラムを実行するような場合にも、本発明を同様に適用することができる。
【０２１１】
このプログラムは、インターネットなどのネットワークを介して配布することができる。また、このプログラムは、ハードディスク、フレキシブルディスク（ＦＤ）、ＣＤ−ＲＯＭ、ＭＯ（Magneto−Optical  disk）、ＤＶＤ（Digital  Versatile  Disc）などのコンピュータで読み取り可能な記録媒体に記録され、コンピュータによって記録媒体から読み出されることによって実行することができる。
【符号の説明】
【０２１２】
１０  探索装置
１１  通信部
１２  記憶部
１３  グラフデータＤＢ
２０  制御部
２１  初期設定部
２２  探索部
２２ａ  頂点処理部
２２ｂ  結合点処理部
２２ｃ  経路生成部
２３  出力制御部
【図１】
2020135207.tif 000006
【図２】
2020135207.tif 000007
【図３】
2020135207.tif 000008
【図４】
2020135207.tif 000009
【図５】
2020135207.tif 000010
【図６】
2020135207.tif 000011
【図７】
2020135207.tif 000012
【図８】
2020135207.tif 000013
【図９】
2020135207.tif 000014
【図１０】
2020135207.tif 000015
【図１１】
2020135207.tif 000016
【図１２】
2020135207.tif 000017
【図１３】
2020135207.tif 000018
【図１４】
2020135207.tif 000019
【図１５】
2020135207.tif 000020
【図１６】
2020135207.tif 000021
【図１７】
2020135207.tif 000022
【図１８】
2020135207.tif 000023
【図１９】
2020135207.tif 000024
【図２０】
2020135207.tif 000025
【図２１】
2020135207.tif 000026
【図２２】
2020135207.tif 000027
【図２３】
2020135207.tif 000028
【図２４】
2020135207.tif 000029
【図２５】
2020135207.tif 000030
【図２６】
2020135207.tif 000031
【図２７】
2020135207.tif 000032
【図２８】
2020135207.tif 000033
【図２９】
2020135207.tif 000034
【図３０】
2020135207.tif 000035
【図３１】
2020135207.tif 000036
【図３２】
2020135207.tif 000037
【図３３】
2020135207.tif 000038
【図３４】
2020135207.tif 000039
【図３５】
2020135207.tif 000040
【図３６】
2020135207.tif 000041
【図３７】
2020135207.tif 000042