初期集団の生成
Posted: 2009年11月18日(水) 22:37
以前お世話になったものです。あのときは、お礼もできずに申し訳ございませんでした。
この場でお礼を言わせてください。ありがとうございました。
前回の方法も悪くはないとはいわれたのですが、違う方法で試したほうがいいと意見をいただきました。
そこで自分なりに考えてみましたが、どうしても次の段階へ進めないので是非ご意見いただきたいと思います。
これが自分が作ったものです。
ということをひたすら繰り返しています。このままではプログラムも長いです。
なにか簡略化するいい方法はありますでしょうか?
今回の初期集団は、前回とは全く別のものです。
通る経路が0 1 4 5 8 9 だとすると
遺伝子座の0の場所に1を、1の場所に4を、4の場所に5を、5の場所に8を、8の場所に9を格納し、
関係のない遺伝子座には、その遺伝子座の番号のノードからつながってるノードをランダムに選ぶ。
という方法をとっています。
しかしながら、現在のプログラムでは、同じところをループしてしまうものが多数でてしまいます。
論文をいくつか読ませていただいた結果、通ったノードに印をつけるというものがありました。
しかし、どのようにプログラムしていいのかわかりませんでした。
よければ、ご意見いただけると嬉しいです。
この場でお礼を言わせてください。ありがとうございました。
前回の方法も悪くはないとはいわれたのですが、違う方法で試したほうがいいと意見をいただきました。
そこで自分なりに考えてみましたが、どうしても次の段階へ進めないので是非ご意見いただきたいと思います。
これが自分が作ったものです。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define START 0
#define GOAL 9
#define NODE 10 //ノードの数
#define PS 10
#define GL 10
#define N START
int main()
{
/*隣接リストの設定
例:ノード0はノード1.2.3と隣接していることを示す*/
const int list[NODE][6]={
//ノード番号
1,2,3,4,7,N,/*0*/
0,2,8,N,N,N,/*1*/
0,1,5,N,N,N,/*2*/
0,5,8,N,N,N,/*3*/
0,5,6,9,N,N,/*4*/
2,3,4,6,7,9,/*5*/
4,5,7,8,9,N,/*6*/
0,5,6,8,N,N,/*7*/
1,3,6,7,N,N,/*8*/
5,4,6,N,N,N /*9*/};
/*隣接行列の設定*/
//行列内の数値は重みとして距離を示すものとする。
const int path[NODE][NODE]={
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
/*0*/ 0,20,35,15,55, 0, 0,43, 0, 0,
/*1*/ 20, 0,33, 0, 0, 0, 0, 0,43, 0,
/*2*/ 35,33, 0, 0, 0,40, 0, 0, 0, 0,
/*3*/ 15, 0, 0, 0, 0,36, 0, 0,45, 0,
/*4*/ 55, 0, 0, 0, 0,32,38, 0, 0,30,
/*5*/ 0, 0,40,36,32, 0,29,36, 0,47,
/*6*/ 0, 0, 0, 0,38,29, 0,52,38,30,
/*7*/ 43, 0, 0, 0, 0,36,52, 0,20, 0,
/*8*/ 0,43, 0,45, 0, 0,38,20, 0, 0,
/*9*/ 0, 0, 0, 0,30,47,30, 0, 0, 0};
/* 初期集団生成 */
int p[PS][G[/url]={0};
int a;//乱数で求めた値を代入する
int f;//出力時の外枠(遺伝子座番号)に利用
int m;//1以上を出力する条件で利用
int x=10;//評価関数に利用したい
int i,j;//初期集団 p[j]
srand( (unsigned int)time(NULL) );
printf("-------------------初期集団------------------\n\n");
printf(" 遺伝子座\n");//外枠、遺伝子座番号表示
printf(" |");
for(f=0;f<10;f++){
printf("%3d",f);
}
printf(" |評価値\n");
printf("---------------------------------------------\n");
/* ここから初期集団表示処理 */
//p[0]のNODE入力
for(i=0;i<PS;i++){ //遺伝子プールの数だけループ
printf("親%2d |",i+1);//外枠なので気にしなくて良し。
for(j=0;j<GL;j++){ //遺伝子座の数だけループ
if(j==0){ //遺伝子座の0座標のときの(ノード0のとき)
a=rand() % 5;
if(a==0){
p[j]=list[0][0];
}else if(a==1){
p[j]=list[0][1];
}else if(a==2){
p[j]=list[0][2];
}else if(a==3){
p[j]=list[0][3];
}else if(a==4){
p[j]=list[0][4];
}
}
a=0;//a初期化
//p[1]のNODE入力
//NODE1とつながっているNODEをランダムで選択
if(j==1){
a=rand() % 3;
if(a==0){
p[j]=list[1][0];
}else if(a==1){
p[j]=list[1][1];
}else if(a==2){
p[i][j]=list[1][2];
//同じノードを通過しないための処理。同一ノードを通過した場合は再度処理をやり直す
}
}
a=0;//a初期化ということをひたすら繰り返しています。このままではプログラムも長いです。
なにか簡略化するいい方法はありますでしょうか?
今回の初期集団は、前回とは全く別のものです。
通る経路が0 1 4 5 8 9 だとすると
遺伝子座の0の場所に1を、1の場所に4を、4の場所に5を、5の場所に8を、8の場所に9を格納し、
関係のない遺伝子座には、その遺伝子座の番号のノードからつながってるノードをランダムに選ぶ。
という方法をとっています。
しかしながら、現在のプログラムでは、同じところをループしてしまうものが多数でてしまいます。
論文をいくつか読ませていただいた結果、通ったノードに印をつけるというものがありました。
しかし、どのようにプログラムしていいのかわかりませんでした。
よければ、ご意見いただけると嬉しいです。