2011|08|
2013|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|05|06|07|08|09|10|11|12|
2016|01|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|

2018-03-07 ワーシャル-フロイド法(その3) vs ダイクストラ法 [長年日記]

/*
  gcc -g wf3.cpp -o fw3
 
  ワーシャル-フロイド法(その3)
 
  スタックオーバーフローが怖いのと処理が遅くなりそうなので、「再帰呼出し」を使わない方法
  (http://www.kobore.net/diary_techno/?date=20180306)
 
  参考:ゼオスTTのブログ
  http://zeosutt.hatenablog.com/entry/2015/05/05/045943
 
*/
 
#include <stdio.h>
 
int d[5][5];  // d[i][k]:ノードiからノードkへの距離 
int next[5][5];  // ノードi から ノードj への最短経路における i の1つ後のノード
 
int main(void)
{
 
  // 変数の初期化
  for(int i = 0; i < 5; i++){
	for(int j = 0; j < 5; j++){
	  d[i][j] = 99999999; // 距離の初期化(でっかい値を入力しておく(INT_MAXは足し算の時に桁上がりが起こるので使わない)
	  next[i][j] = j; // ノードi から ノードj への最短経路における i の1つ後のノード
	}
  }
 
 
  // 確認用の表示
  printf("\n[STEP1]\n");
 
  for(int i = 0; i < 5; i++){
	for(int k = 0; k < 5; k++){
	  printf("d[%d][%d]):%d\t",i,k,d[i][k]);
	  printf("next[%d][%d]):%d\n",i,k,next[i][k]);
	}
  }
 
  //// ここからは実際の距離を手書き
 
  for(int i = 0; i < 5; i++){
	d[i][i] = 0; //// 同じノードへの距離は0になるので、上書き
  }
 
  d[0][2] = 1;  // ノード0からノード2までの距離 1 を上書き
  d[2][0] = 1;  // その逆順(さぼってはダメ)
 
  d[0][1] = 2;  // ノード0からノード1までの距離 2 を上書き
  d[1][0] = 2;  // その逆順
 
  d[0][4] = 6;
  d[4][0] = 6;
  
  d[1][2] = 4;
  d[2][1] = 4;
  
  d[2][3] = 4;
  d[3][2] = 4;
 
  d[3][4] = 2;
  d[4][3] = 2;
  
  // 確認用の表示
  printf("\n[STEP2]\n");
 
  for(int i = 0; i < 5; i++){
	for(int k = 0; k < 5; k++){
	  printf("d[%d][%d]):%d\t",i,k,d[i][k]);
	  printf("next[%d][%d]):%d\n",i,k,next[i][k]);
	}
  }
 
  // 経路長計算
  for (int k =0; k < 5; k++){
	for (int i =0; i < 5; i++){
	  for(int j = 0; j < 5; j++){
		if(d[i][j] > d[i][k] + d[k][j]){
 
		  d[i][j] = d[i][k] + d[k][j];
		  next[i][j] = next[i][k]; //更新処理
		}
	  }
	}
  }
 
  // 計算結果
  printf("\n[STEP3]\n");
 
  for(int i = 0; i < 5; i++){
	for(int k = 0; k < 5; k++){
	  printf("d[%d][%d]):%d\t",i,k,d[i][k]);
	  printf("next[%d][%d]):%d\n",i,k,next[i][k]);
	}
  }
 
  // 経路パス表示
 
  printf("\n[Path]\n");
  for(int i = 0; i < 5; i++){
	for(int k = 0; k < 5; k++){
	  
	  int cur;
	  printf("d[%d][%d]: ",i,k);
	  
	  for (cur = i; cur != k; cur = next[cur][k]){
        printf("%d -> ", cur);
	  }
	  printf("%d\n", k);
	}
  }
}
syntax2html
■ダイクストラ法
開始時間:82[ms]
終了時間:33139[ms]
 
■ワーシャル-フロイド法(その3)
開始時間:84[ms]
終了時間:91[ms]
 
速度比率 4722.428571 倍