大学生活 一覧
一体どうしたらそんな風に譲歩を引き出すことができるのかとっても謎です。。。
とりあえず、長期化が予想された問題は早くに決着を迎えることになりました。
が、相変わらず自分の立場は変わらないわけで*6、これ以上問題を起こさないように
しないといけません。今回、いろんな人に言われたのは、「感情的に対応してはいけない」
ということ。そして「どれだけ自分とうまく合わないと思っている相手であっても、我慢して
仕事だけはやり遂げる」ということです。
Even after the darknest nights, morning always comes.
この言葉を信じて、論文提出まではなんとかやり遂げるのみです。
そこに聴衆はいません
聞いてなんかいません
っていう替え歌(?)を思いついた。
研究に集中している時に横から話しかけられるってのはよくあることだと思うのですが、
それがいつものことだとかなり凹みます。もうちょっと違う環境でも実験したいな?。
とか言いつつ、あと2週間頑張るだけなんですけどね。
とりあえず、昨日まで苦戦したプログラムの修正のおかげで、実験の結果も好調です。
こんなスケジュールで行けば、論文提出1週間前には実験終了になりそうです。
本当ならもうちょっと早くに終了したかったんですけどね?。
探しても探してもわいてくるバグ。今回のバグはかなり難しい!と自負できます。 これはもう、設計段階でどれだけ例外的な場合を考えることができるかにかかっています。 完璧なアルゴリズムに則ってさっさと組んでしまいたいです。
さて、そんなわけでこのブログの読者様にもぜひ挑戦してみて欲しいです。 ちなみに本来のコードを改造して、ちょっとだけ解きやすくなっています。 クラス名が適当なのは無視ということで...。
class Entry { private String id; private double value; public static Comparator<Entry> ID_ASCEND_COMP; // getter, setter は定義済みとします。 } class Application { // 問題のメソッド public List<Entry> merge(List<Entry> list1, List<Entry> list2 ){ Collections.sort(list1, Entry.ID_ASCEND_COMP); Collections.sort(list2, Entry.ID_ASCEND_COMP); Iterator<Entry> it1 = list1.iterator(); Iterator<Entry> it2 = list2.iterator(); Entry e1 = null; Entry e2 = null; List<Entry> merged = new ArrayList<Entry>(); while(it1.hasNext() && it2.hasNext()){ if(e1==null) e1 = it1.next(); if(e2==null) e2 = it2.next(); int key = Entry.ID_ASCEND_COMP.compare(e1,e2); if(key<0){ merged.add(e1); e1 = null; } else if(key==0) { e1.setValue(e1.getValue()+e2.getValue()); merge.add(e1); e1 = null; e2 = null; } else { merged.add(e2); e2 = null } } if(e1!=null) merged.add(e1); if(e2!=null) merged.add(e2); while(it1.hasNext()) merged.add(it1.next()); while(it2.hasNext()) merged.add(it2.next()); return merged; } }
で、このメソッドが何をしているかというと、引数に与えられた2つのコレクションを1つにまとめるということをしています。ただし、IDが重複しているインスタンスがあれば、片方のインスタンスに value を加算してそれを追加するというメソッドです。ちなみに、list1とlist2がnullの場合は考えなくても構いません。(NullPointerExceptionが発生して終了するだけなんで。)また、ID_ASCEND_COMPは、Entryのidをソーとキーとして昇順に並び替えるComparatorです。*7
昨日、あまりに実験結果の評価が悪かったのでプログラムの見直し+実験結果の見直しをしていました。そしたらやっぱりいました、あの嫌なやつ。バグが潜んでいました。今回のは、これまでバグの確認のために使っていたデータ以外の、本番用のデータで確認したらけっこうあっさり分かってしまいました。これはちゃんとテストをしろよ!という神からの思し召しなんでしょうか。それにしても、これまでこんなにバグが潜んでいたのかを思うと凹みます。
しかも間違えていたのが、コレクション中の最小値を見つける部分という、かなり情けない場所。やっぱり例外処理をちゃんとするべきですね。
double min(Collection<Result> col) { double min = Double.MAX_VALUE; for(Result r : col) { min = r.getValue() < min ? r.getValue() : min; } return min; }
はい、これが問題のソースコードです。一見正しそうに見えますが、ちょっと処理が抜け落ちています。さて、どこでしょう…。
運命の日は、2月13日(水)。この日の16時までに論文を提出しないと
もう1年大学で過ごさないといけなくなります。
現実的にはなかなかそういうことはないそうなのですが、毎年何人かは
そういう憂き目に遭っているとのことなので、気を緩めずに頑張って
いきたいところです。
さて、今日はこれまで2回もやり直した実験がやっと成功して、ちょっとだけ
前進した感じです。今やっている実験は、大きく2つのフェーズに分割できます。
1つめは、訓練データを使ってパラメータの最適化するフェーズ。
そして、最適化されたパラメータを用いてテストデータで評価するフェーズです。
これまで幾度となくミスってきたのは前者の実験です。
これがとても時間がかかるのです。時間がかかる上にミスってしまうと
さらに時間がかかるということで、非常に神経を使うフェーズなのですが、
なんとかこれをクリアして、後者のフェーズに移行できました。
こっち側はかなり手間がかかるものの、時間はかからないので根性で乗り切るだけですね。
この実験の結果次第で今後の実験の方針が決まるので、できるだけ都合のいい
結果が出てくれることを祈るのみです…。
今、研究で一番なんとかしないといけない問題が、実験をいかにして早く終わらせるかという点です。一応、今のところ最低ラインは通過しているんですが、もうちょっとちゃんとした形にするためにはどうしても追加実験をしないといけないんです。この追加実験がかなりの曲者。HDDの要領もやたらと食うし、パラメータの数もかなり多いのでめっちゃ時間がかかります。なんとかしないといけないんですが…。
とりあえずソリューションとして考えられるのが、
(1)いくつかの実験パラメータを、予備実験の結果を基にして固定してしまう。
(2)パラメータの数は変更せずに、パラメータの取り得る値を減らす。
(3)外部の計算機なども利用するなどして、物量作戦に出る。
(4)プログラムをできる限り高速化して、資源を有効活用する。
というくらいでしょうか。
(1)から(3)までがわりと妥当な方法です。(4)は、バグが入ってしまう可能性があるので、消極的な改善にとどめるべきでしょう。今やっているのが(1)を行うための予備実験なのですが、なんとか早く終わって欲しいものです。
昨日もバグを取ってたんですけど、結局致命的なやつを取り逃したために
もう1回実験をしなおすことになりました(>Д<;)
今度のバグは、これまでのような凡ミスではなく、プログラムとして組むべき
アルゴリズムを間違えていたというやつです。つまり、自分の頭の中で考えていた
プログラムと、本来必要とされる仕様とがずれていたってことです。
これは、一応作ったものとしては正しいのかもしれませんが、仕様を満たして
なかったら意味はないので…。ついでに高速化もしたので、明日には結果が
出てればいいな?。
今日も今日とて研究室にやってきました。
3日にも実験結果を確認しに研究室に来て、プログラムのバグを発見!
1時間ほど地道に調査して修正していました。今日も3日に発見したバグ修正です。
3日から走らせているプログラムは現在も実行中…。やっぱり終了まで3日はかかる
実験で1回ミスったのは大きいです(>Д<;)
一応、期限は7日なんでなんとか終了する公算はあるんですが、かなりギリギリです。
結果はわりといいことは分かっているんで、それほどあせってはないんですが…。
ともかく明日実験が無事に終わっていることを期待するのみです。
今日取ったバグは、わりと予想通り。
計算用のサーバがNFSで構成されているんですが、違うマシンにあるファイルへの
パスの指定が間違っていました。シンボリックリンクではなぜかうまくいかなかった
ので、単純にファイルをコピーして対処。
とっても場当たり的ですが、一番簡単なソリューションです。
これで、実験の評価まで特に問題なく進められます。
あとは、いかにして実験スピードを上げるか。
そして、いかに論文を書くスピードを上げるか…(ノД`)
研修中に大学のマシンをずっとつけっぱなしにして実験をさせてたんですが、
1週間ぶりに大学に来て確認してみたら、勝手に再起動してました(ノД`)
(つまり、実験が途中で終了+実験が全く進んでない状態。)
そういえばWindows Updateをしないといけないな?とは思っていたんですよ。
でも、まさか勝手に再起動する機能がついてるなんで知りませんでした。
そんなわけで、今後は勝手に再起動しないようにレジストリをいじってみました。
[blog] Windows Updateのダイアログ - よさだやぐぶろぐ
[web] Windows XP Home EditionをSUSクライアントに - @IT
次のキーを追加するだけでOKです。
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU] "NoAutoRebootWithLoggedOnUsers"=dword:00000001
これで勝手に再起動しなくなるはず…です。
さっきやっと研究用プログラムのデバッグが終了して、実際に走らせられる状態にまで持ってこれました。これでほぼJavaのプログラムを書くのは終了ということで、あとは実験スクリプトと論文に着手していく感じになります。のろのろ走るプログラムともこれでさよならですゝ(^O^)丿
[blog] 長丁場の終了 - LostMemories
前回の記録から1週間以上も経っているわけですが、これまで何に苦戦していたかというと、現行のプログラムにも実はバグが存在していて、それが高速化プログラムのテストの動作チェックを妨げていた点です。しかも比較に大きく動作に影響する場所だったりしたので、原因を追及していくことが難しかったのです。で、今日はその現行プログラムのバグも無事にとれ、高速化プログラムがちゃんと動くことが確かめられたというわけです。
…実は、高速化プログラムには現行プログラム以上のバグがあったんですけどね(;´д⊂
とにもかくにもプログラムは完成したので、明日からは新しいプログラムでガリガリ計算させる予定です。