岡本@金沢大学です。
AHPのBASICプログラムが「ゲーム感覚意思決定法:AHP入門」
(刀根 薫、1986)に載っています。
このBASICプログラムに出来るだけ忠実にDelphi3で書き直してみました。
DelphiはWindowsでのプログラミング環境の1つとして高い評価を受けて
いますが、BASICでプログラミングをしてこられた方の参考にして頂ければ
と思います。
BASICをDelphiで書き直すときは、gotoの飛び先はLabelでラベルとして、
宣言しておく、プログラム中の変数は宣言部で予め宣言しておく、などの
変更が必要ですが、以下の2例に見られるように、おおまかには、ほぼ
そのままの形で書き直すことができます。刀根(1986)のBASICプログラムと
比べて下さい。
データ部はテキストファイルとして別に用意するか、定数として宣言部に
移すかします。
1番目の例は、定数として宣言部に移したものです。
======================= 切 り 取 り 線 =======================
{-----------------------------------------------------
Power Method for AHP
刀根 薫(1986)
「ゲーム感覚意思決定法:AHP入門」
のBASICプログラムの
Delphi版
------------------------------------------------------}
{$AppType Console}
Program AHPConst;
uses Printers,SysUtils;
Label 350, 470, 500, 580;
const rc : array[1..12] of extended // p.38
= ( 0.0, 0.0 , 0.58, 0.9, 1.12, 1.24,
1.32, 1.41, 1.45, 1.49, 1.51, 1.53);
const n = 7;
var a : array[1..n, 1..n] of extended
= ((0, 3, 9, 7, 7, 5, 6),
(0, 0, 7, 5, 5, 2, 3),
(0, 0, 0,-3,-3,-7,-6),
(0, 0, 0, 0, 2,-3,-3),
(0, 0, 0, 0, 0,-3,-3),
(0, 0, 0, 0, 0, 0, 2),
(0, 0, 0, 0, 0, 0, 0));
w, ww : array[1..n] of extended;
f : textfile;
iter : Longint = 0;
i, j : Longint;
s, v, rmax1, rmax2, ci, cr : extended;
begin
AssignPrn(f); rewrite(f); // プリンタへの出力の準備
if n > 12 then
begin writeln(f,'項目数が多すぎる'); CloseFile(f); Halt; end;
for i:=1 to n-1 do for j:=i+1 to n do begin
if a[i,j] < 0 then a[i,j]:=-1/a[i,j];
a[j,i]:=1/a[i,j];
end;
for i:=1 to n do a[i,i]:=1.0;
// Initial Value
for i:=1 to n do begin
s:=1; for j:=1 to n do s:=s*a[i,j];
w[i]:=exp((1/n)*Ln(s));
end;
s:=0; for i:=1 to n do s:=s+w[i];
for i:=1 to n do w[i]:=w[i]/s;
// Power Method
350:iter:=iter+1;
for i:=1 to n do begin
v:=0; for j:=1 to n do v:=v+a[i,j]*w[j];
ww[i]:=v;
end;
s:=0; for i:=1 to n do s:=s+ww[i];
rmax2:=s; for i:=1 to n do ww[i]:=ww[i]/s;
if iter = 1 then goto 470;
if abs(rmax2-rmax1) > rmax1/1000 then goto 470;
for i:=1 to n do
if abs(w[i]-ww[i]) > w[i]/1000 then goto 470;
goto 500;
470:rmax1:=rmax2;
w:=ww;
goto 350;
500:// Print
writeln(f);writeln(f,'LAMBDA = ',FloatToStrF(rmax2,ffGeneral,9,4));
writeln(f);
for i:=1 to n do
writeln(f,'w(',i,') = ',FloatToStrF(w[i],ffGeneral,9,4));
writeln(f);
if n < 3 then begin ci:=0; cr:=0; goto 580; end;
ci:=(rmax2-n)/(n-1); cr:=ci/rc[n];
580:writeln(f,'C.I. = ',FloatToStrF(ci,ffGeneral,9,4));
writeln(f,'C.R. = ',FloatToStrF(cr,ffGeneral,9,4));
CloseFile(f);
end.
======================= 切 り 取 り 線 =======================
2番目の例は、データ部をテキストファイルとして独立させた場合のもので
す。
======================= 切 り 取 り 線 =======================
{-----------------------------------------------------
Power Method for AHP
刀根 薫(1986)
「ゲーム感覚意思決定法:AHP入門」
のBASICプログラムの
Delphi版
------------------------------------------------------}
{$AppType Console}
Program AHPFile;
uses Printers,SysUtils;
Label 350, 470, 500, 580;
const rc : array[1..12] of extended // p.38
= ( 0.0, 0.0 , 0.58, 0.9, 1.12, 1.24,
1.32, 1.41, 1.45, 1.49, 1.51, 1.53);
var n : Longint;
a : array[1..12, 1..12] of extended;
w, ww : array[1..12] of extended;
f, fi : textfile;
nm : string;
iter : Longint = 0;
i, j : Longint;
s, v, rmax1, rmax2, ci, cr : extended;
begin
write('Data File = '); readln(nm);
AssignFile(fi,nm); reset(fi);
AssignPrn(f); rewrite(f); // プリンタへの出力の準備
readln(fi, n);
if n > 12 then
begin writeln(f,'項目数が多すぎる'); CloseFile(f); Halt; end;
for i:=1 to n-1 do begin for j:=i+1 to n do begin read(fi, a[i,j]);
if a[i,j] < 0 then a[i,j]:=-1/a[i,j];
a[j,i]:=1/a[i,j]; end; readln(fi);
end; CloseFile(fi);
for i:=1 to n do a[i,i]:=1.0;
// Initial Value
for i:=1 to n do begin
s:=1; for j:=1 to n do s:=s*a[i,j];
w[i]:=exp((1/n)*Ln(s));
end;
s:=0; for i:=1 to n do s:=s+w[i];
for i:=1 to n do w[i]:=w[i]/s;
// Power Method
350:iter:=iter+1;
for i:=1 to n do begin
v:=0; for j:=1 to n do v:=v+a[i,j]*w[j];
ww[i]:=v;
end;
s:=0; for i:=1 to n do s:=s+ww[i];
rmax2:=s; for i:=1 to n do ww[i]:=ww[i]/s;
if iter = 1 then goto 470;
if abs(rmax2-rmax1) > rmax1/1000 then goto 470;
for i:=1 to n do
if abs(w[i]-ww[i]) > w[i]/1000 then goto 470;
goto 500;
470:rmax1:=rmax2;
w:=ww;
goto 350;
500:// Print
writeln(f);writeln(f,'LAMBDA = ',rmax2:9:5);
writeln(f);
for i:=1 to n do
writeln(f,'w(',i,') = ',w[i]:9:5);
writeln(f);
if n < 3 then begin ci:=0; cr:=0; goto 580; end;
ci:=(rmax2-n)/(n-1); cr:=ci/rc[n];
580:writeln(f,'C.I. = ',ci:9:5);
writeln(f,'C.R. = ',cr:9:5);
CloseFile(f);
end.
======================= 切 り 取 り 線 =======================
上のプログラムを実行すると
Data File =
と聞いてきますので、下のデータファイルの名前を設定してリターンキー
を押して下さい。
======================= 切 り 取 り 線 =======================
7
3 9 7 7 5 6
7 5 5 2 3
-3 -3 -7 -6
2 -3 -3
-3 -3
2
======================= 切 り 取 り 線 =======================
上の2つのプログラムについては、
刀根 薫(1986)「ゲーム感覚意思決定法:AHP入門」の解説(Pp.210-213)
を参照して下さい。
岡本安晴
c00279 (at) simail.ne.jp
ここは心理学研究の基礎メーリングリストに投稿された過去の記事を掲載しているページです。