アルゴリズムイントロダクション 練習問題5.1-3
問題
0と1をそれぞれ確率1/2で出力する問題を考える。利用できるのは0か1かを出力する手続きBIASED-RANDOMである。BIASED-RANDOMは1を確率p、0を確率1-pで出力する(0
やっぱり実装まで。期待実行時間は出していない。あと証明もまだ(これはたぶんすぐできる)。
発想
- PK戦のサドンデスで、先攻が勝ったら1、後攻が勝ったら0を返すとすればよい
public class Utility { public static boolean randomBoolean() { boolean a = true; boolean b = true; double p = 0.7; // Any p is OK. s.t. 0 < p < 1 while (!(a ^ b) ) { a = randomBooleanByProbability(p); b = randomBooleanByProbability(p); } return a; } // BIASED-RANDOM public static boolean randomBooleanByProbability(double p) { if (Math.random() < p ) return true; else return false; } }
import static org.junit.Assert.*; import org.junit.Test; import com.gmail.seizans.algorithm.Utility; public class UtilityTest { @Test public void randomBooleanTest() throws Exception { int numberOfTrials = 20000; double minProb = 0.95; double maxProb = 1.05; int counter = 0; boolean isOk = false; for (int i = 0; i < numberOfTrials; i++) { if (Utility.randomBoolean() ) counter++; } if (numberOfTrials * minProb < counter * 2 && counter * 2 < numberOfTrials * maxProb ) { isOk = true; } assertTrue(isOk); } @Test public void randomBooleanByProbabilityTest() throws Exception { double p = 0.66666; int numberOfTrials = 20000; double minProb = 0.95; double maxProb = 1.05; boolean isOk = false; int counter = 0; for (int i = 0; i < numberOfTrials; i++) { if (Utility.randomBooleanByProbability(p) ) counter++; } if (p * numberOfTrials * minProb < counter && counter < p * numberOfTrials * maxProb) { isOk = true; } assertTrue(isOk); } }
アルゴリズムイントロダクション 練習問題5.1-2
問題:
RANDOM(0,1) に対する呼び出しだけを用いて手続き RANDOM(a,b) を実現せよ。実現された手続きの平均実行時間を a と b の関数として表現せよ。
RANDOM(a,b) とは、a<=x<=bな整数xをランダムに返す関数です。
とりあえず実装まで。
発想:
- RANDOM(a,b)を実現するのはRANDOM(0,n)を実現するのと同値だからこれをやる
- nが2の累乗ならばRANDOM(0,1)をln(n)回やればOKなんだけどなぁ・・・
- あ、無効な値になってしまったときはもう1回やればいいや!
import java.util.Random; public class Utility { // This method means Random(0, 1) public static int randomZeroOne() { Random random = new Random(); int result = random.nextInt(2); return result; } public static int log2(int n) { if (n <= 0) { throw new IllegalArgumentException(); } int result = (int) Math.ceil(Math.log(n) / Math.log(2) ); return result; } public static int random(int a, int b) { if (a >= b || a < 0) { throw new IllegalArgumentException(); } int result = 0; int m = log2(b - a); while (true) { for (int i = 0; i < m; i++) { result += randomZeroOne() * Math.pow(2, i); } result += a; if (result <= b) { return result; } else { result = 0; } } } }
import com.gmail.seizans.algorithm.Utility; import static org.hamcrest.CoreMatchers.is; import static com.gmail.seizans.algorithm.Utility.log2; public class UtilityTest { @Test public void log2Test() throws Exception { assertThat(log2(1), is(0) ); assertThat(log2(2), is(1) ); assertThat(log2(3), is(2) ); assertThat(log2(4), is(2) ); assertThat(log2(5), is(3) ); assertThat(log2(6), is(3) ); assertThat(log2(7), is(3) ); assertThat(log2(8), is(3) ); } @Test public void randomTest() throws Exception { int a = 20; int b = 30; boolean isOk = true; int numberOfTrials = 50; for (int i = 0; i < numberOfTrials; i++) { int r = Utility.random(a, b); if (r < a || b < r) { isOk = false; } System.out.println(r); } assertTrue(isOk); } }
とりあえず動いているかのように見える。
しょっぱい点に気づかれたら教えてくださいませ。どうか。
練習中
練習中です。
public class HelloWorld { public static void main(String args[]) { System.out.println("HelloWorld"); } }
public class HelloHatena { public static void main(String args[]) { System.out.println("HelloHatena"); } }
double x = x + x quadruple x = double (double x) factorial n = product [1 .. n] average ns = sum ns `div` length ns last1 :: [a] -> a last1 xs = xs !! (length xs - 1 ) last2 :: [a] -> a last2 xs = head (reverse xs ) init1 :: [a] -> [a] init1 xs = reverse (tail (reverse xs) ) init2 :: [a] -> [a] init2 xs = take (length xs - 1) xs type1 = ['a','b','c'] type2 = ('a','b','c') type3 = [(False,'o'),(True,'1')] type4 = ([False,True],['0','1']) type5 = [tail,init,reverse] type6 = ['1','2','3'] second xs = head (tail xs) swap (x,y) = (y,x) pair x y = (x,y) double1 x = x * 2 palindrome xs = reverse xs == xs twice f x = f (f x)
んー。他の人はソース部分で色つけたりしてるけど、どうやってるんだろう。
→@eller86 さんに教えてもらって解決。
あと、なんだかリストのインデントが深いな。どこの設定だろうか。
奥義書
@mayahjp さんに聞いた奥義書リスト。(東京大学の科目に対応)
東京大学
http://www.is.s.u-tokyo.ac.jp/student/lecture.html
ヘネシーアンドパターソン
パターソンアンドヘネシー
(計算機システム)
「最初にやれ!」
アルゴリズムとデータ構造 AHO(えいほ) だけど pascal だから他でもよい
(アルゴリズムとデータ構造)
オペレーティングシステムコンセプト
Operating System Concepts
(オペレーティングシステム)
「数学寄りならオススメ!」
コンパイラ―原理・技法・ツール〈1〉 (Information & Computing)
Modern Compiler Implementation インなんとか
Types and Programming Languages
(言語処理系論)
「最初にオススメ!」
ふつうのLinuxプログラミング Linuxの仕組みから学べるgccプログラミングの王道
(システムプログラミング実験:「ls作れ」からスタート)
Haskell と Prolog をやるべし
(関数・論理型プログラミング実験)
へねぱたでおk
(計算機構成論)
パス
(知能システム論)
ルンゲクッタとエイトケン加速とかが書いてある本
(連続系アルゴリズム)
CPUのつくりかた系の本
(プロセッサ・コンパイラ実験)
なかった
(コンピュータネットワーク)
ルンゲクッタとかでいいはず
(計算アルゴリズム論)
パス
(分散・並列システム論)
(計算機言語論)
CoqとかSpinをやってるはず
時相論理とか様相論理をやってる
(計算モデル論)
パス(知識処理論)
誰のためのデザイン(ユーザインターフェース)
奥義ではないからパス
(コンピュータビジョン)
(バイオインフォマティクス)
(整体数理モデル論)
1st title
Description test.
test.
How can I write source code in Hatena::Diary?