最短経路問題ダイナミック企画
問題の参考:
http://iprai.hust.edu.cn/icl2002/algorithm/algorithm/technique/dynamic_programming/introduction.httm葃example 1
地図があります。各結点は都市を表しています。二つの結点間の路線は道路を表しています。オンラインの数字は都市間の距離を表しています。図1に示すように、結点Aから結点Eまでの最短距離を探してみます。
深度優先検索法でこの問題を解決できます。再帰式は次の通りです。
ここではvに隣接するノードの集合であり、w(v,u)はvからuまでの辺の長さを示す。
このプログラムの効率はどうですか?訪問した都市以外の都市は毎回訪問するので、時間の複雑さはO(n!)であり、これは「指数級」のアルゴリズムであることが分かります。
まず、このアルゴリズムを観察します。B 1からEまでの最短距離を求める場合、まずC 2からEまでの最短距離を求める。B 2からEまでの最短距離を求めて、C 2からEまでの最短距離を求めました。つまり、C 2からEまでの最短距離を二回求めました。C 1、C 2からEまでの最短距離を求める過程で、D 1からEまでの最短距離も2回求められていることが分かります。全体のプログラムの中で、D 1からEまでの最短距離は4回求められました。解を求める過程において、同時に求められる最短距離が「記録されている」場合は、随時呼び出して、このような状況を回避することができる。そこで、このアルゴリズムを改善して、毎回求めたvからEまでの最短距離を記録して、アルゴリズムの中で再帰的にMinDistance(v)を求めた時に、以前にMinDistance(v)が求められたかどうかを先にチェックして、もし求めたらもう一度求めなくてもいいです。以前の記録を検索すればいいです。このように、すべての点はn個あるので、異なる状態数はn個あり、このアルゴリズムの数はO(n)である。
さらに、この再帰的な呼び出しのオーバヘッドを低減することができるように、この再帰的な再帰的なプッシュに変更することができる。
コードは以下の通りです
(例は「アルゴリズム設計と分析」(夏紅霞編集長)教材147ページの例題から来ています。
12 0 9 7 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
出力ファイル:
0-0-0-0-0-0-0-0-0-0 0-0 0 0-0 0 0-0 0 0-0 0 0-0 0-0 0 0-0 0-0 0-0 0-0 0 0-0-0 0-0 0 0-0 0 0-0 0 0 0 0-0 0 0-0 0 0-0 0-0-0 0 0 0-0 0 0 0-0-0-0 0-0 0 0 0 0 0-0 0 0 0 0-0 0 0 0-0 0 0 0 0-0-0 0 0 0 0 0 0-0 0 0 0 0-0 0 0-0 0 0-0-0 0 0 0-0 0-0-0-0-0-0-0-0-0-0 0 0 0 0 0 0 0-0-0-0-0-0-0 0-0-0-0-最短経路:16 1-->2-->7-->10-->12-->Pressany key to continue
http://iprai.hust.edu.cn/icl2002/algorithm/algorithm/technique/dynamic_programming/introduction.httm葃example 1
地図があります。各結点は都市を表しています。二つの結点間の路線は道路を表しています。オンラインの数字は都市間の距離を表しています。図1に示すように、結点Aから結点Eまでの最短距離を探してみます。
深度優先検索法でこの問題を解決できます。再帰式は次の通りです。
ここではvに隣接するノードの集合であり、w(v,u)はvからuまでの辺の長さを示す。
このプログラムの効率はどうですか?訪問した都市以外の都市は毎回訪問するので、時間の複雑さはO(n!)であり、これは「指数級」のアルゴリズムであることが分かります。
まず、このアルゴリズムを観察します。B 1からEまでの最短距離を求める場合、まずC 2からEまでの最短距離を求める。B 2からEまでの最短距離を求めて、C 2からEまでの最短距離を求めました。つまり、C 2からEまでの最短距離を二回求めました。C 1、C 2からEまでの最短距離を求める過程で、D 1からEまでの最短距離も2回求められていることが分かります。全体のプログラムの中で、D 1からEまでの最短距離は4回求められました。解を求める過程において、同時に求められる最短距離が「記録されている」場合は、随時呼び出して、このような状況を回避することができる。そこで、このアルゴリズムを改善して、毎回求めたvからEまでの最短距離を記録して、アルゴリズムの中で再帰的にMinDistance(v)を求めた時に、以前にMinDistance(v)が求められたかどうかを先にチェックして、もし求めたらもう一度求めなくてもいいです。以前の記録を検索すればいいです。このように、すべての点はn個あるので、異なる状態数はn個あり、このアルゴリズムの数はO(n)である。
さらに、この再帰的な呼び出しのオーバヘッドを低減することができるように、この再帰的な再帰的なプッシュに変更することができる。
コードは以下の通りです
#include <iostream>
#include <fstream>
using namespace std;
ifstream fin("in.txt");
#define maxLength 20
int matrix[maxLength][maxLength]; //
int minPath[maxLength]; //
int trace[maxLength]; //
int v_n; //
int MinDistance(int v)
{
if(minPath[v]>0) return minPath[v];
if(v==v_n-1) return 0; //
int min=1000,t,j;
for(int i=v+1;i<v_n;i++)
{
if(matrix[v][i]>0)
{
t = matrix[v][i]+MinDistance(i);
if(min>t){ min=t; j=i;}
}
}
minPath[v]=min;
trace[v]=j;
return minPath[v];
}
int main()
{
fin>>v_n;
for(int i=0;i<v_n;i++)
{
for(int j=0;j<v_n;j++)
{
fin>>matrix[i][j];
cout<<matrix[i][j]<<"-";
}
cout<<endl;
}
memset(minPath,0,sizeof(int)*maxLength);
memset(trace,0,sizeof(int)*maxLength);
int minD = MinDistance(0);
cout<<" :"<<minD<<endl;
i=0;
cout<<"1-->";
while(minD>0)
{
cout<<trace[i]+1<<"-->";
minD = minD-matrix[i][trace[i]];
i = trace[i];
}
cout<<endl;
return 0;
}
入力ファイル:in.txt (例は「アルゴリズム設計と分析」(夏紅霞編集長)教材147ページの例題から来ています。
12 0 9 7 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
出力ファイル:
0-0-0-0-0-0-0-0-0-0 0-0 0 0-0 0 0-0 0 0-0 0 0-0 0-0 0 0-0 0-0 0-0 0-0 0 0-0-0 0-0 0 0-0 0 0-0 0 0 0 0-0 0 0-0 0 0-0 0-0-0 0 0 0-0 0 0 0-0-0-0 0-0 0 0 0 0 0-0 0 0 0 0-0 0 0 0-0 0 0 0 0-0-0 0 0 0 0 0 0-0 0 0 0 0-0 0 0-0 0 0-0-0 0 0 0-0 0-0-0-0-0-0-0-0-0-0 0 0 0 0 0 0 0-0-0-0-0-0-0 0-0-0-0-最短経路:16 1-->2-->7-->10-->12-->Pressany key to continue