1
0
Files
SimulatedAnnealing/models.cpp
2023-12-31 15:42:33 +01:00

576 lines
15 KiB
C++
Executable File

#include<math.h>
#include<iostream>
#include<cstring>
#include"models.h"
/*
* Model
*/
Model::Model(){
Data T1("Model"),T2("Experience");
m_data = T1;
exp_data = T2;
CostFunction* f;
m_cost = f;
}
Model::Model(const Model& other): m_data(other.m_data),exp_data(other.exp_data),m_cost(other.m_cost){}
Model::Model(Data T){
Data T1("Model");
m_data = T1;
exp_data = T;
CostFunction* f;
m_cost = f;
}
//Model::Model(Data T1, Data T2, CostFunction* f): m_data(T1), exp_data(T2), m_cost(f){}
void Model::setModelData(Data T1){
m_data = T1;
}
void Model::setExpData(Data T2){
exp_data = T2;
}
void Model::setCost(CostFunction* f){
m_cost = f;
}
/*
* Linear Approximation model
*/
//Constructor & Destructor
LinearApprox::LinearApprox(): param({0.,0.}){
Data T1("LinearApprox"),T2("ExperimentalData");
m_data = T1;
exp_data = T2;
m_cost = new Khi2(m_data.getData(),exp_data.getData());
}
LinearApprox::LinearApprox(const LinearApprox& other): param(other.param){
m_data = other.m_data;
exp_data = other.exp_data;
m_cost = other.m_cost;
}
LinearApprox::LinearApprox(Data T): param({0.,0.}){
exp_data = T;
std::vector<std::vector<double>> V1(exp_data.getCard(), std::vector<double> (2,0.));
for(int i=0;i<exp_data.getCard();i++)
V1[i][0] = exp_data.getData()[i][0];
Data T1(V1,"LinearApprox");
m_data = T1;
m_cost = new Khi2(m_data.getData(),exp_data.getData());
}
LinearApprox::LinearApprox(Data T,std::vector<double> par): param(par){
exp_data = T;
std::vector<std::vector<double>> V1(exp_data.getCard(), std::vector<double> (2,0.));
for(int i=0;i<exp_data.getCard();i++){
V1[i][0] = exp_data.getData()[i][0];
V1[i][1] = param[0] + param[1] * exp_data.getData()[i][0];
}
Data T1(V1,"LinearApprox");
m_data = T1;
m_cost = new Khi2(m_data.getData(),exp_data.getData());
}
//Set model data, experimental data and cost function
void LinearApprox::setModelData(Data T1){
m_data = T1;
}
void LinearApprox::setExpData(Data T){
exp_data = T;
std::vector<std::vector<double>> V1(exp_data.getData());
for(int i=0;i<exp_data.getCard();i++)
V1[i][1] = param[0] + param[1]*V1[i][0];
m_data.setData(V1);
//delete m_cost;
//m_cost = new Khi2(exp_data.getData(),m_data.getData());
}
void LinearApprox::setCost(CostFunction* f){
delete m_cost;
m_cost = new Khi2(exp_data.getData(),m_data.getData());
}
//Solution, Neighbor and cost getter
Data LinearApprox::getSol() const {
return m_data;
}
void LinearApprox::setParam(std::vector<double> a){
param = a;
std::vector<std::vector<double>> n_val = m_data.getData();
for(int i=0;i<n_val.size();i++)
n_val[i][1] = param[1] * n_val[i][0] + param[0];
m_data.setData(n_val);
//delete m_cost;
//m_cost = new Khi2(exp_data.getData(),m_data.getData());
}
std::vector<double> LinearApprox::getParam() const {
return param;
}
std::vector<double> LinearApprox::getNeighbor(double ampl) const {
double d_o=0,d_s=0;
d_o = ampl*(2.*rand()/(RAND_MAX+1.)-1.);
d_s = ampl*(2.*rand()/(RAND_MAX+1.)-1.);
std::vector<double> n_param = {param[0]+d_o,param[1]+d_s};
return n_param;
}
double LinearApprox::getCost(){
delete m_cost;
m_cost = new Khi2(exp_data.getData(),m_data.getData());
return m_cost->get();
}
//Export model parameters
void LinearApprox::exportModel() const {
FILE * fich = fopen((exp_data.getName()+".linear_approx.data").c_str(), "w");
fprintf(fich, "y = %lf *x + %lf", param[1], param[0]);
}
void LinearApprox::displayModel() const {
char buffer[32];
memset(buffer, 0, sizeof(buffer));
snprintf(buffer, sizeof(buffer), "%g", m_cost->get());
std::string cost(buffer);
std::vector<std::string> commandsForGnuplot = {"set title \""+m_data.getName()+"\"","set key bmargin","plot '"+exp_data.getName()+".temp' using 1:2 w p pt 1 lc -1 title 'Experimental Data'"," replot '"+exp_data.getName()+".temp' using 3:4 w l dt 2 lc 6 title 'Linear approximation with khi2="+cost+"'"};
FILE * temp = fopen((exp_data.getName()+".temp").c_str(), "w");
FILE * gnuplotPipe = popen ("gnuplot -persistent", "w");
for (int i=0; i < m_data.getCard(); i++){
fprintf(temp, "%lf %lf %lf %lf \n", exp_data.getData()[i][0], exp_data.getData()[i][1], m_data.getData()[i][0], m_data.getData()[i][1]);
}
for (std::string command : commandsForGnuplot){
fprintf(gnuplotPipe,"%s \n", command.c_str());
}
}
//Set and get parameters
Data LinearApprox::getExpData() const {
return exp_data;
}
void LinearApprox::setSlope(double a){
param[1] = a;
std::vector<std::vector<double>> n_val = m_data.getData();
for(int i=0;i<n_val.size();i++)
n_val[i][1] = param[1] * n_val[i][0] + param[0];
m_data.setData(n_val);
//delete m_cost;
//m_cost = new Khi2(exp_data.getData(),m_data.getData());
}
double LinearApprox::getSlope() const {
return param[1];
}
void LinearApprox::setOffset(double b){
param[0] = b;
std::vector<std::vector<double>> n_val = m_data.getData();
for(int i=0;i<n_val.size();i++)
n_val[i][1] = param[1] * n_val[i][0] + param[0];
m_data.setData(n_val);
//delete m_cost;
//m_cost = new Khi2(exp_data.getData(),m_data.getData());
}
double LinearApprox::getOffset() const {
return param[0];
}
/*
* Polynomial Approximation model
*/
//Function to compute the value of a polynom at a point
double polynom(std::vector<double> a, double x){
double y=0,tmp=0;
for(int i=0;i<a.size();i++){
tmp = y;
y = tmp + a[i]*pow(x,i);
}
return y;
}
//Constructor & Destructor
PolynomialApprox::PolynomialApprox(){
Data T1("PolynomialApprox"),T2("ExperimentalData");
m_data = T1;
exp_data = T2;
m_cost = new Khi2(m_data.getData(),exp_data.getData());
std::vector<double> a(3,0.);
param = a;
}
PolynomialApprox::PolynomialApprox(const PolynomialApprox& other):param(other.param){
m_data = other.m_data;
exp_data = other.exp_data;
m_cost = other.m_cost;
}
PolynomialApprox::PolynomialApprox(int n){
std::vector<double> a(n+1,0.);
param = a;
Data T1("PolynomialApprox"),T2("ExperimentalData");
m_data = T1;
exp_data = T2;
m_cost = new Khi2(m_data.getData(),exp_data.getData());
}
PolynomialApprox::PolynomialApprox(Data T, int n){
std::vector<double> a(n+1,0.);
param = a;
exp_data = T;
std::vector<std::vector<double>> V1(exp_data.getCard(), std::vector<double> (2,0.));
for(int i=0;i<exp_data.getCard();i++)
V1[i][0] = exp_data.getData()[i][0];
Data T1(V1,"PolynomialApprox");
m_data = T1;
m_cost = new Khi2(m_data.getData(),exp_data.getData());
}
PolynomialApprox::PolynomialApprox(Data T, std::vector<double> a):param(a){
exp_data = T;
std::vector<std::vector<double>> PolDat, ExpDat = exp_data.getData();
for(int i=0;i<exp_data.getCard();i++){
double x=0.,y=0.;
x = ExpDat[i][0];
y = polynom(param,x);
PolDat.push_back({x,y});
}
Data T1(PolDat,"PolynomialApprox");
m_data = T1;
m_cost = new Khi2(m_data.getData(),exp_data.getData());
}
//Set model data, experimental data and cost function
void PolynomialApprox::setModelData(Data T1){
m_data = T1;
}
void PolynomialApprox::setExpData(Data T){
exp_data = T;
std::vector<std::vector<double>> V1(exp_data.getData());
for(int i=0;i<exp_data.getCard();i++){
V1[i][1] = polynom(param,V1[i][0]);
}
m_data.setData(V1);
//delete m_cost;
//m_cost = new Khi2(exp_data.getData(),m_data.getData());
}
void PolynomialApprox::setCost(CostFunction* f){
delete m_cost;
m_cost = new Khi2(exp_data.getData(),m_data.getData());
}
//Solution, Neighbor and cost getter
Data PolynomialApprox::getSol() const {
return m_data;
}
void PolynomialApprox::setParam(std::vector<double> a){
param = a;
std::vector<std::vector<double>> n_val = m_data.getData();
for(int i=0;i<n_val.size();i++)
n_val[i][1] = polynom(param,n_val[i][0]);
m_data.setData(n_val);
//delete m_cost;
//m_cost = new Khi2(exp_data.getData(),m_data.getData());
}
std::vector<double> PolynomialApprox::getParam() const {
return param;
}
std::vector<double> PolynomialApprox::getNeighbor(double ampl) const {
double d_a=0;
std::vector<double> n_param;
for(int i=0;i<param.size();i++){
d_a = ampl*(2.*rand()/(RAND_MAX+1.)-1.);
n_param.push_back(param[i]+d_a);
}
return n_param;
}
double PolynomialApprox::getCost(){
delete m_cost;
m_cost = new Khi2(exp_data.getData(),m_data.getData());
return m_cost->get();
}
//Export model parameters
void PolynomialApprox::exportModel() const {
FILE * fich = fopen((exp_data.getName()+".polynomial_approx.data").c_str(), "w");
fprintf(fich, "Polynom of degree %li with parameters : \n",param.size());
for(int i=0;i<param.size();i++)
fprintf(fich, "a_{%i} = %lf \n", i, param[i]);
}
void PolynomialApprox::displayModel() const {
char buffer[32];
memset(buffer, 0, sizeof(buffer));
snprintf(buffer, sizeof(buffer), "%g", m_cost->get());
std::string cost(buffer);
std::vector<std::string> commandsForGnuplot = {"set title \""+m_data.getName()+"\"","set key bmargin","plot '"+exp_data.getName()+".temp' using 1:2 w p pt 1 lc -1 title 'Experimental Data'"," replot '"+exp_data.getName()+".temp' using 3:4 w l dt 2 lc 6 title 'Polynomial approximation with khi2="+cost+"'"};
FILE * temp = fopen((exp_data.getName()+".temp").c_str(), "w");
FILE * gnuplotPipe = popen ("gnuplot -persistent", "w");
for (int i=0; i < m_data.getCard(); i++){
fprintf(temp, "%lf %lf %lf %lf \n", exp_data.getData()[i][0], exp_data.getData()[i][1], m_data.getData()[i][0], m_data.getData()[i][1]);
}
for (std::string command : commandsForGnuplot){
fprintf(gnuplotPipe,"%s \n", command.c_str());
}
}
//Set and get parameters
Data PolynomialApprox::getExpData() const {
return exp_data;
}
/*
* Traveling SalesPerson problem
*/
std::vector<int> vdtovi(std::vector<double> Vd){
std::vector<int> Vi;
for(int i=0;i<Vd.size();i++)
Vi.push_back(int(Vd[i]));
return Vi;
}
std::vector<double> vitovd(std::vector<int> Vi){
std::vector<double> Vd;
for(int i=0;i<Vi.size();i++)
Vd.push_back(Vi[i]);
return Vd;
}
//Constructor & Destructor
TSP::TSP(){
Data T1("TSP"),T2("Cities");
T2.randSet(50);
T1.setData(T2.getData());
m_data = T1;
exp_data = T2;
std::vector<int> o(exp_data.getCard(),0);
for(int i=0;i<exp_data.getCard();i++)
o[i] = i;
order = o;
m_cost = new Distance(exp_data.getData(),order);
}
TSP::TSP(const TSP& other):order(other.order){
m_data = other.m_data;
exp_data = other.exp_data;
m_cost = other.m_cost;
}
TSP::TSP(Data T){
exp_data = T;
std::vector<int> o(exp_data.getCard(),0);
std::vector<std::vector<double>> V1(exp_data.getCard(), std::vector<double> (2,0.));
for(int i=0;i<exp_data.getCard();i++){
o[i] = i;
V1[i] = exp_data.getData()[o[i]];
}
order = o;
Data T1(V1,"TSP"+exp_data.getName());
m_data = T1;
m_cost = new Distance(exp_data.getData(),order);
}
TSP::TSP(Data T, std::vector<int> o){
exp_data = T;
order = o;
std::vector<std::vector<double>> V1(exp_data.getCard(), std::vector<double> (2,0.));
for(int i=0;i<exp_data.getCard();i++){
V1[i] = exp_data.getData()[order[i]];
}
Data T1(V1,"TSP"+exp_data.getName());
m_data = T1;
m_cost = new Distance(exp_data.getData(),order);
}
//Set model data, experimental data and cost function
void TSP::setModelData(Data T1){
m_data = T1;
}
void TSP::setExpData(Data T){
exp_data = T;
if(exp_data.getCard() != order.size()){
std::vector<int> o(exp_data.getCard(), 0);
for(int i=0;i<exp_data.getCard();i++)
o[i] = i;
order = o;
m_data.setData(exp_data.getData());
}
else{
std::vector<std::vector<double>> T2(m_data.getData());
for(int i=0;i<exp_data.getCard();i++)
T2[i] = exp_data.getData()[order[i]];
m_data.setData(T2);
}
//delete m_cost;
//m_cost = new Distance(exp_data.getData(),order);
}
void TSP::setCost(CostFunction* f){
delete m_cost;
m_cost = new Distance(exp_data.getData(),order);
}
//Solution, Neighbor and cost getter
Data TSP::getSol() const {
return m_data;
}
void TSP::setParam(std::vector<double> a){
order = vdtovi(a);
std::vector<std::vector<double>> n_val(m_data.getData());
for(int i=0;i<order.size();i++)
n_val[i] = exp_data.getData()[order[i]];
m_data.setData(n_val);
//delete m_cost;
//m_cost = new Distance(exp_data.getData(),order);
}
std::vector<double> TSP::getParam() const {
return vitovd(order);
}
/*
std::vector<double> TSP::getNeighbor(double ampl) const { //This method take 2 random cities and swap them
std::vector<int> n_order_i(order);
for(int i=0;i<floor(10.*ampl+1.);i++){
int indA = 0, indB = 0, tmp = 0;
indA = rand()%order.size();
indB = rand()%order.size();
if(indA!=indB){
tmp = n_order_i[indA];
n_order_i[indA] = n_order_i[indB];
n_order_i[indB] = tmp;
}
}
std::vector<double> n_order_d(vitovd(n_order_i));
return n_order_d;
}
*/
/*
std::vector<double> TSP::getNeighbor(double ampl) const { //This method take one random city and put it at the end of the path
std::vector<int> n_order_i(order);
for(int i=0;i<floor(10.*ampl+1.);i++){
int ind = 0, tmp = 0;
ind = rand()%order.size();
if(ind!=(order.size()-1)){
std::vector<int> n_order_ii(n_order_i);
for(int j=ind;j<(order.size()-1);j++)
n_order_i[j] = n_order_ii[j+1];
n_order_i[order.size()-1] = n_order_ii[ind];
}
}
std::vector<double> n_order_d(vitovd(n_order_i));
return n_order_d;
}
*/
std::vector<double> TSP::getNeighbor(double ampl) const { //This method take a subset of the path and shuffle it
std::vector<int> n_order_i(order);
std::vector<int> tmp;
int set_length = floor(10.*ampl+1.);
int ind_set = 0, ind_new = 0;
ind_set = rand()%(order.size()-set_length+1);
for(int i=0;i<set_length;i++){
tmp.push_back(order[ind_set+i]);
}
for(int i=0;i<set_length;i++){
ind_new = rand()%tmp.size();
n_order_i[ind_set+i] = tmp[ind_new];
tmp.erase(tmp.begin()+ind_new);
}
std::vector<double> n_order_d(vitovd(n_order_i));
return n_order_d;
}
double TSP::getCost(){
delete m_cost;
m_cost = new Distance(exp_data.getData(),order);
return m_cost->get();
}
//Export model parameters
void TSP::exportModel() const {
FILE * fich = fopen((exp_data.getName()+".TSP.data").c_str(), "w");
fprintf(fich, "The Salesperson should go through thoses %li cities in this order to get distance %lf : \n",order.size(),m_cost->get());
for(int i=0;i<m_data.getCard();i++)
fprintf(fich, "%lf %lf \n", m_data.getData()[i][0], m_data.getData()[i][1]);
}
void TSP::displayModel() const {
char buffer[32];
memset(buffer, 0, sizeof(buffer));
snprintf(buffer, sizeof(buffer), "%g", m_cost->get());
std::string cost(buffer);
std::vector<std::string> commandsForGnuplot = {"set title \""+m_data.getName()+"\"","set key bmargin","plot '"+exp_data.getName()+".temp' using 1:2 w p pt 1 lc -1 title 'Experimental Data'"," replot '"+exp_data.getName()+".temp' using 3:4 w l dt 2 lc 6 title 'Short path estimation with distance="+cost+"'"};
FILE * temp = fopen((exp_data.getName()+".temp").c_str(), "w");
FILE * gnuplotPipe = popen ("gnuplot -persistent", "w");
for (int i=0; i < m_data.getCard(); i++){
fprintf(temp, "%lf %lf %lf %lf \n", exp_data.getData()[i][0], exp_data.getData()[i][1], m_data.getData()[i][0], m_data.getData()[i][1]);
}
for (std::string command : commandsForGnuplot){
fprintf(gnuplotPipe,"%s \n", command.c_str());
}
}
//Set and get parameters
Data TSP::getExpData() const {
return exp_data;
}
void TSP::setOrder(std::vector<int> o){
order = o;
std::vector<std::vector<double>> n_val(m_data.getData());
for(int i=0;i<order.size();i++)
n_val[i] = exp_data.getData()[order[i]];
m_data.setData(n_val);
//delete m_cost;
//m_cost = new Distance(exp_data.getData(),order);
}
std::vector<int> TSP::getOrder() const {
return order;
}