事例演習2 最短経路探索 < 課題 >

【 課題1 】
以下のプログラムは,図2-22で示した手順をC言語で記述したものである. ソースコード中の「次にトークンを進めるべきノードの決定」部分の手続きを,NSチャートを用いてプログラム論理設計せよ.同時にC言語を用いてプログラミングせよ.

● モジュール#2 pathSearch (最短経路探索)のC言語ソースコード


 void pathSearch(  int        nNode         //  ノードの数
		,int        startPoint    //  出発ノードの番号 
		,int        endPoint      //  到着ノードの番号
		,Node_type  Node[ ]       //  ノードの接続情報テーブル
		,Link_type  Link[ ]       //  リンクの情報(接続先ノード,距離)テーブル
		,float&     minDist       //  出発ノードから到着ノードまでの最短距離 
		,int  &     nRoute        //  出発ノードから到着ノードまでの経由ノード数 
		,int        routeNode[ ]  //  出発ノードから到着ノードまでのルートノード
                )
{
#define NIL      0
#define UNCHECK  0
#define CHECKED  1
#define INFINITE  999.99
int    p, i, i1, i2 ,node_q;
float  minValue ,dist_q;
int    check_tbl[MAX_NODE+1]   // 通過フラッグが立っているか否かを示すチェック表
      ,route    [MAX_NODE+1];  // 経由した1つ前のノード番号を格納しておく表
float  totalDist[MAX_NODE+1];  // ノードまでの経由距離合計を格納しておく表
//---- 初期値の設定 -----
for (i=1; i <= nNode; i++)
{   
     totalDist [i] = INFINITE;
     check_tbl [i] = UNCHECK;
};

totalDist[startPoint] = 0.0;
route    [startPoint] = NIL;
p  = startPoint;  //-----  開始ノードの設定 -----以後 pは着目しているノードを示す

   while( p != endPoint)   
{  
   /* 【 ノードに到着した各トークンの経過時間比較 】 */
      check_tbl[p] = CHECKED;          // トークンを出発させるノードに通過フラッグを立てる
      i1 = Node[p].link_position;      // Link表におけるノードpのデータの格納開始位置
      i2 = i1 + Node[p].link_size - 1; // Link表におけるノードpのデータの終り位置
    
        for (i = i1; i <= i2; i++)  //  p にリンクされているすべてのノードをチェック
        {
           node_q  = Link[i].connect_node;   // p のリンク先の1つをnode_qとする
           if (check_tbl[node_q] == UNCHECK) // 通過フラッグが立っていないノード?
           {
	        dist_q = Link[i].dist;
                 if(totalDist[p] + dist_q < totalDist[node_q]) 
                 {    
                   /* 【 pを経由したルートの方が,経由距離合計が短いので 
                           p経由に変更する 】  */
		    totalDist[node_q] = totalDist[p] + dist_q;
		    check_tbl[node_q] = UNCHECK;
		    route[node_q]     = p;           // node_q は p を経由する
	         }
	   }
        }
   	/*  【 次にトークンを進めるべきノードの決定 】
             -----  ネットワークのチェックされていないノードの中からそれまでの経路長が
                    最も短いノード p を選び出す.選び出されたpは、次の探索操作で
                    着目するノードになる                                        ---- */


【 課題1】として埋めるべき部分
        <ヒント> 経由合計距離は配列totalDist に格納されている


   } 
    minDist = totalDist[endPoint];
}

【 課題2 】
図2-23で示すような形式で,ノードの接続関係と距離が2次元配列"リンクデータ"に格納されているものから,図2-20(以下に再掲)で示したデータ形式に変換するネットワークデータ表の作成モジュール"nodeBuild"の手順を設計し,C言語でプログラムせよ.

【 課題3 】
最短経路が求まったとして,経由距離合計配列totalDist,経由ノード表route,始点ノードstratNode,終点ノードend_Nodeを入力して,最短の経由距離合計,および始点のノードから終点ノードに向けて経由ノードを表示するモジュール"printRoute"を設計しプログラムせよ.なお,経由するノードの羅列は一旦1次元配列routeNodeに格納してから表示するものとする.

【 課題4 】
次のような関数が与えられているとして,リンク時間の修正ダイアログボック ス2(DialogBox2)のハンドラ関数(DialogModifyLinkProc)の中身をプログラム せよ.ただし,プログラムで用いる大域変数は以下の通りとする.

【 課題5 】
課題4で作成したイベントハンドラ関数を用いて,コントロールキーを押下しなが ら, まず修正すべきリンクの始端ノード・オブジェクトを画面上で選んで左ボタンでクリックし,次に終端ノード・オブジェクトを選んで右マウスボタンをクリックしたとき, DialogBox2を表示するイベントハンドラ関 数GL_RBUTTONDOWN( hInst, hWnd , lParam )の中身をプログラムせよ.ただし,プログラムで用いる大域変数は以下の通りとする.


戻る