Perlでページランクを取得する方法
- 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で取得する方法、宜しくお願い致します。
- syukoukyoku
- お礼率0% (0/21)
- Perl
- 回答数5
- ありがとう数12
- みんなの回答 (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)
なんかもったいないことをしてる気がする>#3. approx とか all とか駆使すればいいような.
- _--_1l1_1_
- ベストアンサー率67% (102/152)
表示がくずれるので、空白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)
えぇと.... あなたは 2つの列ベクトルが同じかどうか判断することができますか?
- _--_1l1_1_
- ベストアンサー率67% (102/152)
課題なのか何なのかよくわかりませんが、 ここで聞いてバレたら面倒なことになるとは想像できないんですか?
補足
課題ではありません。 mat1×mat2を実行し、その答え(当然7行1列)にさらにmat1をかけ、その掛けた答えにさらにmat1を掛けるという動作を繰り返していくと、いずれその答えがほとんど変わらなくなります。その部分で、whileなりfor文から抜け出してその変わらなくなった答え(当然7行1列)を出力したいのです。 そのプログラムを教えて頂ければ幸いです。 PDLをダウンロードしました。
関連するQ&A
- 行列の方程式におけるランクの求め方
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 ファイルハンドルを閉じずに反映させる
お世話になっております。 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
補足
mat1×mat2を実行し、その答え(当然7行1列)にさらにmat1をかけ、その掛けた答えにさらにmat1を掛けるという動作を繰り返していくと、いずれその答えがほとんど変わらなくなります。その部分で、whileなりfor文から抜け出してその変わらなくなった答え(当然7行1列)を出力したいのです。 そのプログラムを教えて頂けたら幸いです。