この論文について教えてください。
この論文のプログラムを実際に打ってやってみたのですが、イマイチ巧くいきません。result.txtに結果が出力されません。なぜでしょうか。また、結果はどのような形で出力されるべきなのでしょうか。教えてください。回答(5)
1.

デフォルトの状態で実行すると、ランダムに配置された30都市を回る計算をE,C,I,Rの4つの機械を使用して計算することになります。
私のノートパソコンのCPUでは、計算に時間がかかりすぎるようなので、とりあえず3都市でやってみたら、結果は出力されましたよ。
result.txt の中身は、こんな感じです。
# cat result.txt
Generations 0
Tour length 182.670761
Orevlap 1.000000
E-machine 0.000000
C-machine 0.000000
I-machine 0.000000
R-machine 0.000000
ホントは、横表示ですけど、そのままコピペすると見にくいので、縦に書き換えてます。
Generations が 0 なので、経路は出力されなかったようですというか、Overlapの値が基準値を超えたので、経路探索を中断したようです。
ちゃんと計算させるには、もうちっと解析しないとよくわかんないです。
この論文書いた人は、スパコンでも使ってるんでしょうか...(^^;
とりあえず、いまんとこはこんな感じです。
お出かけタイムリミットなので、後は、また気が向いたら...
2.

すまんす。(^^;
もう少し解析してみました。
このプログラムは、E,C,I,Rの各機械を、遺伝情報に多様性がなくなるか、遺伝情報をたくさんつくりすぎるかするまで動き続けるプログラムのようです。
通常では、「遺伝情報に多様性がなくなる≒最適化が十分に行われた」と判断してのことだと思います。
E,C,Iの各マシンは、初期パラメータだと、do~whileループを300回、回る間にてきとーに選ばれるようになっています。Rマシンは、300回に一回必ず呼ばれるようになっています。
pdfの文書に載っていたプログラムをそのまま動かすと、ランダムな30都市の場合、2393xxの経路を作成したところで、Overlapが0.9を超えたつまり、多様性が失われたので、最適化が終了したとみなしてプログラムが停止します。
実際、Tour Lengthも、初期値が、「1028.858887」だったのが、「320.029236」となり、最適化が十分行われているのがわかります。
というところで、またしても、お出かけリミットです。(^^;
続きは、また、気が向いたらということで...
3.

fclose()の上にprintf()文というのは、業界用語(なのかな?)では、いわゆるprintfデバッグというやつになります。
プログラムというのは、記述されているからといって、必ず実行されているとは限りません。論理的なミスなどにより、実行されているはずの行が実行されていないなどはよくあることです。
で、組み込みプログラミングなどで、ろくなデバッグ環境がないときに良く行われるのが、いわゆる「printfデバッグ」というやつです。
その行が実行されたかどうか、あるいは、変数値が期待した値に収まっているか、等を確認するために、printf文を使うデバッグ方法です。
今回の場合だと、ファイルが作成されているということは、runsimul()内のfopen()は、実行されていると考えて間違いありません。そして、fopen()の直後に、fprintf()文を使ってファイルの一行目を書いています。ということは、通常のルートをプログラムが通過しているなら、do~while文の直後のfclose()が実行されて、一行目が必ずファイルに残るハズです。で、#7,9の記述になるわけです。
#8の記述によるとファイルはできているようなので、fclose()によるファイルのクローズがされていないことが予想されます。で、printf文をfclose()の上に記述するというのは、fcolse()の前の行に、printf("fclose()\n")のように書いて、do~whileループを正しく抜けているかを確認する作業になります。
何らかのバグにより、do~while文を抜けられていない可能性が、現状の書き込みでは最も高いと思われます。
PS.
コメントにするには、文字数が多すぎるようなので、回答の方に書かせていただきました。
4.

ま、それは、それとして、先刻、15分ほど追いかけてみたら、いきなりバグ発見です。(^^;
あっ。ビルドは、すぐ通りました。gccでは、random()関連がないのと、どうもnotが予約語になっているような感じです。
で、バグですが...
Overlap1関数の中にi,jの変数を使った、三つのforを使った二重ループがあります。そのうちの三つ目で、内側forのループの評価の部分が、「i」になってますよ。そのせいで、「j」の値が、大きくなりすぎて、配列のサイズを超えてしまっているってのが、一つ目のエラーです。
それを直せばとりあえず計算はスタートしますが、最後までは行われずに、まだ違うランタイムエラーが発生します。
...え~っと、これ、コメントがまったく入ってないとこからして、pdfファイルからのコピペじゃなくて、ひょっとして、自分で見て打ち込んだんですか?
えらくしんどい方法を選びましたねぇ...
PS.
またしても、コメントの量を超えてしまったようなので、回答で書きました。
5.

少しだけ、手助けです。
result.txt の中の I-machine ... は、その機械を実行したときに、最適化が成功した場合にカウントされるようになっています。つまり、それぞれの機械がどれだけ、最適化に貢献したかが数値で示されていることになります。
runsimul の使い方は、それで大体あってると思います。ただ、あのプログラムでE機械だけを動かすには、wr=1にしといて、R機械を呼び出している行をコメントアウトするしかないような。(^^;
あと、このプログラムは、シミュレーションの2を実行しているプログラムです。シミュレーションの1は、都市が円形に並んでいる場合、2は、都市がランダムに並んでいる場合と論文中に書いてありますよ。(^^;
このプログラムは、main関数の中でランダムに都市を生成しているので、シミュレーションの2を実行しているんだなと考えられます。
しかし、この遺伝的アルゴリズムというのも面白いですな。私は単なるプログラマで、数学者ではありませんが、切った貼ったのこんなてきとーなやり方で最適化が進んでいくとは、なんか「ほんまかいな?」って感じですね。(^^;
結果がそれを証明しているわけですが...
これは、追試の論文なので、その辺てきとーにすっ飛ばしてるように見えますが、元の論文を読めば、きちんと数学的に証明されてるのかなぁ...それともやっぱり、「やってみたら、こうなりました。」の世界なのかしら?
PS.
またしても、コメント文字数を超えたので解答欄に書きます。
PS2.
大きなお世話かもしれませんが、学校って案外役に立つこと教えてくれてますよ。特に技術系のお仕事に就かれるつもりなら、こういった理論的なお勉強は、絶対にやっといたほうがいいです。
コメント(40)
なるほど...
この間から、ちょくちょくあったプログラムの質問は、コレだったんですね。
「遺伝的アルゴリズム」という言葉は知ってましたが、実際にどういうものかは初めて知りました。
さて...これを噛み砕いて説明するとなると...
回答ありがとうございます。
どんな結果が得られるのかが分かればいいです。
すいませんが噛み砕いて説明していただけませんでしょうか…
>>あるちゅーさん
わざわざありがとうございます!
僕はresult.txtには何も表示されません…
あと、3都市でやったというのはどの部分を設定すればいいのでしょうか??
よろしくお願いします。
既にお気づきかもしれませんが...
都市数の変更は、ココで行います。
/* Number of cities */
#define NVALUE 30
とゆーか、思いっきり、Number of cities って書いてありますよ。(^^;
あと、都市座標は、main 関数の中で設定されています。これを小細工して、都市が等間隔に並ぶようにするとかしたほうが、計算が早く済むのかな?
>>あるちゅ~さん
そこを3にしてみても計算が始まらないようです…
それはどこか間違っているという事でしょうか??
ちなみにコンパイルは成功しました。
コンパイラはborlandです。
resultが出ないのがおかしい…
私が使用したのは、cygwin と一緒にインストールされた gcc & gdb です。
ちなみに、resultが出ないとは、どう「出ない」のですか?
・result.txtが、作成されない。
・ファイルは作成されるが、中身がない。
等、いろいろパターンが考えら得ると思いますが...
詳しい解析どうもありがとうございます。
borlandのコンパイラでは正常にコンパイラされました。しかし、VC++では「'random':識別子が見つかりませんでした。と言ったエラーが出て、そこをrandに直し、実行したのですが、randomをただ単にrandに直すだけじゃあいけないのですね…ちょっとややこしくなりそうなので、borlandのほうだけでいいかなと思い、エラー訂正を諦めました(^^;
result.txtは作成されるのですが、中身が空の状態です…どう考えてもおかしいですよね!?
というわけで、帰ってきました。
なるほど...ファイルは、できてるわけですね。
じゃ、多分、ループが終了する前にプログラムを停止しているか、プログラムがエラーにより強制終了しているかのどちらかだと思いますよ。
ファイルができているということは、fopen()を通っているので、do~whileの後のfclose()が実行されていないのではないかと思います。
デバッガで追いかけるか、fclose()の上にでも、printf文追加してやれば、すぐわかると思います。
fcloseはちゃんと記述してありました。
fcloseの上にprintfとは具体的にどのように記述すればいいのか教えていただけませんでしょうか?
ありがとうございます。
あまりプログラムの経験がない大学院生です…
今度発表会があるんですよね。
それでこの論文を検証して発表しようかなと思いまして。研究テーマは自由なので…
11月7日と12月9日にあります。
それまでに色々とあるちゅ~さんに質問させていただきますのですいませんがよろしくお願いします。
m(_ _)m
fclose()の前にprintfを置いて確認したいと思います。すみませんがまたこのページの確認お願いいたします。
いいですよ。
私も、久しぶりの頭の体操で楽しいので。(^^;
fclose(contrib)の前にprintf("fclose(contrib)\n");を置きましたが結果は変わってないみたいです…
あと、都市数を30から他の値にしてコンパイルして実行するとエラーが出て強制終了されてしまうみたいです…
やっぱりダメです(^^;
random()を自分で作らないとダメなんでしょうか?
プログラム中のrandomは、intの引数を取りますが、どうもこれは、乱数の最大値を規定しているようです。
なので、randとの単純な置き換えでは、うまくいかないと思います。実行エラーになるのは、多分、
index = random(M);
temp = states->tours[index];
こういった場面で、indexの値が配列の大きさを超えてしまっているのではないですか?
random()は変えずにそのままコンパイルしたらいけました。それで、そのまま実行したのですが、都市数を変えるとエラーで強制終了してしまいます。
おかしいです…
具体的にどのようなエラーで終了するのですか?
問題が発生したため、[ファイル名]を中止します。ご不便をおかけして申し訳ございません。で、マイクロソフトに送信しますか?というエラーです。
わかりますでしょうか?
やっぱり、メモリ関係のエラーじゃないでしょうか?
ちなみに、Borlandのrandom関数は、どんな仕様になってるんでしょうか?
メモリ関係とはどういうことでしょう…??
stdlib.hにrandom関数らしきものがありました。アップロードしました。
http://up.spawn.jp/file/up45401.txt
int random(int) は、インライン関数になってるんですねぇ...わたしのなんちゃってrandomと一緒じゃん。(^^;
ま、それは、それとして...
メモリ関係のバグってのは、存在しないメモリにアクセスしようとしたってことです。例えば、100しかない配列の101番目をアクセスしようとしたとか、中身が適当でないポインタに、値を書き込もうとしたとか、そういう類のものです。
デバッガで追いかけてみてはどうでしょうか?
すいません、やっぱりデバッガでおいかけるといった事をやったことがないので具体的にどのようにするのかわかりません…
printfをどうやって使用するのかがわかりません。
僕の作ったプログラムです。
何回もチェックしたので間違いはないと思いますが…
http://up.spawn.jp/file/up45752.txt
random(M)は9より小さくなったのでtours[]の配列を超える事はないと思うのですが。。
あ~...あなたのプログラムダウンロードしました。
まじめに追っかけてみるので、ちょいと待ってください。ちなみに、gccでは、コンパイルできませんでしたけどねぇ...
コンパイルできなかったんですか(^^;
じゃあどこかおかしいと言うことですよね…
>>4
バグ発見どうもありがとうございました!
pdfファイルからそのままコピペってできるんですか!?
実行してみました。そしたらGen Avg Best Overlapの結果とあとランダムな数字が表示された感じです。あと、result.txtには何もありません。。
ランタイムエラーですか…。どうすればいいのやら。。
コピペしてやりましたよ!そしたら結果ちゃんと出ました…今までの苦労はなんだったのか。。あとは色んな解析です。
結果はこうなりました!
http://up.spawn.jp/file/up46379.jpg
http://up.spawn.jp/file/up46380.jpg
すみません、Overlapは何を意味してるんでしょうか??
やはり手入力でしたか...
ちなみに製品マニュアルなんかのpdfファイルでは、コピペにプロテクトかかってるのもあります。
今回のファイルは、プロテクトかかってなかったので、私はコピペでやりました。
結果は、うまく出たようですね。
ちなみに、Overlapは...回答の2番目を参照してください。遺伝子の多様性を表現するパラメータであると思われます。
Overlapは多様性を表現しているんですね。この値が大きくなれば多様性が失われていっていると言うでしょうか?
あと、result.txtの中身についてなんですが、それぞれの機械を一つだけ作用させた結果と言う事でしょうか?論文のように組み合わせた結果ではないのでしょうか?
あともう一つです(^^;
CPU-時間というのはどこを見たらわかるのでしょうか?すみませんがよろしくお願いいたします。
Overlapとresult.txtの内容についての回答は、秘密にしておきましょう。私のこれまでの回答と論文&ソースコードを頑張って読んでみてください。
大学院生なんですよね。ここからは、お勉強の時間です。(^^;
3番目のcpu時間についてですが、推測ですが、論文の作成者は、UNIX系のOSを使用するか、ツール類をインストールするかして、timeコマンドを使用したと思われます。一番お手軽だし。
最後に...この論文は、私にとって非常に有意義なものでした。触れ合える機会を与えてくれてありがとうございました。
ありがとうございます。
timeコマンドですか…色々調べながら噛み砕いていきたいと思います。
result.txtの内容難しいですね。
論文&回答を読んで考えればわかるもんでしょうか?
あとまだまだ聞きたいことがあるのですが…
すみませんが教えていただけませんか。
ナレッジ上での質問には、いつでも答えますよ。
なんか、最近だんだんはまってきたので。(^^;
この質問は、ネタ系じゃなくて、まじめに勉強の質問ですよね。これ以上、今の「丸投げ」状態で、踏み込んでしまうとあなた自身のためにならないですよ。
あなたのわからない部分を、他の人にもわかるように切り出して、「質問」と「回答」の形で、やりとりしましょう。
実際に今の状態で社会に出たら、コテンパン(死語?)にやられますよ。(^^;
問題点、疑問点を整理して人に伝える練習の場として、knowledgeを使ってみてはどうでしょうか?
そうですよね…
ゼミもないし研究室にほとんど行ってないですし、教授もなにも言わないですし(今日やっと明日来いって言われて)で、独学でC言語とか勉強して、研究テーマは何するかもわからず研究室のやってることはこういうことかなくらいでネットで論文さがして噛み砕いて・・・と。言った感じでやっていますがやはりアドバイスもらえる人が周りにいなくてホントに悩んでいます。やめたほうがいいのかな、と。研究室をテキトーに選びすぎたのかなと。で、今はホントにこんな勉強してていいのかなとか考えるし・・・もうイヤですホント。
て言うか・・・あるちゅ~さんに会いに言って会話したいもんです。ちょっと話聞いてもらいたいんですよ。
周りに一緒になって考えてくれる人がいたらホントに必死になってやるんですけどね。いそうにないですし。
result.txtのE-machineとかI-machineの数字が何を意味しているのかわかりません…
それと論文には結果としてE機械だけとそれぞれ組み合わせたのがありますがなぜそんな結果になるのかわかりません…
論文のプログラムはシミュレーション一をやっているのか2をやっているのかわかりません…
もうわからないことだらけで中間発表です。
無理かな・・・・・・・・・
GAにおいて、ある操作がその問題によく効く理由は、一般にはわからないですが、この論文の遺伝子の作り方だと何らかの意味はあるかもしれません。Eだけ(あるいは他の操作だけ)でも大差ない場合もありますし、組み合わせると収束が早くなる場合もあります。どの操作をどのくらいの割合でやれば一番早く収束するのか、というのが論文の筆者が一番知りたいテーマなのでしょう。
いろいろ考える前に、参考文献[1]と[1]に載っている主要な参考文献、GAの基本的な書籍に目を通すことをオススメします。この論文と同じことをやっても修論にはならないですから。。。
オニキスさんどうもありがとうございます。
参考文献に目を通してみます。これは外国の方が書いた論文ですよね。
E機械だけを採用するのであれば
runsimul(&temp_states, 100,0,0,1, &pstats, &pcountry);
とすればいいのでしょうか??
また、R機械の作用頻度を50回中1回作用させるには
E機械だけを採用するのであれば
runsimul(&temp_states, 100,0,0,2, &pstats, &pcountry);
とすればいいのでしょうか?
ありがとうございます。
教授のところに行ったら違うテーマを提案されました。で、また別の勉強をしなくてはいけなくなりました…またこのテーマをやるかもしれないですけどね。このテーマはありふれているらしいです、やっぱり。また時間できましたら考えてみようと思いますのでしばらくお待ちいただけませんでしょうか。
了解です。
でわまたご縁がありましたら...
PS.
コメントの数は、39以上にはならないんですねぇ。
これって、バグ?(^^;




