Skip to content

Commit 0b14ebd

Browse files
authored
removing nParents from inputs, and regolding (#1673)
* removing nParents from inputs, and regolding * pushing KnapsackModel * pushing gold for knapsack Tournament * making the population size exactly equal the user input * removing commented lines * fixing typo in manual * regolding * Adding a conversion script
1 parent a31f89a commit 0b14ebd

File tree

65 files changed

+3461
-15068
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+3461
-15068
lines changed

developer_tools/XSDSchemas/Optimizers.xsd

Lines changed: 27 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,6 @@
9191
</xsd:all>
9292
</xsd:complexType>
9393

94-
<!-- <xsd:complexType name="linearCoolingType">
95-
<xsd:element name="beta" type="xsd:float"/>
96-
</xsd:complexType> -->
97-
9894
<xsd:complexType name="exponentialCoolingType">
9995
<xsd:all>
10096
<xsd:element name="alpha" type="xsd:float"/>
@@ -113,10 +109,6 @@
113109
</xsd:all>
114110
</xsd:complexType>
115111

116-
<!-- <xsd:complexType name="fastCoolingType">
117-
<xsd:element name="c" type="xsd:float"/>
118-
</xsd:complexType> -->
119-
120112
<xsd:complexType name="veryFastCoolingType">
121113
<xsd:all>
122114
<xsd:element name="c" type="xsd:float"/>
@@ -188,14 +180,40 @@
188180
<xsd:attribute name="verbosity" type="verbosityAttr"/>
189181
</xsd:complexType>
190182

183+
<xsd:complexType name="GeneticAlgorithmOptimizer">
184+
<xsd:sequence>
185+
<xsd:element name="samplerInit" type="optInitType" minOccurs="0"/>
186+
<xsd:element name="GAparams" type="GAoptInitType" minOccurs="0" maxOccurs="1"/>
187+
<xsd:element name="convergence" type="SAConvergenceType" minOccurs="0" maxOccurs="1"/>
188+
<xsd:element name="coolingSchedule" type="OptCoolingScheduleType" minOccurs="0" maxOccurs="1"/>
189+
<xsd:element name="variable" type="optVarType" minOccurs="1" maxOccurs='unbounded'/>
190+
<xsd:element name="objective" type="xsd:string" minOccurs="1" maxOccurs="1"/>
191+
<xsd:element name="TargetEvaluation" type="AssemblerObjectType" minOccurs="1" maxOccurs="1"/>
192+
<xsd:element name="constant" type="constantVarType" minOccurs="0" maxOccurs='unbounded'/>
193+
<xsd:element name="ConstantSource" minOccurs="0" maxOccurs='unbounded'>
194+
<xsd:complexType mixed="true">
195+
<xsd:attribute name="class" type="xsd:string" use="required"/>
196+
<xsd:attribute name="type" type="xsd:string" />
197+
</xsd:complexType>
198+
</xsd:element>
199+
<xsd:element name="Sampler" type="AssemblerObjectType" minOccurs="0" maxOccurs="1"/>
200+
<xsd:element name="Constraint" type="AssemblerObjectType" minOccurs="0" maxOccurs="unbounded"/>
201+
<xsd:element name="ImplicitConstraint" type="AssemblerObjectType" minOccurs="0" maxOccurs="unbounded"/>
202+
<xsd:element name="Restart" type="AssemblerObjectType" minOccurs="0" maxOccurs="1"/>
203+
<xsd:element name="restartTolerance" type="xsd:float" minOccurs="0" maxOccurs="1"/>
204+
<xsd:element name="variableTransformation" type="variablesTransformationType" minOccurs="0" maxOccurs="1"/>
205+
</xsd:sequence>
206+
<xsd:attribute name="name" type="xsd:string" use="required"/>
207+
<xsd:attribute name="verbosity" type="verbosityAttr"/>
208+
</xsd:complexType>
191209
<xsd:complexType name="crossoverType">
192210
<xsd:all>
193211
<xsd:element name="crossoverProb" type="xsd:float" />
194212
</xsd:all>
195213
<xsd:attribute name="type" type="xsd:string" />
196214
</xsd:complexType>
197215

198-
<xsd:complexType name="mutationType">
216+
<xsd:complexType name="mutationType">
199217
<xsd:all>
200218
<xsd:element name="mutationProb" type="xsd:float" />
201219
<xsd:element name="locs" type="xsd:string" minOccurs="0" maxOccurs="1"/>
@@ -208,7 +226,6 @@
208226
<xsd:element name="crossover" type="crossoverType" />
209227
<xsd:element name="mutation" type="mutationType" />
210228
</xsd:all>
211-
<xsd:attribute name="nParents" type="xsd:integer" />
212229
</xsd:complexType>
213230

214231
<xsd:complexType name="fitnessType">
@@ -228,31 +245,4 @@
228245
<xsd:element name="survivorSelection" type="xsd:string" />
229246
</xsd:all>
230247
</xsd:complexType>
231-
232-
<xsd:complexType name="GeneticAlgorithmOptimizer">
233-
<xsd:sequence>
234-
<xsd:element name="samplerInit" type="optInitType" minOccurs="0"/>
235-
<xsd:element name="GAparams" type="GAoptInitType" minOccurs="0" maxOccurs="1"/>
236-
<xsd:element name="convergence" type="SAConvergenceType" minOccurs="0" maxOccurs="1"/>
237-
<xsd:element name="coolingSchedule" type="OptCoolingScheduleType" minOccurs="0" maxOccurs="1"/>
238-
<xsd:element name="variable" type="optVarType" minOccurs="1" maxOccurs='unbounded'/>
239-
<xsd:element name="objective" type="xsd:string" minOccurs="1" maxOccurs="1"/>
240-
<xsd:element name="TargetEvaluation" type="AssemblerObjectType" minOccurs="1" maxOccurs="1"/>
241-
<xsd:element name="constant" type="constantVarType" minOccurs="0" maxOccurs='unbounded'/>
242-
<xsd:element name="ConstantSource" minOccurs="0" maxOccurs='unbounded'>
243-
<xsd:complexType mixed="true">
244-
<xsd:attribute name="class" type="xsd:string" use="required"/>
245-
<xsd:attribute name="type" type="xsd:string" />
246-
</xsd:complexType>
247-
</xsd:element>
248-
<xsd:element name="Sampler" type="AssemblerObjectType" minOccurs="0" maxOccurs="1"/>
249-
<xsd:element name="Constraint" type="AssemblerObjectType" minOccurs="0" maxOccurs="unbounded"/>
250-
<xsd:element name="ImplicitConstraint" type="AssemblerObjectType" minOccurs="0" maxOccurs="unbounded"/>
251-
<xsd:element name="Restart" type="AssemblerObjectType" minOccurs="0" maxOccurs="1"/>
252-
<xsd:element name="restartTolerance" type="xsd:float" minOccurs="0" maxOccurs="1"/>
253-
<xsd:element name="variableTransformation" type="variablesTransformationType" minOccurs="0" maxOccurs="1"/>
254-
</xsd:sequence>
255-
<xsd:attribute name="name" type="xsd:string" use="required"/>
256-
<xsd:attribute name="verbosity" type="verbosityAttr"/>
257-
</xsd:complexType>
258248
</xsd:schema>

doc/user_manual/generated/optimizer.tex

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,20 @@ \subsection{GradientDescent}
272272
SPSA, a small value for the shrink factor is recommended. If an
273273
optimization path appears to be converging early, increasing the shrink
274274
factor might improve the search. \default{1.15}
275+
276+
\item \xmlNode{window}: \xmlDesc{integer},
277+
the number of previous gradient evaluations to include when determining a new step
278+
direction. Modifying this allows past gradient evaluations to influence future steps,
279+
with a decaying influence. Setting this to 1 means only the local gradient evaluation
280+
will be used. \default{1}.
281+
282+
\item \xmlNode{decay}: \xmlDesc{float},
283+
if including more than one gradient history terms when determining a new step
284+
direction, specifies the rate of decay for previous terms to influence
285+
the current direction. The decay factor has the form $e^(-\lambda t)$,
286+
where $t$ counts the gradient terms starting with the most recent as 0
287+
and moving towards the past, and $\lambda$ is this decay factor. This
288+
should generally be a small decimal number. \default{0.2}
275289
\end{itemize}
276290

277291
\item \xmlNode{ConjugateGradient}:
@@ -392,7 +406,8 @@ \subsection{GradientDescent}
392406
the name of a function defined in the \xmlNode{Functions} block (see
393407
Section~\ref{sec:functions}). This external function must contain a method
394408
called ``constrain'', which returns True for inputs satisfying the explicit
395-
constraints and False otherwise.
409+
constraints and False otherwise. \nb Currently this accepts any number of constraints from the
410+
user.
396411
The \xmlNode{Constraint} node recognizes the following parameters:
397412
\begin{itemize}
398413
\item \xmlAttr{class}: \xmlDesc{string, required},
@@ -784,7 +799,8 @@ \subsection{SimulatedAnnealing}
784799
the name of a function defined in the \xmlNode{Functions} block (see
785800
Section~\ref{sec:functions}). This external function must contain a method
786801
called ``constrain'', which returns True for inputs satisfying the explicit
787-
constraints and False otherwise.
802+
constraints and False otherwise. \nb Currently this accepts any number of constraints from the
803+
user.
788804
The \xmlNode{Constraint} node recognizes the following parameters:
789805
\begin{itemize}
790806
\item \xmlAttr{class}: \xmlDesc{string, required},
@@ -1094,27 +1110,24 @@ \subsection{GeneticAlgorithm}
10941110
A node containing the criterion based on which the parents are selected. This can be a
10951111
fitness proportional selection such as: a.
10961112
\textbf{\textit{rouletteWheel}}, b.
1097-
\textbf{\textit{stochasticUniversalSampling}}, c.
1098-
\textbf{\textit{Tournament}}, d. \textbf{\textit{Rank}}, or
1099-
e. \textbf{\textit{randomSelection}}
1113+
\textbf{\textit{tournamentSelection}}, c.
1114+
\textbf{\textit{rankSelection}} for all methods nParents is computed
1115+
such that the population size is kept constant. \[ nChildren = 2 \times
1116+
{nParents \choose 2} = nParents \times (nParents-1) = popSize \], solving for nParents we
1117+
get: $nParents = ceil(\frac{1 + \sqrt{1+4*popSize}}{2})$ This will
1118+
result in a popSize a little lareger than the initial one, these excessive children will
1119+
be later thrawn away and only the first popSize child will be kept
11001120

11011121
\item \xmlNode{reproduction}:
11021122
a node containing the reproduction methods. This accepts subnodes that
11031123
specifies the types of crossover and mutation.
1104-
The \xmlNode{reproduction} node recognizes the following parameters:
1105-
\begin{itemize}
1106-
\item \xmlAttr{nParents}: \xmlDesc{integer, required},
1107-
number of parents to be considered in the reproduction phase
1108-
\end{itemize}
11091124

11101125
The \xmlNode{reproduction} node recognizes the following subnodes:
11111126
\begin{itemize}
11121127
\item \xmlNode{crossover}: \xmlDesc{string},
11131128
a subnode containing the implemented crossover mechanisms. This
1114-
includes: a. One Point Crossover, b. MultiPoint
1115-
Crossover, c. Uniform Crossover,
1116-
d. Whole Arithmetic Recombination, or e. Davis’
1117-
Order Crossover.
1129+
includes: a. onePointCrossover, b.
1130+
twoPointsCrossover, c. uniformCrossover.
11181131
The \xmlNode{crossover} node recognizes the following parameters:
11191132
\begin{itemize}
11201133
\item \xmlAttr{type}: \xmlDesc{string, required},
@@ -1133,9 +1146,8 @@ \subsection{GeneticAlgorithm}
11331146

11341147
\item \xmlNode{mutation}: \xmlDesc{string},
11351148
a subnode containing the implemented mutation mechanisms. This
1136-
includes: a. Bit Flip, b. Random Resetting,
1137-
c. Swap, d. Scramble, or
1138-
e. Inversion.
1149+
includes: a. bitFlipMutation, b. swapMutation,
1150+
c. scrambleMutation, or d. inversionMutation.
11391151
The \xmlNode{mutation} node recognizes the following parameters:
11401152
\begin{itemize}
11411153
\item \xmlAttr{type}: \xmlDesc{string, required},
@@ -1159,12 +1171,18 @@ \subsection{GeneticAlgorithm}
11591171

11601172
\item \xmlNode{fitness}: \xmlDesc{string},
11611173
a subnode containing the implemented fitness functions. This includes:
1162-
a. invLinear: $fitness = \frac{1}{a \times obj + b \times penalty}$.
1163-
b. logistic: $fitness = \frac{1}{1+e^{a \times (obj-b)}}$
1174+
1175+
a. invLinear: \[fitness = -a \times obj - b \times \sum_{j=1}^{nConstraints}
1176+
max(0,-penalty_j)\] b. logistic: \[fitness =
1177+
\frac{1}{1+e^{a \times (obj-b)}}\] c. feasibleFirst:
1178+
\[fitness = \begin{cases}
1179+
-obj & g_j(x) \geq 0 \forall j \\
1180+
-obj_{worst} - \sum_{j=1}^{nConstraints} <g_j(x)> & o.w. \\
1181+
\end{cases}\]
11641182
The \xmlNode{fitness} node recognizes the following parameters:
11651183
\begin{itemize}
11661184
\item \xmlAttr{type}: \xmlDesc{string, required},
1167-
[invLin, logistic]
1185+
[invLin, logistic, feasibleFirst]
11681186
\end{itemize}
11691187

11701188
The \xmlNode{fitness} node recognizes the following subnodes:
@@ -1247,7 +1265,8 @@ \subsection{GeneticAlgorithm}
12471265
the name of a function defined in the \xmlNode{Functions} block (see
12481266
Section~\ref{sec:functions}). This external function must contain a method
12491267
called ``constrain'', which returns True for inputs satisfying the explicit
1250-
constraints and False otherwise.
1268+
constraints and False otherwise. \nb Currently this accepts any number of constraints from the
1269+
user.
12511270
The \xmlNode{Constraint} node recognizes the following parameters:
12521271
\begin{itemize}
12531272
\item \xmlAttr{class}: \xmlDesc{string, required},

framework/Optimizers/GeneticAlgorithm.py

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -142,16 +142,19 @@ def getInputSpecification(cls):
142142
fitness proportional selection such as:
143143
a. \textbf{\textit{rouletteWheel}},
144144
b. \textbf{\textit{tournamentSelection}},
145-
c. \textbf{\textit{rankSelection}}, or""")
145+
c. \textbf{\textit{rankSelection}}
146+
for all methods nParents is computed such that the population size is kept constant.
147+
\[ nChildren = 2 \times {nParents \choose 2} = nParents \times (nParents-1) = popSize \]
148+
solving for nParents we get:
149+
\[nParents = ceil(\frac{1 + \sqrt{1+4*popSize}}{2})\]
150+
This will result in a popSize a little lareger than the initial one, these excessive children will be later thrawn away and only the first popSize child will be kept""")
146151
GAparams.addSub(parentSelection)
147152

