初期集団の生成

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
pkt

初期集団の生成

#1

投稿記事 by pkt » 15年前

以前お世話になったものです。あのときは、お礼もできずに申し訳ございませんでした。
この場でお礼を言わせてください。ありがとうございました。
前回の方法も悪くはないとはいわれたのですが、違う方法で試したほうがいいと意見をいただきました。
そこで自分なりに考えてみましたが、どうしても次の段階へ進めないので是非ご意見いただきたいと思います。
これが自分が作ったものです。
#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を格納し、
関係のない遺伝子座には、その遺伝子座の番号のノードからつながってるノードをランダムに選ぶ。
という方法をとっています。
しかしながら、現在のプログラムでは、同じところをループしてしまうものが多数でてしまいます。
論文をいくつか読ませていただいた結果、通ったノードに印をつけるというものがありました。
しかし、どのようにプログラムしていいのかわかりませんでした。
よければ、ご意見いただけると嬉しいです。

non

Re:初期集団の生成

#2

投稿記事 by non » 15年前

1 前にも言ったように、自分が遺伝アルゴリズムをわかるからといって、他の人がわかるわけではない。

2 >前回の方法も悪くはないとはいわれたのですが、違う方法で試したほうがいいと意見をいただきました。
誰が言ったのかは知らないが、前回の方法は何で、今回の方法は何?

3 前回、これで課題は終わりだと言ったよね。
にも、かかわらず、距離まで出てきている。

4 再帰プログラムがいいよとは、すでに伝えたし、サンプルも載せた。

閉鎖

“C言語何でも質問掲示板” へ戻る