web-dev-qa-db-ja.com

グラフ-頂点の重みを使用した最短経路

ここに物品税があります:

特定のグラフの問題では、頂点の重みがエッジの重みの代わりに、またはエッジの重みに追加される場合があります。 Cvを頂点vのコスト、C(x、y)をエッジ(x、y)のコストとします。この問題は、グラフGの頂点aとbの間の最も安いパスを見つけることに関係しています。パスのコストは、パス上で遭遇するエッジと頂点のコストの合計です。

(a)グラフの各エッジの重みがゼロであると仮定します(非エッジのコストは∞です)。すべての頂点1≤v≤nに対してCv = 1と仮定します(つまり、すべての頂点のコストが同じです)。 。 aからbへの最も安価なパスとその時間計算量を見つけるための効率的なアルゴリズムを提供します。

(b)ここで、頂点コストが一定ではなく(ただし、すべて正である)、エッジコストが上記のままであると仮定します。 aからbへの最も安価なパスとその時間計算量を見つけるための効率的なアルゴリズムを提供します。

(c)ここで、エッジと頂点の両方のコストが一定ではない(ただし、すべて正である)と仮定します。 aからbへの最も安価なパスとその時間計算量を見つけるための効率的なアルゴリズムを提供します。


これが私の答えです:

(a)通常のBFSを使用します。

(b)ダイクストラのアルゴリズムを使用しますが、重みを頂点の重みに置き換えます。

(c)

ダイクストラのアルゴリズムも使用する

エッジの重みのみを考慮する場合、ダイクストラのアルゴリズムの重要な部分については、次のようになります。

if (distance[y] > distance[v]+weight) {
    distance[y] = distance[v]+weight; // weight is between v and y
}

さて、頂点の重みについて考えると、次のようになります。

if (distance[y] > distance[v] + weight + vertexWeight[y]) {
   distance[y] = distance[v] + weight + vertexWeight[y]; // weight is between v and y
}

私は正しいですか?

(c)に対する私の答えは単純すぎると思いますよね?

19
Jackson Tale

あなたは正しい方向に進んでおり、解決策は非常に簡単です。

両方のB、Cで、問題を通常のダイクストラに減らします。これは、頂点に重みがないと仮定しています。
このためには、エッジの新しい重み関数である_w':E->R_を定義する必要があります。

_w'(u,v) = w(u,v) + vertex_weight(v)
_

(b)w(u,v) = 0(またはconst)で、ソリューションは(c)にも適合します!

その背後にある考え方は、エッジを使用することで、エッジの重みと、ターゲットの頂点に到達するためのコストがかかります。ソースのコストはすでに支払われているので、あなたはそれを無視します1

アルゴリズムを変更する代わりに、問題を減らすことは、通常、使用、証明、分析がはるかに簡単です!。


(1)このソリューションでは、ソースの重みを「見逃す」ため、sからtへの最短パスは次のようになります。dijkstra(s,t,w') + vertex_weight(s)_ [where dijkstra(s,t,w')は、_w'_を使用したsからtまでの距離です。

15
amit

頂点の重みは、2つの頂点a1とa2のすべての頂点aを、重みaのa1からa2までのエッジでスライスすることで削除できます。

あなたはダイクストラのアルゴリズムを採用するのに適していると思います。

4
Thomash