いもあらい。

プログラミングや哲学などについてのメモ。

軽蔑者。

2006-03-23 13:09:00 |  Etc...
本を眺めていて、興味深い表現があったので。

ニーチェの『善悪の彼岸』を眺めていて(読んでいて、ではない。難しいって、これ・・・)、とても興味深い言葉があったので、メモ。

自分自身を軽蔑する者も、やはり常にその際なお軽蔑者として自分を尊敬する。
(第4章より)



オタクには、「自分の堕落っぷりをネタにする」というか、自虐癖というか、がありますが、その影にも力への意志というものが見えるということに気づかされます。
自分自身の愚かしさに気づけないのもどうかとは思いますが、だからといって「気づいてるんだよ」ということだけに満足してしまって、むしろそれを善しとするのは、ルサンチマンっぽいですねぇ。

自分自身の愚かしさを、価値を転換させるネタにしてしまうのでなく、自分をより高みへと導くための力にしていかなきゃいけないんでしょう。多分。


Xのインストール。

2006-03-21 18:19:00 |  Gentoo...
Xのインストール。
あと、wacomのタブレットのこととか。

とりあえずGentoo Linuxのインストール、あと起動はそこそこにうまくいったので、次はXのインストール。

けど、マニュアルを見るとなんかややこしいことになっているっぽくて・・・
Xサーバー設定ガイド
モジュラー化されたXへの移行手引き
このモジュラー化とやらで、上のドキュメントの内容がどれほど影響を受けるのかが分かりません。
とくに、

Note: モジュラー化でインストールすると、いくつかのvncアプリもnvidia-glxやwacomのような外部ドライバも、/usr/lib/xorg/modulesの代わりに/usr/lib/modulesに何かをインストールしていると、動作しないでしょう。これらのうちの多くは、インストール処理に追加されたモジュラー化Xの検知処理を備えており、したがってモジュラー化Xをインストールした後に再度mergeされる必要があります。(モジュラー化された...より)



というのが気になります。(日本語の意味がよく分かりませんが・・・)

しばらく調べてみたのですが埒が明かないので、とりあえずインストールしてみることに。
# emerge xorg-x11
・・・めちゃくちゃ時間かかった。
2~3時間くらいかかった気が。

まぁ何はともあれ
# Xorg -configure
# X -config /root/xorg.conf.new
・・・失敗。

wacomのドライバーを入れてないからかなぁ、と思い、
# emerge linuxwacom
・・・めちゃくちゃ時間かかった。
(しかも、このときには気づいていなかったけれど、失敗してた、、、)
けど、うまくいかない。

ふとここで、env-updateをしていなかったことに気づく。
さっそく
# env-update
# source /etc/profile
のあとに、
# Xorg -configure
# X -config /root/xorg.conf.new
・・・失敗。

じっくりと調べていくと、mouseのデバイスパスが間違っていたことが判明。
/dev/mouse0となっていたのを/dev/input/mouse0と修正。
これでやっと、一応灰色の画面が出るようになった。

ちょっとメモ。
マウスがどのデバイスファイル?になっているのかを調べるには、
# cat /dev/input/mouse0
とかとすればいい。
なっていれば、動かしたときに文字列がぐわーと表示される。
(ただ、下手するとコンソールの文字がおかしくなる・・・どうやって直せばいいんだろう?)
ネットをみると、もっとスマートなやり方もあるっぽい。
# modprobe usbdevfs
# mount -t usbdevfs none /proc/bus/usb
# cat /proc/bus/usb/devices
とかやっているけれど、各コマンドの意味がまだちょっと。。。

そのあと、xorg.confのmanページを見たりして、設定。
これでマウスでもタブレットでもカーソルは動くようになり、また解像度も1280x1024に出来ました。
(startxをして出てくるxtermのフォントが小さいのが問題ではありますが。まぁ、いずれ解決したいです。←Linuxにおけるフォントの仕組みがまだ分かっていない)

でも、これではタブレットを絶対座標で使うことが出来ず、非常に不便なので、
# man wacom
としてwacomのドライバのmanページを見ながら、Mouse1のところを修正。

が、なぜかペンを動かしてもカーソルが動かなくなりました。
いろいろオプションを変えてみてもダメ。

で、調べて出てきた資料がこれ。(最初から、“linux wacom”をキーワードに調べるんじゃなくて、“gentoo wacom”をキーワードで調べればよかった・・・OTL)
というか、このwiki優秀すぎます。(昔はそう思わなかったけれど、gentooのドキュメントってけっこうしっかりしてますよね)
曰く、

Note that you may be required to recompile xorg-x11 with the 'sdk' use flag to compile linuxwacom succesfully.(上記ぺーじより)



とのこと。
つまり、xorg-x11を'sdk'USEフラグをつけてコンパイルしないと、linuxwacomのインストールに失敗するよ、と。(もっと早く言ってよ、、、)

ということで、
# USE='sdk' emerge xorg-x11
とsdkのUSEフラグをつけてマージ。

それが終わったら今度は
# emerge linuxwacom
依存関係のある他のものはすでにインストールされていたので、ほどなくしてインストール完了。
今度は失敗していなかった。

で、カーネルの再構築。
Device Drivers->Input device support以下、

 <*> Event interface


Device Drivers->USB Support以下、

 <M> Wacom Intuos/Graphire tablet support


として、コンパイル。

このあと、さっきの設定のままstartxをしたのだけれど、あいかわらずタブレットは反応せず。
ログを見ると、
Wacom unable to read first byte of request '~#' answer after 3 tries
と出てる。
これだけ特徴あるエラーメッセージならと検索してみれば、ヒットして、なんかデバイスがちゃんとつながってないやらなんやらのアドバイス。
といっても、
# cat /dev/input/mouse1
としてタブレット動かせば、ちゃんと反応するし・・・
(ちなみに、画面がおかしくなったらresetとすればいいらしい。試してないけど)

が、ここで。
# cat /proc/bus/input/devices
とすると、どうやらタブレットは/dev/input/mouse1でもあるけれど、/dev/input/event2でもあることが判明(どっちかがリンク?ls -lとしても確かめられなかった・・・)
ということで、/dev/input/event2としたところ、これが正解!
ちゃんと動きました。

