Perlでページランクを取得する方法

このQ&Aのポイント
  • Perlを使用してページランクを取得する方法について教えてください。
  • PDLモジュールを使用してリンク隣接行列を定義し、列ベクトルとの行列積を繰り返すことでページランクを計算します。
  • while文を使用して行列積の計算を繰り返し、答えが変わらなくなったところでループを抜ける処理を書く方法を教えてください。
回答を見る
  • ベストアンサー

Perlでページランクを取得する方法

プログラミングが得意な方お願いします。 下図のリンクのページランクをPerlで実装したいのですが、 まずPDLモジュールをダウンロードし、リンク隣接行列を下記のように定義しました。 use PDL::Lite; my $mat1 = pdl [ [0, 1, 1/2, 0, 1/4, 1/2, 0], [1/5, 0, 1/2, 1/3, 0, 0, 0], [1/5, 0, 0, 1/3, 1/4, 0, 0], [1/5, 0, 0, 0, 1/4, 0, 0], [1/5, 0, 0, 1/3, 0, 1/2, 1], [0, 0, 0, 0, 1/4, 0, 0], [1/5, 0, 0, 0, 0, 0, 0] ]; そして下記の列ベクトルと上記の行列をかけてその答えと上記の行列をかけてさらにその答えと上記の行列をかけて・・・を繰り返し、掛けても答えが変わらなくなったところでその列ベクトルの値を取り出し正規化して出力するという方法を考えました。 my $mat2 = pdl [ [1], [1], [1], [1], [1], [1], [1] ]; ここで質問ですが、上記の処理をwhile文で実行したいのですが掛けても答えが変わらなくなったところでwhileからループを抜ける処理はどのように書いたら良いのでしょうか? Perlは初心者で、行列同士の比較はwhileの条件文ではできないでしょうし、列ベクトルの要素を一つ一つ比較する方法も分かりません。 以上写真のページランクをperlで取得する方法、宜しくお願い致します。

  • Perl
  • 回答数5
  • ありがとう数12

質問者が選んだベストアンサー

  • ベストアンサー
回答No.5

use PDL::Ufunc; を追加し、次でループ脱出 if(all $ans_now == $ans_before){last;} ただし、$ans_nowは今回の演算結果, $ans_beforeは前回の演算結果 PDLのhelp allより: ======================= Module PDL::Ufunc all Return true if all elements in piddle set   ...(snip) =======================

その他の回答 (4)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

なんかもったいないことをしてる気がする>#3. approx とか all とか駆使すればいいような.

回答No.3

表示がくずれるので、空白2文字を全角空白にしていることに注意。 use feature 'say'; use PDL; my $matrix1 = pdl( [ [ 1, 2 ], [ 3, 4 ] ] ); print '--- matrix1', $matrix1; # --- matrix1 # [ # [1 2] # [3 4] # ] my $vector1 = pdl( [ [5], [6] ] ); print '--- vector1', $vector1; # --- vector1 # [ # [5] # [6] # ] my $answer = $matrix1 x $vector1; print '--- answer', $answer; # --- answer # [ # [17] # [39] # ] my $vector2 = pdl( [ [7], [8] ] ); print '--- vector2', $vector2; if ( compare_vector($vector1,$vector2) ) {   say '$vector1 == $vector2'; } else {   say '$vector1 != $vector2'; } # --- vector2 # [ # [7] # [8] # ] # $vector1 != $vector2 my $vector3 = pdl( [ [5], [6] ] ); print '--- vector3', $vector3; if ( compare_vector($vector1, $vector3) ) {   say '$vector1 == $vector3'; } else {   say '$vector1 != $vector3'; } # --- vector3 # [ # [5] # [6] # ] # $vector1 == $vector3 sub compare_vector {   my $v1 = shift;   my $v2 = shift;   if ($v1->getndims != $v2->getndims) {     return 0;   }   my $dims = $v1->getndims;   for (my $i = 0; $i < $dims; $i++) {     if ($v1->at(0, $i) != $v2->at(0, $i)) {       return 0;     }   }   return 1; }

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

えぇと.... あなたは 2つの列ベクトルが同じかどうか判断することができますか?

syukoukyoku
質問者

補足

