-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
215 lines (187 loc) · 6.86 KB
/
main.py
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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
import sys
import numpy as np
from PyQt4.QtGui import *
from PyQt4 import QtCore
from GUI import Ui_MainWindow
from PlotHandlers.matplotlibPlotHandler import PlotHandler
# from PlotHandlers.visvisPlotHandler import PlotHandler
# from PlotHandlers.pyqtgraphPlotHandler import PlotHandler
import testFunction as tF
import PopulationUtils
import evolutionAlgorithms as eA
# algorithms - used for switch-like selection
INDEX_ALGORITHM = [
None,
eA.ClimbingHillAlgorithm,
eA.SimulatedAnnealingAlgorithm,
eA.DifferentialEvolution,
eA.SOMA,
eA.EvolutionStrategy
]
class AppWindow(QMainWindow, Ui_MainWindow):
"""
Root application widget
"""
def __init__(self, parent=None):
QMainWindow.__init__(self, parent)
Ui_MainWindow.__init__(self)
self.setupUi(self)
# canvas with graph
layout = QVBoxLayout(self.graphicsView)
layout.setContentsMargins(0, 0, 0, 0)
self.graphicsView.setLayout(layout)
# create plotHandler
self.plotHandler = PlotHandler(self)
layout.addWidget(self.plotHandler.get_widget())
self.changeButton.clicked.connect(self.update_plot)
self.generateButton.clicked.connect(self.generate_population)
# ToolBox with algorithms
QtCore.QObject.connect(self.chooseSearchToolBox,
QtCore.SIGNAL('currentChanged(int)'),
self,
QtCore.SLOT('algorithm_change_callback(int)')
)
# Run button
self.ButtonRun.clicked.connect(self.run_button_callback)
# Step Button
self.ButtonStep.clicked.connect(self.step_button_callback)
# Evolution algorithm important properties
self.algorithm = None
self.test_functions = None
self.fitness_function = None
self.actualPopulation = None
# Plot initialization
self.initialize_plot()
def initialize_plot(self):
"""
Initialize plot and test functions
:return:
"""
self.test_functions = [
tF.firstDeJong, tF.rosenbrocksSaddle, tF.thirdDeJong, tF.forthDeJong,
tF.rastrigin, tF.schewefel, tF.griewangkova,
tF.sineEnvelope, tF.sineWave, tF.MultiPurposeFnc
]
self.update_plot()
@QtCore.pyqtSlot()
def update_plot(self):
"""
Updates fitness function surface graph
If there is some population - generates new one
"""
x1 = self.mindoubleSpinBox.value()
x2 = self.maxdoubleSpinBox.value()
x3 = self.pointsdoubleSpinBox.value()
self.fitness_function = self.test_functions[self.chooseFunctionComboBox.currentIndex()]
# regenerate population
if self.actualPopulation is not None:
template = self.get_specimen_template()
n = self.numOfSpecimenSpinBox.value()
# generate new population
self.actualPopulation = PopulationUtils.generate_population(
self.get_specimen_template(),
n,
self.fitness_function
)
# Add reference to algorithm and update
if self.algorithm is not None:
self.algorithm.set_specimen_template(template)
self.algorithm.set_population(self.actualPopulation)
# surface plot data
x = np.arange(x1, x2, x3)
y = x
z = None
if self.fitness_function.__name__ is tF.MultiPurposeFnc.__name__:
print 'gooo'
z = tF.MultiPurposeFnc.graph_z(x, y)
else:
z = self.fitness_function(np.meshgrid(x, x))
# Draw all at once
self.plotHandler.updatePlot(x, y, z, population=self.actualPopulation)
@QtCore.pyqtSlot()
def generate_population(self):
"""
Generate Population and set it
:return:
"""
template = self.get_specimen_template()
n = self.numOfSpecimenSpinBox.value()
self.actualPopulation = PopulationUtils.generate_population(
template,
n,
self.fitness_function)
# Add reference to algorithm
if self.algorithm is not None:
self.algorithm.set_specimen_template(template)
self.algorithm.set_population(self.actualPopulation)
# Show population
self.plotHandler.updatePopulation(self.actualPopulation)
def get_specimen_template(self):
"""
Generates specimen template according to given constraints
:return:
"""
min_const = self.mindoubleSpinBox.value()
max_const = self.maxdoubleSpinBox.value()
only_integer = self.intCheckBox.isChecked()
data_type = 'real'
if only_integer:
data_type = 'integer'
return [(data_type, (min_const, max_const))] * 2
def update_callback(self, actual_population, best_population, done=False):
"""
Callback for algorithms to trigger after each iteration
:param actual_population:
:param best_population:
:param done:
:return:
"""
self.actualPopulation = actual_population
# TODO: Save best population to log Widget
if done:
print 'Algorithm finished'
# self.actualPopulation = best_population
self.plotHandler.updatePopulation(best_population)
else:
self.plotHandler.updatePopulation(self.actualPopulation)
@QtCore.pyqtSlot()
def run_button_callback(self):
"""
Execute algorithm
:return:
"""
if self.algorithm is not None:
self.algorithm.run()
@QtCore.pyqtSlot()
def step_button_callback(self):
"""
Triggers when step button is clicked
:return:
"""
if self.algorithm is not None:
self.algorithm.step()
self.plotHandler.updatePopulation(self.algorithm.population)
@QtCore.pyqtSlot(int)
def algorithm_change_callback(self, index):
"""
Triggers when algorithm is changed from toolbox
:param index:
:return:
"""
if index < (len(INDEX_ALGORITHM)):
if INDEX_ALGORITHM[index] is None:
print 'None'
return
self.algorithm = INDEX_ALGORITHM[index](self.actualPopulation,
self.fitness_function,
self.get_specimen_template(),
self.update_callback
)
print '{0} - {1} selected '.format(index, INDEX_ALGORITHM[index].__name__)
else:
return
if __name__ == '__main__':
app = QApplication(sys.argv)
ui = AppWindow()
ui.show()
sys.exit(app.exec_())