けれど、ちゃんと絶対座標で動いていない感じ。。。
絶対座標で動かないことには、使いづらくてしょうがないですからねぇ。
が、オプションで試行錯誤した結果、以下のオプションでちゃんと絶対座標になりました。
最終的なxorg.confは次のような感じ。
==> /etc/xorg.conf (部分省略)<==
Section "ServerLayout"

  Identifier  "X.org Configured"
Screen 0 "Screen0" 0 0
InputDevice "Mouse0" "CorePointer"
InputDevice "Tablet" "SendCoreEvents"
InputDevice "Keyboard0" "CoreKeyboard"


EndSection

Section "Files"
   (省略)
EndSection

Section "Module"
   (省略)

  Load  "wacom"


EndSection

Section "InputDevice"

  Identifier  "Keyboard0"
Driver "keyboard"
Option "XkbModel" "jp106"
Option "XkbLayout" "jp"


EndSection

Section "InputDevice"

  Identifier  "Mouse0"
Driver "mouse"
Option "Device" "/dev/input/mouse0"
Option "ZAxisMapping" "4 5" #スクロール


EndSection

Section "InputDevice"

  Identifier  "Tablet"
Driver "wacom"
Option "Device" "/dev/input/event2"
Option "Type" "stylus"
Option "Mode" "Absolute"
Option "USB" "on"
Option "TopX" "0"
Option "TopY" "0"
Option "KeepShape" "on" #最後の3行で完全な絶対座標に


EndSection

Section "Monitor"

  Identifier  "Monitor0"


  (省略)
EndSection

Section "Device"

  Identifier  "Card0"


  (省略)
EndSection

Section "Screen"

  Identifier "Screen0"
Device "Card0"
Monitor "Monitor0"
DefaultDepth 24 #色


  (省略)

  Subsection "Display"
Viewport 0 0
Depth 24
Modes "1280x1024"
Modes "1024x768"
EndSubSection


EndSection

そのあと、ウィンドウマネージャーを何にしようかというのでひたすら迷う。。。
最初はKDEを入れちゃおうと思っていたんだけれど、せっかくだから総合環境を入れるのでなく少しずつ作っていくのもGentooっぽいかなぁ、とも。(にしても、いろいろなウィンドウマネージャーがあるもので。)

