576 lines
15 KiB
C++
Executable File
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;
|
|
}
|