Month: 11月 2010

HT-03AにカスタムROM入れたら全自動再起動マシーンができた件

さすがに素のままのHT-03Aにもうんざりしてきた(そして買い換えるモチベーション/金がない)ので、rootとって2.2ベースのカスタムROMでも入れることにした。

とりあえずぐぐって出てきたコムギさんとこのとおりにrootをとって、リカバリできるようにして、元のflashをバックアップ。で、CM6-FroyoRedux-2.0-32b.zipをどこからか入手してきて入れてみる。そしてOCしないわけにもいくまいと思い、oc710-cm-2.6.34.5-signed.zipを入れてみる。

見た目いい感じに動いて、普通に使えて感動した(ただしAPNがデフォルトでビズホの方になってないので注意)が、電源抜くと数分で勝手に再起動するようになってしまった。1日持ち歩いてみたが、ひたすら再起動を続けてくれる。

とりあえず別のを入れてみようと思い、oc710-cm-2.6.34.5-signed.zipとgapps-mdpi-tiny-20101020-signed.zip、そしてOCのためにoc710-cm-2.6.34.5-signed.zipを入れてみたが、変わらず再起動マシーンのまま。

さすがにお話にならないので、もう一度入れ直してみた。こんどは入れる前にリカバリメニューからwipeを3種類行った。一番上のと、cacheと、dalvik VM cache(だっけ?)の3つをちゃんと全部行い、OCのために入れた上述の3つめのやつも入れないことにした。すると再起動病は嘘のように収まり、非常に実用的なfroyo入りHT-03Aができた。これはすばらしい。

rootとってあるので、overclockwidgetを入れて610MHzくらいまでOCして問題なく常用できている。ただカスタムROMは入れた段階で(本来の)定格である518MHzくらいになっているので、入れたままでも元よりは軽い。

とてもいい感じだ。CPUのアーキテクチャ的な理由でFlashは入らないが、ATOM trialとかOpera mobileとか2.2が必要なアプリはだいたい使える。すばらしすぎる。開発者の皆様に感謝。

Differential Evolution on Ubuntu

Differential Evolution という手法があって、GAより少ない計算量で良い結果が出るかもしれないという話を聞いたので、試してみることにした。
とりあえずhttp://www.icsi.berkeley.edu/~storn/code.htmlでC++(けっこう種類があるのにPerlはなかった)のソース(devcpp.zip)を落としてきて、コンパイルしてみる。C++をまともに自分でコンパイルしたことがほとんど無かったので困った。Makefileくらいつけといてくれたらいいのに。仕方ないのでMakefileの書き方を勉強して書いた。

CXXFLAGS = -Wall
testobjs = DETest.o DESolver.o
bin = test

all: $(testobjs)
	$(CXX) $(CXXFLAGS) -o $(bin) $^

DESolver.o: DESolver.h DESolver.cpp
	$(CXX) $(CXXFLAGS) -c $^

DETest.o: DETest.cpp
	$(CXX) $(CXXFLAGS) -c $^

clean:
	rm $(testobjs) $(bin)

で、これでmake叩くがコンパイルは通らない。このページを良く読むと、MS Visual C++ 5.0とか書いてある。えー。g++じゃないんですか。僕の環境は、Ubuntu 10.04 + gcc 4.4.3です。VC++なんてもちろんないです。

$ make
g++ -Wall -c DETest.cpp
DETest.cpp:71: error: ‘::main’ must return ‘int’
DETest.cpp: In function ‘int main()’:
DETest.cpp:96: error: return-statement with no value, in function returning ‘int’
make: *** [DETest.o] エラー 1

これはまあいい。main()がvoidじゃ嫌だというので、int型に直して、return 0;してあげればおk。

int main(void)
{
  (中略)
	return 0;
}

で、またmake叩くが通らない。

