-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathGA.c
183 lines (171 loc) · 4.79 KB
/
GA.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
//
// GA.c
// Genetic_Algorithm
//
// Created by He11o_Liu on 2016/10/13.
// Copyright © 2016年 He11o_Liu. All rights reserved.
//
#include "GA.h"
void printNChessman(Individual object){
int i;
for(i = 0 ; i < N;i++)
printf("%d ",object[i]);
printf("\n");
}
/**
* 这个函数用于算N皇后的适应度
* N利用宏定义 (c语言不好实现对数组指针获取其数组长度)
* Param Individual 判断个体
* return Fitness_FN 适应度
* Author 刘年
* 2016-10-14
*/
int Fitness_FN(Individual object){
int row = 0,i = 0,collion = 0;
for( i = 0; i<N ; i++ )
for(row = i+1; row <N;row++)
if((object[row] == object[i]+row -i)||
(object[row] == object[i]-row +i)||
(object[row] == object[i])) collion ++ ;
return N*(N-1)/2 - collion;
}
/**
* 这个函数用于从种群中随机根据适应度随机选取一个适合的个体
* Param Population 种群
* Param Fitness_FN 适应函数
* return Individual 选择的个体
* Author 刘年
* 2016-10-14
*/
Individual Random_Selection(Population pop,int (*Fitness_FN)()){
int i = 0 , sum = 0, selectNum = 0;
int popFN[pop.length];
for(i = 0; i<pop.length;i++){
popFN[i] = Fitness_FN(pop.Population[i]);
sum += popFN[i];
}
selectNum = rand()%sum;
i = 0;
while(selectNum > 0){
selectNum -= popFN[i];
if(selectNum < 0) break;
i++;
}
return pop.Population[i];
}
/**
* 交配函数,从父亲和母亲的基因中随机继承一段
* Param Individual father 父亲
* Param Individual mother 母亲
* Param Individual 孩子
* Author 刘年
* 2016-10-14
*/
void Reproduce(Individual father,Individual mother,Individual* child){
int randomLength = 0,i = 0;
randomLength = rand()%N;
for(i = 0; i < N; i ++)
if(i < randomLength) (*child)[i] = mother[i];
else (*child)[i] = father[i];
}
/**
* 获取小概率可能性
* return bool 小概率为true
* Author 刘年
* 2016-10-14
*/
bool SmallRandomProbability(){
// srand((unsigned int)time(0));
return rand()%1000<SmallProbablity?true:false;
}
/**
* 变异函数 当小概率发生时 子代基因发生变异
* Param Individual 发生变异的对象
* Return Individual 变异后的个体
* Author 刘年
* 2016-10-14
*/
Individual Mutate(Individual object){
int MutatePos,MutateData;
// srand((unsigned int)time(0));
MutatePos = rand()%N;
MutateData = rand()%N+1;
object[MutatePos] = MutateData;
return object;
}
/**
* 添加新的个体到种群中
* Param Individual 需要添加的个体
* Param Population 添加到的种群
* Author 刘年
* 2016-10-14
*/
void AddNewPopulation(Population* pop,Individual individual){
int i = 0;
for(i = 0; i < N;i++) pop->Population[pop->length][i] = individual[i];
pop->length ++;
}
/**
* 种群中已经有足够多的个体符合要求
* Param Individual 需要添加的个体
* Param Population 添加到的种群
* Author 刘年
* 2016-10-14
*/
bool FitEnough(Population pop,int (*Fitness_FN)()){
int i = 0,fitcount = 0;
int fit = N*(N-1)/2;
bool ans = false;
for(i = 0 ; i < pop.length;i++)
if( Fitness_FN(pop.Population[i]) == fit) fitcount ++;
if(fitcount > 0) ans = true;
return ans;
}
/**
* 返回种群中最佳个体
* Param Population 种群
* Param Fitness_FN 适应函数
* Return Individual 最佳个体
* Author 刘年
* 2016-10-14
*/
Individual ChooseBestIndividual(Population pop,int (*Fitness_FN)()){
int i = 0;
int max = 0,maxi = 0;
for(i = 0 ; i < pop.length;i++)
if( Fitness_FN(pop.Population[i]) > max) maxi = i;
return pop.Population[maxi];
}
/**
* 遗传算法主方法
* Param Population 种群
* Param Fitness_FN 适应函数
* Return Individual 最佳个体
* Author 刘年
* 2016-10-14
*/
Individual Genetic_Algorithm(Population pop,int (*Fitness_FN)()){
Population new_population;
Individual father,mother,child;
int i = 0,Generation = 0;
//init population
srand((unsigned int)time(0));
new_population.Population = malloc(pop.length*sizeof(int*));
for(i = 0; i<pop.length;i++)
new_population.Population[i] = malloc(N*sizeof(int));
child = malloc(sizeof(N*sizeof(int)));
while(!FitEnough(pop,Fitness_FN)&&Generation<500000){
new_population.length = 0;
for(i = 0; i < pop.length ; i++){
father = Random_Selection(pop,Fitness_FN);
mother = Random_Selection(pop,Fitness_FN);
Reproduce(father,mother,&child);
if(SmallRandomProbability())
child = Mutate(child);
AddNewPopulation(&new_population,child);
}
pop.Population = new_population.Population;
Generation ++;
}
return ChooseBestIndividual(pop,Fitness_FN);
}