回答:
これがpgRoutingでのshortest_path(ダイクストラのアルゴリズム)の動作です。ソースとターゲットが同じエッジが2つある場合は、ランダムな1つ(正確には、データベースから出力される最初のエッジ)が使用されます。修正方法はわかりませんが、いくつかの回避策があります。
可能であれば、これらのエッジの1つを2つに分割する必要があります。私はそれをテストしていませんが、それはその振る舞いを修正するはずです。
データセットを変更できない場合のその他の解決策。テーブルに「shorter_alternative」フィールドを追加します。サンプルクエリ。必要に応じて変更してください。私はそれがアイデアを説明することを望みます:
UPDATE roads t1
SET shorter_alternative = t2.id
FROM roads t2
WHERE
((t2.source = t1.source AND t2.target = t1.target) OR
(t2.source = t1.target AND t2.target = t1.source)) AND
(t2.length < t1.length)
これで、エッジ '0.098'にはエッジ '0.011'のIDが含まれます。他のすべてのエッジは、shorter_alternativeフィールドにnullを持ちます。shortest_pathクエリを実行した後、返されたデータセットを確認します。shorter_alternativeフィールドが設定されている行がある場合は、それを変更します。
問題はすでに前の回答で説明されています。これは、「頂点ベース」の最短パスアルゴリズムの問題であり、ソースとターゲットのみを考慮します。
課題トラッカーにチケットがあり、アルゴリズムの実装を変更するための可能な解決策があります:https : //github.com/pgRouting/pgrouting/issues/34 (誰かがこれを試してプルリクエストを送信できるといいですね;- )
別の可能性は、前述のように「並行道路リンク」を分割することです。または、両方の道路リンクを「認識する」ようにエッジからエッジにルーティングするShooting Starアルゴリズムを使用することもできます。
または、コストで道路ネットワークを注文し、ソースとターゲットの明確な組み合わせのみを選択することもできます。
SELECT * FROM shortest_path(
'SELECT DISTINCT ON (source, target)
gid as id,
source::integer,
target::integer,
cost::double precision
FROM ways ORDER BY source, target, cost',
true,false
);
これは、最も安価なルートを検索することを前提としています。それ以外の場合は、する必要がありORDER BY ... DESC
ます。
これがパフォーマンスに影響する場合は、試す必要があります。
私は実際に問題を修正するpgRoutingのパッチを作成しました:https : //github.com/pgRouting/pgrouting/issues/78