-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding first version of genetic search algorithm based on random
- Loading branch information
Showing
2 changed files
with
217 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
#include "genetic_search.hpp" | ||
#include <algorithm> | ||
#include <iostream> | ||
#include <fstream> | ||
#include <iomanip> | ||
|
||
namespace apex { | ||
|
||
namespace random { | ||
|
||
double inline myrand() { | ||
return ((double) rand() / (RAND_MAX)); | ||
} | ||
|
||
size_t GeneticSearch::get_max_iterations() { | ||
size_t max_iter{1}; | ||
for (auto& v : vars) { | ||
switch (v.second.vtype) { | ||
case VariableType::doubletype: { | ||
max_iter = max_iter * v.second.dvalues.size(); | ||
break; | ||
} | ||
case VariableType::longtype: { | ||
max_iter = max_iter * v.second.lvalues.size(); | ||
break; | ||
} | ||
case VariableType::stringtype: { | ||
max_iter = max_iter * v.second.svalues.size(); | ||
break; | ||
} | ||
default: { | ||
break; | ||
} | ||
} | ||
} | ||
// want to see multiple values of each one | ||
//return max_iter; | ||
return std::min(max_iterations, (std::max(min_iterations, max_iter))); | ||
} | ||
|
||
class log_wrapper { | ||
private: | ||
std::ofstream myfile; | ||
public: | ||
log_wrapper(const std::map<std::string, Variable>& vars) { | ||
myfile.open("tuning.csv"); | ||
myfile << "iter,"; | ||
for (auto& v : vars) { myfile << v.first << ","; } | ||
myfile << "time" << std::endl; | ||
} | ||
~log_wrapper() { | ||
myfile.close(); | ||
} | ||
std::ofstream& getstream() { | ||
return myfile; | ||
} | ||
}; | ||
|
||
void GeneticSearch::evaluate(double new_cost) { | ||
static log_wrapper log(vars); | ||
static size_t count{0}; | ||
if (++count % 10000 == 0) { std::cout << count << std::endl; } | ||
log.getstream() << count << ","; | ||
for (auto& v : vars) { log.getstream() << v.second.toString() << ","; } | ||
log.getstream() << new_cost << std::endl; | ||
if (new_cost < cost) { | ||
if (new_cost < best_cost) { | ||
best_cost = new_cost; | ||
std::cout << "New best! " << new_cost << " k: " << k; | ||
for (auto& v : vars) { v.second.save_best(); } | ||
for (auto& v : vars) { std::cout << ", value: " << v.second.toString(); } | ||
std::cout << std::endl; | ||
} | ||
cost = new_cost; | ||
} | ||
//for (auto& v : vars) { v.second.choose_neighbor(); } | ||
k++; | ||
return; | ||
} | ||
|
||
} // random | ||
|
||
} // apex | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
#pragma once | ||
#include <vector> | ||
#include <string> | ||
#include <iostream> | ||
#include <cstdint> | ||
#include <cstdlib> | ||
#include <algorithm> | ||
#include <cmath> | ||
#include <random> | ||
#include <limits> | ||
#include <map> | ||
#include "apex_types.h" | ||
#include "apex_assert.h" | ||
|
||
namespace apex { | ||
|
||
namespace random { | ||
|
||
enum class VariableType { doubletype, longtype, stringtype } ; | ||
|
||
class Variable { | ||
public: | ||
std::vector<double> dvalues; | ||
std::vector<long> lvalues; | ||
std::vector<std::string> svalues; | ||
VariableType vtype; | ||
size_t current_index; | ||
size_t best_index; | ||
void * value; // for the client to get the values | ||
size_t maxlen; | ||
Variable () = delete; | ||
Variable (VariableType vtype, void * ptr) : vtype(vtype), current_index(0), | ||
best_index(0), value(ptr), maxlen(0) { } | ||
void set_current_value() { | ||
if (vtype == VariableType::doubletype) { | ||
*((double*)(value)) = dvalues[current_index]; | ||
} | ||
else if (vtype == VariableType::longtype) { | ||
*((long*)(value)) = lvalues[current_index]; | ||
} | ||
else { | ||
*((const char**)(value)) = svalues[current_index].c_str(); | ||
} | ||
} | ||
size_t get_next_neighbor() { | ||
current_index = (rand() % maxlen); | ||
APEX_ASSERT(current_index < maxlen); | ||
set_current_value(); | ||
return current_index; | ||
} | ||
void save_best() { best_index = current_index; } | ||
void set_init() { | ||
maxlen = (std::max(std::max(dvalues.size(), | ||
lvalues.size()), svalues.size())) - 1; | ||
current_index = 0; | ||
set_current_value(); | ||
} | ||
std::string getBest() { | ||
if (vtype == VariableType::doubletype) { | ||
*((double*)(value)) = dvalues[best_index]; | ||
return std::to_string(dvalues[best_index]); | ||
} | ||
else if (vtype == VariableType::longtype) { | ||
*((long*)(value)) = lvalues[best_index]; | ||
return std::to_string(lvalues[best_index]); | ||
} | ||
//else if (vtype == VariableType::stringtype) { | ||
*((const char**)(value)) = svalues[best_index].c_str(); | ||
return svalues[best_index]; | ||
} | ||
std::string toString() { | ||
if (vtype == VariableType::doubletype) { | ||
return std::to_string(dvalues[current_index]); | ||
} | ||
else if (vtype == VariableType::longtype) { | ||
return std::to_string(lvalues[current_index]); | ||
} | ||
//else if (vtype == VariableType::stringtype) { | ||
return svalues[current_index]; | ||
//} | ||
} | ||
}; | ||
|
||
class GeneticSearch { | ||
private: | ||
double cost; | ||
double best_cost; | ||
size_t kmax; | ||
size_t k; | ||
std::map<std::string, Variable> vars; | ||
const size_t max_iterations{1000}; | ||
const size_t min_iterations{100}; | ||
public: | ||
void evaluate(double new_cost); | ||
GeneticSearch() : | ||
kmax(0), k(1) { | ||
cost = std::numeric_limits<double>::max(); | ||
best_cost = cost; | ||
//std::cout << "New Session!" << std::endl; | ||
//srand (1); | ||
srand (time(NULL)); | ||
} | ||
double getEnergy() { return best_cost; } | ||
bool converged() { return (k > kmax); } | ||
void getNewSettings() { | ||
/* Increment neighbour */ | ||
for (auto& v : vars) { v.second.get_next_neighbor(); } | ||
} | ||
void saveBestSettings() { | ||
for (auto& v : vars) { v.second.getBest(); } | ||
} | ||
void printBestSettings() { | ||
std::string d("["); | ||
for (auto v : vars) { | ||
std::cout << d << v.second.getBest(); | ||
d = ","; | ||
} | ||
std::cout << "]" << std::endl; | ||
} | ||
size_t get_max_iterations(); | ||
std::map<std::string, Variable>& get_vars() { return vars; } | ||
void add_var(std::string name, Variable var) { | ||
vars.insert(std::make_pair(name, var)); | ||
kmax = get_max_iterations(); | ||
/* get max iterations */ | ||
//std::cout << "Max iterations : " << kmax << std::endl; | ||
} | ||
}; | ||
|
||
} // random | ||
|
||
} // apex |