投稿者:チムセー
投稿日:2013年 5月29日(水)18時33分39秒
|
|
|
LET t0=TIME
RANDOMIZE
DECLARE EXTERNAL FUNCTION AP
DECLARE EXTERNAL FUNCTION TOP
DIM IN(1 TO 18,1 TO 10) !10個体を準備11から18は子孫
DIM CIN(1 TO 18,1 TO 10)
DIM INA(1 TO 18) !個体の評価値
FOR i=1 TO 10 !20個体をランダムに作成
FOR n=1 TO 10
LET IN(i,n)=INT(RND*2)
NEXT N
LET INA(i)=AP(IN,i)
NEXT i
FOR i=1 TO 10000 !世代数
!交叉
LET A=INT((TOP(INA)/100))
LET B=TOP(INA)-INT((TOP(INA)/100))*100
FOR t=1 TO 4
FOR n=1 TO 10
LET IN(10+2*t-1,n)=IN(A,n)
LET IN(10+2*t,n)=IN(B,n)
NEXT n
FOR n=1 TO 10
IF RND>0.9 THEN
LET IN(10+2*t-1,n)=IN(10+2*t-1,n)+IN(10+2*t,n)
LET IN(10+2*t,n)=IN(10+2*t-1,n)-IN(10+2*t,n)
LET IN(10+2*t-1,n)=IN(10+2*t-1,n)-IN(10+2*t,n)
END IF
NEXT n
NEXT t
FOR n=1 TO 10
LET CIN(1,n)=IN(A,n)
LET CIN(2,n)=IN(B,n)
NEXT n
FOR t=3 TO 10
FOR n=1 TO 10
LET CIN(t,n)=IN(t+8,n)
NEXT n
NEXT t
FOR t=1 TO 10 !IN書き出し&突然変異
FOR n=1 TO 10
IF RND>0.05 THEN
LET IN(t,n)=CIN(t,n)
ELSE
LET IN(t,n)=1-CIN(t,n)
END IF
NEXT n
NEXT t
FOR t=1 TO 10
LET INA(t)=AP(IN,t)
NEXT t
NEXT i
LET P1=INT((TOP(INA)/100))
PRINT INA(P1)
PRINT time-t0
END
EXTERNAL FUNCTION AP(IN(,),i) !個体評価
DEF f(x)=SIN(3*x)+0.5*SIN(9*x)+SIN(15*x+50)
FOR n=0 TO 9
LET T=IN(i,n+1)
LET m=m+T*2^n
NEXT n
LET AP=f(m/1023)
END FUNCTION
EXTERNAL FUNCTION TOP(INA()) !優秀な個体の検索,返り値は配列番号0102見たいに上位2桁から一番
LET NO1=-10 !評価値の最低値以下の値
LET NO2=-10 !評価値の最低値以下の値
FOR i=1 TO 10
IF NO1<INA(i) THEN
LET NO1=INA(i)
LET TNO1=i
END IF
NEXT i
FOR i=1 TO 10
IF NO2<INA(i) AND i<>TNO1 THEN
LET NO2=INA(i)
LET TNO2=i
END IF
NEXT I
LET TOP=TNO1*100+TNO2
END FUNCTION
|
|
|
投稿者:島村1243
投稿日:2013年 5月29日(水)19時31分13秒
|
|
|
チムセーさんへのお返事です。
珍しい方法ですが、方法の名称は有るのでしょうか?
また、使い方を知りたいのですが、最大値を求めたい関数を指定する箇所は下記「DEF f(x)」でしょうか?
EXTERNAL FUNCTION AP(IN(,),i) !個体評価
DEF f(x)=SIN(3*x)+0.5*SIN(9*x)+SIN(15*x+50)
また、最大値が得られるXの値を知るにはどこで「print x」を記述すれば良いでしょうか?
よろしくご教示お願い致します。
|
|
|
投稿者:山中和義
投稿日:2013年 6月 1日(土)06時10分40秒
|
|
|
> No.3069[元記事へ]
島村1243さんへのお返事です。
チムセーさんが不在のようなので、代わりに回答します。
> 珍しい方法ですが、方法の名称は有るのでしょうか?
●遺伝的アルゴリズム(Genetic Algorithm、GA)で関数の最大値を求める問題
複雑な関数、特に山がいくつもあるような関数y=f(x)の最大値を数値的に求める。
適応度は関数f(x)の値、染色体(個体)の表現型は実数xとなる。
染色体の遺伝子型は、実数xをビット配列で表したものとなる。
最大値が入っていそうな区間0≦x<aを定める。
解の精度を定め、染色体の長さNを決める。a/2^Nの精度で解が求まることになる。
> 最大値を求めたい関数を指定する箇所は下記「DEF f(x)」でしょうか?
そうですね。 y=f(x)のグラフを描いてみました。
DEF f(x)=SIN(3*x)+0.5*SIN(9*x)+SIN(15*x+50)
SET WINDOW -1,3,-2,2
DRAW grid(0.5,0.5)
FOR x=-1 TO 3 STEP 1/2^8
PLOT LINES: x,f(x);
NEXT x
PLOT LINES
END
> また、最大値が得られるXの値を知るにはどこで「print x」を記述すれば良いでしょうか?
xはIN(,)より、P1番目が候補で10ビットなので、
END文の前に、
LET m=0
FOR n=1 TO 10
LET T=IN(P1,n)
LET m=m+T*2^(n-1)
NEXT n
PRINT "x="; m/1024
END
または、
LET m=0
FOR n=10 TO 1 STEP -1
LET m=m*2+IN(P1,n)
NEXT n
PRINT "x="; m/1024
END
とすればよいと思います。
補足 本プログラムの解析
非負整数のみの処理なので、0≦x<1の範囲ですね。
染色体の長さは10ビットなので、1024分割になります。
次の世代の10個体について
・選択淘汰は、エリート選択による適応度がベスト1,2の2個体
・上記の2個体を親として、染色体の各々の遺伝子について0.1の確率で交叉させた8個体
・突然変異は、染色体の各々の遺伝子について0.05の確率でビットの0,1を反転させる。
私もサンプルをつくってみました。
交叉は、Aaに対して(2進法で見ると)Ab,Acは近傍を表すので、山登り法に相当します。
また、突然変異は、特に上位ビットが変わればDb,Dcなので、焼きなまし法に相当します。
!遺伝的アルゴリズム(Genetic Algorithm、GA)で関数の最大値を求める問題
RANDOMIZE
DEF F(x)=SIN(3*x)+0.5*SIN(9*x)+SIN(15*x+50) !適応度
LET N=10 !染色体の長さ
LET M=9 !個体数 ※Mは3以上
DIM X(M) !個体
FOR i=1 TO M !第0世代
LET X(i)=INT(RND*2^N) !x=[0,1)を2^N分割
NEXT i
MAT PRINT x; !debug
DIM NX(M) !次の世代
FOR t=1 TO 2000 !世代交代を進めて進化させる
!選択淘汰(Selection)
!※エリート選択による適応度がベスト1,2,3(一番大きな数から順に3つ)の3個体
LET A=-99999 !1番目 値は-∞
LET B=A !2番目
LET C=A !3番目
FOR i=1 TO M
LET W=F(X(i)/2^N) !関数f(x)の値
IF W>A THEN
LET C=B !降格
LET XC=XB
LET B=A
LET XB=XA
LET A=W !ベスト1
LET XA=i
ELSE
IF W>B THEN
LET C=B !降格
LET XC=XB
LET B=W !ベスト2
LET XB=i
ELSE
IF W>C THEN
LET C=W !ベスト3
LET XC=i
END IF
END IF
END IF
NEXT i
!!!PRINT XA;A; XB;B XC;C !debug
LET NX(1)=X(XA)
LET NX(2)=X(XB)
LET NX(3)=X(XC)
!上記の3個体を親として、各々の染色体について交叉(Cross Over)させた6個体
!※親Aa,Bb → 子Ab,Ba 親Aa,Cc → 子Ac,Ca 親Bb,Cc → 子Bc,Cb
LET p=2^INT(N/2) !1点交叉法(上位と下位)
LET NX(4)=INT(NX(1)/p)*p+MOD(NX(2),p) !Ab
LET NX(5)=INT(NX(2)/p)*p+MOD(NX(1),p) !Ba
LET NX(6)=INT(NX(1)/p)*p+MOD(NX(3),p) !Ac
LET NX(7)=INT(NX(3)/p)*p+MOD(NX(1),p) !Ca
LET NX(8)=INT(NX(2)/p)*p+MOD(NX(3),p) !Bc
LET NX(9)=INT(NX(3)/p)*p+MOD(NX(2),p) !Cb
FOR i=1 TO M !次の世代へ
LET X(i)=NX(i)
!各々の染色体について0.01の確率で遺伝子を変異させる
!※1つのビットの0,1を反転させる
IF RND<0.01 THEN LET X(i)=bitreverse(INT(RND*N),X(i)) !突然変異(Mutation)
NEXT i
NEXT t
MAT PRINT x; !debug
LET x0=X(1)/2^N !進化の結果
PRINT "x=";x0; " f(x)=";f(x0) !検算 x=.140792279664446 f(x)=1.84931356430434
END
!UBASIC ビット演算関連より
EXTERNAL FUNCTION bitreverse(n,x) !n番目のビットを反転する ※n,xは非負整数
LET d=2^n !n桁
LET a=INT(x/d)
LET bitreverse=(INT(a/2)*4-a+1)*d+MOD(x,d) !大きい桁+NOT+小さい桁
END FUNCTION
|
|
|
戻る