さんざ迷ったあげく、とりあえずOpenboxを入れてみることに。依存関係もなかったし、オフィシャルのページがすっきりしているのが好印象。(開発が遅そうなのが気にかかるけれど)
# emerge x11-wm/openbox
で、使ってみて。
・・・物足りない。まぁ、カスタマイズしてないから当たり前なんだろうけれど(^^;
ただ、なんかカスタマイズするためにいろいろ調べるのが面倒になったので(音を出したいんですよ、イベントに対して。けど、情報が・・・?)、なら、ということでopenboxをアンインストールしてKDEを入れることに。

もうウィンドウマネージャーを見て回るので体力を使い果たしていたので、手抜き。
# emerge kde
・・・えと、何時間たったろう?(爆)
現在約3時間経って、まだコンパイル中。
むー、こんなんだったらとりあえずはOpenbox入れておいて、あとでカスタマイズしてけばよかったかも・・・

(後記:すっごい時間かかってKDE入れたけれど、なんか微妙に思ったので結局Fluxboxを入れましたとさ。^^;)


gensplashについて。

2006-03-20 21:31:00 |  Gentoo...
gensplashおよびfbsplashについて。
参考URL: http://gentoo-wiki.com/HOWTO_gensplash (英語)

前回のエントリで書いたとおり、ブートのときに画像を表示させる方法(+α)について。

以下、上記参考URLの内容をざっと意訳したもの。(訳せるところだけ訳したもの、とも言う。辞書はたまにしか引いていないので、ところどころテキトーです)



gensplash、およびfbsplashとは?
gensplash
Gentoo Linuxのブートプロセスを、メッセージやアニメーション、プロセスバーを表示することで、よりカッコよく(enrich)見せるようにするためのツール群(または、プロジェクト)。
各ツールは~splashと名づけられていて、お互いにかかわりあっている。

fbsplash
gensplashの一つで、ブート時やリブート時、シャットダウン時にコンソールの背景に画像を表示させたり、サイレントモードに切り替えたりするもの。
/dev/fbsplashというデバイスを通してアクセスするので、Frame Bufferデバイスが必要。

Frame Bufferデバイスとは?
(よく分からないけれど、抽象的な描画スペースとインターフェースを用意することで、ハードウェアの低レベル処理について知らなくてもいいようにしたもの、ってことなのかな?)

インストール
以下はvesafbの場合(といっても、大体はこれで大丈夫みたいですが)。必要なら、読み替えること。

カーネルの再構築
まず、splashutilsをマージ。
# emerge splashutils

欲しければ、テーマをマージ。
# emerge splash-themes-gentoo
# emerge splash-themes-livecd

そのあとは/usr/src/kernelの指すディレクトがカーネルソースのディレクトリであるかを確認して、カーネルの再構築。

必要なオプションは、以下(全部組み込むこと)。
Device Drivers->Graphics support以下、

 [*] Support for frame buffer devices
<*> VESA VGA graphics support
(VESA driver typeはvesafb-tng)
(HRESxVRES@FREQ) VESA default mode
(例えば、1024x768@72とか)
[*] Support for the framebuffer splash


Device Drivers->Graphics support->Console display driver support以下、

 [*] Video mode selection support
<*> Framebuffer Console support


もし、initramsfs image(後述)を読み出したいなら、以下のオプションも指定すること。
Device Drivers->Block devices以下、

 <*> RAM disk support
(4096) Default RAM disk size (kbytes) (NEW)
[*] Initial RAM disk (initrd) support


逆に、以下のオプションは指定しないこと。
Device Drivers->Graphics support

 [ ] Enable Tile Blitting Support


これでカーネルを再構築して、古いカーネルに置き換えること。

Initramfs Imageについて
ブートプロセスの早いうちから背景に画像を表示させるには、initramfsが必要となります。(必要がなければ「ブートローダーの設定」まで読み飛ばすこと。)

方法は2つありますが、推奨されている方、すなわち起動時に読み込む方法のみを取り上げます。
(参考までに。もうひとつの方法は、カーネルに組み込んでしまう、というものです。)

Initramfs Imageを起動時に読み込む方法
この方法の場合、Initramfs Imageを1つのファイルとして作る必要があります。
といってもやらなければならないことはただ1つで、splash_geninitramfsを使ってファイルをinitrdファイルに変換するだけです。
# cd /etc/splash
# splash_geninitramfs -g /boot/fbsplash-emergence-1024x768 -v -r 1024x768 emergence
/etc/splashはsplashのテーマが置かれているディレクトリです。
オプションの-gでinitrdファイルの名前を指定し、-rでサイズを指定します。-vは冗長出力の指定です。引数にはテーマを指定します。

(bootsplashのテーマをfbsplashのテーマに変換する方法は割愛)

ブートローダーの設定
カーネルオプションの設定
まず、Frame Bufferデバイスのオプションを指定する必要があります。
例えば、
video=vesafb:ywrap,mtrr,1024x768-16@85
1024x768-16@85のところは、適当な値にしてください。
(16のところでは色の深さ、85のところではリフレッシュレートを指定してください。)

次に、fbsplashのオプションを指定します。
例えば、
splash=verbose,theme:emergence
verboseのところではverboseまたはsilentが指定できます。
silentにした場合、ブート時の情報がすべて隠れます(と書いてあるけれど、隠れるどころか画像が表示されなくなる・・・バグ?※)。verboseとした場合は、すべて表示されます。
theme:の後ろにはテーマを指定します。

※どうやら、新しいバージョンのカーネルの場合は、ブート時の情報を隠すにはquietというオプションを書いてやる必要があるようです。すなわち、
splash=verbose,theme:emergence quiet
ってな感じで。
verboseをsilentにすると、どうもうまくいかない感じがします。
ただ、隠されるのはあくまでdmesgで表示されるメッセージのみで、デーモンの起動などは全部表示されるようです。

Initramfs Imageを使う場合
もしInitramfs Imageを使う場合には、initrdを指定します。(※これはカーネルのオプションではないので注意。)
例えば、
initrd /boot/fbsplash-emergence-1024x768
(※これはGRUBの場合。)
という風に、さっき変換したファイルを指定してください。

grub.confの例
例えば、自分の環境であれば次のようになります。
==> /boot/grub/grub.conf <==
title Gentoo Linux 2.6.15-r1
root (hd0,2)
kernel /boot/gen_kernek.2.6.15r1.fb root=/dev/hda3 video=vesafb:ywrap,mtrr,1024x768-32@72 splash=verbose,theme:emergence
initrd /boot/fbsplash_emergence_1024x768

本当は1280x1024なんですが、文字が小さすぎて目に悪いので、1024x768になってます(^^;

これを
# grub-install /dev/hda
として、書き込むわけです。

すべてのコンソールに背景を表示させる
もしすべてのコンソールにスプラッシュスクリーンを持たせたいのであれば、次のコマンドを実行します。
# rc-update add splash default
defaultだとブートの終わりあたりに表示されるので、もしすぐに表示させたいのであれば、defaultのかわりにbootを指定してください。

(あとは割愛)


Gentooインストールメモ。

2006-03-16 13:34:00 |  Gentoo...
Gentoo Linuxのインストールメモ。

かつては一度あきらめたJavaですが(Perlと比べると分かりにくすぎる。オブジェクト指向に慣れてなかったのもあるけど。)、Perlでプログラミングしていて限界を感じるので(標準のモジュールではGUIプログラミングが出来ないのと、コンソールアプリにしろCursesを使うのにモジュールをインストールしなくちゃいけなくって、このインストールに挫折した、、、root権限がないとこういったののインストールは限りなくめんどくさい)、もう一度がんばってみようかな、と思うわけです。

で、プログラミングするならunix環境(というかvi)が欲しいわけですが、仮にGUIプログラムを作ったとしても、その実行の様子を例えばssh越しのコンソールでは見ることが出来ないわけです。
以前はとりあえずネットワーク越しにプログラミングはして、それをFTPを使ってデスクトップに持ってきて、で、実行してたりしたのですが、それではめんどくさいしネットワークを使っている意味が薄れる。
だからといって、Windows環境でプログラミングするのもなぁ、というのがあるわけです。(まぁ、vimはありますが、CUI環境(=MS-DOS)がダルすぎる・・・)

ということで、LinuxをPCにインストールしようかな、と思い、なんとなくよさげなGentoo Linuxをインストールしてみることにしました。



インストールCDはすでに焼いておいたので、とりあえず起動。
dokeymapというオプションはヘルプには出てなかったけれど、雑誌に載っていたので、次のようにしました。
boot: gentoo dokeymap
たしかにkeymapを選ぶ画面は出たけれど、反映されてないOTL
にしても、起動画面がけっこうオサレですw

passwdでrootのパスワードを変更しておいて、ifconfigを実行。
eth0にちゃんとIPアドレスが割り当てられてました。
pingもちゃんと通っているみたいです。

さて、問題のディスクの準備。
今回、めんどうだったのでWindowsのバックアップ取ってません(爆
まぁ、消えたら消えたでインストールし直せばいいし、データ類は別のHDDに入ってるし。

fdiskを使って、以下のように設定。(/dev/hda1は変更なし)

  Device   Boot  Size    System
/dev/hda1 * 約30GB W95 FAT32
/dev/hda2 512MB Linux swap
/dev/hda3 * 約8GB Linux


そのあと、ファイルシステムの適用とマウント。
# mkswap /dev/hda2
# swapon /dev/hda2
# mkreiserfs /dev/hda3
# mount /dev/hda3 /mnt/gentoo
ってな感じで。(#はプロンプト)
ファイルシステムは雑誌お勧めのReiserFSってのにしてみました。

一応時間の設定。
# date
Thu Mar 16 14:16:06 UTC 2006
…UTC?
調べたら、UTCは協定世界時とやらで、グリニッジ標準時とほぼ同じとのこと。(ちなみに日本標準時はJSTらしい。)
時計を見れば14:16くらいだから、どうやら間違っているっぽい…
ということで、
# date 031605292006
(date MMDDhhmmYYYYで設定できるらしい)
と、UTCにしてみた。

で、stage tarballのインストール。
stage1からやっていくのも面白そうだけれど、時間がかかりそうなので今回はパス。
ということで、stage3のtarballをダウンロード。

まず/mnt/gentooにいってから、links2というウェブブラウザ(でも、スマートな感じがしない・・・)で、ミラーサイトにアクセス。
このとき、x86,i586,i686と3つ用意されていて、違いが分からない(^^;
調べたら、それぞれCPUの種類(というのかな?)を指してるんですね。(←もとがMacユーザなのでハードウェア関係は滅法弱い)
Pentium4はi686に分類される(もちろん、x86でもあるのだけれど)ようなので、i686用のをダウンロードしてきました。

にしても、i810(これはチップセットですよね?)とか、なんでこんな味も素っ気もない名前をつけるのかなぁ。
分かりにくいったらありゃしない。

# tar xvjpf stage3(略).tar.bz2
で展開。
ちなみにjはbz2の解凍、pはパーミッションの保存だそうで。

次はPortageのインストールとやら。
これ、雑誌には書いてなかったなぁ・・・(まぁ、2003年の記事だし、しょうがないのかな)
さっきと同じようにlinks2を使ってスナップショットのtarballをダウンロードしてきて、
# tar xvjf portage(略).tar.bz2 -C usr/
ってな感じで展開。-Cは説明が書いてなかったけれど、調べたら展開するディレクトリの指定とのこと。

ここでコンパイルオプションの設定。
ということで、etc/make.conf.exampleを見てたら、marchの設定ところに、…,i686(Pentium Pro),…,pentium4となっていて、頭にハテナマーク。
調べたら、Pentium4はi686と微妙に違うっぽい・・・? i686はP6マイクロアーキテクチャとかいうやつっぽい。で、Pentium3まではたしかにこのP6何とやららしいんだけど、Pentium4はNetBurstとかいうアーキテクチャらしくて、これとP6何とやらとの関係がよく分からない・・・
まぁ、しょうがないので、etc/make.confを以下のように設定。
CHOST="i686-pc-linux-gnu"
CFLAGS="-O3 -march=pentium4 -pipe"
CXXFLAGS="${CFLAGS}"
MAKEOPTS="-j2"
※CFLAGSのところの-O3のOは大文字のO。
まぁ、bin/lsとして動くみたいだし、大丈夫でしょう。多分。

で、ミラーサイトの設定。
# mirrorselect -i -o >>etc/make.conf
と、
# mirrorselect -i -o -r >>etc/make.conf
といわれるがままに設定。
(最初、スペースを押してXをつけて選択するのを忘れてた(^^;

DNS情報のコピー。
# cp -L /etc/resolve.conf /mnt/gentoo/etc/
オプションの-Lはシンボリックリンクをコピーしないようにするため、とのことだけど、どこにもシンボリックリンクなどない気が・・・?

このあと、
# mount -t proc none /mnt/gentoo/proc
# mount -o bind /dev /mnt/gentoo/dev
と必要なマウントをして、
# chroot /mnt/gentoo /bin/bash
# env-update
# source /etc/profile
# export PS1="(chroot) $PS1"
として、やっと新しい環境へ。
(最後の行はプロンプトの変更だから、別にいらない気も・・・)

バイトに行く時間(午後5時)なので、中断。
とりあえず
# emerge --sync
とPortageツリーの更新だけしておいた。

帰ってきた(午後11時半)ので再開。

次はprofileの選択とやら。
特に変更はいらなそう。

ただ、lsコマンドで何個か見慣れないオプションがあったので、そのメモ。
Fはおなじみで、/、@、*とファイルの種類を表してくれるもの。
Gは、グループの表示をしないというもの。
gは、lとほとんど同じだけれど、所有者を表示しないというもの(多分)。
dはディレクトリの「中身」を表示するのではなく、ディレクトリをファイルとみなして表示するもの。(例えば、ls etc/とすると、普通はたくさんのファイルが表示されるけれど、ls -d etc/とすると、etc/とだけ表示される。)

あと、lnコマンドにも見慣れないオプションがあったので、やはりメモ。
fは、指定したリンクと同名のリンクがすでにあれば、それに置き換える、というもの(あってる?)。
nは、ディレクトリへの(シンボリック)リンクを、ディレクトリとしてではなくファイルとして扱うというもの(デフォルトではディレクトリとして扱われる)。

で、USE変数の設定。
実はこれが一番よく分からない・・・
この指定をすることでどれくらい環境を統一できるものなんだろう?
それと、そんなに共通するようなフラグがあるもんなのかなぁ、と。
とりあえず気をつけなきゃいけないことは、グローバルな変更を加えたいなら、/etc/make.profile/以下のデフォルトのファイルをいじるんじゃなくて、/etc/make.confにその設定を書くこと、ということ。
今回は特にいじらず。

ロケール指定は、デフォルトの/etc/locales.buildで大丈夫そうだったので、マニュアル通り
# mkdir -p /etc/portage
# echo "sys-libs/glibc userlocales" >>/etc/portage/package.use
としておきました。

さて、いよいよカーネルのインストール。

けど、そのまえにタイムゾーンの設定。
といっても、
# cp /usr/share/zoneinfo/Japan /etc/localtime
とするだけ。(ちなみにこのJapanってファイル、バイナリファイルなのにびっくり)
ためしに
# date
とすると、Fri Mar 17 00:56:06 JST 2006
って感じで、ちゃんとあっています。

今回使ったカーネルソースは、gentoo-sourcesというもの。
# USE="-doc symlink" emerge gentoo-sources
と、完全にマニュアル通りw
USEフラグで渡した-docは他の依存関係をインストールしないため、symlinkは/usr/src/linuxのシンボリックリンクを自動で修正するためらしい。

カーネルをインストールする前にマニュアルに従ってpciutilsをインストール。
lspciをすることでPCIバスとそれにつながっているデバイスすべての情報が表示されるとのこと。
おまけで書いておくと、lsmodとするとモジュールの状態が表示される。(これは、/proc/modulesの情報を整形してるだけらしい)

さて、
# cd /usr/src/linux
# make menuconfig
としてカーネルの設定。

・・・やっぱりよく分からない(^^;
とりあえず必須になっているものと必要そうなのにチャックを付けて設定完了。(現在午前4時、、、)
# make && make modules_install
# cp arch/i386/boot/bzImage /boot/gen_kernel.2.6.15r1
ってな感じでコンパイル&インストール終了。
(コンフィギュアファイルが.configって名前で保存されるって知らなくて名前を変えちゃってたから、最初失敗(^^;

このあとシステムの設定をしていくみたいなので、いつまでもnanoを使うのはいやだったからさっそくvimをインストール。
まず
# emerge -s vi |less
で検索して、
# emerge app-editors/vim
でインストール。
まだインストールの調整の仕方とかは分からないけれど、お手軽w

さっそくインストールしたvimを使って/etc/fstabを編集。

 /dev/hda3           /           reiserfs  noatime      0 1
/dev/hda2 none swap sw 0 0
/dev/cdroms/cdrom0 /mnt/cdrom auto noauto,user 0 0
none /proc proc defaults 0 0
none /dev/shm tmpfs nodev,nosuid,noexec 0 0


ってな感じに修正。(cdromのオプションについてるuserはroot以外にもマウントできるようにするものらしい)
Windowsやデータの入っているディスクのマウントの設定はとりあえず後回し。

・・・日が昇ってきた。眠い。
疲れてきたのでネット巡回しながらやってたら6時過ぎてるし。

ホスト名とドメイン名の設定。
ホスト名は/etc/conf.d/hostname、ドメイン名は/etc/conf.d/domainnameで設定。
けど、ドメイン名は設定しなかった。

このconf.dをちょっとみてたらkeymapsというファイルがあって、さっそく修正。
KEYMAP="jp106"
とした。
この修正を反映させるにはどうしたらいいのかが分からなかったんだけれど、/etc/init.d/keymaps(シェルスクリプト)を使って、
# /etc/init.d/keymaps start
としたら、(何個かエラーは出たけれど)修正が反映された感じ。
これでvimがより快適に使えるw

ネットワークの設定の続きにいって、/etc/conf.d/netに
config_eth0=( "dhcp" )
と書いておいた。
で、ブート時に自動で起動するように、
# rc-update add net.eth0 default
としておいた。
ついでに、
# rc-update add keymaps defalut
も。
(domainnameは設定してないので付け加えなかった。)

あとはテキトーに/etc/hostsをいじって、ネットワークの設定終わり。

ちょっとサークルへ顔を出すので中断(午前10時)。
で、帰ってきてちょっと寝て、再開(午後11時)。

rootのパスワードを設定して、/etc/rc.confはエディタをvimに変えて、/etc/conf.d/keymapsはすでに設定してあったので無視。
/etc/conf.d/clockはCLOCK="local"と変更。
これでシステムの諸変更は終了。

ちなみにnet.eth0をrc-updateをしてたかどうか忘れてたので、ちょっと調べたところ、
# rc-update show [runlevel]
とすることで、runlevelでどのプログラムが立ち上がるかを見ることが出来るようだ。(もちろんnet.eth0は入ってた。Blogに書いてあるし(爆)

で、システムログツールのインストール。
雑誌ではsysklogdをインストールしていたので、(調べるのも面倒だし)自分もsysklogdをインストール。
# emerge app-admin/sysklogd
# rc-update add sysklogd default
マニュアルによればsysklogdにはログをローテーションする機能がないのであとでlogrotateを入れたほうがいいとのこと。

次はcronデーモン。
と思ったのだけれども、よくよく考えるとサーバじゃないんだし定期的に走らせるプログラムもないから、パスで。
比較するのが面倒だったからでは多分ありませんw

locateは欲しいから、インストール。
# emerge sys-apps/slocate
って、データベースの更新をcronでやんなきゃOTL
ということで、改めてcronデーモンのインストール。
めんどいので、雑誌に書いてあったdcronで。
# emerge sys-process/dcron
# rc-update add dcron default
# crontab /etc/crontab

あと、ファイルシステムツールをインストール。
ReiserFSを選んだので、
# emerge sys-fs/reiserfsprogs
とインストール。

DHCPクライアントのインストール。
# emerge net-misc/dhcpcd
デーモンなんだろうけれど、rc-updateはしなくてもいいのかな・・・?(というか、dhcpcdというスクリプトはない・・・?)

残るはブートローダのインストールのみ、と思ったら、起動画面で画像を表示するにはフレームバッファのサポートを有効にしていなきゃいけないっぽいんで、カーネルの再構築。。。
よく分からなかったので、とりあえず以下のような感じのを追加。
Device Drivers->Graphics support以下で、
 <*> Support for frame buffer devices
 <M> VESA VGA graphics support
 <M> Intel 830M/845G/852GM/855GM/865G support
(上のは、ちゃんと起動したらどちらかに絞る)
 [*] Support for the framebuffer splash
あと、
Device Drivers->Graphics support->Console display driver support以下の
 [*] Video mode selection support
 <*> Framebuffer Console support
(多分、いらないのもあるんだろうなぁ・・・)
とりあえずコンパイルしたのを
# cp arch/i386/boot/bzImage /boot/gen_kernel.2.6.15r1.fb
と/boot以下に別名でコピー。

やっとGRUBのインストール。
# emerge sys-boot/grub
で、/boot/grub/grub.confの編集。
以下のような感じで。
==> /boot/grub/grub.conf <== (←この書き方、いいですねw)
timeout 30
default 0
splashimage=(hd0,2)/boot/grub/splash.xpm.gz
#Gentoo Linux
title=Gentoo Linux 2.6.15-r1
root (hd0,2)
kernel /boot/gen_kernel.2.6.15r1.fb root=/dev/hda3 vga=0x31B video=vesafb:mtrr,ywrap
#Gentoo Linux(No Frame Buffer)
title=Gentoo Linux 2.6.15-r1(no_fb)
root (hd0,2)
kernel /boot/gen_kernel.2.6.15r1 root=/dev/hda3
#Windows
title=WindowsXP
rootnoverify (hd0,0)
makeactive
chainloader +1
まぁ、ほとんどマニュアル通りでw
(にしても、グラフィックカード(チップ?)がオンボードで、メモリが共用の場合には、ビデオRAMってどのサイズを指定すればいいんだろう?)

GRUBのインストール。
マニュアル通りに
# grep -v rootfs /proc/mounts > /etc/mtab
としてから、
# grub-install /dev/hda
ちゃんとインストールできたみたい。

で、再起動したんだけれどGRUBが・・・?
ちょっと調査。
原因判明。grub.confの位置が間違ってた、、、
/etc/grub.confではなく、/boot/grub/grub.confですね。
(上のも修正しました。)

修正して再起動。
ちゃんと起動しましたw
けど、kernelに与えるオプションが間違っているっぽくて、ブートスプラッシュが表示されない・・・
というか、モジュールで設定したのが悪そうな気もするので、取り込む形でカーネルの再構築。
・・・してもダメだった。んー、どうしたものか。(そもそも表示されないのかなぁ・・・?)

とりあえず、Windowsは無事起動&データの破損も(多分)なし。
もう遅い(という表現は変だけれど、とりあえず午前4時半)ので、あとは課題ということで。

追記。
なんだかんだで起きてて現在午前6時半。
なんかbootsplashはもうサポートが終わりで、今後はfbsplashというのに置き換わっていくらしい。
とりあえずlivecdみたいな起動の仕方ではないけれど、うまくいったみたい。
詳細は後で新しいエントリに書きます。


遺伝的アルゴリズム。

2006-03-14 02:41:00 |  Prog...
遺伝的アルゴリズム(もどき)による彩色アルゴリズム。

前回のエントリの通り、作りかけで放置していたので作り上げてみた。
といっても、終了判定が完全な手抜き。
とりあえず1000世代進めたら終了という、とんでもない終了判定を今回は採用してみた。(というのも、それ以外の終了判定にするには、実験を繰り返してみないことにはなんともいえないから。)

にしても、予想通りというかなんというか、彩色問題には遺伝的アルゴリズムはあまり向いてない感じがなんとも。
まぁ、パラメータの調整を全然していないから、完全に結論付けるのはまだ早いけれど。

遺伝的アルゴリズムを実装してみて思ったのが、パラメータの数が多すぎるということ。
挙げていくと、

  1. 最初に用意する遺伝子の数


  2. 淘汰は何世代ごとに起こすか


  3. 淘汰させるとき、何個の遺伝子を残すか


  4. 交配させるとき、何割の遺伝子を交配させるか


  5. 変異はどれくらいの割合で起こるか


  6. 1回の変異での、遺伝子の変化の度合い



今回は一番最初の以外はコマンドラインからパラメータを設定できるようにしたけれど、これだけあると解析が大変・・・
パラメータを動かすことによって結果にどのような影響が出るのかも予測しづらい。
なんか、このパラメータを調整すること自体が最適化理論を必要としそうな感じ・・・

あと、彩色問題の場合は「最適化されたときの値」というのが分からないので、終了判定が非常に難しい。
やはり実験を繰り返して解析をすることで、最高値が連続○回出たら終了、とか、この問題サイズに対しては○世代進めれば(だいたい)最適解が得られる、とかを調べていくしかなさそう。

まぁ、途中の様子とかを出力できるようにプログラムを改良して、で、解析していきたいと思います。時間があれば。



一応プログラムの概要。

“各点を彩色する色”の配列を遺伝子としています。
(たとえば、点1を1、点2を2、点3を3という色で塗るのであれば、遺伝子は1-2-3となるわけです。)

生物の場合はA,T,G,Cが遺伝子をなす物質(記号)となりますが、このプログラムでは点を塗る色が高々点の数個であることを利用して、1,2,…,|V(G)|が遺伝子をなす記号となっています。

最初ランダムに遺伝子が100個作られ、交配、変異が決められたパラメータにしたがって行われます。
交配される遺伝子はランダムに選ばれます。
また、変異する遺伝子も、すでにある遺伝子、交配によって得られた遺伝子両方が一緒くたにされた状態で、ランダムに選ばれます。(これは微妙によくない仕様かな・・・?)

こうして世代が進んでいき、決められたパラメータだけ世代が進むと、淘汰が起きます。
淘汰は、遺伝子の適応度の高いものが100個残されるようになっています。
遺伝子の適応度は次の式で定まります:
-(使われている色の数)-n×(隣接していて、同じ色の点の数) (※nは1以上)

こうして1000世代進んだら終了で、その時点で適応度の最も高い遺伝子の情報を整理して出力。

ちなみにデフォルトのパラメータは

  1. 淘汰を起こす周期: 3


  2. 交配する割合: 5


  3. 変異を起こす割合: 1


  4. 変異の度合い: 2



ってな感じですね。



以下、ソース。

=Graph.pm=
以前のと同じなので省略。

=DNA.pm=
package DNA;

#--------------------------------------------------
# DNA.pm ver.1.0 06/03/12
#
# 彩色情報を保持するクラス
#
# =フィールド=
# color 彩色の色の配列
# num 彩色情報の長さ
#
# =メソッド=
# obj new(num);
# オブジェクトを作成する
# インスタンスから呼び出された場合、
# インスタンスのコピーをする
# obj オブジェクト
# num 点の数
#
# void init(num);
# オブジェクトを初期化する
# obj オブジェクト
# num 点の数
#
# void copy(obj);
# フィールドをコピーする
# obj コピー元のオブジェクト
#
# void mutate(rate);
# 突然変異を起こさせる
# rate 突然変異の度合い(0~9)
#
# new mate(obj);
# 交配させて新しいオブジェクトを作る
# new 新しいオブジェクト
# obj 交配させるオブジェクト
#
# color get_color(void);
# 彩色の色を得る
# color 彩色の色の配列
#
# void set_color(color);
# 彩色の色を決定する
# color 彩色の色の配列
#
# bool check_color(a, b);
# 同じ色かを調べる
# bool 同じ色なら1
# a 対象の点
# b 対象の点
#--------------------------------------------------

sub new{

    my ($obj, $num) = @_;


    my $new;
my $class;


    if($class = ref $obj){
$new = bless {}, $class;
$new->copy($obj);
}
else{
$new = bless {}, $obj;
$new->init($num);
}


    return $new;


}

sub init{

    my ($self, $num) = @_;


    my $color = [];


    foreach(1..$num){
my $rand = int(rand $num);
++$rand;
push @$color, $rand;
}


    $self->{color} = $color;
$self->{num} = $num;


}

sub copy{

    my ($self, $obj) = @_;


    $self->set_color($obj->get_color());
$self->{num} = $obj->{num};


}

sub mutate{

    my ($self, $rate) = @_;


    my @color = $self->get_color();
my $n = $self->{num};


    if($rate != 0){
#変異させる数を得る
my $mutates = int($n * $rate / 10);
if($mutates == 0){
$mutates = 1;
}
if($mutates >= $n){
$mutates = $n-1;
}


        #変異させる要素を決める
my @target;
foreach(1..$mutates){
push @target, int(rand $n);
}


        #変異させる
foreach(@target){
$color[$_] = ($color[$_] + int(rand $n)) % $n + 1;
}
}


    $self->set_color(@color);


}

sub mate{

    my ($self, $obj) = @_;


    my $new = $self->new();
my @obj_color = $obj->get_color();


    my $num = $obj->{num} - 1;
my $segment = int(rand $num) + 1;


    foreach($segment..$num){
$new->{color}[$_] = $obj_color[$_];
}


    return $new;


}

sub get_color{

    my $self = shift @_;


    return @{$self->{color}};


}

sub set_color{

    my ($self, @color) = @_;


    $self->{color} = \@color;


}

sub check_color{

    my ($self, $a, $b) = @_;


    if($self->{color}[$a-1] == $self->{color}[$b-1]){
return 1;
}
else{
return 0;
}


}

1;

=Environ.pm=
package Environ;

#--------------------------------------------------
# Environ.pm ver.1.0 06/03/12
#
# Environクラス
# 環境を定める
#
# =フィールド=
# graph Graphクラスのインスタンス
# DNA DNAクラスのインスタンスの配列
# max 淘汰のときに残る数(最初に生成するDNAの数)
# age 世代
# cycle 淘汰を起こす周期(1-)
# mate_per 交配率(0-10)
# mutate_per 変異率(0-10)
# mutate_rate 変異の度合い(0-9)
#
# =メソッド=
# obj new(graph, max);
# オブジェクトを作成する
# obj オブジェクト
# graph Graphクラスのインスタンス
# max DNAクラスの初期数
#
# obj init(graph);
# オブジェクトを初期化する
# obj オブジェクト
# graph Graphクラスのインスタンス
# max DNAクラスの初期数
#
# void next(void);
# 一世代進める
#
# void selection(void);
# 淘汰を行い、maxの数にする
#
# num value(DNA);
# 適応度を得る
# 適応度は-(使っている色数)-n*(隣接してて同じ色の点の組の数)
# num 適応度
# DNA 対象となるDNAインスタンス
#
# DNA get_max_DNA(void);
# 適応度が最大のDNAを得る
# DNA 条件を満たすDNAインスタンス
#
# age get_age();
# ageを得る
# age 世代
#
# void set_max(max);
# maxをセットする
# max 淘汰のときに残る数
#
# void set_cycle(cycle);
# cycleをセットする
# cycle 淘汰を起こす周期(1-)
#
# void set_mate_per(mate_per);
# mate_perをセットする
# mate_per 交配率(0-10)
#
# void set_mutate_per(mutate_per);
# mutate_perをセットする
# mutate_per 変異率(0-10)
#
# void set_mutate_rate(mutate_rate);
# mutate_rateをセットする
# mutate_rate 変異の度合い(0-9)
#--------------------------------------------------

use Graph;
use DNA;

#初期値--------------------
my %default = (

    max         =>  100,
cycle => 3,
meta_per => 5,
mutate_per => 1,
mutate_rate => 2,


);

#クロージャー
sub get_default{

    my $key = shift @_;
return $default{$key};


}
#--------------------------

sub new{

    my ($class, $graph, $max) = @_;


    my $obj = bless {}, $class;
return $obj->init($graph, $max);


}

sub init{

    my ($self, $graph, $max) = @_;


    if(!$max){
$max = &get_default(max);
}


    $self->{graph} = $graph;
$self->{max} = $max;
$self->{age} = 1;
$self->{cycle} = &get_default(cycle);
$self->{meta_per} = &get_default(meta_per);
$self->{mutate_per} = &get_default(mutate_per);
$self->{mutate_rate} = &get_default(mutate_rate);


    my $num = $graph->get_n();
$self->{DNA} = [];
foreach(1..$max){
push @{$self->{DNA}}, DNA->new($num);
}


    return $self;


}

sub next{

    my $self = shift @_;


    my $DNA = $self->{DNA};
my @new;


    #交配
my $nums = int((@$DNA * $self->{mate_per}) / (10 * 2));
foreach(1..$nums){
my $rand1 = int(rand @$DNA);
my $rand2 = int(rand @$DNA);
push @new, $DNA->[$rand1]->mate($DNA->[$rand2]);
}


    #突然変異
$nums = int(@new * $self->{mutate_per} / 10);
foreach(1..$nums){
my $rand = int(rand @$DNA);
$DNA->[$rand]->mutate($self->{mutate_rate});
}


    @$DNA = (@$DNA, @new);
$self->{DNA} = $DNA;


    ++$self->{age};


    #淘汰
if(($self->{age} % $self->{cycle}) == 0){
$self->selection();
}


}

sub selection{

    my $self = shift @_;


    my $max = $self->{max};
my $DNA = $self->{DNA};


    @$DNA = sort {$self->value($b) <=> $self->value($a)} @$DNA;


    my $new;
foreach(1..$max){
push @$new, shift @$DNA;
}


    $self->{DNA} = $new;


}

sub value{

    my ($self, $DNA) = @_;


    my $value = 0;
my $graph = $self->{graph};
my @color = $DNA->get_color();
my $num = $graph->get_n();


    #使われている色の数
my %color_list;
foreach(@color){
$color_list{$_} = 0;
}
$value -= scalar(keys %color_list);


    #隣接していて同じ色の点の数
my $i, $j;
foreach $i (1..$num){
foreach $j (1..$num){
if(
$graph->check_nbr($i, $j)
&&
$DNA->check_color($i, $j)
){
--$value;
}
}
}


    return $value;


}

sub get_max_DNA{

    my $self = shift @_;


    my $DNA = $self->{DNA};
@$DNA = sort {$self->value($b) <=> $self->value($a)} @$DNA;


    return $DNA->[0];


}

sub get_age{

    my $self = shift @_;
return $self->{age};


}

sub set_max{

    my ($self, $max) = @_;
$self->{max} = $max;


}

sub set_cycle{

    my ($self, $cycle) = @_;
$self->{cycle} = $cycle;


}

sub set_mate_per{

    my ($self, $mate_per) = @_;
$self->{mate_per} = $mate_per;


}

sub set_mutate_per{

    my ($self, $mutate_per) = @_;
$self->{mutate_per} = $mutate_per;


}

sub set_mutate_rate{

    my ($self, $mutate_rate) = @_;
$self->{mutate_rate} = $mutate_rate;


}

1;

=genetic_paint=
#!/usr/bin/perl

#--------------------------------------------------
# genetic_paint ver.1.0 06/03/12
#
# 遺伝的アルゴリズムによる点彩色
#
# =オプション=
# -t 対話的にグラフを作成
# -s 標準入力からグラフを作成
# -v 冗長出力をする
# -h ヘルプを出力
# --cycle=num cycleをnumにする
# --mate_per=per mate_perをperにする
# --mutate_per=per mutate_perをperにする
# --mutate_rate=rate mutate_rateをrateにする
# 何も指定されないときには-tvが指定され、
# デフォルトの値が利用される
#--------------------------------------------------

use Graph;
use DNA;
use Environ;

sub print_help{

    print <<END_OF_HELP;


genetic_graph: 遺伝的アルゴリズムによる点彩色

=構文=
genetic_graph [-tsvh] [--cycle=num] [--mate_per=per] [--mutate_per=per] [--mutate_rate=rate]

=オプション=

  • t 対話的にグラフを作成


  • s 標準入力からグラフを作成


  • v 冗長出力をする


  • h ヘルプを出力
    • cycle=num 淘汰を起こす周期(1-)


    • mute_per=per 交配率(0-10)


    • mutate_per=per 変異率(0-10)


    • mutate_rate=rate 変異の度合い(0-9)





オプションを指定しなかった場合、-tvとデフォルト
の値が指定されて実行される

END_OF_HELP
}

sub anly_opt{

    my $opt;


    $opt->{t} = 1;


    foreach(@ARGV){
if(!/=/){
if(/t/){
$opt->{t} = 1;
$opt->{s} = 0;
}
elsif(/s/){
$opt->{t} = 0;
$opt->{s} = 1;
}


            if(/v/){
$opt->{v} = 1;
}


            if(/h/){
$opt->{h} = 1;
}
}
else{
if(s/--cycle=//){
$opt->{cycle} = $_;
if($_ < 1){
&error("オプションが不正です");
}
}
elsif(s/--mate_per=//){
$opt->{mate_per} = $_;
if($_ < 0 or $_ > 10){
&error("オプションが不正です");
}
}
elsif(s/--mutate_per=//){
$opt->{mutate_per} = $_;
if($_ < 0 or $_ > 10){
&error("オプションが不正です");
}
}
elsif(s/--mutate_rate=//){
$opt->{mutate_rate} = $_;
if($_ < 0 or $_ > 9){
&error("オプションが不正です");
}
}
}
}


    if(scalar(@ARGV) == 0){
$opt->{v} = 1;
}


    return $opt;


}

sub error{

    my $msg = shift @_;
print "$msg\n";
exit;


}

sub main{

    my $opt = &anly_opt();
my $graph;
my $env;
my $best;


    if($opt->{h}){
&print_help();
exit;
}


    if($opt->{t} == 1){
$graph = Graph->talk_new();
}
elsif($opt->{s} == 1){
$graph = Graph->input_new();
}
else{
&error("グラフが作成されません");
}


    if($opt->{v} == 1){
$| = 1;
print "グラフのチェック中...";
$| = 0;
}
if($graph->check()){
if($opt->{v} == 1){
print "OK\n\n";
}
}else{
&error("グラフになっていません");
}


    $env = Environ->new($graph);


    if(exists $opt->{cycle}){
$env->set_cycle($opt->{cycle});
}
if(exists $opt->{mate_per}){
$env->set_mate_per($opt->{mate_per});
}
if(exists $opt->{mutate_per}){
$env->set_mutate_per($opt->{mutate_per});
}
if(exists $opt->{mutate_rate}){
$env->set_mutate_rate($opt->{mutate_rate});
}


    if($opt->{v} == 1){
$| = 1;
print "グラフ彩色中...";
$| = 0;
}
while(1){
$env->next();
if(&determine($env)){
last;
}
}
if($opt->{v} == 1){
print "OK\n\n";
}


    $best = $env->get_max_DNA();
my @color = $best->get_color();


    #データの整理
my $i = 0;
my %list;
foreach(@color){
$list{$_} .= "$i<>";
++$i;
}
$i = 1;
@color = ();
foreach(keys %list){
my @nums = split /<>/,$list{$_};
foreach(@nums){
$color[$_] = $i;
}
++$i;
}


    if($opt->{v} == 1){
print "隣接行列\n";
$graph->print_matrix();
print "\n各点の色\n";
}
$i = 1;
foreach(@color){
printf "v%02d:%3d\n", $i, $_;
++$i;
}


}

sub determine{

    my $env = shift @_;


    if($env->get_age() > 1000){
return 1;
}
else{
return 0;
}


}

&main();

いやぁ、無駄に長い(^^;
オプションを解析するクラスを一つ作っちゃった方がいいんですよねぇ。