-
Notifications
You must be signed in to change notification settings - Fork 0
/
annealing.go
140 lines (117 loc) · 5.05 KB
/
annealing.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
// Package Simulated is package that will model simulated annealing.
// It include all the main function of Simulated Annealing Algorithm.
package Simulated
import (
"fmt"
"math"
"math/rand"
"github.com/pamungkaski/go-simulated-annealing/visualizer"
)
// AnnealingModel is the main interface that holds all of the AnnealingModel Business Logic.
type AnnealingModel interface {
//KeepGoing is a function that will check whether temperature already reached minimum to stop the loop.
KeepGoing() bool
// Cost function is the function that being simulated.
CostFunction(firstValue, secondValue float64) float64
// AcceptanceProbability is the function that will calculate which value that is more likely to be the answer.
AcceptanceProbability(oldCost, newCost float64) float64
// GenerateNeighbor is a function that will continuesly create another solution based on its current
GenerateNeighbor() (float64, float64)
// Cooling is the function to decrease temperature by alpha percent.
Cooling()
// Visualizing is a function that will visualize models into an image.
Visualizing()
// AppendSolution is a function that will input and save the accepted solution into annealing struct.
AppendSolution(firstValue, secondValue, Energy float64)
//InputBest is a function that will save the best solution iterator number into the struct.
InputBest(it int)
// BestSolution is a function that print saved best solution and its accuration.
BestSolution()
}
// Visualizer is interface that holds contrace
type Visualizer interface {
Visualize(XList, YList, ZList []float64)
}
// Annealing is the struct that implement AnnealingModel interface.
// This struct will hold the temperature, alpha, and value range.
type Annealing struct {
temperature float64
alpha float64
minValue float64
maxValue float64
goal float64
minimumTemperature float64
solutionXList []float64
solutionYList []float64
solutionZList []float64
best int
visualizer Visualizer
}
// NewAnnealing is a function that create AnnealingModel instance using already set params.
func NewAnnealing(temperature, alpha, minValue, maxValue, goal, minimumTemperature float64) AnnealingModel {
return &Annealing{
temperature: temperature,
alpha: alpha,
minValue: minValue,
maxValue: maxValue,
goal: goal,
minimumTemperature: minimumTemperature,
visualizer: &visualizer.Plotting{},
}
}
// KeepGoing is a function that will check whether temperature already reached minimum to stop the loop.
func (a *Annealing) KeepGoing() bool {
return a.temperature > a.minimumTemperature
}
// Cost function is the function that being simulated.
func (a *Annealing) CostFunction(firstValue, secondValue float64) float64 {
var result float64
fVSquare := firstValue * firstValue
sVSquare := secondValue * secondValue
fVSin := math.Sin(firstValue)
sVCos := math.Cos(secondValue)
subtrahend := math.Sqrt(fVSquare+sVSquare) / math.Pi
insideExponential := math.Abs(1 - subtrahend)
exponent := math.Exp(insideExponential)
result = -1 * math.Abs(fVSin*sVCos*exponent)
return result
}
// AcceptanceProbability is the function that will calculate which value that is more likely to be the answer.
func (a *Annealing) AcceptanceProbability(oldCost, newCost float64) float64 {
var result float64
deltaCost := newCost - oldCost
result = math.Exp(-1.0 * deltaCost / a.temperature)
return result
}
// GenerateNeighbor is a function that will continuesly create another solution based on its current
func (a *Annealing) GenerateNeighbor() (float64, float64) {
randomNumber := rand.Float64()
firstValue := randomNumber*(a.maxValue-a.minValue) + a.minValue
randomNumber = rand.Float64()
secondValue := randomNumber*(a.maxValue-a.minValue) + a.minValue
return firstValue, secondValue
}
// Cooling is the function to decrease temperature by alpha percent.
// The idea of this function to limit / stop the neighbor generation.
func (a *Annealing) Cooling() {
a.temperature *= a.alpha
}
// Visaulizing is a function that will call a visualizer to do a visualization of the model solution.
func (a *Annealing) Visualizing() {
a.visualizer.Visualize(a.solutionXList, a.solutionYList, a.solutionZList)
}
// AppendSolution is a function that will input and save the accepted solution into annealing struct.
func (a *Annealing) AppendSolution(firstValue, secondValue, energy float64) {
a.solutionXList = append(a.solutionXList, firstValue)
a.solutionYList = append(a.solutionYList, secondValue)
a.solutionZList = append(a.solutionZList, energy)
}
// InputBest is a function that will save the best solution iterator number into the struct.
func (a *Annealing) InputBest(it int) {
a.best = it
}
// BestSolution is a function that print saved best solution and its accuration.
func (a *Annealing) BestSolution() {
accuration := math.Abs(a.solutionZList[a.best] / a.goal)
fmt.Printf("fV:= %f sV:= %f E:= %f, Accuration:= %f%%\n", a.solutionXList[a.best], a.solutionYList[a.best], a.solutionZList[a.best], accuration*100)
}