$ make
g++ -Wall -c DETest.cpp
g++ -Wall -c DESolver.h DESolver.cpp
DESolver.cpp: In member function ‘void DESolver::Setup(double*, double*, int, double, double)’:
DESolver.cpp:57: error: argument of type ‘void (DESolver::)(int)’ does not match ‘void (DESolver::*)(int)’
DESolver.cpp:61: error: argument of type ‘void (DESolver::)(int)’ does not match ‘void (DESolver::*)(int)’
・・・・・
(後略)
えー。で、いろいろ調べて、そもそもこの::*的な何かは関数ポインタ的な何かではないのか、とか勉強して、そもそも型が違うじゃないかと。とりあえず&つけとけばいいんじゃない?と思ってつけたら、コンパイラに&DESolver::hoge ってしろ、と言われたので、ぜんぶこうした。

    // 略
		case stBest1Exp:
		    calcTrialSolution = Best1Exp;
			break;

                //↑before after↓

		case stBest1Exp:
		    calcTrialSolution = &DESolver::Best1Exp;
			break;
    // 略

そしたらmake通って、無事Testプログラムも動作した。めでたしめでたし。まあ、この計算結果が正しいのかどうかは知らん。つーかDifferencial Evolutionって日本語だとあんまり情報無いんだけど、いまいちなのかな?あんまり新しい手法でもないみたいだし。まあ試してみるけど。

プロセスを監視する

GAのためにクライアントを何万回も走らせてるんだけど、数百回に1回、なぜかクライアントが死なない(暴走する)。原因もよくわからないし、再現を待ってるほど暇じゃないので、スマート(嫌味)に解決することにした。すなわち、n秒以上動いている特定のプロセスを殺すスクリプトをcronで回す。なんて美しい手法。orz

use Proc::ProcessTable;
$t = new Proc::ProcessTable;
my $i = 0;
foreach $p ( @{$t->table} ){
    if ($p->cmndline =~ 'program_name'){
        if (time() - $p->start > 10){
            system('pkill -9 program_name');
            print "killed ", $p->cmndline, "\n";
        }
    }
}

これで、10秒(6行目)以上動いてるprogram_nameというプロセスがあれば殺せる。これを1分ごとに回せば、たまに暴走してるプロセスがあっても無駄なく進められるだろう。GA回してるプログラム側からは、結果のファイルopenの例外を拾ってスコアを0にしてしまえば良い。さしずめ突然死というところか。結果にどの程度影響があるのかは知らん。

あと、数階層下まで一気にディレクトリを作りたいときは、mkdirじゃなくてmkpathを使うといいらしい。

use File::Path;
if (!-d $dir){
    mkpath($dir);
}

これで$dirが無いときは作れる。

twitter bot @genryo_bot のはなし

Syntax highlighterいれてみた。ので、コードを少し貼ってみる。

とりあえずこないだTwitterでフォロー返しに不具合があって、良く出力を見ていたらフォロワーが100人ぴったりだった。慌ててAPIとかNet::Twitterのドキュメントを見ると、1回に100ずつしか得られないとのこと。pagingかcursorを利用するかして何度かアクセスしろ(これってAPIアクセス数は増えるのかな?)とのことだったので、next_cursorに0が帰ってくるまで何度もアクセスして、followers()で得られたuserを1つの配列に突っ込むようにしといた。

my @followers;
my $cursor = -1;
while ($cursor) {
    my $f = $nt->followers({cursor => $cursor}) or die "error while getting followers $!\n";
    $cursor = $f->{next_cursor};
    foreach my $u (@{$f->{users}}) {
        push @followers, $u;
    }
}

これでたぶん数百フォロワーいても大丈夫。twitter先生のことなので、2回目だけアクセス失敗とか平気であるからちゃんとチェックしておきましょう。僕はこれ忘れて100人目より後のフォロワー全部を一度リムーブしましたorz

あとはまってたのは、in_reply_to_status_idに渡すID。ステータスのIDを渡すものだと知らず、ひたすらユーザーIDを渡して、reply toが表示されないなぁおかしいなぁって思ってたorz

で、このBOTはフォロー返しして、TLにある太りそうな発言にうっとうしいReplyを返すのが仕事。発言を全部MeCabに突っ込んで要素に分割して、あらかじめ指定した順番で太りそうな名詞と(助詞と)動詞の組み合わせが出てきてるかどうか見てるだけ。超単純なんだけど、MeCabのおかげで動詞を原形で指定できるから、けっこう幅広いパターンに引っかかっていい感じ。

文字列が太りそうか判断するパッケージ”Fat”を作ったんだけど、中身が上に書いたことくらいしかなくて100行くらいしかないしだいぶアレなのでソースは貼らないw