4 #ifndef DIGNEA_NOVELTYSEARCH_H
5 #define DIGNEA_NOVELTYSEARCH_H
7 #include <dignea/distances/Distance.h>
12 #include <dignea/utilities/exceptions/EmptyPopulation.h>
16 #include <nlohmann/json.hpp>
24 typedef vector<float> Descriptor;
35 Descriptor castDescriptor(
const std::vector<F> &from) {
36 Descriptor castedVector;
37 castedVector.reserve(from.size());
38 std::transform(from.begin(), from.end(), std::back_inserter(castedVector),
39 [](F value) { return static_cast<float>(value); });
55 const float &threshold = 2000,
56 const float &finalThresh = 0.0001,
63 vector<S> run(vector<S> &population,
const Problem<S> *problem)
override;
65 virtual void cmpFinals(vector<S> &population,
68 virtual void insertIntoArchive(
const S &solution);
70 inline const vector<S> &getArchive()
const {
return this->noveltyArchive; }
72 virtual json to_json();
74 float getThreshold()
const {
return this->threshold; }
76 float getK()
const {
return this->k; }
78 float getFinalThresh()
const {
return this->finalSThreshold; }
81 virtual vector<Descriptor> beforeRun(
const vector<S> &population);
83 virtual vector<Descriptor> beforeCmpFinals(
const vector<S> &population);
85 virtual void insertFinal(
const S &solution);
88 unique_ptr<Distance<float>> distance;
89 vector<S> noveltyArchive;
91 vector<Descriptor> finalSsDesc;
94 float finalSThreshold;
106 template <
typename S>
108 const float &threshold,
109 const float &finalThresh,
const int &k)
110 : distance(move(dist)),
111 threshold(threshold),
112 finalSThreshold(finalThresh),
123 template <
typename S>
125 vector<Descriptor> combinedPop;
126 combinedPop.reserve(population.size() + this->noveltyArchive.size());
127 for (
const S &solution : population) {
128 vector vars = solution.getVariables();
129 combinedPop.push_back(castDescriptor(vars));
131 for (
const S &solution : noveltyArchive) {
132 vector vars = solution.getVariables();
133 combinedPop.push_back(castDescriptor(vars));
156 template <
typename S>
159 vector<Descriptor> combinedPopulation = beforeRun(population);
163 vector spars =
sparseness(combinedPopulation, this->distance.get(), k);
165 if (population[0].getNumberOfObjs() == 2) {
169 for (
unsigned int i = 0; i < population.size(); i++) {
170 population[i].setDiversity(spars[i]);
172 population[i].setObjAt(1, spars[i]);
183 template <
typename S>
185 const vector<S> &population) {
186 vector<Descriptor> descriptors;
187 descriptors.reserve(population.size());
188 for (
const S &solution : population) {
189 vector vars = solution.getVariables();
190 descriptors.push_back(castDescriptor(vars));
204 template <
typename S>
207 if (population.size() == 0) {
208 std::string where =
"NoveltySearch::cmpFinals";
209 throw EmptyPopulation(where);
212 std::cout << fmt::format(
"{:=^120}",
" Including inds. final solution set ")
214 std::cout << fmt::format(
"{:=^120}",
"") << std::endl;
215 std::cout << fmt::format(
"{:^30}\t{:^30}\t{:^20}({})\t{:^20}",
"Sparseness",
216 "Biased Fitness",
"Greater than threshold",
217 this->finalSThreshold,
"Archive len()")
219 std::cout << fmt::format(
"{:=^120}",
"") << std::endl;
222 if (population[0].getNumberOfObjs() == 1) {
224 if (finalSs.empty()) {
226 for (S &sol : population) {
227 if (sol.getFitness() > 0.0) {
228 this->insertFinal(sol);
239 vector descriptors = beforeCmpFinals(population);
240 for (
unsigned int i = 0; i < descriptors.size(); i++) {
241 float spars =
sparseness(descriptors[i], this->finalSsDesc,
243 if ((population[i].getBiasedFitness() > 0.0) &&
244 (spars > this->finalSThreshold)) {
245 this->insertFinal(population[i]);
250 std::cout << fmt::format(
251 "{:>20}\t{:>30}\t{:>20}\t{:>20}", spars,
252 solution.getBiasedFitness(),
253 (spars > this->finalSThreshold ?
"Yes" :
"No"),
262 "problem is nullptr in NoveltySearch::cmpFinals. When using "
263 "MOEIG cmpFinals must receive the problem as well";
264 throw(std::runtime_error(where));
266 if (finalSs.empty()) {
268 for (S &sol : population) {
269 if (sol.getObjAt(0) > 0.0) {
270 this->insertFinal(sol);
278 vector descriptors = beforeCmpFinals(population);
279 for (
unsigned int i = 0; i < descriptors.size(); i++) {
280 float spars =
sparseness(descriptors[i], this->finalSsDesc,
282 if ((population[i].getObjAt(0) > 0.0) &&
283 (spars > this->finalSThreshold)) {
284 this->insertFinal(population[i]);
298 template <
typename S>
311 template <
typename S>
313 this->noveltyArchive.push_back(solution);
324 template <
typename S>
326 this->finalSs.push_back(solution);
327 this->finalSsDesc.push_back(castDescriptor(solution.getVariables()));
330 template <
typename S>
333 data[
"name"] =
"Novelty Search";
335 data[
"threshold"] = this->threshold;
vector< float > sparseness(const vector< Descriptor > &population, Distance< float > *metric, const int k)
Computes the sparseness of all individuals in the population vector Based on the Novelty Search from ...
Definition: KNN.cpp:81
nlohmann::json json
Definition: MinKnap.h:85
void sortByObj(vector< S > &population, const int &objNumber, const Problem< S > *problem)
Sorts the population of individuals by the given objective according to the problem....
Definition: Sorter.h:36
void sortByFitness(vector< S > &population)
Sorts the population by fitness in descending order.
Definition: Sorter.h:69
Front class which stores the final results of an EA execution.
Definition: Front.h:26
Class to represent the Novelty Search Algorithm.
Definition: NoveltySearch.h:50
virtual vector< Descriptor > beforeRun(const vector< S > &population)
Performs computational work necessary for running the NS This method creates a combined population us...
Definition: NoveltySearch.h:124
Front< S > getResults() override
Returns the results obtained by the Novelty Search in a Front object.
Definition: NoveltySearch.h:299
virtual void cmpFinals(vector< S > &population, const Problem< S > *problem=nullptr)
Compares the individuals in the population against the neighbors inside the archive of final Ss....
Definition: NoveltySearch.h:205
virtual void insertFinal(const S &solution)
Method to insert a new individual into the final set of solutions The default behaviour is to get all...
Definition: NoveltySearch.h:325
vector< S > run(vector< S > &population, const Problem< S > *problem) override
Novelty Search Algorithm It looks for novelty using the genotypes of the individuals in the populatio...
Definition: NoveltySearch.h:157
virtual void insertIntoArchive(const S &solution)
Method to insert a new individual into the noveltyArchive of novelty solutions.
Definition: NoveltySearch.h:312
Class to represent a Problem in the tool. It includes the basic information for a problem a few metho...
Definition: Problem.h:29
Search algorithm interface for dignea. Use this class as the skeleton to define local or other types ...
Definition: Search.h:23