-
Notifications
You must be signed in to change notification settings - Fork 2
/
option.go
160 lines (148 loc) · 4.07 KB
/
option.go
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
package goga
import "time"
type Option func(*ga) error
// OptionWithDefaultGenerator use the reflect to generate random values for the properties of provided type.
/*
type model struct {
age int64 `ga:min:0,max:100`
height float64 `ga:"min:0,max:1"`
}
// ...
OptionWithDefaultGenerator(model{})
*/
// TODO add body
// func OptionWithDefaultGenerator(t any) Option {
// return func(g *ga) error {
// return nil
// }
// }
// OptionWithWeightFunc takes a function to calculate chance of the solution to be selected during crossover.
// Cost and score will be defined separately (Generic solution) based on how the individual is calculated and gets score
/*
TODO add example
*/
func OptionWithWeightFunc(fn WeightFunc) Option {
return func(g *ga) error {
if fn == nil {
return ErrInvalidNilArgs("fitness function")
}
g.weightFunc = fn
return nil
}
}
// OptionWithPopulationFunc define operations such as cross over, mutation and replacement during each iteration of GA.
/*
TODO add example
*/
func OptionWithPopulationFunc(fn PopulationFunc) Option {
return func(g *ga) error {
if fn == nil {
return ErrInvalidNilArgs("population function")
}
g.population = fn
return nil
}
}
// OptionWithGeneratorFunc generator to make solutions randomly
/*
TODO add example
*/
func OptionWithGeneratorFunc(fn func() Model) Option {
return func(g *ga) error {
if fn == nil {
return ErrInvalidNilArgs("generator function")
}
g.generator = fn
return nil
}
}
// OptionWithSelection make subset of the population is selected for the next generation based on their fitness scores.
//
// default: 0.2,0.6,0.2
//
// ex: the following options works the same.
//
// OptionWithSelection(0.2,0.6,0.2) // 20% top, 60% crossover, 20% random
// OptionWithSelection(20,60,20) // 20% top, 60% crossover, 20% random
// OptionWithSelection(1,3,1) // 20% top, 60% crossover, 20% random
func OptionWithSelection(top, mutation, random float64) Option {
return func(g *ga) error {
sum := top + mutation + random
if sum == 0 {
return ErrInvalidSelection(top, mutation, random, "sum must not be zero")
}
top = top / sum
mutation = mutation / sum
random = random / sum
g.config.selection.top = top
g.config.selection.mutation = mutation
g.config.selection.random = random
return nil
}
}
// OptionWithStepInterval is a function that returns an Option which sets the interval between two generations.
// It is useful for runtime processes where you want to continuously improve the parameters, especially in cases where the cost function is not constant and changes over time.
//
// default: 0 (no wait)
//
// ex:
//
// OptionWithStepInterval(30 * time.Second)
func OptionWithStepInterval(d time.Duration) Option {
return func(g *ga) error {
g.config.stepsInterval = d
return nil
}
}
// OptionWithMaximumNumberOfSteps is a function that returns an Option which sets the maximum number of steps for a genetic algorithm.
//
// default: 1000
//
// ex:
//
// OptionWithMaximumNumberOfSteps(1000)
func OptionWithMaximumNumberOfSteps(n int64) Option {
return func(g *ga) error {
g.config.maxNumOfSteps = n
return nil
}
}
// OptionWithTargetCost is a function that returns an Option which sets the target cost for a genetic algorithm.
// The target cost specifies the point at which the process will stop once it reaches that cost.
//
// default: 0.05
//
// ex:
//
// OptionWithTargetCost(0.2)
func OptionWithTargetCost(v float64) Option {
return func(g *ga) error {
g.config.targetCost = v
return nil
}
}
// OptionWithInitialPopulation is a function that returns an Option that sets the initial population of the genetic algorithm.
//
// default: 1000
//
// ex:
//
// OptionWithInitialPopulation(10000)
func OptionWithInitialPopulation(n int) Option {
return func(g *ga) error {
g.config.initialPopulation = n
return nil
}
}
// OptionWithNumberOfThreads specify the number of thread in Cost calculation step.
//
// default: 12
// ex:
//
// OptionWithNumberOfThreads(24)
func OptionWithNumberOfThreads(n int) Option {
return func(g *ga) error {
g.config.numberOfThreads = n
return nil
}
}