|
1 | 1 | package GA
|
2 | 2 |
|
| 3 | +import ( |
| 4 | + "fmt" |
| 5 | + "math" |
| 6 | + "math/rand" |
| 7 | + "time" |
| 8 | +) |
| 9 | + |
3 | 10 | var (
|
4 |
| - groupSize int //种群大小 |
5 |
| - selectRand int //轮盘选择概率 |
6 |
| - crossRand int //交叉概率 |
7 |
| - mutationRand int //变异概率 |
| 11 | + groupSize int //种群大小 |
| 12 | + chromosomeSize int //染色体长度 |
| 13 | + selectRand float64 //轮盘选择概率 |
| 14 | + crossRand float64 //交叉概率 |
| 15 | + mutationRand float64 //变异概率 |
| 16 | + group []Person //种群 |
| 17 | + bestPerson Person //当前最好的个体 |
| 18 | + r *rand.Rand |
8 | 19 | )
|
9 | 20 |
|
10 | 21 | //Person 个体
|
11 | 22 | type Person struct {
|
12 |
| - chromosomes []int //染色体 |
| 23 | + chromosome []int //染色体 |
| 24 | + value float64 //适应值 |
13 | 25 | }
|
14 | 26 |
|
15 | 27 | //Init 初始化函数
|
16 | 28 | //初始化设置种群大小、轮盘选择概率、交叉概率
10000
经变异的概率
|
17 |
| -func Init(GroupSize, SelectRand, CrossRand, MutationRand int) { |
| 29 | +func Init(GroupSize, ChromosomeSize int, SelectRand, CrossRand, MutationRand float64) { |
18 | 30 | groupSize = GroupSize
|
19 | 31 | crossRand = CrossRand
|
20 | 32 | selectRand = SelectRand
|
21 | 33 | mutationRand = MutationRand
|
| 34 | + chromosomeSize = ChromosomeSize |
| 35 | + r = rand.New(rand.NewSource(time.Now().UnixNano())) |
| 36 | + bestPerson.chromosome = make([]int, chromosomeSize) |
22 | 37 | }
|
23 | 38 |
|
24 | 39 | //InitGroup 初始化种群
|
25 | 40 | //根据种群大小随机产生一些个体填充
|
26 | 41 | func InitGroup() {
|
27 |
| - |
| 42 | + group = make([]Person, groupSize) |
| 43 | + for i := 0; i < groupSize; i++ { |
| 44 | + group[i].chromosome = make([]int, chromosomeSize) |
| 45 | + for j := 0; j < chromosomeSize; j++ { |
| 46 | + if r.Float64() > selectRand { |
| 47 | + group[i].chromosome[j] = 1 |
| 48 | + } |
| 49 | + } |
| 50 | + } |
28 | 51 | }
|
29 | 52 |
|
30 | 53 | //Fitness 计算适应值
|
31 |
| -func Fitness() { |
| 54 | +func Fitness(person Person) float64 { |
| 55 | + x := decode(person) |
| 56 | + return x + 10*math.Sin(5*x) + 7*math.Cos(4*x) |
| 57 | +} |
32 | 58 |
|
| 59 | +//解码 |
| 60 | +func decode(person Person) float64 { |
| 61 | + var sum float64 |
| 62 | + //解码 |
| 63 | + for i := 0; i < chromosomeSize; i++ { |
| 64 | + //二进制染色体转十进制值 |
| 65 | + if person.chromosome[i] == 1 { |
| 66 | + sum = sum + math.Pow(2.0, float64(i)) |
| 67 | + } |
| 68 | + } |
| 69 | + return sum * 9 / (math.Pow(2.0, 14.0) - 1) |
33 | 70 | }
|
34 | 71 |
|
35 | 72 | //Select 选择
|
36 | 73 | func Select() {
|
| 74 | + newGroup := make([]Person, groupSize) |
| 75 | + for i := 0; i < groupSize; i++ { |
| 76 | + newGroup[i].chromosome = make([]int, chromosomeSize) |
| 77 | + rnd := r.Float64() |
37 | 78 |
|
| 79 | + A: |
| 80 | + for j := 0; j < groupSize; j++ { |
| 81 | + if group[j].value > rnd*bestPerson.value { |
| 82 | + copy(newGroup[i].chromosome, group[j].chromosome) |
| 83 | + break A |
| 84 | + } |
| 85 | + if j == groupSize-1 { |
| 86 | + copy(newGroup[i].chromosome, bestPerson.chromosome) |
| 87 | + } |
| 88 | + } |
| 89 | + } |
| 90 | + group = newGroup |
| 91 | + newGroup = nil |
38 | 92 | }
|
39 | 93 |
|
40 | 94 | //Cross 交叉
|
41 | 95 | func Cross() {
|
42 |
| - |
| 96 | + for i := 0; i < groupSize; i = i + 2 { |
| 97 | + if r.Float64() < crossRand { |
| 98 | + crossPosition := r.Intn(chromosomeSize - 1) |
| 99 | + if crossPosition == 0 || crossPosition == 1 { |
| 100 | + continue |
| 101 | + } |
| 102 | + //交叉 |
| 103 | + for j := crossPosition; j < chromosomeSize; j++ { |
| 104 | + tmp := group[i].chromosome[j] |
| 105 | + group[i].chromosome[j] = group[i+1].chromosome[j] |
| 106 | + group[i+1].chromosome[j] = tmp |
| 107 | + } |
| 108 | + } |
| 109 | + } |
43 | 110 | }
|
44 | 111 |
|
45 | 112 | //Mutation 变异
|
46 | 113 | func Mutation() {
|
| 114 | + for i := 0; i < groupSize; i++ { |
| 115 | + if r.Float64() < mutationRand { |
| 116 | + mutationPosition := r.Intn(chromosomeSize - 1) |
47 | 117 |
|
| 118 | + //单点变异 |
| 119 | + if group[i].chromosome[mutationPosition] == 0 { |
| 120 | + group[i].chromosome[mutationPosition] = 1 |
| 121 | + } else { |
| 122 | + group[i].chromosome[mutationPosition] = 0 |
| 123 | + } |
| 124 | + } |
| 125 | + } |
48 | 126 | }
|
49 | 127 |
|
50 | 128 | //GA 遗传算法
|
51 | 129 | func GA() {
|
| 130 | + //初始化 |
| 131 | + Init(100, 14, 0.5, 0.6, 0.05) |
| 132 | + //初始化种群 |
| 133 | + InitGroup() |
| 134 | + |
| 135 | + //遗传循环 |
| 136 | + for i := 0; i < 1000; i++ { |
| 137 | + |
| 138 | + //计算适应值 |
| 139 | + for j := 0; j < groupSize; j++ { |
| 140 | + group[j].value = Fitness(group[j]) |
| 141 | + |
| 142 | + //保存当前最好的个体 |
| 143 | + if group[j].value > bestPerson.value { |
| 144 | + copy(bestPerson.chromosome, group[j].chromosome) |
| 145 | + bestPerson.value = group[j].value |
| 146 | + } |
| 147 | + } |
| 148 | + |
| 149 | + fmt.Println("第", i, "代最好个体:", bestPerson.value, " ", decode(bestPerson)) |
| 150 | + |
| 151 | + //选择 |
| 152 | + Select() |
| 153 | + |
| 154 | + //交叉 |
| 155 | + Cross() |
52 | 156 |
|
| 157 | + //变异 |
| 158 | + Mutation() |
| 159 | + } |
53 | 160 | }
|
0 commit comments