
No License
C++
2020年06月03日
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define GENE 20 //個数
#define BIT 8 //箱の数
#define MAX 30 //量の最大値
#define GENERATION 30 // 世代数
#define CROSSOVER 0.2 // 交伹率
#define MUTATION 0.05 // 突然変異率
//構造体の定義
struct Gene
{
int quantitiy[BIT]; //量
int price[BIT]; //価格
int bit[BIT]; //入れるか入れないか
int sum_price; //価格の合計値
int sum_quantity; //量の合計値
}gene[GENE], gene2;
struct Elite
{
int sum_price;
int sum_quantity;
}elite;
int generation_count;
void input()
{
for (int i = 0; i < GENE; i++)
{
FILE *file;
errno_t error;
error = fopen_s(&file, "data.txt", "r");
for (int j = 0; j < BIT; j++)
{
fscanf_s(file, "%d,%d", &gene[i].quantitiy[j], &gene[i].price[j]);
//遺伝子の初期化
gene[i].bit[j] = rand() % 2;
//printf("%2d,%2d,%2d\n", gene[i].quantitiy[j], gene[i].price[j], gene[i].bit[j]);
}
fclose(file);
//printf("**************************\n");
}
return;
}
void calculation()
{
for (int i = 0; i < GENE; i++)
{
gene[i].sum_price = 0;
gene[i].sum_quantity = 0;
for (int j = 0; j < BIT; j++)
{
if (gene[i].bit[j] == 1)
{
gene[i].sum_price += gene[i].price[j];
}
if (gene[i].bit[j] == 1)
{
gene[i].sum_quantity += gene[i].quantitiy[j];
}
}
//printf("%2d, %2d\n",gene[i].sum_quantity, gene[i].sum_price);
}
//printf("**************************\n");
}
void evalution()
{
for (int i = 0; i < GENE; i++)
{
if (gene[i].sum_quantity > MAX)
{
gene[i].sum_price = -1 * gene[i].sum_price;
}
//printf("%2d, %2d\n", gene[i].sum_quantity, gene[i].sum_price);
}
//printf("**************************\n");
}
void sort()
{
//printf(" 量 価格\n");
for (int i = 0; i < GENE; ++i)
{
for (int j = i+1; j<GENE; ++j)
{
if (gene[i].sum_price < gene[j].sum_price)
{
gene2 = gene[i];
gene[i] = gene[j];
gene[j] = gene2;
}
}
//printf("%2d, %2d\n", gene[i].sum_quantity, gene[i].sum_price);
}
for (int i = 0; i < GENE; i++)
{
if (gene[i].sum_price < 0)
{
gene[i].sum_price = -1 * gene[i].sum_price;
}
}
for (int i = 0; i < 4; i++)
{
gene[GENERATION-i] = gene[i];
}
elite.sum_price = gene[0].sum_price;
elite.sum_quantity = gene[0].sum_quantity;
printf(" elite %3d %3d\n", elite.sum_quantity, elite.sum_price);
for (int i = 0; i < BIT; i++)
{
printf("%d ", gene[0].bit[i]);
}
printf("\n");
}
void crosscover()
{
int point /*交叉する位置*/, random_gene1 /*1つ目の親個体*/, random_gene2 /*2つ目の親個体*/, bit2 /*入れ物*/;
for (int i = 0; i < (int)(GENE * CROSSOVER); i++)
{
point = rand() % (BIT - 2) + 2; // 交叉する位置をランダムで選択
random_gene1 = rand() % (GENE - 1) + 1; // 1つ目の親個体
do
{
random_gene2 = rand() % (GENE - 1) + 1; //2つ目の親個体
} while (random_gene2 == random_gene1); //random_gene1とrandom_gene2が同じだったらrandom_gene2を選択し直し
// 交叉
for (int j = point; j < BIT; j++)
{
bit2 = gene[random_gene1].bit[j];
gene[random_gene1].bit[j] = gene[random_gene2].bit[j];
gene[random_gene2].bit[j] = bit2;
}
}
}
void mutation()
{
int random_bit/*突然変異させる遺伝子*/, random_gene/*突然変異させる個体*/, mutation_bit/*突然変異後の値*/;
for (int i = 0;i < (int)(GENE * MUTATION);i++)
{
random_bit = rand() % (BIT - 2) + 1; // 突然変異させる遺伝子をランダムで選択
random_gene = rand() % (GENE - 1) + 1; // 突然変異させる個体をランダムで選択
do
{
mutation_bit = rand() % (BIT - random_bit) + random_bit;
} while (gene[random_gene].bit[random_bit] == mutation_bit); // 元の遺伝子とは違うものが出るまで繰り返し
gene[random_gene].bit[random_bit] = mutation_bit;
}
}
int main()
{
srand((unsigned)time(NULL)); // 乱数の初期化
input();
calculation();
evalution();
printf("初期値 \n");
sort();
for (int i = 0; i < GENERATION; i++)
{
printf("第%2d世代\n", i+1);
crosscover();
mutation();
calculation();
evalution();
sort();
}
return 0;
}
No one still commented. Please first comment.