The net is vast
プログラミングや、コンピュータなどの備忘録です。 主にRuby, Java, Linux, 等を扱います。アルゴリズムも扱いたいな。
ラベル プログラミング の投稿を表示しています。 すべての投稿を表示
ラベル プログラミング の投稿を表示しています。 すべての投稿を表示
0:00

dreamhost(linux) + rsyncで差分バックアップをする方法

Category: By jx
中学校の頃からデジカメで写真を撮ってきて、バックアップをろくにとっていませんでした。いつもバックアップしようと思うのですが、当時はCD-Rに入りきらないし、DVD-Rがでてもその頃にはDVD-Rにも入りきらない状態でした。だからいつも億劫になってしまってバックアップを取ってこなかったのです。

それじゃまずいだろということで、さすがに良い歳にもなったのでそろそろまじめにバックアップを考えました。調べてみると最近はいろいろと手段があるようでした。WebサービスであればDropboxが有名ですが、これは容量制限が結構小さいので無理ですし、最近でてきたトレンドマイクロ オンラインストレージ SafeSyncもあまり使い勝手が良くないようです。

ここは、技術者の端くれとしてバックアップスクリプトを自分で書くのだということで、調べているとrsyncがバックアップしてくれるらしい記述を発見。--link-destというオプションをつけると、差分バックを取ってくれるようです。仕組みは意外とシンプルで、linuxの仕組みを使っていて感心しました。

ext2系のファイルフォーマットではi-nodeという仕組みでファイルを管理しています。ハードリンクを使うと同じi-nodeを指し示す別名のファイルを作成する事ができるのです。つまり、ファイル名は異なっても指し示しているファイルは同じ物です。つまり、このrsync --link-destを使ってバックアップを使用している限り、任意の時点からの差分バックアップが簡単にとれるのです。

また、私はDreamHostでサーバをレンタルしているのですが、このDreamHostはディスク容量が無制限なので、自由にバックアップする事ができます。しかし、本当に無制限で大丈夫なんでしょうかね?まぁちゃんとunlimited diskと書いてあるのでありがたく使わせてもらいましょう。

肝心のスクリプトですが、こんな感じになりました。これを定期的に実行すればバックアップは完璧ですね!
SOURCE_DIR=~/Documents/backuped
DEST_HOST=user@dreamhost.com
DEST_DIR=/home/user/backup
DATE=`TZ=JST-9 date "+%Y%m%d%H%M%S"`

CURRENT=$DEST_DIR/current
RELATIVE_CURRENT=../current
THIS_TIME=$DEST_DIR/$DATE

rsync -av --delete --link-dest $RELATIVE_CURRENT $SOURCE_DIR $DEST_HOST:$THIS_TIME
ssh $DEST_HOST "rm -fr $CURRENT; ln -s $THIS_TIME $CURRENT"
 
0:34

vim-quickrunを使って高速開発

Category: , By jx
最近プログラミングコンテストチャレンジブックを読もうとしています。 そこで、c++を勉強してみようかと考えているのですが、学習効率の向上のため、vimで高速に開発できないものかといろいろ調べてみたところ、quickrun.vimというものが見つかりました。

quickrun.vimの種類

quickrun.vimには2種類あるみたいでujihisaさんが作ったquickrun.vimとthincaさんが作ったvim-quickrunがあるみたい。で、ujihisaさんの昨日はthincaさんのvim-quickrunに取り込まれてるらしいので、vim-quickrunを使えば良いみたいです。

インストール

vim-quickrunはShougoさんが作ったvimshellを必要としているのでそちらも必要になります。また、Vimは7.2以上が必要条件のようです。 そして、これらをpluginにコピーしてやればOK。
git clone http://github.com/Shougo/vimshell.git
git clone http://github.com/thinca/vim-quickrun.git
pushd .
cd vimshell
cp -R * ~/.vim/
popd
cd vim-quickrun
cp -R * ~/.vim/
これでうまく動きます。かなり快適に勉強できますよ!! vim-quickrunオススメ!
 
0:53

Dreamhostで自分だけがアクセスするgitレポジトリを作成する

