二分探索

Latest Author IL_mstaIL_msta /Date 2018-02-13 19:54:20 / Views 2714
1 (Favした一覧ページはユーザーページから)

二分探索 (binary search)は、全順序集合$S$に対し単調な関数$f : S \rightarrow \{0,1\}$が与えられた時、$f(x) = 1$となる最小の$x$を見つける、あるいは近似するアルゴリズムである。

(だれか加筆してください)

・探索対象
f(x) >= [F_TERGET]となる最小値[x]を調べる
xは整数としてみる。

・目的関数f(x)が満たす条件
f(x)は単調増加関数。(_)
f(x) <= f(x+|α|)

・初期区間の区間端が満たす条件
[NG,OK]	(NG<=OK)
//[NG]の設定
NG = 0;//適当に入れてる
/*//やったことない
NG = 0;
sub = -1;//sub<0	減少方向に持っていく
while( f(NG) >= F_TERGET ){
	NG += sub;//オバフロ
	sub *= 2;//オバフロ
}
*/
//f(NG) < F_TERGET が成立する値[NG]
//f(NG) >= F_TERGET が成立しない値[NG]
/*
f(-inf)>=F_TERGET
の場合はどうなるんだろうね?
*/

//[OK]の設定
OK = 1;
while( f(OK) < F_TERGET ){
	OK *= 2;//オーバーフロー
}
/*//区間が負の場合に出会ったことが無い
OK = 1;
add = 1;//add>0増加方向に持っていく
while( f(OK) < F_TERGET ){
	OK += add;//オーバーフロー
	add *= 2;//オーバーフロー
}
*/
//f(OK) >= F_TERGET	が成立する値[OK]
//f(OK) < F_TERGET が成立しない値[OK]

・1step
while(OK-NG>1 /*続行条件*/)
{
	//中央値の取得
	mid = (OK+NG)/2;//オーバーフローに注意NG+(OK-NG)/2
	F_mid = f(mid);//fの計算オーダー
	
	//判定
	if( F_mid < F_TERGET ){
		//区間[NG,mid]上にF_TERGETはない。f([NG,mid]) < F_TERGET
		//f(x)<[F_TERGET]が成立する最大値[x]は、[mid]以上
		//f(x)>=[F_TERGET]が成立しない最大値[x]は、[mid]以上
		NG = mid;
	}
	else{//F_mid >= F_TERGET;
		//区間[mid,OK]上にF_TERGETはある。f([mid,OK]) >= F_TERGET
		//f(x)>=[F_mid]が成立する最小値[x]は、[mid]以下
		OK = mid;
	}
	/*
	調べる区間が[NG,OK]から
	[NG,mid]又は[mid,OK]に変更される。
	この1stepで区間は半分ぐらいになる。
	*/
}
答えは[OK]