スケジュール管理手法PERT-Time 解 説 “最早開始時間計算のアルゴリズム” 【 最早開始時間計算アルゴリズムはどこに役立つか 】 ① 多数の仕事を多くの人が協力して行うとき,遅くても いつまで仕事が終わるか事前に計算するアルゴリズム. 「スケジュール管理」の標準アルゴリズムとして有名. (実用上は,最も重点的に管理すべきクリティカルパスや作業工程が どの程度余裕があるかの日数計算等の計算も含む) ② 最短経路探索と同様に,情報処理技術者試験にもよく 出題される代表的なアルゴリズム (とゆうことは ソフトウェア開発技術者が知っておくべき基本的な アルゴリズム). 【問題】 グループを組んで,以下のような作業項目と作業日数を もつプログラムを開発するとしたとき,このプログラムは最も早く て何日後に完成するか? (注)“データベーススキーマ設計”と“CGIプ ログラムの調査”が終わらないと次の作業 “CGIプログラムの設計”は開始できない. CGIプログラムの設計 12日 4 6 データベースのスキーマ設計 プログラム機能の決定 1 5日 5日 9日 CGIプログラム作成&テスト 8日 DBアクセス 7日 2 プログラム作成 7 総合テスト 4日 CGIプログラムの調査 3日 3 10日 画面設計 HTML調査と デザイン 《 5 6日 ホームページ作成 C/S型プログラム開発作業を例としたアローダイアグラム 》 8 1 基本的な考え方は,すべて最短経路探索と同じ. トークンを同じ速さで移動させる. 4 6 5日 9日 8日 5日 1 12日 7日 2 7 3 3日 10日 5 6日 4日 8 2 トークンの移動結果を各ノードに記録して置く 14 -∞ 22 22 ノード4に入ってくる入力アーク数 -∞ 5 11 1 1 5日 4 経由時間合計 -∞ 21 12日 1つ前の経由ノード ノードに入ってくる 入力アークの数 (あらかじめ計算) 6 -∞ 21 5日 9日 8日 7日 2 7 3日 3 8 -∞ 221 1 10日 6日 5 -∞ 1 -∞ 23 4日 8 3 トークンがノードに到着したとき ① すべてのトークンが到着してるかを見て,到着していなければ待つ(=トークンを 出発させ,次の仕事を始めるためには,前の仕事がすべて終わらなければならな いことを意味している). ノードにトークンが到達したら,“入力アーク数” 14 (=未到着のトークン数を示すデータを兼ねて いる)を一つ減らす. すでにトークンが 出発したノードでは “入力アーク数”は 0以外の数(例えば -1)にしておく. 2 1 22 4 5 1 経由時間合計 -∞ 12日 6 2 1 1つ前の経由ノード ノードに入ってくる 入力アークの数 5日 9日 8日 -1 1 7日 2 5日 7 3日 10日 3 8 2 20 1 5 6日 -∞ 21 -∞ 23 4日 -∞ 21 8 ② ノードに記録されている経由時間合計とトークンが経由してきた時間合計を比較する もしトークンが経由してきた時間合計の方が長ければ ・ノードの経由時間合計を長い方に書き換える ・1つ前の経由ノードをトークンが経由してきたノードに書き換える 経由時間合計の長い方の時間が経たな 15 14 ければ,次の仕事は開始できないので, 最も長い経由時間合計(=その時間にな れば,次の仕事が開始できる最早の時 間) -∞ 6 21 32 20 4 経由時間合計 12日 1つ前の経由ノード ノードに入ってくる 入力アークの数 をノードに記録する.同時に1つ前の経由 ノードを記録する 5日 9日 8日 5日 1 7日 2 5 1 ‐1 7 3日 10日 3 5 6日 8 18 2 3 2‐1 20 -∞ 23 4日 -∞ 21 8 4 トークンがノードから出発するとき ③ 経由時間合計が一番短いノードからトークンを出発させる. なぜなら,計算の都合上,一気にトークンが次のノードに移動したのであって,一番 短い経由時間合計の時間には,他のトークンは実際にはアーク上にあり,出発でき ない. 15 出発させるノードを探すには,入力 ノード数がゼロ(=すべてのトークン が到着)のノードだけ探せばいい. (※入力ノード数が-1のノードは, すでにトークンが出発したノードを 示しているので対象外) 9日 1 5日 -∞ 6 21 3 4 20 経由時間合計 12日 1つ前の経由ノード ノードに入ってくる 入力アーク数 5日 8日 7日 2 7 5 1 -1 3日 3 10日 8 5 6日 18 2 3 2-1 20 -∞ 23 4日 -∞ 21 8 アルゴリズムをプログラムにするときの考え方 アークで接続している先のノード番 号と作業時間は,link表がもって いる. 例えば,ノード2から接続し ているノードと時間は・・ link[i].connectNode link[i].time 15 History[ 4 ].totalTime 3 History[ 4 ].previousNode 20 History[ 4 ].inputArcCount 4 (詳しくはデータ構造で説明) 9日 対応 int q ; // トークンを送るノード番号 5日 1 7日 2 5 3日 1 ‐1 q = 4; // ノード4にトークンを送る 3 8 2 2‐1 int p ; // 着目しているノード番号 p = 3; // ノード3に着目する 《 最早開始時間計算のアルゴリズム 》 経由経路表(route)の初期値として0,最長経由時間合計表(totalTime) の初期値として -∞をそれぞれ設定する p に 始点ノード番号をセットする // トークンをpに置く pが終点ノードに一致するまで繰返す // トークンがpに到着するまで繰り返す pにリンクしているすべてのノードについて繰返す // 繰返しトークンを移動する qをリンク先のノードの番号とする; ノードqまでの時間をtime_q とする; トークンの到着 Yes ①ノードqにまだトークンが未到着のアークがあるか(“入力アーク数”>0) No /* Yes // トークンの1つの移動先をqとする ②ノードqに到着したトークンの数と経過距離の比較 */ ノードpまでの経由時間 + time_q > ノードqの経由時間 No /* ノードpを経由したルートの方が,経由時間合計が短いので ノードp経由に変更する */ ノードqの“経由時間合計”をノードpの“経由時間合計”+ time_q にする ノードqの“1つ前の経由ノード”をpにする ノードqの“入力アーク数”を一つ減らす //qの未到達のアーク数を減らす すべてのトークンが出発したことを示すために“入力アーク数”を-1にする トークンの 出発 /* ③ 次にトークンを出発させるノードの決定 */ ネットーク全体から“入力するアーク数”が0で ,かつ経由時間の最も短い ノードを選び出し,次にトークンを進めるべきノードをpとする 【参考】最短経路探索のアルゴリズム 経由経路表(route)の初期値として0,最短経由距離表(totalDist) の初期値として ∞をそれぞれ設定する p に 始点ノード番号をセットする pが終点ノードに一致するまで繰返す // トークンをpに置く // トークンがpに到着するまで繰り返す pにリンクしているすべてのノードについて繰返す // 繰返しトークンを移動する トークンの到着 qをリンク先のノードの番号とする; ノードqまでの距離をdist_q とする Yes //トークンの1つの移動先をqとする ノードqの出発済みを示すフラッグが降りているか? /* ①ノードqに到着したトークンの経過距離比較 */ ノードpまでの経由距離 + dist_q < ノードqの経由距離 Yes /* ノードpを経由したルートの方が,経由距離合計が短いので ノードp経由に変更する */ ノードqの“経由距離”をノードpまでの“経由距離 ”+dist_qにする; ノードqの“1つ前の経由ノード”をpにする; ノードqのフラッグを下げる No No トークンが出発済みであることを示すために,ノードpのフラッグを上げる トークンの 出発 /* ② 次にトークンを出発させるノードの決定 */ ネットーク全体からフラッグが立っていなくて,かつ経由距離の最も短い ノードを選び出し,次にトークンを進めるべきノードをpとする 《 ネットワークを表すデータ構造 》 Node[ 1 ] 1 1 3 2 2 ノード2に接続す るリンク(=アー ク)データの位置 (linkPosition) ノード1に接続す るリンク(=アー ク)データの位置 (linkPosition) Link[] 1 2 5 2 2 4 2 4 9 time 5 4 6 7 12日 6 5日 8日 7日 2 3日 ノード4に接続する リンク数(linkSize) 4 7 5 10 6 12 7 5 9日 1 2 ノード4に接続す るリンク(=アー ク)データの位置 (linkPosition) 4 connectNode 5日 6 ノード3に接続す るリンク(=アー ク)データの位置 (linkPosition) 3 3 3 4 3 10日 7 5 6 日 4日 8 8 アルゴリズムの設計と並んで データ構造をいかに設計するかが,計算効率のよさを決める データ構造設計の重要性
© Copyright 2024 ExpyDoc