mat1×mat2を実行し、その答え(当然7行1列)にさらにmat1をかけ、その掛けた答えにさらにmat1を掛けるという動作を繰り返していくと、いずれその答えがほとんど変わらなくなります。その部分で、whileなりfor文から抜け出してその変わらなくなった答え(当然7行1列)を出力したいのです。 そのプログラムを教えて頂けたら幸いです。

回答No.1

課題なのか何なのかよくわかりませんが、 ここで聞いてバレたら面倒なことになるとは想像できないんですか?

syukoukyoku
質問者

補足

課題ではありません。 mat1×mat2を実行し、その答え(当然7行1列)にさらにmat1をかけ、その掛けた答えにさらにmat1を掛けるという動作を繰り返していくと、いずれその答えがほとんど変わらなくなります。その部分で、whileなりfor文から抜け出してその変わらなくなった答え(当然7行1列)を出力したいのです。 そのプログラムを教えて頂ければ幸いです。 PDLをダウンロードしました。

関連するQ&A

  • 連立方程式、ランク

    1、(mxn)の行列, (m×1)のベクトルをそれぞれA,bとし、行列A のランクをrとする.このとき,連立方程式Ax=bの解はそれぞ れ(i)一意に求まる場合 ii)無数に存在する場合 iii)存在しない 場合が考えられる.それぞれはどのような場合に生じるかを記せ。 また,上記の方程式の解が存在しないときの最小自乗解は何か. 2.Xはmxnの行列でランク(階数)はrである.このとき,Xは  X=BCと表現できることを示せ、ただしBはmxrの列正則な  行列,Cはrxnの行正則な行列である.

  • 連立方程式、ランク

    1、(mxn)の行列, (m×1)のベクトルをそれぞれA,bとし、行列A のランクをrとする.このとき,連立方程式Ax=bの解はそれぞ れ(i)一意に求まる場合 ii)無数に存在する場合 iii)存在しない 場合が考えられる.それぞれはどのような場合に生じるかを記せ。 また,上記の方程式の解が存在しないときの最小自乗解は何か. 2.Xはmxnの行列でランク(階数)はrである.このとき,Xは  X=BCと表現できることを示せ、ただしBはmxrの列正則な  行列,Cはrxnの行正則な行列である. 解答を載せましたが、これで合っていますか?

  • 行列の方程式におけるランクの求め方

    A、b、xという行列があって(xは解ベクトル)、Ax=bとしたときに、rankAとrank (A|b)を同時に求めたいとします。そのとき、行列(A|b)に基本変形を施して いくわけですが、行基本変形だけでなく、列基本変形も使ってよいと先生がおっ しゃっていました。でも、列基本変形を用いると、(A|b)という形が崩れてしま うのではないでしょうか?

  • 線形代数 部分空間の基底を求める

    写真の3番の(ii)が分かりません。 W1とW2の基底から行列を作り、係数行列に行基本変形を行ったところ、ランクは1となりました。 W1に属するベクトルの1次結合= W2に属するベクトルの1次結合、となるようにするとW1∧W2の基底として、(1,i,-1,-i)tが得られました。 W1+W2の基底は、上記の係数行列はW1とW2の基底から成ることより、一次独立なベクトルの数あると思うのですが、そのランクは1のため1つとなってしまい答えと合いません…。 W1∧W2の基底を求める方法も含めて教えて頂けないでしょうか。 ∧は積集合、tは転置のことです。

  • 線形従属なベクトルの見つけ方

    700行700列くらいの正方行列がExcelにあります。 rankをmatlabで計算しますと670くらいとなります。 どこのベクトルが線形従属になっているか探したいのですが方法が思い浮かびません。 どなたかお助けください。お願いします。

  • perlのif文(条件の指定方法)につきまして

    おそらく単純な事だと思われますが、 不慣れなものでお付き合いいただけますとありがたいです。 if( $hoge == $testdata){ # 条件が一致した場合の処理 } $hoge には、2 が入っています。(文字列) $testdata には、2,6,10 が入っています。(文字列) 1対1であれば、上記の記述でいけるのですが、 カンマ区切りの復数の値と一致判定する方法がわかりません。 まず、配列にして my @testdata_hairetu = split(/,/, $testdata); などやってみましたが、 その後の条件文との絡みなどで詰まっています。 復数値がある場合に一つ一つ照合(判定)していく方法をご教授いただけないでしょうか。 foreachの内部でifとかかなと調べ中です。 perlは記述方法がいろいろあるようなのですが、できれば短さよりもわかり易い方が有難いです。 どうぞよろしくお願いします。

  • Perl ファイルハンドルを閉じずに反映させる

    お世話になっております。 Perl(プログラミング言語)について質問です。 openメソッドで開いたファイルハンドルに print文で書込みを行った際に、ファイルハンドルをcloseせずに、 書込みを反映させる方法はありますか? 開くのはファイルではなく(他プロセスへの)パイプです。 $| を設定してもだめでした (例としては perl1.pl , perl2.pl を用意する <perl1.pl> $i; open(OUT,"| perl2.pl") while(1){ print OUT "$i" $i++  } close(OUT) <perl2.pl> while( <STDIN> ) { print $_; } のようなことをやりたいです。 上記のようなスクリプトを実行したところ、 perl1のcloseが実行されるまで反映されません。 これをcloseをせずに反映させる方法はありますでしょうか? よろしくお願いします。

    • ベストアンサー
    • Perl
  • PerlでPostgreSQL呼出で結果が取得できない

    以下のような感じでPerlでPostgreSQLからデータを取得しようとしています。 テスト用の環境ではうまく動いていたのですが、いざ本番用環境に移行すると何故か結果が取得できません。 my $command = 'psql -h 255.255.255.255 -U username -c "select * from test" |'; open( IN, $command ) while( <IN> ) {   $result .= $_; } close( IN ); テスト環境ではデータが取得できていたので、プログラムの構文的には間違っていないと思うのですが、 PerlやPostgreSQL、サーバー等の環境設定について経験が浅い為、原因がさっぱり分かりません。 なお、2行目のopenには成功しているようですが、whileループ中には入っていないようです。 どのようにして原因の切り分けが出来るでしょうか? また、解決にはどのようにすれば良いでしょうか? ※補足要求をいただければ、比較的早く補足できると思いますので、  必要な情報があれば合わせてご指示ください。 ※原因の切り分けがちゃんと出来ていないため、カテゴリが違う可能性があります。  ご容赦ください。

    • ベストアンサー
    • Perl
  • 線形代数 一次独立について

    n個のあるn次元ベクトル(n行1列のベクトル)が一次独立であることを示すには、 例えば簡単のためにいまn=4としますけど、 その4つのベクトルを横に並べた新たな行列をAとし、 それを行基本変形をしてrank A = 4を示せば十分ですよね? 一応示し方は合ってるとは思うんですが確認しておきたいのでよろしくお願いします。それと、もしほかの方法があるのであれば、教えてください。

  • perlのdo-while文で抜け出せない 

    perlのwhile,do-while,last文に関する質問です。 1) code1のようなプログラムを作ったのですが   eでdo_whileを抜け出すことができませんがなぜでしょうか。 ---code1(eで抜け出せない)(NG)--- my $sum=0; do{  my $a=<STDIN>;  chomp($a);  $sum=$sum+$a; }while($a ne 'e'); print $sum; -------------------------------- 2) 抜け出す方法をいろいろ試していたら   while(1)にしてlastで抜けるようにすると   code2ではeで抜け出すことができるように   なりましたが、   do~while(1)にしたcode3では、  「Can't "last" outside a loop block at …」C   というエラーが発生します。   code2とcode3はwhileがdo~whileになって   条件を見る位置がループの始めか終わりの   違いだけなのに、なぜ、code2ではOKで、   code3ではエラーになるのでしょうか。 ---code2(eで抜け出せる)(OK)----- my $sum=0; while(1) {  my $a=<STDIN>;  chomp($a);  last if ($a eq 'e');  $sum=$sum+$a; }; print $sum; --------------------------------- ---code3(エラーになる)(NG)----- my $sum=0; do{  my $a=<STDIN>;  chomp($a);  last if ($a eq 'e');  $sum=$sum+$a; }while(1); print $sum; --------------------------------- よろしくお願いします。 Windows7 , ActivePerl(v5.16.3)

    • ベストアンサー
    • Perl

専門家に質問してみよう