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
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]);
|
|
}
|
|
}
|
|
|