[fpr 1019] AHPのプログラム

岡本安晴

岡本@金沢大学です。

  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


スレッド表示 著者別表示 日付順表示 トップページ

ここは心理学研究の基礎メーリングリストに投稿された過去の記事を掲載しているページです。