Category: By jx
今までSubversionを利用していたのですが、Herokuを使う事もあり普段使うバージョン管理ツールもgitにしようとしています。そこで、自分が自由に使えるレポジトリを創りたかったのですが、githubだと有料だし、せっかくDreamhostを借りているんだからここでレポジトリを作成したいと思います。なるべく簡単にいきます。手間をかけたくないですからね。

レポジトリの作成

まずプロジェクトを格納するディレクトリを作成します。以下のように作成しておけばレポジトリを追加したくなったら~/git/以下にディレクトリをどんどん掘って行けば良いですね。
[DREAMHOST]$ mkdir -p ~/git/SomeProject.git
今度は作成したディレクトリをレポジトリにします。
[DREAMHOST]$ cd ~/git/SomeProject.git
[dreamhost]$ git --bare init
今度はローカルホストでレポジトリをcloneします。
[localhost]$ git clone ssh://USERNAME@DREAMHOST/home/USERNAME/git/SomeProject.git
さらに、このレポジトリに名前を付けておきましょう。
[localhost]$ git remote add NAME ssh://USERNAME@DREAMHOST/home/USERNAME/git/SomeProject.git
ここまですれば簡単にgitを使う事ができます。 ローカルでの変更後
[localhost]$ git add -A
[localhost]$ git commit -m 'some message'
[localhost]$ git push NAME master
 
18:47

Bashで実行ファイルのディレクトリを取得する方法

Category: By jx
ネットで探してもBashで実行ファイルのディレクトリを取得する方法がなかなか見つからなかった。 やっと見つけたのが以下のページ shでスクリプトの実行ディレクトリを取得する - 進・日進月歩
echo $(cd $(dirname $0);pwd)
 
15:26

HTMLの文字コードの指定方法についての不思議

Category: By jx

自分が作ってるサイトのページHome - CapoeiraでIEにて文字化けが発生すると言われていました。ちゃんと、HTMLのmetaタグにContentTypeを指定していたにも関わらずです。そこで、調べてみると、HTML Document Representationに載っていました。優先される順に書くと、

  1. An HTTP "charset" parameter in a "Content-Type" field.
  2. A META declaration with "http-equiv" set to "Content-Type" and a value set for "charset".
  3. The charset attribute set on an element that designates an external resource.

となっています。日本語訳から持ってくると、

  1. HTTPヘッダのContent-Typeフィールドの、charsetパラメータ。
  2. META要素で、http-equiv属性値がContent-Typeかつvalue属性の値にcharset情報があるもの。
  3. 外部リソースを指している要素に設定されているcharset属性値。

3番目は何をさしているのはよくわかりませんが、少なくとも1番目と2番目は逆であるべきだと思うのですが、なんでこのような順序になっているのでしょうか?管理者がcharset=euc-jpで設定していても、各HTMLの作成者がUTF-8で書いていれば、そちらを優先すべきだと思うのですが、なにか理由があるのでしょうか。ん〜不思議

 
0:44

fastlookup_bookmarklet ブックマークレットで辞書を引く

Category: By jx

fastlookup alc なんかがあると、辞書を引くのが簡単です。でも、userscriptが使えないとだめだったりして、最近はもっぱらChromeを使用しているため、使えません。仕方ないので、YAHOO Pipesを利用して、YAHOOの英和辞書を引くブックマークレットを作成しました。自分はIEを使わないので、IEには非対応ですが、簡単に対応できるはずです。

必要なときだけブックマークレットを読みこめばいいし、使い勝手は悪くないと思います。

使い方は簡単。ブックマークレットを実行したら、辞書を引きたい単語を選択してください。Firefox, Webkit系で動くはずです。

fastlookup_bookmarklet

 
0:12

Dijkstra's AlgorithmとA-Star AlgorithmをJavaScriptで実装してみた

Category: , By jx

ダイクストラ法とA-StarアルゴリズムをJavaScriptで実装してみた。

ダイクストラ法は確かに動いているように思えるけど、A-Starの方はうまく動いていないように見えるというか、全然高速化されていない。こんなもんなのかな?知ってる人いたら教えてください。

