Skip to content

Commit c8c4fed

Browse files
committed
NSGA2: introduce a new Optimize function that takes the front and the paretoSet, so we can avoid introducing new template parameters.
1 parent e2b67b2 commit c8c4fed

3 files changed

Lines changed: 191 additions & 163 deletions

File tree

include/ensmallen_bits/nsga2/nsga2.hpp

Lines changed: 85 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,7 @@ namespace ens {
5151
* see the documentation on function types included with this distribution or
5252
* on the ensmallen website.
5353
*/
54-
template<
55-
typename MatType,
56-
typename ColType = typename ForwardType<MatType>::bvec,
57-
typename CubeType = typename ForwardType<MatType>::bcube
58-
>
59-
class NSGA2Type
54+
class NSGA2
6055
{
6156
public:
6257
/**
@@ -68,8 +63,7 @@ class NSGA2Type
6863
*
6964
* @param populationSize The number of candidates in the population.
7065
* This should be atleast 4 in size and a multiple of 4.
71-
* @param maxGenerations The maximum number of generations allowed
72-
* for NSGA-II.
66+
* @param maxGenerations The maximum number of generations allowed for NSGA-II.
7367
* @param crossoverProb The probability that a crossover will occur.
7468
* @param mutationProb The probability that a mutation will occur.
7569
* @param mutationStrength The strength of the mutation.
@@ -78,15 +72,14 @@ class NSGA2Type
7872
* @param lowerBound Lower bound of the coordinates of the initial population.
7973
* @param upperBound Upper bound of the coordinates of the initial population.
8074
*/
81-
NSGA2Type(
82-
const size_t populationSize = 100,
83-
const size_t maxGenerations = 2000,
84-
const double crossoverProb = 0.6,
85-
const double mutationProb = 0.3,
86-
const double mutationStrength = 1e-3,
87-
const double epsilon = 1e-6,
88-
const ColType& lowerBound = ColType(1, GetFillType<MatType>::zeros),
89-
const ColType& upperBound = ColType(1, GetFillType<MatType>::ones));
75+
NSGA2(const size_t populationSize = 100,
76+
const size_t maxGenerations = 2000,
77+
const double crossoverProb = 0.6,
78+
const double mutationProb = 0.3,
79+
const double mutationStrength = 1e-3,
80+
const double epsilon = 1e-6,
81+
const arma::vec& lowerBound = arma::zeros(1, 1),
82+
const arma::vec& upperBound = arma::ones(1, 1));
9083

9184
/**
9285
* Constructor for the NSGA2 optimizer. This constructor provides an overload
@@ -107,36 +100,62 @@ class NSGA2Type
107100
* @param lowerBound Lower bound of the coordinates of the initial population.
108101
* @param upperBound Upper bound of the coordinates of the initial population.
109102
*/
110-
NSGA2Type(
111-
const size_t populationSize = 100,
112-
const size_t maxGenerations = 2000,
113-
const double crossoverProb = 0.6,
114-
const double mutationProb = 0.3,
115-
const double mutationStrength = 1e-3,
116-
const double epsilon = 1e-6,
117-
const double lowerBound = 0,
118-
const double upperBound = 1);
103+
NSGA2(const size_t populationSize = 100,
104+
const size_t maxGenerations = 2000,
105+
const double crossoverProb = 0.6,
106+
const double mutationProb = 0.3,
107+
const double mutationStrength = 1e-3,
108+
const double epsilon = 1e-6,
109+
const double lowerBound = 0,
110+
const double upperBound = 1);
111+
112+
/**
113+
* Optimize a set of objectives. The initial population is generated using the
114+
* starting point. The output is the best generated front.
115+
*
116+
* @tparam ArbitraryFunctionType std::tuple of multiple objectives.
117+
* @tparam MatType Type of matrix to optimize.
118+
* @tparam CallbackTypes Types of callback functions.
119+
* @param objectives Vector of objective functions to optimize for.
120+
* @param iterate Starting point.
121+
* @param callbacks Callback functions.
122+
* @return MatType::elem_type The minimum of the accumulated sum over the
123+
* objective values in the best front.
124+
*/
125+
template<typename MatType,
126+
typename... ArbitraryFunctionType,
127+
typename... CallbackTypes>
128+
typename MatType::elem_type Optimize(
129+
std::tuple<ArbitraryFunctionType...>& objectives,
130+
MatType& iterate,
131+
CallbackTypes&&... callbacks);
119132

120133
/**
121134
* Optimize a set of objectives. The initial population is generated using the
122135
* starting point. The output is the best generated front.
123136
*
124137
* @tparam ArbitraryFunctionType std::tuple of multiple objectives.
125138
* @tparam MatType Type of matrix to optimize.
139+
* @tparam CubeType Type of front.
126140
* @tparam CallbackTypes Types of callback functions.
127141
* @param objectives Vector of objective functions to optimize for.
128142
* @param iterate Starting point.
143+
* @param front The generated front.
144+
* @param paretoSet The generated Pareto set.
129145
* @param callbacks Callback functions.
130146
* @return MatType::elem_type The minimum of the accumulated sum over the
131147
* objective values in the best front.
132148
*/
133-
template<typename InputMatType,
149+
template<typename MatType,
150+
typename CubeType,
134151
typename... ArbitraryFunctionType,
135152
typename... CallbackTypes>
136-
typename InputMatType::elem_type Optimize(
137-
std::tuple<ArbitraryFunctionType...>& objectives,
138-
InputMatType& iterate,
139-
CallbackTypes&&... callbacks);
153+
typename MatType::elem_type Optimize(
154+
std::tuple<ArbitraryFunctionType...>& objectives,
155+
MatType& iterate,
156+
CubeType& front,
157+
CubeType& paretoSet,
158+
CallbackTypes&&... callbacks);
140159

141160
//! Get the population size.
142161
size_t PopulationSize() const { return populationSize; }
@@ -169,37 +188,53 @@ class NSGA2Type
169188
double& Epsilon() { return epsilon; }
170189

171190
//! Retrieve value of lowerBound.
172-
const ColType& LowerBound() const { return lowerBound; }
191+
const arma::vec& LowerBound() const { return lowerBound; }
173192
//! Modify value of lowerBound.
174-
ColType& LowerBound() { return lowerBound; }
193+
arma::vec& LowerBound() { return lowerBound; }
175194

176195
//! Retrieve value of upperBound.
177-
const ColType& UpperBound() const { return upperBound; }
196+
const arma::vec& UpperBound() const { return upperBound; }
178197
//! Modify value of upperBound.
179-
ColType& UpperBound() { return upperBound; }
198+
arma::vec& UpperBound() { return upperBound; }
180199

181-
//! Retrieve the Pareto optimal points in variable space. This returns an
182-
// empty cube until `Optimize()` has been called.
183-
const CubeType& ParetoSet() const { return paretoSet; }
200+
/**
201+
* Retrieve the Pareto optimal points in variable space. This returns an
202+
* empty cube until `Optimize()` has been called. Note that this function is
203+
* deprecated and will be removed in ensmallen 3.x! Use `Optimize()`
204+
* instead.
205+
*/
206+
template<typename MatType = arma::cube>
207+
[[deprecated("use Optimize() instead")]] MatType ParetoSet() const
208+
{
209+
return conv_to<MatType>::from(paretoSet);
210+
}
184211

185-
//! Retrieve the best front (the Pareto frontier). This returns an
186-
//! empty cube until `Optimize()` has been called.
187-
const CubeType& ParetoFront() const { return paretoFront; }
212+
/**
213+
* Retrieve the best front (the Pareto frontier). This returns an empty cube
214+
* until `Optimize()` has been called. Note that this function is
215+
* deprecated and will be removed in ensmallen 3.x! Use `Optimize()`
216+
* instead.
217+
*/
218+
template<typename MatType = arma::cube>
219+
[[deprecated("use Optimize() instead")]] MatType ParetoFront() const
220+
{
221+
return conv_to<MatType>::from(paretoFront);
222+
}
188223

189224
/**
190225
* Retrieve the best front (the Pareto frontier). This returns an empty
191226
* vector until `Optimize()` has been called. Note that this function is
192227
* deprecated and will be removed in ensmallen 3.x! Use `ParetoFront()`
193228
* instead.
194229
*/
195-
[[deprecated("use ParetoFront() instead")]] const std::vector<MatType>& Front()
230+
[[deprecated("use ParetoFront() instead")]] const std::vector<arma::mat>& Front()
196231
{
197232
if (rcFront.size() == 0)
198233
{
199234
// Match the old return format.
200235
for (size_t i = 0; i < paretoFront.n_slices; ++i)
201236
{
202-
rcFront.push_back(MatType(paretoFront.slice(i)));
237+
rcFront.push_back(arma::mat(paretoFront.slice(i)));
203238
}
204239
}
205240

@@ -359,7 +394,7 @@ class NSGA2Type
359394
//! The number of objectives being optimised for.
360395
size_t numObjectives;
361396

362-
//! The numbeer of variables used per objectives.
397+
//! The number of variables used per objectives.
363398
size_t numVariables;
364399

365400
//! The number of candidates in the population.
@@ -381,30 +416,28 @@ class NSGA2Type
381416
double epsilon;
382417

383418
//! Lower bound of the initial swarm.
384-
ColType lowerBound;
419+
arma::vec lowerBound;
385420

386421
//! Upper bound of the initial swarm.
387-
ColType upperBound;
422+
arma::vec upperBound;
388423

389424
//! The set of all the Pareto optimal points.
390425
//! Stored after Optimize() is called.
391-
CubeType paretoSet;
426+
arma::cube paretoSet;
392427

393428
//! The set of all the Pareto optimal objective vectors.
394429
//! Stored after Optimize() is called.
395-
CubeType paretoFront;
430+
arma::cube paretoFront;
396431

397432
//! A different representation of the Pareto front, for reverse compatibility
398433
//! purposes. This can be removed when ensmallen 3.x is released! (Along
399434
//! with `Front()`.) This is only populated when `Front()` is called.
400-
std::vector<MatType> rcFront;
435+
std::vector<arma::mat> rcFront;
401436
};
402437

403-
using NSGA2 = NSGA2Type<arma::mat>;
404-
405438
} // namespace ens
406439

407440
// Include implementation.
408441
#include "nsga2_impl.hpp"
409442

410-
#endif
443+
#endif

0 commit comments

Comments
 (0)