@include "GA.awk" ## alphametic.awk (覆面算サンプル) written by Yさ BEGIN{ rz_Setup="setup"; # rz_Finish="finish"; rz_Initialization="Initialization"; # 初期集団の生成 rz_Result="Result"; #  結果の表示 rz_Fitness="Fitness"; # 適応度の算出 rz_Termination="Termination"; # 終了判定 rz_Selection="Selection"; # 選択 rz_Crossover="Crossover"; #  交叉 rz_Mutation="Mutation"; # 突然変異 rz_Regeneration="Regeneration"; # 再生 (※次世代を現世代の配列にコピー) start(); } # 事前準備 function setup(){ P=30; # 個体数 Cr=80; # 交叉率(%) Mr=10; # 突然変異率(%) # 問題の分解 # WORD[], WordCnt, Top[], TopCnt, Use[], Cnv[], GeneSize if(FORMULA=="") FORMULA="SEND + MORE = MONEY"; WordCnt=split(FORMULA, WORD, /[ \+=]*/); delete ch; for(n=1; n<=WordCnt; ++n){ sz=length(WORD[n]); for(p=1; p<=sz; ++p) ++ch[substr(WORD[n],p,1)]; } delete Use; delete Cnv; for(t in ch) Use[GeneSize++]=t; # Use[遺伝子の位置] = 使用文字 if(GeneSize>10){ print "impossible condition [", GeneSize, "]"; exit; } for(n=0; n=0; --p){ swap(num, n, p); sequence(num, n-1); swap(num, n, p); } } } function NotYetDisplay(num, key,n){ for(n=0; n=10) p-=10; DNA[t][n]=DNA[1][p]; } ++x; } random(t,DNA); } function random(t,tgt, n){ for(; t<=P; ++t){ for(n=0; n<10; ++n) tgt[t][n]=tgt[1][n]; for(n=0; n<10; ++n) swap(tgt[t],n,rnd(10)); } } function swap(a,p1,p2, tmp){ tmp=a[p1]; a[p1]=a[p2]; a[p2]=tmp; } # 結果の表示 function Result( t,n,x){ if(GeneSize>10) exit; printf("\n[%d]\n", G); for(t=1; t<=P; ++t){ printf("%2d: ", t); for(n=0; nans)?(ans/term):(term/ans); ev += int(dif*10); } return ev; } function calcTerm(tgt, n,term){ for(n=1; n=0)?(n):(-n)); } # # 終了判定 # function Termination(){ if(MAX1000) printf("*"); else printf(" "); if(prevMAX=300); } # 再生 (※次世代を現世代の配列にコピー) function Regeneration(dst,src,t, n){ for(n=0; n<10; ++n) dst[t][n]=src[t][n]; } # # 選択 # function Selection(nxDNA, t,x,n,n1,n2){ for(t=1; t<=int(P*0.2); ++t){ ++x; for(n=0; n<10; ++n) nxDNA[x][n]=DNA[Idx[t]][n]; } if(x>0 && ((P-x)%2)){ ++x; for(n=0; n<10; ++n) nxDNA[x][n]=nxDNA[1][n]; } for(t=x+1; t=Cr){ for(n=0; n<10; ++n){ dst[c1][n]=src[p1][n]; dst[c2][n]=src[p2][n]; } return; } cut=rnd(GeneSize-1)+1; if(rnd(100)>=50) cross(p1,p2,src,c1,c2,dst, 0,cut, cut); else cross(p1,p2,src,c1,c2,dst, cut, 10, 0); } function cross(p1,p2,src,c1,c2,dst, st,ed, st2, n,list1,list2,p,x){ delete list1; delete list2; for(n=st; n