148153
# Reproduction
149154
reproduction = InputData.parameterInputFactory('reproduction', strictMode=True,
150155
printPriority=108,
151156
descr=r"""a node containing the reproduction methods.
152157
This accepts subnodes that specifies the types of crossover and mutation.""")
153-
reproduction.addParam("nParents", InputTypes.IntegerType, True,
154-
descr="number of parents to be considered in the reproduction phase")
155158
# 1. Crossover
156159
crossover = InputData.parameterInputFactory('crossover', strictMode=True,
157160
contentType=InputTypes.StringType,
@@ -289,7 +292,7 @@ def handleInput(self, paramInput):
289292
self._parentSelectionInstance = parentSelectionReturnInstance(self,name = parentSelectionNode.value)
290293
# reproduction node
291294
reproductionNode = gaParamsNode.findFirst('reproduction')
292-
self._nParents = reproductionNode.parameterValues['nParents']
295+
self._nParents = int(np.ceil(1/2 + np.sqrt(1+4*self._populationSize)/2))
293296
self._nChildren = int(2*comb(self._nParents,2))
294297
# crossover node
295298
crossoverNode = reproductionNode.findFirst('crossover')
@@ -319,7 +322,7 @@ def handleInput(self, paramInput):
319322

320323
# Check if the fitness requested is among the constrained optimization fitnesses
321324
# Currently, only InvLin and feasibleFirst Fitnesses deal with constrained optimization
322-
## TODO: @mandd, please explore the possibility to conver the logistic fitness into a constrained optimization fitness.
325+
## TODO: @mandd, please explore the possibility to convert the logistic fitness into a constrained optimization fitness.
323326
if 'Constraint' in self.assemblerObjects.keys() and self._fitnessType not in ['invLinear','feasibleFirst']:
324327
self.raiseAnError(IOError, 'Currently constrained Genetic Algorithms only support invLinear and feasibleFirst fitnesses, whereas provided fitness is {}'.format(self._fitnessType))
325328
self._objCoeff = fitnessNode.findFirst('a').value if fitnessNode.findFirst('a') is not None else None
@@ -354,7 +357,7 @@ def initialize(self, externalSeeding=None, solutionExport=None):
354357

355358
meta = ['batchId']
356359
self.addMetaKeys(meta)
357-
self.batch = self._populationSize*(self.counter==0)+self._nChildren*(self.counter>0)
360+
self.batch = self._populationSize
358361
if self._populationSize != len(self._initialValues):
359362
self.raiseAnError(IOError, 'Number of initial values provided for each variable is {}, while the population size is {}'.format(len(self._initialValues),self._populationSize,self._populationSize))
360363
for _, init in enumerate(self._initialValues):
@@ -431,7 +434,7 @@ def _useRealization(self, info, rlz):
431434
coords={'chromosome':np.arange(np.shape(offSprings)[0]),
432435
'Constraint':[y.name for y in (self._constraintFunctions + self._impConstraintFunctions)]})
433436
## FIXME The constraint handling is following the structure of the RavenSampled.py,
434-
# there are many utility functions that can be simplified and/or merged with
437+
# there are many utility functions that can be simplified and/or merged together
435438
# _check, _handle, and _apply, for explicit and implicit constraints.
436439
# This can be simplified in the near future in GradientDescent, SimulatedAnnealing, and here in GA
437440
for index,individual in enumerate(offSprings):
@@ -525,20 +528,24 @@ def _useRealization(self, info, rlz):
525528
repeated.append(j)
526529
repeated = list(set(repeated))
527530
if repeated:
528-
newChildren = self._mutationInstance(offSprings=children[repeated,:], distDict = self.distDict, locs = self._mutationLocs, mutationProb=self._mutationProb,variables=list(self.toBeSampled))
529-
children.data[repeated,:] = newChildren.data
531+
if len(repeated)> children.shape[0] - self._populationSize:
532+
newChildren = self._mutationInstance(offSprings=children[repeated,:], distDict = self.distDict, locs = self._mutationLocs, mutationProb=self._mutationProb,variables=list(self.toBeSampled))
533+
children.data[repeated,:] = newChildren.data
534+
else:
535+
children = children.drop_sel(chromosome=repeated)
530536
else:
531537
flag = False
532-
533-
self.batch = np.shape(children)[0]
538+
# keeping the population size constant by ignoring the excessive children
539+
children = children[:self._populationSize,:]
534540

535541
daChildren = xr.DataArray(children,
536542
dims=['chromosome','Gene'],
537543
coords={'chromosome': np.arange(np.shape(children)[0]),
538544
'Gene':list(self.toBeSampled)})
545+
539546
# 5 @ n: Submit children batch
540547
# submit children coordinates (x1,...,xm), i.e., self.childrenCoordinates
541-
for i in range(np.shape(daChildren)[0]):
548+
for i in range(self.batch):
542549
newRlz={}
543550
for _,var in enumerate(self.toBeSampled.keys()):
544551
newRlz[var] = float(daChildren.loc[i,var].values)

0 commit comments

Comments
 (0)