先日から、やっておりました。遺伝的アルゴリズムてきなものです。
授業の課題だったのですが、先日発表が終わったので掲載してみます。
いわゆる「斜方投射」ってやつです。
大まかな流れは
①0~90°でランダムに角度を生成。
②それぞれの飛距離を計算。
③飛距離の大きいものが全体数から、半分選出。
④角度の何桁目、何桁目を遺伝情報として交換。
⑤遺伝情報をもとに、2個体から4個体を生成。
⑥50パーセントの確率で、2個体だけ遺伝情報(角度値)の小数点以下がランダム値で増減。
⑦ループになる⇒②
問題なのは、収束の判定をどうするのか。
最適解でなくても収束するので、どうしたものか?
と思いながら作っていたが割とそうでもなかった。
でプログラムが得意でない僕は、上位の選出が一番難しかった。
なので、こんな感じのプログラムになった。
void touta(double *distance)
{
int i=0,j=0,k=0;
double eps=EPS,dis[NUM];
char lost_f=0;
for(i=0;i<NUM;i++)
{
dis[i] = distance[i];
}
i=0;
j=0;
while(i!=NUM/2)
{
if(dis[j]<eps)
{
g_lost_num[i]=j;
dis[j]+=100;
i++;
}
j++;
if(j>=NUM)
{
j=0;
eps += EPS;
}
}
/*selection*/
j=0;
for(i=0;i<NUM;i++)
{
/*i_num is lost or not*/
k=0;
lost_f=0;
for(k=0;k<(NUM/2);k++)
{
if(g_lost_num[k]==i)lost_f=1;
}
/*not, surv*/
if(lost_f==0)
{
g_surv_theta[j] = g_theta[i];
j++;
}
}
}
小さい値をですね、少しずつ足していきます。
足すたびに、すべての個体と比較します。
で、より低かった個体の配列番号を記録します。
ナンバーが50個選ばれます。
で、選ばれなかったナンバーの値だけ、別の配列に入れます。
というような感じになります。
この小さい値というのがネックです。
一桁減らすだけで、計算量が飛躍的に増えるので、重いです。
ですが、ここが重要なんでして。角度の精度が出るかでないかのメインポイントです。
ここが大きいと、低いほうの精度が重要に成るほうの遺伝情報が、抹殺されてしまうので・・・。
でもまあ、うまくいったからいいか。
[0回]
PR