You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

161 lines
4.8 KiB

#include <stdlib.h>
#include "tsp.h"
#define ELETE_SELECTION YES /* エリート戦略で選択 */
/* 距離(または適合度)でソートするための比較関数 */
int compare_fitness(const void *a, const void *b) {
Gene_set *ga = (Gene_set *)a;
Gene_set *gb = (Gene_set *)b;
// 適合度が良い(小さい)順に並べる
if (ga->fitness < gb->fitness) return -1;
if (ga->fitness > gb->fitness) return 1;
return 0;
}
/* 遺伝子集団 gene_group の中で突然変異を起こす */
void mutation(Gene_set gene_group[GENE_NUM])
{
int i, target;
/* どの遺伝子を変異させるか */
#if ELETE_SELECTION /* 1/2 */
for (i = ELETE; i < GENE_NUM; i++ )
#else
for (i = 0; i < GENE_NUM; i++ )
#endif /* ELETE_SELECTION 1/2 */
{
/* その遺伝子が突然変異対象に選ばれたら */
if ((rand() / (double)RAND_MAX) < MUTATION_RATIO)
{
/* どの位置を変異させるか */
target = rand() % CITY_NUM;
/* 残っている都市の数以内でランダムに選ぶ */
gene_group[i].gene[target] = rand() % (CITY_NUM - target);
}
}
}
/* 遺伝子集団 gene_group の中で選択を行う */
void selection(Gene_set gene_group[GENE_NUM])
{
#if ELETE_SELECTION /* 2/2 */
elete(gene_group);
#else
tournament(gene_group);
#endif /* ELETE_SELECTION 2/2 */
}
/* トーナメント方式による選択 */
void tournament(Gene_set gene_group[GENE_NUM])
{
int i, j, k, l;
int min_fitness_index;
int random_gene_index[SELECT_NUM];
Gene_set next_gene_group[GENE_NUM];
/* すべての候補がそろうまで */
for (i = 0; i < GENE_NUM; i++)
{
for (j = 0; j < SELECT_NUM; j++)
{
/* 全遺伝子の中からランダムに被らないよう複数選ぶ */
while (1)
{
k = rand() % GENE_NUM;
for (l = 0; l < j; l++)
{
if (k == random_gene_index[l])
{
break;
}
}
/* 最後まで一致しなかったら採用 */
if (l == j) break;
}
random_gene_index[j] = k;
}
min_fitness_index = random_gene_index[0];
/* 選んだ個体の中から適合度が最も良い(小さい)ものを選び,次の世代とする */
for (j = 1; j < SELECT_NUM; j++)
{
if (gene_group[min_fitness_index].fitness > gene_group[random_gene_index[j]].fitness)
{
min_fitness_index = random_gene_index[j];
}
}
copy_gene_set(&next_gene_group[i], &gene_group[min_fitness_index]);
}
copy_gene_group(gene_group, next_gene_group);
}
/* エリート戦略による選択 */
void elete(Gene_set gene_group[GENE_NUM])
{
int i, j, k, l;
int min_fitness_index;
int random_gene_index[SELECT_NUM];
Gene_set next_gene_group[GENE_NUM];
/* 全個体を適合度の良い順(小さい順)に並び替える */
qsort(gene_group, GENE_NUM, sizeof(Gene_set), compare_fitness);
/* 上位 ELETE 個を次世代にコピーする */
for (i = 0; i < ELETE; i++)
{
copy_gene_set(&next_gene_group[i], &gene_group[i]);
}
/* 残りの枠(ELETE ~ GENE_NUM)をトーナメント方式で埋める */
for (i = ELETE; i < GENE_NUM; i++) {
for (j = 0; j < SELECT_NUM; j++) {
while (1)
{
k = rand() % GENE_NUM;
for (l = 0; l < j; l++)
{
if (k == random_gene_index[l]) break;
}
if (l == j) break;
}
random_gene_index[j] = k;
}
min_fitness_index = random_gene_index[0];
for (j = 1; j < SELECT_NUM; j++)
{
if (gene_group[min_fitness_index].fitness > gene_group[random_gene_index[j]].fitness)
{
min_fitness_index = random_gene_index[j];
}
}
copy_gene_set(&next_gene_group[i], &gene_group[min_fitness_index]);
}
copy_gene_group(gene_group, next_gene_group);
}
/* 遺伝子セットの複写 */
void copy_gene_set(Gene_set *gene_set_to, Gene_set *gene_set_from)
{
int i;
for (i = 0; i < CITY_NUM; i++)
{
gene_set_to->gene[i] = gene_set_from->gene[i];
}
gene_set_to->length = gene_set_from->length;
gene_set_to->fitness = gene_set_from->fitness;
}
/* 遺伝子集団の複写 */
void copy_gene_group(Gene_set gene_group_to[GENE_NUM], Gene_set gene_group_from[GENE_NUM])
{
int i;
for (i = 0; i < GENE_NUM; i++)
{
copy_gene_set(&gene_group_to[i], &gene_group_from[i]);
}
}