Create Map:
(function() {
var start;
var tdList;
var mapSize = 10;
var map; 
var dijkstra = function(sx, sy, gx, gy, astar) {
 var startTime = new Date().getTime();
 var masterList = new NodeList(); // Node全てを格納するリスト
 var openList = new NodeList(); // スコアが確定していないノードを格納するリスト
 var closeList = new NodeList(); // スコアが確定したノードを格納するリスト
 var maxWidth = map[0].length; // 地図の幅
 var maxHeight = map.length; // 地図の高さ

 message(''); // ログ
 // 地図データからノードを作成
 for (var i = 0, len = map.length; i < len; i++) {
  for (var j = 0, jlen = map[i].length; j < jlen; j++) {
   masterList.add(new Node(j, i));
  }
 }

 // スタートノードの設定
 var targetNode = masterList.get(sx, sy);
 targetNode.score = 0;
 closeList.add(targetNode); // スタートノードはcloseListに格納しておく

 var whileCount = 0;
 while (true) {
  whileCount++;
  // 次のノードを探索
  var checkNodePositions = [[targetNode.x, targetNode.y - 1], [targetNode.x, targetNode.y + 1], [targetNode.x - 1, targetNode.y], [targetNode.x + 1, targetNode.y]];
  for (var i = 0, len = checkNodePositions.length; i < len; i++) {
   var checkNodePosition = checkNodePositions[i];
   // 地図の範囲外であれば探索しない
   if (checkNodePosition[0] < 0 || checkNodePosition[0] > maxWidth - 1 ||
     checkNodePosition[1] < 0 || checkNodePosition[1] > maxHeight - 1) {
    continue;
   }
   var checkNode = masterList.get(checkNodePosition[0], checkNodePosition[1]);
   if (checkNode.type == 0) continue; // 壁だったら処理しない
   if (closeList.get(checkNodePosition[0], checkNodePosition[1])) continue; // スコアが確定していればなにもしない
   if (!openList.get(checkNodePosition[0], checkNodePosition[1])) {
    openList.add(checkNode); // openListにもcloseListにも無ければopenListに格納しておく
   }
   var score;
   if (astar) {
    score = targetNode.score + 1 + Math.abs(checkNodePosition[0] - gx) + Math.abs(checkNodePosition[1] - gy);
    //console.log(score);
   } else {
    score = targetNode.score + 1; // この経路を辿ったときのスコアはtargetNode.score + 1
    //console.log(score);
   }
   // スコアが格納されていない、またはほかの経路よりも効率が良ければスコアと、一つ前のノードをセットする
   if (isNaN(checkNode.score) || checkNode.score > score) {
    checkNode.score = score;
    checkNode.parent = targetNode;
   }
  }
  // openListが0になってしまったら、辿ることができないということ
  if (openList.length() == 0) {
   message('No route!');
   return;
  }
  // 現在openListに格納されている最小のスコアのノードはスコアを確定し、closeListに格納する
  targetNode = openList.getMin();
  openList.remove(targetNode);
  closeList.add(targetNode);
  targetNode.score = targetNode.score;
  if (targetNode.x == gx && targetNode.y == gy) break;
 }
 var endTime = new Date().getTime();
 message(endTime - startTime + 'ms' + ' whileCount:' + whileCount);
 showRoute(targetNode); // ルートを表示する
}
var message = function(value) {
 document.getElementById('message').innerHTML = value;
}
var showRoute = function(targetNode) {
 var td = tdList.get(targetNode.x, targetNode.y);
 td.className = 'scotch route';
 td.style.backgroundColor = 'green';
 var parent = targetNode.parent;
 if (parent) showRoute(parent);
}
var createMapData = function(count) {
 map = [];
 start = [0, 0];
 for (var i = 0, len = mapSize * count; i < len; i++) {
  var row = [];
  for (var j = 0, jlen = mapSize * count; j < jlen; j++) {
   var r = Math.floor(Math.random() * 100) % 5;
   row.push(r);
  }
  map.push(row);
 }
}
var createMap = function() {
 var graph = document.getElementById('graph');
 graph.innerHTML = '';
 var table = graph.appendChild(document.createElement('table'));
 table.style.borderCollapse = 'collapse';
 var tbody = table.appendChild(document.createElement('tbody'));
 tdList = new Table();

 for (var i = 0, len = map.length; i < len; i++) {
  var tr = tbody.appendChild(document.createElement('tr'));
  var row = [];
  for (var j = 0, jlen = map[i].length; j < jlen; j++) {
   var td = tr.appendChild(document.createElement('td'));
   observe(td, 'click', analyse);
   td.style.border = '1px solid white';
   td.style.width = '10px';
   td.style.height = '10px';
   if (map[i][j] == 0) {
    td.className = 'scotch wall';
    td.style.backgroundColor = 'red';
   }
   else td.className = 'scotch';
   tdList.set(j, i, td);
  }
 }
}
var analyse = function(event) {
 var target = event.target || event.srcElement;
 var trChildren = target.parentNode.children;
 var tbodyChildren = target.parentNode.parentNode.children;
 var x,y;
 for (var i = 0, len = trChildren.length; i < len; i++) {
  if (trChildren[i] == target) {
   x = i;
   break;
  }
 }
 var tr = target.parentNode;
 for (var i = 0, len = tbodyChildren.length; i < len; i++) {
  if (tbodyChildren[i] == tr) {
   y = i;
   break;
  }
 }
 if (start[0] == x && start[1] == y) {
  message('Start is equals to Goal');
  return;
 }
 if (target.className.indexOf('wall') != -1) {
  message('Your clicked cell is wall');
  return;
 }
 // routeをクリアする
 tdList.each(function(td) {
  var className = td.className;
  var classNameList = className.split(/ /);
  for (var i = classNameList.length - 1; i >= 0; i--) {
   if (classNameList[i] == 'route') {
    classNameList.splice(i, 1);
    td.style.backgroundColor = '';
   }
  }
  td.className = classNameList.join(' ');
 });
 var astar = document.getElementById('astar20090824').checked;
 dijkstra(start[0], start[1], x, y, astar);
 start = [x, y];
}
var observe = function(target, type, listener) {
 if (target.addEventListener) target.addEventListener(type, listener, false);
 else target.attachEvent('on' + type, function() { listener.call(target, window.event); });
}
var Node = function(x, y) {
 this.x = x;
 this.y = y;
 this.type = map[y][x];
}
Node.prototype.score = NaN;
Node.prototype.parent = null;

var NodeList = function() {
 this.data = {};
}
NodeList.prototype.add = function(value) { this.data[value.x + ',' + value.y] = value; }
NodeList.prototype.get = function(x, y) { return this.data[x + ',' + y]; }
NodeList.prototype.length = function() {
 var count = 0;
 for (var key in this.data) {
  count++;
 }
 return count;
}
NodeList.prototype.remove = function(value) { delete this.data[value.x + ',' + value.y]; }
NodeList.prototype.getMin = function() {
 var data = this.data;
 var min = null;
 for (var node in data) {
  if (!min) {
   min = data[node];
   continue;
  }
  if (min.score > node.score) min = data[node];
 }
 return min;
}
var Table = function() {
 this.data = {};
}
Table.prototype.set = function(x, y, value) { this.data[x + ',' + y] = value; }
Table.prototype.get = function(x, y) { return this.data[x + ',' + y]; }
Table.prototype.each = function(func) {
 var data = this.data;
 for (var key in data) {
  func(data[key]);
 }
}

observe(document.getElementById('mapSelect20090824'), 'change', function(event) {
 var target = event.target || event.srcElement;
 var value = target.value;
 createMapData(value);
 createMap();
});
createMapData(1);
createMap();
})();
 
23:31

集合知プログラミング第11章 進化する知性

 
23:20

集合知プログラミング第9章 高度な分類手法:カーネルメソッドとSVM

 
0:54

集合知プログラミング第7章 決定木によるモデリング

例によって、勉強したので公開
 
0:03

集合知プログラミング第5章 最適化

とりあえず勉強会用資料を作成した。基本的に自分が勉強するための資料なので、うまくまとまってもいないけど公開します
 
2:29

集合知プログラミング第3章のドラフト

途中だけど、とりあえず外から見えるようにしておく。