特定のノードを通過する最短経路


8

私は自分の問題の効率的な解決策を見つけようとしています。G100個のノード(各ノードに番号が付けられています)を含む正の重み付きグラフがあり、それが非循環グラフであると仮定しましょう。したがって、2、2、2、1などのエッジは存在できません。ノードのリストを取得しましたG。グラフから10としましょう。これらの各ノードも配列にあるとしましょう。そのリストから、ノード1から100までの、それらのノードの少なくとも特定の(5つとしましょう)を通過する最短パスの総重みを見つける方法を探しています。

簡略化するために、0 ... 5の6つのノードを持つグラフを考えます。ノード1と4は、通過するように指定できるポイントとしてマークされています。既存のパスが0-1-2-5、0-3-4-5、および1-4であるとしましょう。ここで、3から4を除くすべてのエッジが5として重み付けされているとします。3から4は1として重み付けされます。最短パスアルゴリズムを実行すると、基本的にパス0-3-4-5が検出されます。指定されたポイントの最小量を指定して、量2を試してください。その後、アルゴリズムは15として重み付けされた0-1-4-5で実行されます。

私はこのように書きました

    shortestPath(destinationNode, minAmount) 

        if(destinationNode == srcNode && minAmount < 1) 
            return 0

        else if(destinationNode == srcNode && minAmount > 1) 
            return INFINITY

        int destNo = destinationNode get number
        int cost = INFINITY
        for (int i = 0; i < destNo; i++)
            if (d[i][destNo] != null) 
                int minimumAmountCount = minAmount;
                for (int j = 0; j < marked.length(); j++) 
                    if (marked[j] == i) 
                        minimumAmountCount = minimumAmountCount - 1;

                cost = MIN(cost, shortestPath(Node(i), minimumAmountCount);

        return cost;

基本的に、宛先ノードとそのリストからのノードの最小数を使用して、このアルゴリズムを呼び出します。まず、これが再帰関数であり、停止ポイントが必要であることを確認します。これは、渡された宛先がソースノード(基本的にはノード#0)と等しい場合です。チェックする必要がある2番目のケースは、十分な量を訪問したかどうかです。したがって、1(0または負の数)未満の場合、十分なポイントを訪問し、ノード#0からノード#0までの距離が0になるため0を返します。十分な量を訪問しなかった場合は、無限大を返すため、アルゴリズムは他のパスを考慮します。

したがって、戻り部分が機能するためには、宛先ノードの番号を定義する必要があります(100のノードがあると考えると、最初の開始ではノード#99になります)、コストを無限大として初期化する必要があります。

次に、0(基本的にノード#0)から始まり、現在のノード番号までforループを実行します。これは、グラフに後方エッジがないためです。ノード番号を使用して、これらのノードに既存の重みがあるかどうかをマトリックスから確認します。存在する場合は、現在の最小量の変数を初期化し、ループを実行して、現在の宛先へのソースがマークされたノードのリストにあるかどうかを確認します。マークされている場合は、最小量を減らすだけです。

最後のステップでは、宛先を現在のソースとして、現在の最小量で変更して、関数を再度実行します。

しかし、ネストされたループの最悪の場合の複雑さはO(| Node | ^ 2)になり、完全な繰り返しはO(| Node | ^ 2 * | Edges |)になるという事実を考えると、非常に高価に見えます。それで、この問題の他の効率的な解決策はありますか?


アルゴリズムを言葉で説明できますか?
Yuval Filmus 2013年

@YuvalFilmus今やった
Sarp Kaya 2013

回答:


2

12の特別なノードのすべてのペア(ノード1、100、および特定のノードの10のすべて)間の最短経路を計算し、これらをこれら12のノードのみで構成される新しいグラフのエッジ長として使用します。これで、12個のノードを含むグラフがあり、少なくとも5つの他のノードを使用する1から100までの最短パスを見つけたいと考えています。これで、このグラフでアルゴリズム(これは単なる動的プログラミングだと思います)を使用できます。新しいグラフのソリューションは、元のグラフのソリューションを提供します。これは、新しいグラフのソリューションのエッジを、最初のステップで計算した最短パスで置き換えることによって見つけることができます。

たとえば、新しいグラフには4つのノードがあります。新しいグラフのエッジの長さは、0-1:5、0-4:6、0-5:11、1-4:5、1-5:10、4-5:5です。これらはノード間の最短経路に対応しますi そして j元のグラフ。リストの1つのノードを含む最短パスは0-4-5で、長さは11です。このパスの各エッジを最初のステップで計算されたパスに置き換えると、元のパスの0-3-4-5が得られます。グラフ。


いいえ、少なくとも5つの他のノードはありません。と仮定するN すべてのノードです LN ここで、Lはノードのリストであり、 |P|<=|L|ここで| P | グラフを作成する必要がある最小点の量です。Pの内容は、L要素の最小量(| P |)を使用するため、Lから取得されます。したがって、10のリストから少なくとも5つのノードです
Sarp Kaya

質問に例を追加しましたので、それを確認してください。
Sarp Kaya 2013

ただし、新しいグラフでは、開始ノードと終了ノードのほかに、10個のノードしかありませ
Peter Shor 2013年

1
私は、言って起動し、その後、元のグラフを構築する新しいグラフを。その後、新しいグラフ上で変更の問題を解決する転送元のグラフに液バックを。新しいグラフには12個のノードしか含まれていません。新しいグラフの距離は、元のグラフで選択したこれらのノード間の最短経路に対応しています。
Peter Shor 2013年

2
私はするつもりはありません。他の誰かが私の解決策を取り、疑似コードでそれを説明する別の答えを書きたい場合、彼らは先に進んで自由に感じるべきです。
Peter Shor 2013年

0

100個のノードしかなく、アークが指定されているか、計算が容易であれば、心配する必要はありません。

そうでない場合:グラフはおそらく非常に疎です(アークのないノードよりもアークのあるノードのペアの多く)。したがって、リンクされたリストまたは他のデータ構造を使用して、非アークをスキップする必要なく、アークのみを反復できるようにします。そのようなデータ構造の名前は言語に依存します。PerlのハッシュやPHPの連想配列など、さまざまなタイプのJavaまたはC#リストまたは辞書の品質。

それらを使用して、ノードからフォワードアーク(つまり、コストと宛先ノードのペア)へのマッピングと、ノードからバックワードアークへのマッピングを構築します。

各ノードから各中間ノードまで、および各中間ノードから各ノードまでのノード間距離を保持するためにさらに2つ割り当て、標準アルゴリズム(フロイド、ダイクストラとも呼ばれる、または誤って、ウォーシャルのもの)。

最終的なノード間の距離を保持するためにもう1つ割り当て、次のように計算します

d(x,y)=minzI(d(x,z)+d(z,y))
中間ノード用 I

100個のノードはありません。例の番号を付けたいだけです。疑似コードまたはjava / C ++言語を使用して文章を説明していただけますか?
Sarp Kaya 2013

私は怠惰です。ごめんなさい。
reinierpost 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.