From bbea00afb7aca0272aca7005a26730a1a3a50993 Mon Sep 17 00:00:00 2001 From: Gonzalo Menendez Berch - ENS <gonzalo.menendez@pcunix79.fing.edu.uy> Date: Wed, 5 Dec 2018 21:50:32 -0300 Subject: [PATCH] Fuck this shit mate --- .../AlgoritmoGenetico/malva/inc/Mallba | 1 - .../malva/inc/Mallba/Makefile | 14 + .../malva/inc/Mallba/Matrix.hh | 337 ++++++++++++++ .../malva/inc/Mallba/Messages.h | 112 +++++ .../malva/inc/Mallba/Rarray.h | 145 ++++++ .../malva/inc/Mallba/Rlist.h | 415 ++++++++++++++++++ .../malva/inc/Mallba/States.cc | 228 ++++++++++ .../malva/inc/Mallba/States.hh | 64 +++ .../malva/inc/Mallba/States.o | Bin 0 -> 12968 bytes .../malva/inc/Mallba/mallba.hh | 26 ++ .../malva/inc/Mallba/netstream.cc | 380 ++++++++++++++++ .../malva/inc/Mallba/netstream.hh | 161 +++++++ .../malva/inc/Mallba/netstream.o | Bin 0 -> 18752 bytes .../malva/inc/Mallba/random.hh | 50 +++ .../malva/inc/Mallba/time.hh | 43 ++ .../AlgoritmoGenetico/malva/rep/GA/MainLan | Bin 186536 -> 186536 bytes .../AlgoritmoGenetico/malva/rep/GA/MainSeq | Bin 186536 -> 186536 bytes .../malva/rep/GA/datos_columnas | 18 +- .../malva/rep/GA/datos_filas | 16 +- .../AlgoritmoGenetico/malva/rep/GA/newGA.cfg | 6 +- .../malva/rep/GA/newGA.req.cc | 43 +- .../malva/rep/GA/newGA.req.o | Bin 88016 -> 88424 bytes .../malva/rep/GA/res/sol.txt | 20 +- malva/inc/Mallba | 1 - malva/inc/Mallba/Makefile | 14 + malva/inc/Mallba/Matrix.hh | 337 ++++++++++++++ malva/inc/Mallba/Messages.h | 112 +++++ malva/inc/Mallba/Rarray.h | 145 ++++++ malva/inc/Mallba/Rlist.h | 415 ++++++++++++++++++ malva/inc/Mallba/States.cc | 228 ++++++++++ malva/inc/Mallba/States.hh | 64 +++ malva/inc/Mallba/States.o | Bin 0 -> 12968 bytes malva/inc/Mallba/mallba.hh | 26 ++ malva/inc/Mallba/netstream.cc | 380 ++++++++++++++++ malva/inc/Mallba/netstream.hh | 161 +++++++ malva/inc/Mallba/netstream.o | Bin 0 -> 18752 bytes malva/inc/Mallba/random.hh | 50 +++ malva/inc/Mallba/time.hh | 43 ++ 38 files changed, 4015 insertions(+), 40 deletions(-) delete mode 120000 ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba create mode 100644 ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/Makefile create mode 100644 ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/Matrix.hh create mode 100644 ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/Messages.h create mode 100644 ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/Rarray.h create mode 100644 ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/Rlist.h create mode 100644 ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/States.cc create mode 100644 ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/States.hh create mode 100644 ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/States.o create mode 100644 ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/mallba.hh create mode 100644 ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/netstream.cc create mode 100644 ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/netstream.hh create mode 100644 ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/netstream.o create mode 100644 ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/random.hh create mode 100644 ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/time.hh delete mode 120000 malva/inc/Mallba create mode 100644 malva/inc/Mallba/Makefile create mode 100644 malva/inc/Mallba/Matrix.hh create mode 100644 malva/inc/Mallba/Messages.h create mode 100644 malva/inc/Mallba/Rarray.h create mode 100644 malva/inc/Mallba/Rlist.h create mode 100644 malva/inc/Mallba/States.cc create mode 100644 malva/inc/Mallba/States.hh create mode 100644 malva/inc/Mallba/States.o create mode 100644 malva/inc/Mallba/mallba.hh create mode 100644 malva/inc/Mallba/netstream.cc create mode 100644 malva/inc/Mallba/netstream.hh create mode 100644 malva/inc/Mallba/netstream.o create mode 100644 malva/inc/Mallba/random.hh create mode 100644 malva/inc/Mallba/time.hh diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba deleted file mode 120000 index 5cd551c..0000000 --- a/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba +++ /dev/null @@ -1 +0,0 @@ -../src \ No newline at end of file diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/Makefile b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/Makefile new file mode 100644 index 0000000..b6d64fb --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/Makefile @@ -0,0 +1,14 @@ +include ../environment + +OBJS = States.o netstream.o + +all: $(OBJS) + +States.o: States.cc States.hh + $(CXX) $(CPPFLAGS) States.cc -c + +netstream.o: netstream.cc netstream.hh + $(CXX) $(CPPFLAGS) netstream.cc -c + +clean: + rm -f *.o *~ *% diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/Matrix.hh b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/Matrix.hh new file mode 100644 index 0000000..cc30ae7 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/Matrix.hh @@ -0,0 +1,337 @@ +/***************************************************************************** +*** *** +*** Este fichero decribe el template Matrix, para el manejo de matrices. *** +*** Tambien permite el manejo de vectores, los que trata como matrices cuya*** +*** primera dimension es 1. *** +*** *** +*****************************************************************************/ +#ifndef _MATRIX +#define _MATRIX + +#include "Messages.h" +#include <assert.h> + +template <class T> class Matrix +{ + private: + T *_matrix; + T nulo,neutro,inverso; + int _dimX,_dimY; + + public: + Matrix() + { + _dimX = _dimY = 0; + _matrix = NULL; + } + + Matrix(const int x,const int y,const T nulo = 0.0,const T neutro = 1.0,const T inverso = -1.0) + { + assert(x >= 1); + assert(y >= 1); + + int k = 0; + + _dimX = x; + _dimY = y; + + this->nulo = nulo; + this->neutro = neutro; + this->inverso = inverso; + + _matrix = new T [_dimX*_dimY]; + if(!_matrix) show_message(7); + + for(int i = 0; i < x; i++) + { + for(int j = 0; j < y ; j++) + { + _matrix[k] = (i!=j?nulo:neutro); + k++; + } + + } + } + + Matrix(const int y,const T nulo = 0.0,const T neutro = 1.0,const T inverso = -1.0) + { + assert(y >= 1); + + _dimX = 1; + _dimY = y; + + this->nulo = nulo; + this->neutro = neutro; + this->inverso = inverso; + + _matrix = new T [_dimY]; + if(!_matrix) show_message(7); + + _matrix[0] = neutro; + for(int j = 1; j < y ; j++) + _matrix[j] = nulo; + } + + Matrix(const Matrix<T> &m) + { + + _dimX = m.dimX(); + _dimY = m.dimY(); + + nulo = m.nulo; + neutro = m.neutro; + inverso = m.inverso; + + _matrix = new T [_dimX*_dimY]; + if(!_matrix) show_message(7); + + for(int i = 0; i < (_dimX*_dimY); i++) + { + _matrix[i] = m[i]; + } + } + + + ~Matrix() + { + remove(); + } + + T &operator()(const int x,const int y) const + { + if((x >= _dimX) || (y >= _dimY)) + show_message(14); + + return (T&)(*(_matrix + (x*_dimX) + y)); + } + + T &operator[](const int y) const + { + if(y >= (_dimX*_dimY)) + show_message(14); + + return (T&)(*(_matrix + y)); + } + + T &operator()(const int y) const + { + if(y >= (_dimX*_dimY)) + show_message(14); + + return (T&)(*(_matrix + y)); + } + + Matrix<T> &operator=(const Matrix<T> &m) + { + remove(); + + _dimX = m.dimX(); + _dimY = m.dimY(); + + _matrix = new T [_dimX*_dimY]; + if(!_matrix) show_message(7); + + for(int i = 0; i < (_dimX*_dimY); i++) + { + _matrix[i] = m[i]; + } + + return (*this); + } + + bool operator==(const Matrix<T> &m) const + { + if((_dimX != m.dimX()) || (_dimY != m.dimY())) + return false; + + for(int i = 0; i < (_dimX*_dimY); i++) + if(_matrix[i] != m[i]) return false; + + return true; + } + + bool operator!=(const Matrix<T> &m) const + { + return !((*this) == m); + } + + Matrix<T> operator*(const Matrix<T> &m) + { + int x = (m.dimX()!=_dimY?0:_dimX); + int y = (x!=0?m.dimY():0); + T acum = nulo; + + Matrix<T> res(x,y); + + for(int i = 0; i < _dimX; i++) + for(int j = 0; j < m.dimY(); j++) + { + acum = nulo; + for( int k = 0; k < _dimY; k++) + acum += (*this)(i,k)* m(k,j); + res(i,j) = acum; + } + + return Matrix<T>(res); + + } + + Matrix<T> &operator*=(const Matrix<T> &m) + { + int x = (m.dimX()!=_dimY?0:_dimX); + int y = (x!=0?0:m.dimY()); + T acum = nulo; + + Matrix<T> res(x,y); + + for(int i = 0; i < _dimX; i++) + for(int j = 0; j < m.dimY(); j++) + { + acum = nulo; + for( int k = 0; k < _dimY; k++) + acum += (*this)(i,k)*m(k,j); + res(i,j) = acum; + } + + (*this) = res; + + return (*this); + + } + + Matrix<T> operator*(const T &elem) + { + Matrix<T> res(_dimX,_dimY); + + for(int i = 0; i < (_dimX*_dimY); i++) + res[i] = _matrix[i] * elem; + + return Matrix(res); + } + + Matrix<T> &operator*=(const T &elem) + { + for(int i = 0; i < (_dimX*_dimY); i++) + _matrix[i] *= elem; + + return (*this); + } + + Matrix<T> operator+(const Matrix<T> &m) + { + int x = (m.dimX()!=_dimX?0:_dimX); + int y = (m.dimY()!=_dimY?0:_dimY); + + Matrix<T> res(x,y); + + for(int i = 0; i < (x*y); i++) + res[i] = _matrix[i] + m[i]; + + return Matrix<T>(res); + } + + Matrix<T> &operator+=(const Matrix<T> &m) + { + int x = (m.dimX()!=_dimX?0:_dimX); + int y = (m.dimY()!=_dimY?0:_dimY); + + for(int i = 0; i < (x*y); i++) + _matrix[i] += m[i]; + + return (*this); + } + + Matrix<T> operator-(const Matrix<T> &m) + { + Matrix<T> res(); + + res = m * inverso; + return (*this) + res; + } + + + Matrix<T> &operator-=(const Matrix<T> &m) + { + Matrix<T> res(); + + res = m * inverso; + (*this) += res; + + return (*this); + } + + Matrix<T> Traspuesta() + { + Matrix<T> res(_dimY,_dimX); + + for(int i = 0; i < _dimX; i++) + for(int j = 0; j < _dimY; j++) + res(j,i) = (*this)(i,j); + + return Matrix<T>(res); + } + + Matrix<T> &nula() + { + for(int i = 0; i < (_dimX*dimY); i++) + _matrix[i] = nulo; + + return (*this); + } + + Matrix<T> &identity() + { + register int k = 0; + + for(int i = 0; i < _dimX; i++) + for(int j = 0; j < _dimY; j++) + { + _matrix[k] = (i!=j?nulo:neutro); + k++; + } + + return (*this); + } + + unsigned int size() const + { + return (sizeof(T)*_dimX*_dimY); + } + + char *to_string() const + { + return (char *) _matrix; + } + + Matrix<T> &to_Matrix(char *_cadena) + { + T *ptr = (T *)_cadena; + + for(int i = 0; i < (_dimX*_dimY) ; i++) + { + _matrix[i] = *ptr; + ptr++; + } + + return (*this); + } + + + int dimX() const + { + return _dimX; + } + + int dimY() const + { + return _dimY; + } + + void remove() + { + if(_matrix != NULL) + delete [] _matrix; + } +}; + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/Messages.h b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/Messages.h new file mode 100644 index 0000000..e46b1d8 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/Messages.h @@ -0,0 +1,112 @@ +/*****************************************************************************/ +/*** ***/ +/*** Modificado por G.J.L.P. ***/ +/*** Añadidos nuevos mensajes que indican falta de algún ***/ +/*** Fichero de Configuración (No específico para ningún ***/ +/*** problema) o nuevos errores. ***/ +/*** ***/ +/*****************************************************************************/ + +#ifndef RLFAP_MESSAGES +#define RLFAP_MESSAGES + +#ifndef MAX_BUFFER +#define MAX_BUFFER 200 +#endif + +#include <iostream> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +using namespace std; + +inline void show_message(int value) +{ + switch (value) + { + case 1: cout << endl << "Error: number of arguments in the execution call is incorrect !!" + << endl; break; + case 2: cout << endl << "Error: It's imposible find Configuration file !!" << endl; + break; + /* Específicos de RLFAP */ + case 3: cout << endl << "Error: It is imposible find the Celar problem definition file (cst.txt) !!" + << endl; break; + case 4: cout << endl << "Error: It is imposible find the Celar domains file (dom.txt) !!" + << endl; break; + case 5: cout << endl << "Error: It is imposible find the Celar links file (var.txt) !!" + << endl; break; + case 6: cout << endl << "Error: It is imposible find the Celar constraints file (ctr.txt) !!" + << endl; break; + /* Fallos de Memoria */ + case 7: cout << endl << "Error: No avalible memory for \"malloc\" operation !!" << endl; + break; + case 8: cout << endl << "Error: in \"free\" operation !!" << endl; + break; + /* Específicos del MaxCut */ + case 9: cout << endl << "Error: It is imposible find the Maxcut file (Maxcut.txt) !!" + << endl; break; + /* Genéricos de Falta de ficheros de configuracion adicionales al mensaje 2 */ + case 10: cout << endl << "Error: It's imposible find Configuration file (Config.cfg) !!" + << endl; break; + case 11: cout << endl << "Error: It's imposible find Skeleton Configuration File (Ske.cfg) !!" + << endl; break; + case 12: cout << endl << "Error: It's imposible find Instance Problem File !!" << endl; + break; + case 13: cout << endl << "Error: It's imposible find Resultate File !!" << endl; + break; + case 14: cout << endl << "Error: Index out of Range !!" << endl; + break; + default: cout << endl << "Unkown Error !!" << endl; + } + + cout << endl << " " << endl; + exit(-1); +} + +inline void continue_question() +{ + fflush(stdout); + cout << endl << "Press any key to continue..." << endl; + fflush(stdin); + getc(stdin); +} + +inline void get_path(const char *source,char *target) +{ + int last = 0; + + for(int i = 0; i < strlen(source); i++) + { + target[i] = source[i]; + if(target[i] == '/') + last = i; + } + target[last+1] = '\0'; +} + +inline unsigned count_lines(char *file_name) // returns the number of lines of a file +{ + char line[MAX_BUFFER]; + FILE *file; + int count=0; + + if ((file=fopen(file_name,"r"))==NULL) + { + fflush(stdout); + printf("File not found !"); + } + + while (!feof(file)) + { + if (fgets(line,MAX_BUFFER,file)) count++; + else + { + fclose(file); + break; + } + } + return count; +} + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/Rarray.h b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/Rarray.h new file mode 100644 index 0000000..5d1a1c2 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/Rarray.h @@ -0,0 +1,145 @@ +/****************************************************************************** +*** *** +*** Template para el manejo dinámico de arrays *** +*** Añadido métodos para invertir todo o parte del array. *** +*** *** +******************************************************************************/ + +#ifndef ARRAY_INC +#define ARRAY_INC 1 +#include <iostream> +#include <assert.h> + +using namespace std; + +template<class E1> class Rarray +{ + private: + E1 *first; + int count; + + public: + Rarray() + { + first = NULL; + count = 0; + } + + ~Rarray() + { + remove(); + } + + E1* get_first() const + { + return first; + } + + void message_a(int cod) const + { + switch (cod) + { + case 1: cout << endl << "The size of array must be upper that 0 !!!" ; + } + } + + Rarray(const int size_a) + { + if (size_a<0) message_a(1); + first = new E1[size_a]; + count=size_a; + } + + void remove() + { + if (count!=0) + delete [] first; + } + + int size() const + { + return count; + } + + E1& operator[](int pos) const + { + return (E1&)(*(first + pos)); + } + + friend ostream& operator<< (ostream& os,const Rarray<E1>& a) + { + for (int i=0;i<a.size();i++) + os << endl << a[i]; + return os; + } + + Rarray<E1>& operator=(const Rarray<E1>& source) + { + remove(); + count = source.size(); + first = new E1[count]; + + for (int i=0;i<count;i++) + (*this)[i] = source[i]; + + return (*this); + } + + + Rarray<E1>& invert() + { + return invert(0,count-1); + } + + Rarray<E1>& invert(const int pos1, const int pos2) + { + int max,min,half,i,j; + E1 aux; + + if(pos1 > pos2) + { + max = pos1; + min = pos2; + } + else + { + max = pos2; + min = pos1; + } + + assert((min > 0) || (min < count-1)); + half = ((max-min)/2) + 1; + + for(i = min,j=max; i< half; i++,j--) + { + aux = first[min]; + first[min] = first[max]; + first[max] = aux; + } + + return (*this); + } + + Rarray<E1>& sort(int (*comp)(const E1 &,const E1 &)) + { + E1 aux; + int j; + + for (int i=1; i < count ; i++) + { + aux = first[i]; + j = i - 1; + while ( (comp(aux,first[j])) && (j >= 0) ) + { + first[j+1]= first[j]; + j--; + } + first[j+1] = aux; + } + + return (*this); + } + +}; // end of class + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/Rlist.h b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/Rlist.h new file mode 100644 index 0000000..f561d0b --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/Rlist.h @@ -0,0 +1,415 @@ +/****************************************************************************** +*** *** +*** Este template sirve para el manejo de listas din�micas *** +*** *** +******************************************************************************/ + +#ifndef LIST_INC +#define LIST_INC 1 +#include <iostream> +#include <stdlib.h> +#include <Messages.h> + +using namespace std; + +template<class E> class Rlist_item +{ + public: + E *useful_data; // pointer to the structure stored in the list + Rlist_item<E> *next; + Rlist_item<E> *previous; + + Rlist_item(E& new_data) + { + useful_data=&new_data; + next=NULL; + previous=NULL; + } + + Rlist_item(E *new_data) + { + useful_data=new_data; + next=NULL; + previous=NULL; + } + + ~Rlist_item() + { + } + + Rlist_item<E>& next_item() + { + return *(next); + } + + Rlist_item<E>& previous_item() + { + return *(previous); + } + + bool is_last() + { + return (next==NULL); + } + + bool is_first() + { + return (previous==NULL); + } + + E& data() + { + return *(useful_data); + } +}; + +template<class E> class Rlist +{ + private: + Rlist_item<E> *first; // first item in the list + Rlist_item<E> *last; // last item un the list + int count; // number of items in the list + + public: + // constructor + Rlist() + { + first=NULL; + last=NULL; + count=0; + } + + // destructor + ~Rlist() + { + remove(); + } + + // Return the size of the list + int size() const + { return count; } + + // Go back to the initial state of the list + void reset() + { + first=NULL; + last=NULL; + count=0; + } + + // Add a item at the final of the list + Rlist<E>& append(E& new_item) + { + Rlist_item<E> *new_Rlist_item=new Rlist_item<E>(new_item); + if (first==NULL) + { + first=new_Rlist_item; + new_Rlist_item->next=NULL; + new_Rlist_item->previous=NULL; + } + else + { + last->next=new_Rlist_item; + new_Rlist_item->previous=last; + } + last=new_Rlist_item; + count++; + return *this; + } + + Rlist<E>& append(E *new_item) + { + append(*new_item); + return (*this); + } + + // Add a item in a position ( pos ) of the list + Rlist<E>& add_pos(E& new_item, const int pos) + { + if (pos==size()-1) + return append(new_item); + + if (pos==-1) + return add(new_item,NULL); + else + return add(new_item,get_at(pos).useful_data); + } + + // Add a item in the list in the position next to "previous item" + Rlist<E>& add(E& new_item,E *previous_item) + { + if (first==NULL) + return append(new_item); + + Rlist_item<E> *new_Rlist_item=new Rlist_item<E>(new_item); + + if (previous_item==NULL) // Add the item like the first of the list + { + new_Rlist_item->next=first; + new_Rlist_item->previous=NULL; + first->previous=new_Rlist_item; + first=new_Rlist_item; + } + else + { + int previous_position=get_position(*previous_item); + if (previous_position==-1) return(*this); + Rlist_item<E> *previous_Rlist_item = &( get_at(previous_position)); + new_Rlist_item->next=previous_Rlist_item->next; + new_Rlist_item->previous=previous_Rlist_item; + if (previous_Rlist_item->next!=NULL) + (previous_Rlist_item->next)->previous=new_Rlist_item; + else last=new_Rlist_item; + previous_Rlist_item->next=new_Rlist_item; + } + count++; + return *this; + } + + // Return a pointer to the first item of the list + Rlist_item<E> *get_first() const + { return first; } + + // Assign a item like the first item in the list + void set_first(Rlist_item<E> *new_first) + { first=new_first; } + + // Return a pointer to the last item of the list + Rlist_item<E> *get_last() const + { return last; } + + // Assign a item like the last item in the list + void set_last(Rlist_item<E> *new_last) + { last=new_last; } + + // Return the item at position "pos" + E& operator[](int pos) const + { + return *(get_at(pos).useful_data); + } + + // Return the Rlist_item at position "pos" + Rlist_item<E>& get_at(int pos) const + { + Rlist_item<E> *present=first; + for (int k=0;k<size();k++) + if (k==pos) return *present; + else present=present->next; + } + + // Return the item position in the list + int get_position(const E& item) const // probado + { + Rlist_item<E> *present=first; + int i=0; + + while(present!=NULL) + { + if (present->useful_data==&item) return i; + i++; + present=present->next; + } + return -1; // the object has not been found + } + + // Delete a item of the list + Rlist<E>& delete_item(E& item) + { + int position = get_position(item); + + if (position==-1) return *this; + Rlist_item<E> *present=&(get_at(position)); + + if (&item==first->useful_data) // is the first + { + if (&item==last->useful_data) + { + delete(first->useful_data); + delete(first); + first=NULL; + last=NULL; + count=0; + } + else + { + first=first->next; + first->previous=NULL; + delete(present->useful_data); + delete(present); + count--; + } + } + else + { + if (&item==last->useful_data) + { + last=present->previous; + last->next=NULL; + delete(present->useful_data); + delete(present); + count--; + } + else + { + (present->next)->previous=present->previous; + (present->previous)->next=present->next; + delete(present->useful_data); + delete(present); + count--; + } + } + return *this; + } + + // Delete a item of the list without free the useful_data + Rlist<E>& delete_item_1(E& item) + { + int position = get_position(item); + + if (position==-1) return *this; + Rlist_item<E> *present=&(get_at(position)); + + if (&item==first->useful_data) // is the first + { + if (&item==last->useful_data) + { + delete(first); + first=NULL; + last=NULL; + count=0; + } + else + { + first=first->next; + first->previous=NULL; + delete(present); + count--; + } + } + else + { + if (&item==last->useful_data) + { + last=present->previous; + last->next=NULL; + delete(present); + count--; + } + else + { + (present->next)->previous=present->previous; + (present->previous)->next=present->next; + delete(present); + count--; + } + } + return *this; + } + + // Delete item at position "pos" + Rlist<E>& delete_item_by_position(const int pos) + { return delete_item(*(get_at(pos).useful_data)); } + + // Delete the last item in the list + Rlist<E>& delete_last() + { return delete_item(*(last->useful_data)); } + + // delete all items in the list + Rlist<E>& remove() + { + Rlist_item<E> *next,*present=first; + while (present!=NULL) + { + next=present->next; + delete(present->useful_data); + delete(present); + present=next; + } + first=NULL; + last=NULL; + count=0; + return *this; + } + + // Join a new list to this list + Rlist<E>& join(Rlist<E>& new_list) + { + if (new_list.size()==0) + return *this; + + if (first==NULL) + { + first=new_list.get_first(); + last=new_list.get_last(); + } + else + { + last->next=new_list.get_first(); + (new_list.get_first())->previous=last; + last = new_list.get_last(); + } + count += new_list.size(); + new_list.reset(); + return *this; + } + + // Show items of the list + friend ostream& operator<<(ostream& os, const Rlist<E>& list) + { + Rlist_item<E> *present=list.get_first(); + if (list.get_first()==NULL) os << endl << "THE LIST IS EMPTY !!"; + while (present!=NULL) + { + os << endl << (*(present->useful_data)); + // Falta el operador para stat. + // (habra que ver) + present=present->next; + } + return os; + } + + // Copy the list passed + Rlist<E>& operator=(const Rlist<E>& source) + { + E *new_item; + remove(); + if (source.first==NULL && source.last==NULL) + { + first=NULL; + last=NULL; + count=0; + } + else + { + for (int i=0;i<source.size();i++) + { + if ((new_item=(E *)malloc(sizeof(E)))==NULL) + show_message(7); + (*new_item)=*(source.get_at(i).useful_data); + append(*new_item); + } + } + return *this; + } + + // Invert the order of items in the list + Rlist<E>& invert() + { + Rlist_item<E> *present,*interchange; + + present=first; + + for (int i=0;i<size();i++) + { + interchange=present->next; + present->next=present->previous; + present->previous=interchange; + present=interchange; + } + interchange=first; + first=last; + last=interchange; + return (*this); + } +}; // end of class +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/States.cc b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/States.cc new file mode 100644 index 0000000..f36d197 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/States.cc @@ -0,0 +1,228 @@ +/****************************************************************************** + Modified by Carlos Cotta Porras + April 2001 + + Modified by G.J.L.P +******************************************************************************/ + + +#include <string.h> +#include "States.hh" + +// Methods of class State_Vble + + // constructors + State_Vble ::State_Vble () + { + name=NULL; + nitems=0; + length=0; + content=NULL; + } + + State_Vble ::State_Vble (const char *st_name) + { + name=strdup(st_name); + nitems=0; + length=0; + content=NULL; + } + + State_Vble::State_Vble (const char *st_name,StateCenter& sc) + { + name=strdup(st_name); + nitems=0; + length=0; + content=NULL; + sc.add(*this); + } + + State_Vble ::State_Vble (const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length) + { + name=strdup(st_name); + nitems=0; + length=0; + content=NULL; + set_contents(new_contents,new_nitems,new_length); + } + + State_Vble ::State_Vble (const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length,StateCenter& sc) + { + name=strdup(st_name); + nitems=0; + length=0; + content=NULL; + set_contents(new_contents,new_nitems,new_length); + sc.add(*this); + } + + + // Set the name of a state vble. + void State_Vble ::set_name (const char* st_name) // Set the name of a state vble. + { + if (name!=NULL) + free(name); + name=strdup(st_name); + } + + // Get the name of a state vble. + char* State_Vble ::get_name () const // Get the name of a state vble. + { + return name; + } + + // Number of basic items + unsigned long State_Vble ::get_nitems() const // Number of basic items + { + return nitems; + } + + // Get the total number of bytes + unsigned long State_Vble ::get_length () const // Get the total number of bytes + { + return length; + } + + // Fill up a state vble. + void State_Vble ::set_contents (const char *new_contents, unsigned long new_nitems, unsigned long new_length) + { + if (content!=NULL) + free(content); + content=(char *)malloc(new_nitems * new_length); + memcpy(content,new_contents,(new_nitems*new_length)); + nitems=new_nitems; + length=new_length; + } + + // Obtain the contents of a state vble. + void *State_Vble ::get_contents (char *read_contents, unsigned long& read_nitems, unsigned long& read_length) const + { + memcpy(read_contents,content,nitems * length); + read_nitems=nitems; + read_length=length; + return NULL; + } + + ostream& operator<< (ostream& os,const State_Vble& st) + { + os << endl << st.name + << endl << st.nitems + << endl << st.length + << endl << st.content; + + return os; + } + + State_Vble ::~State_Vble () + { + free(content); + free(name); + } + +// Methods of class StateCenter + + StateCenter::StateCenter():state_variables() + {} + + // searchs a state variable + State_Vble *StateCenter::find(const char *st_name) const + { + Rlist_item<State_Vble> *current_state=state_variables.get_first(); + + for (int i=0;i<state_variables.size();i++) + { + if (!(strcmp(current_state->data().get_name(),st_name))) + return &(current_state->data()); + current_state=¤t_state->next_item(); + } + return NULL; + } + + // Add one state variable + void StateCenter::add(State_Vble& st) + { + State_Vble *found_state=find(st.get_name()); + if (found_state==NULL) + state_variables.append(st); + else + cout << endl << "You are trying to introduce a state variable that is yet used in the skeleton !!" << st.get_name(); + } + + void StateCenter::add(State_Vble *st) + { + State_Vble *found_state=find(st->get_name()); + if (found_state==NULL) + state_variables.append(*st); + else + cout << endl << "You are trying to introduce a state variable that is yet used in the skeleton !!" << st->get_name(); + } + + // Remove one state variable + void StateCenter::remove(const char* st_name) + { + State_Vble *found_state=find(st_name); + if (found_state!=NULL) + state_variables.delete_item_1(*found_state); + } + + // Update the contents of one vble. + void StateCenter::update(const char* st_name, const State_Vble& st) const // Update the contents of one vble. + { + State_Vble *found_state=find(st_name); + if (found_state!=NULL) + { + char *a=(char *)malloc(found_state->get_nitems() * found_state->get_length()); + unsigned long nitems,length; + st.get_contents(a,nitems,length); + found_state->set_contents(a,nitems,length); + free(a); + } + } + + // Get a vble. with a given name + State_Vble& StateCenter::get(const char* st_name) const // Get a vble. with a given name + { + State_Vble *found_state=find(st_name); + return *found_state; + } + + // Allows an easy iterated extraction + State_Vble* StateCenter::get_next(const State_Vble& st) const + { + State_Vble *found_state=find(st.get_name()); + if (found_state==NULL) return NULL; + if ( state_variables.get_at(state_variables.get_position(*found_state)).is_last()) return NULL; + else return &(state_variables.get_at(state_variables.get_position(*found_state)).next_item().data()); + } + + // returns the number of state variables + unsigned int StateCenter::size() const + { + return state_variables.size(); + } + + // Obtain the contents of a state vble. of name st_name + void StateCenter::get_contents_state_variable(const char *st_name,char *read_contents, unsigned long& read_nitems, unsigned long& read_length) const + { + get(st_name).get_contents(read_contents,read_nitems,read_length); + } + + // Fill up a state vble.of name st_name + void StateCenter::set_contents_state_variable(const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length) const + { + get(st_name).set_contents(new_contents,new_nitems,new_length); + } + + void StateCenter::removeAll() + { + while(state_variables.get_first()) + { + Rlist_item<State_Vble>* v = state_variables.get_first(); + remove(v->useful_data->get_name()); + } + } + + StateCenter::~StateCenter() + { + removeAll(); + } diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/States.hh b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/States.hh new file mode 100644 index 0000000..e3a215f --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/States.hh @@ -0,0 +1,64 @@ +/******************************************************************************************************** +*** *** +*** Class StateCenter: Pool of state variables for skeletons *** +*** *** +*** Class State_Vble: State Variable of a skeleton *** +*** *** +*********************************************************************************************************/ + +#ifndef STATE_CENTER +#define STATE_CENTER 1 + +#include "Rlist.h" +#include <iostream> + +class StateCenter; + +class State_Vble +{ + private: + char *name; + unsigned long nitems; + unsigned long length; + char *content; + + public: + // constructors + State_Vble (); + State_Vble (const char *st_name); + State_Vble (const char *st_name,StateCenter& sc); + State_Vble (const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length); + State_Vble (const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length,StateCenter& sc); + + void set_name (const char* st_name); // Set the name of a state vble. + char* get_name () const; // Get the name of a state vble. + unsigned long get_nitems() const; + unsigned long get_length () const; // Get the total number of bytes + void set_contents (const char *new_contents, unsigned long new_nitems, unsigned long new_length); // Fill up a state vble. + void *get_contents (char *read_contents, unsigned long& read_nitems, unsigned long& read_length) const; // Obtain the contents of a state vble. + friend ostream& operator<< (ostream& os,const State_Vble& st); + ~State_Vble (); +}; + +class StateCenter +{ + private: + Rlist<State_Vble> state_variables; + + public: + StateCenter(); + State_Vble *find(const char *st_name) const; // search a state variable + void add(State_Vble& st); // Add one state variable + void add(State_Vble *st); // Add one state variable + void remove(const char* st_name); // Remove one state variable + void removeAll(); // Removes all variables + void update(const char* st_name, const State_Vble& st) const; // Update the contents of one vble. + State_Vble& get(const char* st_name) const; // Get a vble. with a given name + State_Vble* get_next(const State_Vble& st) const; // Allows an easy iterated extraction + unsigned int size() const; // returns the number of state variables + void get_contents_state_variable(const char *st_name,char *read_contents, unsigned long& read_nitems, unsigned long& read_length) const; // Obtain the contents of a state vble. of name st_name + void set_contents_state_variable(const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length) const; // Fill up a state vble.of name st_name + ~StateCenter(); +}; + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/States.o b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/States.o new file mode 100644 index 0000000000000000000000000000000000000000..f5e95c8928fb22e26363c12820d0e56fd98709d2 GIT binary patch literal 12968 zcmeHNeQ;FQb$`+V+JLjWadAwF8=f;7SJ?4dD?Th))Yc*`dTSP2)<T@};m5LCeGHP8 z>^_0y+J?+(N!~oLmDUqy5}bIZZ6=d;#>~|1#QC7IfslA&m(se;#MH#8KOiy&$Hiu- z6ZLoQyLWZ=?QUpi{AVxo^xpm5bIv_q_uTjHvNx7kS6^4BsaB`msm=8is%d9GJNMin z9y_$_wZ($A0e#{L;4)5754Uc=yocm{3Eht-4g0?h`-8JC*y$44KI25Er0W!PTaHfk z2bXne+9sFbl2LfuZ#Z`u#aU~<%WPkecb`!>=HIgI=u~i7hh{hpNBgJx!@*^fGzI$I ze#qke5bsAn7u^)M-;Zv@-+vWzIeV8F_KR~9ZLr@+1fM>ikn<(%UmJGkl7#)fVV@8h zB<!@`uy=;GY>RG<Zi_xpHh*+ebmIp5xHRJf!+tq#|BQ@rl|NDPK*B!fbpqLyuzzLP z?-=$OSNb`!iQC5%w?8nPB%G8N`Ujs*hTJ)vPJi5<*JwDMA;XSok!ccjG`MUZ$%@`j z9)Ogj>*0ok)4wF)><%TIQGdd@({MV@8qT4Hi=Z`%uLLJo)oa?mKWo(t`?tZ#Fv1=@ zlJ7K1!Ejx&p*U;UM}w0uVLV~aN;mz^u%Cw|QY#;cPB=gGk!UakCw~Fz=)S$JT5xhc zJqC~Lfn-TvayFddP7=3|8x8{8aW?K8nqN}zaj=qt!AXKhI~6*`$YNJRMo&q`=^8RN z6kit>UIWU6{g$-wO>QBgXV_;|Rzyv>9Qmp2aePM>l24tEW}|&Ro}lpG|85q3J2QJS zc;w=_@1WB^rMwq+8Y=0}fCL0C{V75Jd*#2!<-d7#`i5Di&lQ&*9=FdJzVWlp9=-5V zoiO}dn8w6<rHE9HU&OeeoKj0nCPDiaH>2m)XL<cN(H$b!(Asv_Gv#XBzO*SBIUlz_ zq?~oSLx!`gIKB7UnLGNY3difB?Zb_Lw)h{u*>KurWJ+06oF03{aAeJ(1&gqt&d^$O zR|XJPFR(I@>ChTW_dQo>`+{Nr*nKQc2PeM^{pP%WE2$f|j~Px(q$bu*Qz<pyz!;^b zbzikbV;o#X%-`?9AEYYMOH6`H3r-e+m8IDkWE!QGa9?m4)1V@+tgk{nks~t)rv8!2 ztE+tBVVY-&aiYTy3?;im_}W@yIGd2UYjO323b9Zfss`$-s2Q-y2WeZjQ3gb}x;Y?q z*e9f*!pyuNCJ^<Q6~1a!&#+&uR`pO%wrmq(sXA@2e=N&f9EDlz9|`+KF-OA2l7la3 z1Cds^8%e@`7m(OXP_YFq%|&wED(&Xo)c?o#qlj;5KPygKVJte@J#RAF8-kNhQ)by$ zB0rs3=&rN&dTXiS^!f|W)fvT8V;AJ+t=6}b4@FKD-`~4vX0f1e`)8}G@O+)&?De<( z=An1R4hIpdkfT`RG34llBNS!IRe>RIMYIb$VVL`3;MU#W&O8r>kfg>M?)0nFFEN}O zMa6THkhI?aBTDDuDI<9A1*5&rx{cl>jN*BbYjUNOgb4xQEBw07PKM4kL5i5i&ASsm z5~VU!zUiFvfvBJIPrP^(-j=&HJebDPS9_Jn?&Gc;6rSMIm)+-siALD|E7SxOBg2*y z4x!HCM#1%tOIbLEZC|8)**XO**0flqbMHrjro8^4&Qkpo(%ku6!BqVI4u-{@m5oO6 zeQUYVz92aH8kuVU1_A%L@OyiGaPnJ(&Bc5s>O9mKdKUK27H1#1A#PucoSIqa?jLP0 zSi^|-2B*W{b_MY+JnYx3-6S6Q1o4lT#Lwl^PA2<8aaIU^<hsc8%!2-@w&$!hg=yr^ zZhzZl${$4C(PTA4-A~xZXTFa5DOAEs$YYcNV%D+8AmQIo^(D{D3uI4mcJH@mo)y$? zg3Ka8-kEu^IQs)=rlIrd%-5O!usfB%4{k&`I|hHEko}8v>1zhPQ@%<{A?$7h)OtXE z{GaIY{%atG8fl*u{&!m4Xi=4vyB10~cELBcya&x7pGaLAXDMFstUFx3TM`c5Ym4Wt z>ySQT{D>}`uim@Qh!juQ|0xEsO^v-E{7QZ(HT&XG@%*RRF+G*b=vHoGXmmigvii`d zmCN>xr89a;&s!-gqwh}ThEh9*K{S}M^r5^yk+Jl#e5Mbyz%qJ%XJ$BKWk>ZJZ`5XI z@#Y1GAN&(>D^(!J?H|0(9Ti(D)dAsF!aS|Jv-1wUsr#Ny%k|aamT*LGX^yOJZi}qe zn|d*`0ZjycYs+%tTrAn^9_-cX#zS>WuW9g4K@-|KZ;)eRx#O9zW{K(YPPGbYCz=o# z4TK8y0|7sfMqJy)h^E~_cZ}_?j|P?$e0K-*t$`)zM?pz)zbxtI$va_(<g<92#4}-s zJy<LH$0W9q?rQ^~N9)%HmK^lO0{Ve@(LmGw`CWnL!h%NvP0@gk5m2lZ`mH2-;dM<@ zya$Q*fUhf{?<d~E{GLGbK%fcwLT}001h!Vm*G4jcA0WH-6JKH8sIbhP!@zK#q|M?} zgJ>V4IUe<`4d@5wtqn9Cm>&%^?_UrNv=$n=0v*1dx`lyOsEp}BQc^g!h<trm%K9Xp z$)AP#9$^dl=4W#3dKyEcxqm6K3;~$C!oGN*`N4(4H6;VrE$Rw1b#jZ{7=M=ZM{6gU z9-HgGx=>kdEUHhHI$evp-RE@yfA1nUCoCzagM`iH#D;)A5LnXX<^;v{kfeKn=rCXP zxYk42^1xC){`@1*mGVQE$$ux=Jf~}SK!3=!3ke)wRDWNo6I-OM0qN%@-xu-h^%Y`U zzj<Lm?@}I1z~Pi%kWX1dvHY6kSGiBe6@M$SRn`1|vgGo0aI=tcTGFdEMR|KsVt<Th zuU?x<8fY5P-XIyTMoW2VNZK&TjZ<Exk5Xc)8dCRQPeN3fhHntXQdMWju0}%8lDLGJ zx!giv3-jvN&ndPTG|%w4)(1ilh!sE*DjWH7p7!o+<%p*F@UL3)Y0B&6qdsjxIUsvJ zO`H)`jQKP;pi1*;AFG0rKJ*1$-YC@d3>W?d_J_FYm_9_Onoqk%J(k^l;zX+q5*?rR ziAoTNPrJ4P7d5`7UF7Y`=2J!1GvtG1-bVI)hWS%PC=UEu7B5{gZmWTRLE?(e)mziP z1iYG-Pu9Tys)n5JOS}hnYGQxG{oip_lYbgG>Aw$mYBGhj%XlVyN}yUP^R7og34h9i zua@{>iHm&;&zpf)n>SShACz)JxKmSd3N`R=N_>~37yBOgj!RtaOJa`${tEDF`n**G zzf=SNum*lNQm2~ybPas620mQ_r~QNcuggG*{T6n;T>}THpzo0MY7f4y27a@|w@Z4l zKSO>Dcs08clK!Nm7ke=1vo+`^YT$dNoRBPK9gsooFKgiRtw(<7k@R9O20iT~)$mV2 zKf(`7dZp(YiC>hZQtYRY^LgOa>?OaDoMu@nzeq}=ITD|ixT@5DE%B2Q7keb=|4HH@ z+7!{y7459Vb%~2T4kMp|Kw*~$-z@Qc5?6J2kHim4oc1tk2Y}yLA8<SPt9F9F0A9`B z@6?d<qZ;%t*TBycjvV#2D>djfvpaF`+GxTw^J6>AxS6CcmwY&#*38XGE75A2L)oFx zAxjG<I-7yrvp#99N?Q}VGVye*wJ&S#8S2Z7#)$l$NVDKJKZkFg&X(Bj3M^6uYl-!& z2e;JX-gWDev5n@&=-Ncg)bduYZ){f;F@mLh!q$AoGDlM*86mGfm&piixlXMEibSZk zo{vSE#o&;Y8Ogg^Rv8}7j1E|Xl}1EbX!3M+)XI!nc~W3xL>oyB4`<WbNM<CxYofvi zVRkZNg3#-^2ni?+m8;Q0TFy<B?i~RkBn;<!liA)fT9TX0uGlqZxzR~xSM?8%<w<?` z6{dh7X+>6>W)}TSYQ!8G&1Z5}JPkCG9!%v-E0-Fw@(6US7ubp&sr*n{QO6ObW;2#t zZT75Bt}ut)>DtT<O3VmxWjB&`Wl0lR0UD7tpd7MXZzioaSNc#E^Hot`ReCs+%Ed6! zV#c$1x+qgiHduqX>>hJRs?SWP@>WIabyZ2nE|rcEk+z+PT_#t`+cHp6u8(kZW&hA< zpU5`&FFoSsDJNKw>g$X3@+=eTu1sggEIf_wsf@iyi{7$n$bVc$r^t`1(9EURRS4&j ztqNg<F+E%np%^Dwoy&}5ce@MF+}t<Zvs)Ng?zPopyZR6~@>^xTmXoePvJ3xG29^25 zUCEhoD|R&*EAvASX4Hb_%C_9jmy#*6$y6scG;0qnt`%<jmQCJrJ74WpI7@4{jIGV} zPIP!!77(tD$j`3(!?{d<*fa;m$IV@tTs}LR8XmGH%-y2$mPu2|o3vW7WRUpz%*r^H z6S6}jzZZAu&Axor988V&4P)h)>G70_P>iFxi|;+!GiZOL@3{}@G!rdDAR6IIaVdO+ zKr}D?OD<eN{~rw3@vP)rVEBy;zZvg+)V%T^WjLq5!tk5Gr{vemy^!S49<T6EGMv73 z72e2j`eso0Muv0wTN%#f4>0^@Cg*Dm=W?E6IG6J`4CiuAGn~tLo#9;0WrlNm7vMdP z8u^FY+sN=+FsA%)yTnPCKVbOA8uSA-=qGE?KT(7JnHu!&ZxNd2)#qJCPiG8D|4)#i zXmsQFQijuSo{D}s!+HMyIm79UL(xCU@D&VymEoNJ9K%}}{S}6D`Z~PFQ6qclELhEZ zo5YEY=fmv`=lO7_#3?O;OwK)wp67$faGpO8F`VbgV-okq<=c#YHJi6#0Xk@;Kli`R za9)>o*1(@&_%g^+{yD;M?$4hxocsS54CnN(N!;uIU;}CI>VFgNYToM^&i(&siF^GY zX7t?ucQKs%e=Ebe|FaVJ`hP#8=l*|-;oSdM7|#7u^b2!EyyzDSW$!=Kz(1&g2R~L_ z&KidEc@qr(BR22-4F5F4(+t-cKEd!th96`&&!1Nq&hz0-hI2i`@_Uf-`7S2^fg1SZ z4CnH{#qc#u&i5GJ#qggq{5FQa!Ehe0OEvKAY(M3GXd#2p=*H{e7udR9jxm)Fml)3L zZGx?@m5lzoHSqgb9&-6FGn~tRlEsDV`5eP}ygHd58ks(MhI2p2?M0kmk}s6K*Wj5N zVR2jvr@fLIt;f4@DV)x6sZkwRk4xe7ZbOZ5E}!_R5thKE=n11nVUtTu^wl52yHy8w zT|Se186tsDET|DqmuiN5P`EDpeIC3=_78aQeX{?Q2cMGtXFRx~`-ulXEc^4wAT*_q zI>%h&!PR*sop*A2bzb?52iM85XeT{*hs0m^;M*nMES;tFQRj5y9$cNfJ>|jG`I>sK zQ*zWfntC5oxH?DMDicxR>b&fb2Uq81hdsDDFZ-njSLbE_<-yf?nevmGw@0p%g!G5P z)p=Q-;p<!%i@#rHIPs`+w68E+E^$HsJ%*R%c{o2YVx@LyVSJ3c_d)fP%M7Q&_|Cy0 z7Ct>wT6jl3uL&URIh)`IT4DT}4{DMZ3AbwDfppr;jHffZEEDqa0fmn>DHk-UoQ0Dr z7ouYgGnLDwCL|!_{JyWda5_6Og7XJ0JesvKVf=c3D@3MuO8(5C*`LGF7L>?kG0jKN z-h_;5zxs4Y*~+){-wvpDNw=5owfI$?;QSPCFTW0qmeK-Tys7%(Q-xFxhBy(Psiu?6 z4qUvoQjtbe>wxs96ju7sJ0!K6aMAoSy$KR6>6usIa@nh{_;w(fwfMdC-hKqUge{<? zXKlNj-z(Q^e=m55pY|}`1||P}9K^G-U+IwoM$ew<wPz*2ikA|j_*8#f@_XYqE&0{? zxT5#!pT|J8_zgC>98;2!;<pf&(qF~T0Y<0mUO!!w^DBCgi019@2U>0Z%W{4-56w>^ z6~Dp{0VALIJPy44znuRG@K&2YL@zgJY95-O?DWom1Q^ZVjH|4D-0jgjJZ~y~>V5)) z>Y3BsD)~7^&tBTo67!g^HB0`VcoInIujJD2q}A+ilJ=jJg311CaVdV~7ph&}*aOlo z-$H*i?Yw&{{q^ckeXs6Bd|4L7R=MfW?|xMOyz|p*WVQL5KZOA_^*!tMD*g9AyjC=j literal 0 HcmV?d00001 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/mallba.hh b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/mallba.hh new file mode 100644 index 0000000..e4a35c0 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/mallba.hh @@ -0,0 +1,26 @@ +/***************************************************************************** +*** *** +*** Este fichero hace algunas declaraciones y declara algunos tipos comu- *** +*** nes a todos los algoritmos implementados. *** +*** *** +*****************************************************************************/ + +#ifndef INC_mallba_hh +#define INC_mallba_hh + +#define skeleton namespace +#define requires +#define provides +#define hybridizes(x) +#define inherits typedef +#define as + +enum Direction { minimize=-1,maximize=1}; + +extern const double plus_infinity; +extern const double minus_infinity; + +#define false 0 +#define true 1 + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/netstream.cc b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/netstream.cc new file mode 100644 index 0000000..932e89e --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/netstream.cc @@ -0,0 +1,380 @@ +/*************************************************************************** + *** netstream.cc *** + *** v1.6 - July 2001 *** + ** *** + *** v1.5 - March 2001 *** + *** v1.0 - November 2000 *** + *** *** + *** v1.5 extends v1.0: *** + *** .- Changes metods init() and finalize() to be static *** + *** .- Incorporates process group management *** + *** .- Do not consider LEDA anymore *** + *** .- Contains a method "int my_pid()" for easy invokations *** + *** .- Adds "unsigned" and "long double" input/output *** + *** *** + *** v1.6 extends v1.5: *** + ** .- Internal in/out buffers for packed separated *** + *** *** + *** Communication services for LAN/WAN use following the message *** + *** passing paradigm. *** + *** STREAM C++ VERSION *** + *** MPI implementation *** + *** Developed by Erique Alba *** + ***************************************************************************/ +#include "netstream.hh" +// Default constructor +NetStream::NetStream() +{ + this->reset(); // Reset to default values member variables + packin_buffer = new char[MAX_PACK_BUFFER_SIZE]; + packout_buffer = new char[MAX_PACK_BUFFER_SIZE]; +} +// Init the underlying communication library (MPI) +NetStream::NetStream (int argc, char ** argv) +{ + init(argc,argv); + this->reset(); + packin_buffer = new char[MAX_PACK_BUFFER_SIZE]; + packout_buffer = new char[MAX_PACK_BUFFER_SIZE]; +} +// Default destructor +NetStream::~NetStream() +{ + delete [] packin_buffer; delete [] packout_buffer; + this->reset(); +} +// Give default values to member variables +void NetStream::reset(void) +{ + default_target = default_source = 0; + pack_in_progress = false; + packin_index = packout_index = 0; + pending_input_packet = false; + pack_in = pack_out = false; + broadcast = false; + my_communicator = MPI_COMM_WORLD; +} +// Init the communication system. Invoke it only ONCE +void NetStream::init(int argc, char** argv) +{ + static bool system_up = false; // Is MPI already running? + if (!system_up) + { MPI_Init(&argc,&argv); + system_up = true; + } +} +// Shutdown the communication system. Invoke it ONCE +void NetStream::finalize(void) +{ + MPI_Finalize(); // Unconditional Finalization +} +// BASIC INPUT/OUTPUT SERVICES +// =================================================================================== + +NetStream& NetStream::operator>> (bool& d) +{ rcv(&d,1,NET_BOOL,default_source); return(*this); } + +NetStream& NetStream::operator<< (bool d) +{ send(&d,1,NET_BOOL,default_target); return(*this); } +NetStream& NetStream::operator>> (char& d) +{ rcv(&d,1,NET_CHAR,default_source); return(*this); } +NetStream& NetStream::operator<< (char d) +{ send(&d,1,NET_CHAR,default_target); return(*this); } +NetStream& NetStream::operator>> (short& d) +{ rcv(&d,1,NET_SHORT,default_source); return(*this); } +NetStream& NetStream::operator<< (short d) +{ send(&d,1,NET_SHORT,default_target); return(*this); } +NetStream& NetStream::operator>> (int& d) +{ rcv(&d,1,NET_INT,default_source); return(*this); } +NetStream& NetStream::operator<< (int d) +{ send(&d,1,NET_INT,default_target); return(*this); } +NetStream& NetStream::operator>> (long& d) +{ rcv(&d,1,NET_LONG,default_source); return(*this); } +NetStream& NetStream::operator<< (long d) +{ send(&d,1,NET_LONG,default_target); return(*this); } +NetStream& NetStream::operator>> (float& d) +{ rcv(&d,1,NET_FLOAT,default_source); return(*this); } +NetStream& NetStream::operator<< (float d) +{ send(&d,1,NET_FLOAT,default_target); return(*this); } +NetStream& NetStream::operator>> (double& d) +{ rcv(&d,1,NET_DOUBLE,default_source); return(*this); } +NetStream& NetStream::operator<< (double d) +{ send(&d,1,NET_DOUBLE,default_target); return(*this); } +NetStream& NetStream::operator>> (char* d) +{ rcv(d,MAX_MSG_LENGTH,NET_CHAR,default_source); return(*this); } +NetStream& NetStream::operator<< (char* d) +{ send(d,strlen(d)+1,NET_CHAR,default_target); return(*this); } +NetStream& NetStream::operator>> (void* d) +{ rcv(d,MAX_MSG_LENGTH,NET_CHAR,default_source); return(*this); } +NetStream& NetStream::operator<< (void* d) +{ send(d,strlen((char*)d)+1,NET_CHAR,default_target); return(*this); } +// Extended data types from version 1.5 on +NetStream& NetStream::operator>> (unsigned char& d) +{ rcv(&d,MAX_MSG_LENGTH,NET_UNSIGNED_CHAR,default_source);return(*this); } + +NetStream& NetStream::operator<< (unsigned char d) +{ send(&d,1,NET_UNSIGNED_CHAR,default_target); return(*this); } +NetStream& NetStream::operator>> (unsigned short int& d) +{ rcv(&d,MAX_MSG_LENGTH,NET_UNSIGNED_SHORT,default_source);return(*this); } +NetStream& NetStream::operator<< (unsigned short int d) +{ send(&d,1,NET_UNSIGNED_SHORT,default_target); return(*this); } +NetStream& NetStream::operator>> (unsigned int& d) +{ rcv(&d,MAX_MSG_LENGTH,NET_UNSIGNED,default_source); return(*this); } + +NetStream& NetStream::operator<< (unsigned int d) +{ send(&d,1,NET_UNSIGNED,default_target); return(*this); } +NetStream& NetStream::operator>> (unsigned long int& d) +{ rcv(&d,MAX_MSG_LENGTH,NET_UNSIGNED_LONG,default_source);return(*this); } + +NetStream& NetStream::operator<< (unsigned long int d) +{ send(&d,1,NET_UNSIGNED_LONG,default_target); return(*this); } +NetStream& NetStream::operator>> (long double& d) +{ rcv(&d,MAX_MSG_LENGTH,NET_LONG_DOUBLE,default_source); return(*this); } + +NetStream& NetStream::operator<< (long double d) +{ send(&d,1,NET_LONG_DOUBLE,default_target); return(*this); } +// SET-GET TARGET AND SOURCE PROCESSES +NetStream& __set_target(NetStream& n, const int p) { return n._set_target(p); } +NetStream& NetStream::_set_target(const int p) +{ assert(p>=0); default_target = p; return (*this); } +NetStream& __get_target(NetStream& n, int* p) { return n._get_target(p); } +NetStream& NetStream::_get_target(int* p) +{ *p = default_target; return (*this); } +NetStream& __set_source(NetStream& n, const int p) { return n._set_source(p); } +NetStream& NetStream::_set_source(const int p) +{ /*assert(p>=0);*/ default_source = p; return (*this); } +NetStream& __get_source(NetStream& n, int* p) { return n._get_source(p); } +NetStream& NetStream::_get_source(int* p) +{ *p = default_source; return (*this); } +// Get the number of processes involved in the communications +int NetStream::pnumber(void) +{ int numprocs, rvalue; + rvalue = MPI_Comm_size(my_communicator,&numprocs); + assert(rvalue==MPI_SUCCESS); + return numprocs; +} +// MANIPULATORS: SYNCHRONIZATION AND PACKING SERVICES +// =================================================================================== +// Get the process ID [0, 1, 2, ...] fro the calling process +NetStream& __my_pid(NetStream& n, int* pid) +{ + return n._my_pid(pid); +} +NetStream& NetStream::_my_pid(int* pid) +{ + MPI_Comm_rank(my_communicator,pid); + return (*this); +} +// EASY access to rank - Returns the process ID of the calling process +int NetStream::my_pid(void) +{ int pid; + this->_my_pid(&pid); + return pid; +} +// Sit and wait until all processes are in the same barrier +// Can be used as a MANIPULATOR +NetStream& barrier(NetStream& n) +{ + return n._barrier(); +} +NetStream& NetStream::_barrier(void) +{ int status; + status = MPI_Barrier(my_communicator); + assert(status==MPI_SUCCESS); + return (*this); +} +// Wait for an incoming message in any input stream +NetStream& NetStream::_wait(const int stream_type) // class +{ + int rvalue; + MPI_Status status; + assert(stream_type==regular||stream_type==packed||stream_type==any); + if( ((stream_type==packed) || (stream_type==any) )&& (pending_input_packet) ) + //if( (stream_type==packed) && (pending_input_packet) ) + return (*this); // wait befor packet_begin when already received + rvalue = MPI_Probe(default_source,stream_type,my_communicator,&status); + assert(rvalue==MPI_SUCCESS); + return (*this); +} + +NetStream& NetStream::_wait2(const int stream_type, int& tipo) // class +{ + int rvalue; + MPI_Status status; + assert(stream_type==regular||stream_type==packed||stream_type==any); + if( ((stream_type==packed) || (stream_type==any) )&& (pending_input_packet) ) + //if( (stream_type==packed) && (pending_input_packet) ) + return (*this); // wait befor packet_begin when already received + rvalue = MPI_Probe(default_source,stream_type,my_communicator,&status); + assert(rvalue==MPI_SUCCESS); + if (status.MPI_SOURCE == 0){ + tipo = 1; + } + return (*this); +} +NetStream& __wait(NetStream& n, const int stream_type) // helper +{ + return n._wait(stream_type); +} +// Marks the beginning of a packed information +NetStream& pack_begin(NetStream& n) +{ + return n._pack_begin(); +} +NetStream& NetStream::_pack_begin(void) +{ + int rvalue=MPI_SUCCESS; + MPI_Status status; + if(!pack_in_progress) + { pack_in_progress = true; + packin_index = packout_index = 0; + pack_in = false; + pack_out = false; + if (!pending_input_packet) + { _probe(packed,pending_input_packet); + if(pending_input_packet) + rvalue = MPI_Recv(packin_buffer, MAX_PACK_BUFFER_SIZE, NET_PACKED, + default_source, PACKED_STREAM_TAG, my_communicator, &status); + } + } + return (*this); +} +// Marks the end of a packed and flush it to the net +NetStream& pack_end(NetStream& n) +{ + return n._pack_end(); +} +NetStream& NetStream::_pack_end(void) +{ + int rvalue, mypid; + if (pack_in_progress) + { + if(pack_out) + { if(broadcast) // Packet broadcast + { broadcast = false; + _my_pid(&mypid); + rvalue = MPI_Bcast(packout_buffer,packout_index,NET_PACKED, + mypid,my_communicator); + assert(rvalue==MPI_SUCCESS); + } + else + { rvalue = MPI_Send(packout_buffer, packout_index, NET_PACKED, + default_target,PACKED_STREAM_TAG,my_communicator); + assert(rvalue==MPI_SUCCESS); + } + } + pack_in_progress = false; + pack_in = pack_out = false; + packin_index = packout_index = 0 ; + } + return (*this); +} +// Check whether there are awaiting data +NetStream& probe(NetStream& n, const int stream_type, int& pending) +{ + return n._probe(stream_type, pending); +} +NetStream& NetStream::_probe(const int stream_type, int& pending) +{ + MPI_Status status; + int rvalue; + assert(stream_type==regular||stream_type==packed||stream_type==any); + rvalue = MPI_Iprobe(default_source,stream_type,my_communicator,&pending,&status); + assert(rvalue==MPI_SUCCESS); + return (*this); +} +// Broadcast a message to all the processes +NetStream& broadcast(NetStream& n) +{ + return n._broadcast(); +} +NetStream& NetStream::_broadcast(void) +{ + broadcast = true; + return (*this); +} +// PRIVATE SERVICES +// =================================================================================== +// Usually, the length is the number of bytes for every net type +// When packing we must use in the pack calls the numer of items (length divided by type size) +// Any char is encoded with a leading field of length +void NetStream::send(void* d, const int len, const NET_TYPE type, const int target) +{ + int rvalue = MPI_SUCCESS, length = len; + // PACKING SERVICE + if(pack_in_progress) + { + pack_out = true; + assert(pack_out!=pack_in); // Error condition + if(type==NET_CHAR) + send(&length,sizeof(NET_INT),NET_INT,target); // Recursive call to store string length + else + length = 1; + rvalue = MPI_Pack(d,length,type,packout_buffer,MAX_PACK_BUFFER_SIZE,&packout_index,my_communicator); + assert(rvalue==MPI_SUCCESS); + return; + } + if(broadcast) // Regular broadcast, packed broadcast managed in _pack_end() + { int mypid; + + broadcast = false; + _my_pid(&mypid); + rvalue = MPI_Bcast(d,len,type,mypid,my_communicator); + assert(rvalue==MPI_SUCCESS); + return; + } + rvalue = MPI_Send(d,len,type,target,REGULAR_STREAM_TAG,my_communicator); + assert(rvalue==MPI_SUCCESS); +} +void NetStream::rcv (void* d, const int len, const NET_TYPE type, const int source) +{ MPI_Status status; + int rvalue = MPI_SUCCESS, length=len; + if(pack_in_progress) + { +// if(!pack_in && !pending_input_packet) +// rvalue = MPI_Recv(packin_buffer, MAX_PACK_BUFFER_SIZE, NET_PACKED, +// default_source, PACKED_STREAM_TAG, my_communicator, &status); + pack_in = true; + pending_input_packet = false; + assert(pack_out!=pack_in); + if(type==NET_CHAR) + rcv(&length,sizeof(NET_INT),NET_INT,source); // Gets the string length + else + length = 1; + rvalue = MPI_Unpack(packin_buffer, MAX_PACK_BUFFER_SIZE, &packin_index, d, + length, type, my_communicator); + assert(rvalue==MPI_SUCCESS); + return; + } + + rvalue=MPI_Recv(d,len,type,source,REGULAR_STREAM_TAG,my_communicator,&status); + assert(status.MPI_ERROR==MPI_SUCCESS); + assert(rvalue==MPI_SUCCESS); +} +/////////////////////////////////////// GROUP MANAGEMENT //////////////////////////////// +// Set the netstream to a new communicator +void NetStream::set_communicator(NET_Comm comm) +{ + my_communicator = comm; +} +// Get the present communicator in this netstream +NET_Comm NetStream::get_communicator(void) +{ + return my_communicator; +} +// Create a new group inside the present communicator +NET_Comm NetStream::create_group(NET_Comm comm, int color, int key) +{ int rvalue; + NET_Comm newcomm; + rvalue=MPI_Comm_split(comm,color,key,&newcomm); + assert(rvalue==MPI_SUCCESS); + return newcomm; +} +// Create a bridge between local and remote MATCHING call +NET_Comm NetStream::create_inter_group(NET_Comm lcomm, int lrank, NET_Comm bcomm, int rrank, int strtype) +{ int rvalue; + NET_Comm newcomm; + rvalue=MPI_Intercomm_create(lcomm,lrank,bcomm,rrank,strtype,&newcomm); + assert(rvalue==MPI_SUCCESS); + return newcomm; +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/netstream.hh b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/netstream.hh new file mode 100644 index 0000000..5c24a3d --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/netstream.hh @@ -0,0 +1,161 @@ +/*************************************************************************** + *** netstream.cc *** + *** v1.6 - July 2001 *** + ** *** + *** v1.5 - March 2001 *** + *** v1.0 - November 2000 *** + *** *** + *** v1.5 extends v1.0: *** + *** .- Changes metods init() and finalize() to be static *** + *** .- Incorporates process group management *** + *** .- Do not consider LEDA anymore *** + *** .- Contains a method "int my_pid()" for easy invokations *** + *** .- Adds "unsigned" and "long double" input/output *** + *** *** + *** v1.6 extends v1.5: *** + ** .- Internal in/out buffers for packed separated *** + *** *** + *** Communication services for LAN/WAN use following the message *** + *** passing paradigm. *** + *** STREAM C++ VERSION *** + *** MPI implementation *** + *** Developed by Erique Alba *** + ***************************************************************************/ +#ifndef INC_netstream +#define INC_netstream +#include "mpi.h" +#include <assert.h> +#include <string.h> +// Class NetStream allows to define and use network streams trhough LAN and WAN +#define REGULAR_STREAM_TAG 0 // Used for tagging MPI regular messages +#define PACKED_STREAM_TAG 1 // Used for tagging MPI packet messages +#define NET_TYPE MPI_Datatype // Network allowable data types +#define NET_BOOL MPI_CHAR // Bools like chars +#define NET_CHAR MPI_CHAR +#define NET_SHORT MPI_SHORT +#define NET_INT MPI_INT +#define NET_LONG MPI_LONG +#define NET_UNSIGNED_CHAR MPI_UNSIGNED_CHAR +#define NET_UNSIGNED_SHORT MPI_UNSIGNED_SHORT +#define NET_UNSIGNED MPI_UNSIGNED +#define NET_UNSIGNED_LONG MPI_UNSIGNED_LONG +#define NET_FLOAT MPI_FLOAT +#define NET_DOUBLE MPI_DOUBLE +#define NET_LONG_DOUBLE MPI_LONG_DOUBLE +#define NET_BYTE MPI_BYTE +#define NET_PACKED MPI_PACKED +#define NET_Comm MPI_Comm +#define MAX_MSG_LENGTH 204800 // Max length of a message +#define MAX_PACK_BUFFER_SIZE 204800 // Max length of a packed message +// Help structure for manipulators having one int& argument +class NetStream; +struct smanip1c // "const int" +{ NetStream& (*f)(NetStream&, const int); // The ONE argument function + int i; // The argument + smanip1c( NetStream&(*ff)(NetStream&,const int), int ii) : f(ff), i(ii) {} // Constuctor +}; +struct smanip1 // "int*" note: references do not work! "int&" +{ NetStream& (*f)(NetStream&, int*); // The ONE argument function + int* i; // The argument + smanip1( NetStream&(*ff)(NetStream&, int*), int* ii) : f(ff), i(ii) {} // Constuctor +}; +// Tags for the available streams +const int any = MPI_ANY_TAG; // Tag value valid for any stream +const int regular = REGULAR_STREAM_TAG; // Tag value for regular stream of data +const int packed = PACKED_STREAM_TAG; // Tag value for packed stream of data +// Tags for sources +const int any_source = MPI_ANY_SOURCE; // Tag value valid for any source +class NetStream +{ + public: + NetStream (); // Default constructor + // Constructor with source integer left unchanged + NetStream (int, char **); // Init the communications + ~NetStream (); // Default destructor + static void init(int,char**); // Init the communication system. Invoke it only ONCE + static void finalize(void); // Shutdown the communication system. Invoke it ONCE + // GROUP management + void set_communicator(NET_Comm comm); // Set the netstream to a new communicator + NET_Comm get_communicator(void); // Get the present communicator in this netstream + static NET_Comm create_group(NET_Comm comm, int color, int key); // Create a new group inside the present communicator + // Create a bridge between local and remote MATCHING call + static NET_Comm create_inter_group(NET_Comm lcomm, int lrank, NET_Comm bcomm, int rrank, int strtrype); + +// BASIC INPUT SERVICES <comments> BASIC OUTPUT SERVICES +// ============================================================================================================ + NetStream& operator>> (bool& d); NetStream& operator<< (bool d); + NetStream& operator>> (char& d); NetStream& operator<< (char d); + NetStream& operator>> (short& d); NetStream& operator<< (short d); + NetStream& operator>> (int& d); NetStream& operator<< (int d); + NetStream& operator>> (long& d); NetStream& operator<< (long d); + NetStream& operator>> (float& d); NetStream& operator<< (float d); + NetStream& operator>> (double& d); NetStream& operator<< (double d); + NetStream& operator>> (char* d); /*NULL terminated*/ NetStream& operator<< (char* d); + NetStream& operator>> (void* d); /*NULL terminated*/ NetStream& operator<< (void* d); + // Extended data types from version 1.5 on + NetStream& operator>> (unsigned char& d); NetStream& operator<< (unsigned char d); + NetStream& operator>> (unsigned short int& d); NetStream& operator<< (unsigned short int d); + NetStream& operator>> (unsigned int& d); NetStream& operator<< (unsigned int d); + NetStream& operator>> (unsigned long int& d); NetStream& operator<< (unsigned long int d); + NetStream& operator>> (long double& d); NetStream& operator<< (long double d); + int pnumber(void); // Returns the number of processes + bool broadcast; // Determines whether the next sent message is for broadcasting + // Input MANIPULATORS for modifying the behavior of the channel on the fly + // NO ARGUMENTS + NetStream& operator<< (NetStream& (*f)(NetStream& n)) { return f(*this); } // NO arguments + NetStream& _barrier(void); // Sit and wait until all processes are in barrier + NetStream& _pack_begin(void); // Marks the beginning of a packed information + NetStream& _pack_end(void); // Marks the end of a packed and flush it to the net + NetStream& _probe(const int stream_type, int& pending); // Check whether there are awaiting data + NetStream& _broadcast(void); // Broadcast a message to all the processes + // ONE ARGUMENT + // "const int" + NetStream& operator<< (smanip1c m) { return m.f((*this),m.i); }// ONE int& argument constant + // "int*" + NetStream& operator<< (smanip1 m) { return m.f((*this),m.i); }// ONE int& argument + // BASIC CLASS METHODS FOR MANIPULATORS + NetStream& _my_pid(int* pid); // Returns the process ID of the calling process + NetStream& _wait(const int stream_type); // Wait for an incoming message in the specified stream + NetStream& _wait2(const int stream_type, int& tipo); + NetStream& _set_target(const int p); // Stablish "p" as the default receiver + NetStream& _get_target(int* p); // Get into "p" the default receiver + NetStream& _set_source(const int p); // Stablish "p" as the default transmitter + NetStream& _get_source(int* p); // Get into "p" the default transmitter + // AUXILIAR PUBLIC METHODS FOR ALLOWING EASY MANAGEMENTS OF NETSTREAMS + int my_pid(void); // Returns the process ID of the calling process + private: + int default_target, default_source; // Default process IDs to send-recv data to-from + bool pack_in_progress; // Defines whether a packet is being defined with "pack_begin-pack_end" + int packin_index; // Index to be used for extracting from a IN packed message - v1.6 + int packout_index; // Index to be used for adding to an OUT packed message - v1.6 + int pending_input_packet;//Is there a pending packet already read into the IN buffer? - v1.6 + char* packin_buffer; // Buffer to temporary storage of the IN packed being defined - v1.6 + char* packout_buffer; // Buffer to temporary storage of the OUT packed being defined - v1.6 + bool pack_in, pack_out; // Define whether input-output packed message is being used + void reset(void); // Reset member variables of this class + NET_Comm my_communicator; // Communicator of this netstream + void send(void* d, const int len, const NET_TYPE type, const int target); + void rcv (void* d, const int len, const NET_TYPE type, const int source); +}; // class NetStream + // MANIPULATORS (must be static or non-member methods in C++ -mpiCC only allows non-member!-) + // NO ARGUMENTS + NetStream& barrier(NetStream& n); // Sit and wait until all processes are in barrier + NetStream& broadcast(NetStream& n); // Broadcast a message to all the processes + NetStream& pack_begin(NetStream& n); // Marks the beginning of a packed information + NetStream& pack_end(NetStream& n); // Marks the end of a packed and flush it to the net + // ONE ARGUMENT + NetStream& __my_pid(NetStream& n, int* pid); // Returns the process ID of the calling process + inline smanip1 my_pid(int* pid){ return smanip1(__my_pid,pid); } // manipulator + NetStream& __wait(NetStream& n, const int stream_type);// Wait for an incoming message - helper + inline smanip1c wait(const int stream_type){ return smanip1c(__wait,stream_type); } // manipulator + NetStream& __set_target(NetStream& n, const int p); // Stablish "p" as the default receiver + inline smanip1c set_target(const int p){ return smanip1c(__set_target,p); } // manipulator + NetStream& __get_target(NetStream& n, int* p); // Get into "p" the default receiver + inline smanip1 get_target(int* p){ return smanip1(__get_target,p); } // manipulator + NetStream& __set_source(NetStream& n, const int p); // Stablish "p" as the default transmitter + inline smanip1c set_source(const int p){ return smanip1c(__set_source,p); } // manipulator + NetStream& __get_source(NetStream& n, int* p); // Get into "p" the default transmitter + inline smanip1 get_source(int* p){ return smanip1(__get_source,p); } // manipulator + // TWO ARGUMENTS - not used yet + NetStream& probe(NetStream& n, const int stream_type, int& pending); // Check whether there are awaiting data +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/netstream.o b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/netstream.o new file mode 100644 index 0000000000000000000000000000000000000000..fb40ece360fb739d83d40beffbf1b01c031a15aa GIT binary patch literal 18752 zcmbuH4RBo5b%39KKpUg1*2Ha=K;m_x+Hz{tT_FqE!9;8AS}S{Pul0kCfBLkRS7t$$ zHmfK9fLn_Za=cw@W=TmV3CvV2ZsJTCMoilYW+*7NW77_FOeUm2nL&n3!ITCE2!+NS z_niCA(Vo4#Z!Ly9qkZpv_uO;NJ@@C`y?5;+;pn=`iVA~Mg>k!)e`0DFW1;+go4Rc? zzF>Hi?1FrjajwIKPv<(S@p87K7H${W#A9E)c18d){l?iE$ZrM`Iz3Rg7;JP$GQWQt zC7v~WRYv|Ul4<v;C%9?YaXMGG_yLqs@{#NjUu5Enb&V~My{|z$WnSNL5e0L${>b>d z-mx_ZjLhNs+DN9kesob}Qr-TiDu4DG%&drvpYfg^$e}-(|A}ONMaExO*YeH{<OUkq zKe9ddJn_-Nn#_UfNao|yk;%`arO4z;`=Y!8|6EUH0Vq2IIlX*#E0)dt;pw`?V^~bj z$IJsR45l3)JwLnERlYpLCwrthGHKP<Di<bZMn9JgL8LGqC0%~%2kdUnju(`tXuZ4x z{Df9@jt90!-q@U>g7#&7;L0_T4CpNF#!uOea`Eq;TnA12u5bL~$^*+!RzT~H)?_=p zp!)i3cXReWh|UGBcLUVfSH|G8Y_POHXE<B>(+l>y!GQ*J;5OwzB=ZvZu+=;9i_s-T zKD0teT;N^Jxv&~*;8Fv+w96p~&$H3eKE24<PW=P>JGkc=J5p;{zOf?#V|2yY_FCg? zI}F%%zj3bJ9?k7)G=n!D6`;BPHug=!+MpT~hPDc1c4ScmhU8Oq6-G3aZEwy-=X#d) zx23(Tgc(Sc9mr)jS7#3_3O<Q*5{&bPP<BJJQbmna_rRZCxpJknni^J9W<1LNumtO# zc`<v$1<lZznVoMxxPk4IcH>6Qu3Ow@&sWg@Fuu^-2fQ#vRuoQ=YF_LJ7!w~^3+H+u zw^w9xtM?fUh8^1t-id#)UWEp8WjDAW%)ZDZ^q09H*>QUYr_z`zux<N)Jyy54%y`u2 z3z#g<)>JspC&AuePiN+Lz1_jg^ANsJ=4arH7i*X4sdrg@V@F_;?+8@XO<Vz|gZE#C zcTKeJftTRn9C(T~QPqKtfwhQaH#9^iH!KQe-UvR4Zbvik*`80#Y`?Q^;uVmGn0R;W z3hoT<g83QxTjnLJv!KUuF9Ri+-+%&YN9%0q_Gy>x6UuIG4hLrRqS?|#JGkgv|3^n$ zr>?0sqEA(WuXZZ|x_F~wH*IDmrERR{Y?u?F|D3`AJ_XF6ks8W&RJR?2={i4+=7(kO z)5}*?7V96#IO|t+)%<Y~$M?gj8dtIY2o!Ls(5ZkG_`d*Ssp(f${h)3kyq5|Kfd1=B z>Bm-iALU(|e6O1D@D2Yv?0+g3`cL&_4BidDiDX_^@#aGCcEG7u%qO3<eD^7s?277F zu05+iW&2!PB7WuC$5kqR&h3NU4|?LMS`SwPV(qa5hVN?CYxD2_U{7yn=ELsH3v-i& zpC*f1s~=xCF#ExLs1}KJ6Hh}ozyJU2DdRhE4^u`hb_IK0o0~Im+UxcNGZ&+o3u3aH zm@$Lf>L$L2V`cn|ALoqI*vL4>Grz)_(hEa9^G-DLmOaO8zcXvq`zAiBo46m!Ow3r% zl^&9P;Df5+Ku+~UZM=tY8FSJ3z0}RcOKaa=KHKDM6<G+s%O2wpP&G{Qp~v}Re)%}& z%azA5UM?TUbh&&S!{zdE%$Cc?9)S6C-wD*Bqqu%f`8dYPmB%qvE+5BGxqKWm<??ZG zl+Mo_Xoj~~etcv*3ZL<98kx*5nXbARPjmOkf8U9In)3H@`72i{jG=@zVx<%DeU1J7 zM(Xx8ej~j<J~*0Kvu0zg)9mhTZx45O8zWZS8XYNQsd)cA=J2SsWR1E@4v|zN77TZF zZSE?Rx6PQ=p%f@jC-#mG#?yxn7f@7`*rUPt&><MA&Ix@>_WRIk`|!SfzD)_MTh(aw z>VBx0l`xY-Rw8ZgO%IQz8dz+F59o@yQuGLHxo+v|`b%n_Q?-9Mxkoyc?%&^l?CZjX zP#h`&fl)~FKrcU%7~1n`6wJkAsr153rH6MX8dMPAW2t6T1i`61Hb1)JT+&wJQ2szX zX*GQY`&b@}U(LMXV1IW!olYjw#qNVn8K~6I=)T>h<TykQ`bQF$X~olf6GdKjw70MJ zHFRw1UG8gXY-$Ynn*4zl|EfTXuc0fk#}|oPHov(^)lGdH17j8Ub{Q21Jry_B*0^#o zgz@XyP2|LCy5dXKPxs648gzTcD-&)P+_G%Ny|Jj$RP!)O+{pScza9xBG>nT|yL`VY zkA56S2B{H0LT+CYa?s`pe1?SkJa(D1DuX`GAcLefUEqrBmk1y!J$u|9Wa_O3S1ETH zg&=*-zNoSus5>SpS5K_Q&Qfx%CFG*Sq&|GrV`6<+AB&jUuz`BsxxnoTUT3JfV(c+3 z#19qU&2x2qOw)xin<4f^lm}g16tkC!=VR8btY9oY)b#j(xhmlUl7%12Zim~ST;TSE zY~LCHuOOLYBy+Sf<o1qNh1_lTEpU57ZcosbMH|~lmh0^UHb@M=ys-`6-L{SOP=73! zD^czQu|ZMJAJ6-?0{C+zGcINBv1K~1yVKnocekx`w+7vQ+s?<D9kg9rg@yBNg$%wz zswCUKS(6KaM1<Hq7~8dO&t&CVxA!>2#&@(j=x!LlW~009kUP@rjz!#&pu27T0(V2u z?F+iSAiUP?YKQvc7|D?y)pu1pY;pUxs%B96(^ttqf0g`8lz%hUiuK=-*Y8mSlg19` z3;TY`{}Wk$TfTg(OnyC-Nm0JqvjqJ|D<K5qRU6&DKJG$lp7{Pe<S<?{B<B>b*{kI9 zz;ud-k2-KE{WzA}D1XUZJWMrSBk;VF@-|SPIF5BaihW|dI_i#9wz;?UxcegRZEM{z z=nvQ#AR^Eig4cyq);jmLpgX4Kg_EQU>uiK^-n~QFK_AYP$(t>ccezZS_gXYW^SWlQ zxlCTHOx|FbyklkZPL#=;DU<hFnY@q7<SnAXuE!eZ13%?aw^DOfNMqP0+lZ-mC$#t- zG{>V(%OMZ4920h-YU8)K309P<44TZeoGSY*t5L(K;!dySR2dW$!QF6QA>`2yPE`g~ zgaKTe;I9JSsAJ^PGRhku9wUAO@$VA%5m)1g@~R9M-Q_PoC;3@&gyr8SK1CegSD3yE z&*)Dd@vqw0!0*t=eVY6@@mZ2n?@ze@d*V~XZ=vfO#QW&^HoD#b^+Eldw(t#Hs{|Jq zxI78V=TsT$peGOLuFAmHDNOczx42z)src3uY1&Qv`a(6vUgAqNZok8e+vQs%&uc|4 zwx4*Efw)!~wc;s%TLqER(|w@ldeP6>&V$6;r~vo3M}gyb)zc{l{;Y$Z7m24x5w2Y^ zy$O6tWxl;QB3B&rzvIBKh4(SmOV{ruKBcVD`xx&1z)RI@70I6`dG5EH9C$x*eZ70w zL4StidAz9iA=vtngZw{`e2kisUNy#x#QTWz2zifqN|XOQOtcuEG2+~_zfPRj%d8*I zjZuC|)1M$dt?3^pK0{os$)R2k11}ZlpO8FvMYT=``G0nhKTq;LXn#!X=SAXv;%fa) z0_Z=_liZFsK*3V}{1I@J*VoP8AU;L<)w&+^Z*kDGgXDR=dklSnWD)0eCp@b37sO|v z-7u*&JzP%!FXiXs4*aL2XA0th2_9AYH{#R8)!H9&-g40MKFRw?!8qxugI8K9e{g++ zahoQ2x)@EwXEfeP{5)~)hY8}dn*5&;zeHSpF94su2fUO&e?{_rq?pIo6U1{GKTUi_ z<1Z1vL|m<FF>b_tG*PksPl(5et93odUkBweK4TjHGVy8RY8?;qxGpMHuUkp}k|w{N zxSu8f_Gc&YK8+6%&k^T(jS-*G<iA7w67ePABc>C?eKd8ewK?#oftT|C9LcBP`xz#+ zCWPy&#B&<|Z{pJ$$E6I$^Ss8tK>U)%mlF5TE0XQ5BJS6Clz2?zCh?TU)5LQcpCCT1 z@$VBqukpVleo5oc5ckm1h5dh#xSu!;Z{q{vZ5sarXg`cwj5xpdR{}59ULlgtY4U>( z@`YQ}=JxHIR?Tg>H7AFXRyY}p^@mrD92&6_`^?dlQ797#nEAc9a55ZNWty?Ba8J*j z=DOZZ?LD2FH<_kZ=2qJE3-6zoc&kafiSv|SY2xnXJbh_V!cF01*Zh26Wvcyn*qWWE zH!b#F@VpH);|_E<wm+GipF_96j`yb!4>ZxXz1mg}&(}(zwRpE53p+a57=<6Zz()W- zn(*Tm{Ak9HmH5#DokH}rmFWcZqwxMh+TMhuBf5EQFlugIx2`+fWA+5sM#I>phT{7) z>4087gyln98`Ft_M$_DT@SvGWq(_E_;)6-+kh$Lv<@dy6n$b{^n*2a8@PwlihJ|Js zIuHyK4F*cU)`28izc&Gnp{{lGSXfjWRfcKCM@AB9%N&R&2SGH@WQt+el^?RnB0aE0 zPCMn{80KQpJQGD#u4obRVPtqT-Jb|^Q5@_x5=Bc}rIH0!i;C)2^K*j=51u)hBM`2_ zdfjU7J7lJkFiw(rv2=Xs9uR9aDN{J8TWO)<TFZ->MyXwEpJIU0TWJasItxAGNk^57 z;ptCdzL;kqqs3Iyj?kusP);+pEB)~iOWk$D`~WIic^(o<bd%~73TGZwuv0x2%0MG4 zJ-ZWolS9-cyAu5vmw-Q?Q)pwQQY08!C>YHFzqva-9N&XZt1-E1?okvgEF&g9JBV-u zRwywz65d@zv_S_lBSkWrcOZj<Nc43e14RU*Tqpx098OdR6GO#0T2BIncNGa~lLpA# zT_mGTX&|F@r2KrZqSQNttyHKcJreHH0)<G66e2BDh_qNC(t?FZixwg+T!8cm5s?-r zET{zvkrpXLTBs0du|lK;E6{@TRX<E3qeIF5xHX(s6Pak$KnqTW1rnNz#cxa%czb3_ z!Hc9Y_|9)idl2GjIhr%=7phuR!$+8Ia6O1?^~>;cH%yxauNQom1OIcu8-)CE2mT}C z_%#`A|K2ux<ryKr0`A$LGsJcISB3l^3;8z$m-TvAa9OYab>NM(KY?}^!QWxLfwWR^ z+;?U_ZxbB%TA8mWj&;SoTIMeZ{tdw|2t8;wN_O8CT-tq4@Gl8Hp9uZZE}uK1Ke+e8 z{;VcD$Z=1VIiD*c4+?%4$>Rn6yosKN1($x>`;rEHvw%Ztp=XTb_4xc;@Q{#yMd(Mn zuTec`1($Z;5*)u1alL*k^vn40IVEOG{kYGF2`^GV?k8eGF5~YZuGgzma9OW?LJ!(~ zgz9ApF74hYxUAQN&@bzCT*yoPe<`@s|3krLy-qmjcVk5%;YIeJWr9Z_kK^A&oa4Nc z>bpvC=}(*B(x3H0zpU@wf_DnLhlC!C1KS-FT-yD%;L`4cLcg^8g5XhM_kz%ac5kBk zzAd=4`<~#keLoTUrCr|0<9M?E8rl!j`>k7WSuZbfG$ZxjE%*jeuZIQSBzQ0Eb74X~ zJ@CivJ|?*AC*KuZ_LC{%T(8$qDWo3@F5~vN;Idv%3jMNP=LMJj<UfQSY%jL^hTzif zMZu-r4}^Yc*8}@jm@q!w@W=7-5!dUxOmJzpQSdJdJ*`5&wEImVFYC2VaH)Tz;Idv@ z9rWKXxUAO`4*Y@x_rU%XCOtku2afw|rR4v{fzJqzYa5RLzY8w?=OaY)N6LQ@_PH?W zer|E#_dD=u2Y$hUyJ$aEw|h+R1o*}EIwiOqr@tW1{p}G|8^d@-aM>Sb1(*Hd9id<L zH-q+B(a$}?pM}JAyI#Si-Nk~-e!g7jmv;R^9{V}h>sG;~{@VqY^@=#?-z?;%{yPMh z`gaNb6%mKM4*JIhmvMX4fuDBZZ#wX*T5tlA-Y#Er;P6k%O3L>;@NozJr~^Okz~6M> zRbt;-#^-Aee7oQWpe8&nhKO@N+-X<S7!_Q$<6*&NKRGJ&%YOJn!SR>RZ1-`Y2m256 ze-vEWeOhp7_pHz_?c(n|Fk$;Hfj`#2kk%c@{eo{1JRtbD1aB7nLBU%De?st9!Ixlw zA)(#d;E(;m-xFX$-UffnpAhTJcESG|1tH<31ODdZ#X4l8;6D?5gWwkg$KQ&u9=KHr ztFfH!@#3R<beCLK1Y?4Ud7FANj2(1EzKrhilA?Q-=V$&^JaTePN#->9DSAGs@$>Y2 zM&ll8kC!#>BmS<&W5f-*vY&nQyh!6IdT!A87(L&n@f<y~9o9cZe2*qSP0t54K10tB zX`CB}%dvhR-atB|$@A|4Ueh@L9^hk*^SOU5>0|v<^vwF0^ZEWxO`gy9QyS;<{f9I@ zMg9Jy#`(Pdd5!z16J6FgpTG0>Q_RM{8IrFT-}{jB`FpFzXGuP)aXx>4NaK9Yj=xjE z#CG|d{g)c&bM_B4&gbllC?2eb&)J(b&gbks8s~F%OXGab{)oo;JpGKu`8@sC8t3!$ zYKjy4$>-_y8t3!$kjD8uy-(wOp8lA|Q}n)nPUAV^zt;FPasDYH`+1)DP2zhE=3OG* zs&Nm!r+YN+C!W%HjQDYlr-+}_c#ilPjZYJw)%bbhmo<KgxR<_naDDmQyjkOXZXVG% zpPS?FCor)dJ~uz8aXue68b=Q8v*NqqYNhS#U3`~L48|L+#6inw+ynoF$Y|U>GGa9D z?e8}e2m2E#JXhO2m@pdC!<dZ<0*!FqDIZ(;5w56B36?vMY{b3c#1NPq8nzOR@b6e| zhJPXjJN$O}#9ih<I=&B#s`FdBuAk-eNhr*};gWjV=z+d|DVb%!Xjsi%eZX)^re=jZ zJH_bwue2Uw?%^A{;@%_bY@=tsMCb=G-a4D0kJzT{53a>9Erma{Pty`2mA>TWyTU8I zKIY&GxI>*z<#l=e8P{gW&^MXbKF5pm^z!YHfehD*GJS>ozgt4M=kk2*BBqx=M&)sB zClkky%f}%T?{)uYsr-+%44+g6_e1c9<>6nz7Nld;sn{N8>d#5YDAoRbYwQx-&ZrK* z(sFs`xE@3Me)y9qNA_=)5bjYH6JLKI?o|eT{1cUz4DY!d^T&y4)i-9SJikv_p8e<N zpTJG2`X8kFM`&Q7I&2ay&-F*H_gz5740bF?_<yX(r2CK0y6-3-!$T8DDSE$L5BE#p WPq&ZTAtmkCLk1+?U$LKx<M;m{=Bs=F literal 0 HcmV?d00001 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/random.hh b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/random.hh new file mode 100644 index 0000000..ae6bde6 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/random.hh @@ -0,0 +1,50 @@ +/****************************************************************************** +*** *** +*** Este fichero contiene funciones (en general inlines) para generar núme- *** +*** ros aleatorios y otras funciones relacionadas con ello *** +*** *** +*******************************************************************************/ + +#ifndef INC_random_hh +#define INC_random_hh + +#include <stdlib.h> + + +inline double undefined () +{ + double zero = 0; + return zero/zero; +} + +// Returns a valeu greater than any other +inline double infinity () +{ + double one=1.0; + double zero=0.0; + return one/zero; +} + +// Returns a random number in [0,1]. +inline double rand01 () +{ + return drand48(); +} + +// Returns a random number +inline int rand_int (float min,float max) +{ + int value=rand(); + int range= (int)(max - min); + int order = value % (range+1); + return ((int)min + order); +} + +// selects a seed +inline void random_seed(long int seed) +{ + srand48(seed); + srand(seed); +} + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/time.hh b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/time.hh new file mode 100644 index 0000000..088f4d5 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba/time.hh @@ -0,0 +1,43 @@ +/****************************************************************************** +*** *** +*** Este fichero incluye algunas funciones útiles para la medicion de tiem- *** +*** pos. *** +*** *** +******************************************************************************/ + +#ifndef INC_time_hh +#define INC_time_hh + +#define MAXTIME 4294 + +#include <time.h> +#include <sys/time.h> +#include <unistd.h> + +// return time in microseconds +inline float _used_time() +{ + struct timeval tv ; + static long tiempo = -1; + float u_clock; + + gettimeofday(&tv,NULL); + + if(tiempo < 0) tiempo = tv.tv_sec; + + u_clock = ((float)(tv.tv_sec - tiempo)*1000000.0) + ((float)tv.tv_usec); + return u_clock; + +} + + +inline float _used_time(float time) +{ + float dif=_used_time() - time; + if (dif<0) dif = 0; + return dif; +} + + + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/MainLan b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/MainLan index dab1dc79bf353d0f899df5ff03cb425d66216531..ab6538e4f63e54e48c3ad994081e40e4ac249c95 100755 GIT binary patch delta 30832 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�hln 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 delta 30356 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 E12z7i_y7O^ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/MainSeq b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/MainSeq index 55e5b86acc0295e756cbd36ef7de88c13a26e95d..83e93383c8484d0538e85437637a30b8e1cc4bb0 100755 GIT binary patch delta 30830 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î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 Ch_Y$` delta 30367 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 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/datos_columnas b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/datos_columnas index 03e3fe4..ca3e2b1 100644 --- a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/datos_columnas +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/datos_columnas @@ -1,11 +1,11 @@ 10 -1 3 -2 1 1 1 -1 1 1 -1 1 3 -3 1 1 +1 4 +2 1 +3 6 1 1 1 1 -1 2 -2 1 1 -1 2 2 -4 1 1 +2 1 1 1 +1 3 +2 1 +1 2 1 +1 3 1 +1 4 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/datos_filas b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/datos_filas index 36f7a6c..b005d6f 100644 --- a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/datos_filas +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/datos_filas @@ -1,11 +1,11 @@ 10 -5 1 -1 1 1 -1 3 +2 3 +1 +3 1 +1 3 1 +2 3 2 1 3 -1 1 1 +1 2 1 1 +1 1 3 1 +3 1 1 1 3 1 -1 1 -1 1 1 1 -5 3 -1 1 1 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.cfg b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.cfg index c7caf7a..681f85a 100644 --- a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.cfg +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.cfg @@ -1,12 +1,12 @@ 10 // number of independent runs -100 // number of generations -60 // number of individuals +1000 // number of generations +100 // number of individuals 100 // size of offsprings in each generation 1 // if replaces parents for offsprings, or only offsprings may be new parents 1 // display state ? Selections // selections to apply 1 3 // selection of parents -2 0 // selection of offsprings +2 4 // selection of offsprings Intra-Operators // operators to apply in the population 0 0.6 // crossover & its probability 1 1.0 0.01 // mutation & its probability diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.req.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.req.cc index 87caff6..ccb9c22 100644 --- a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.req.cc +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.req.cc @@ -476,7 +476,7 @@ skeleton newGA double Solution::fitness () { - //cout << "ESTOY ENTRANDO A FITNESS" << endl; + //cout << "ESTOY ENTRANDO A FITNESS" << endl; double fitness = 0.0; std::vector<std::vector<int>> datosDeFilas = _pbm.datosFilas(); std::vector<int> cantGruposDeFila = _pbm.cantGruposFila(); @@ -487,6 +487,7 @@ skeleton newGA int cantGrupos= cantGruposDeFila[i]; int iteradorGrupos=0; int resultado=0; //Resultado de la diferencia entre el bloque que tiene que haber y el bloque en el juego + int cantUnos=0; bool terminoBloque = true; while (columna < _pbm.cantColumnas()) { @@ -494,6 +495,7 @@ skeleton newGA { cantSeguidos++; terminoBloque=false; + cantUnos++; } else { @@ -516,12 +518,38 @@ skeleton newGA } columna++; //Si se termino la columna y faltan bloques - if((columna == _pbm.cantColumnas()) && (iteradorGrupos < cantGrupos)) - { - int restar= cantGrupos - iteradorGrupos; - fitness= fitness + 2100*restar; - } + } + if (cantSeguidos > 0) + { + if (iteradorGrupos < cantGruposDeFila[i]) + { + resultado= abs(datosDeFilas[i][iteradorGrupos] - cantSeguidos); //valor absoluto de la resta + } + else + { + resultado = cantSeguidos; + } + fitness= fitness + 1000 * resultado; + terminoBloque=true; + iteradorGrupos++; + resultado=0; + } + if(iteradorGrupos != cantGrupos) + { + int restar= abs(cantGrupos - iteradorGrupos); + fitness= fitness + 1100*restar; + } + int totalUnos = 0; + for(int j = 0; j< cantGrupos; j++) + { + totalUnos += datosDeFilas[i][j]; + } + if(cantUnos != totalUnos) + { + int restar= abs(totalUnos - cantUnos); + fitness= fitness + 300*restar; + } } extern int currentBestFitness; if (fitness < currentBestFitness) @@ -540,7 +568,7 @@ skeleton newGA if (_var[col][fil] != 0 && _var[col][fil] != 1) { cout << "fitness end" << endl; - exit(EXIT_FAILURE); + //exit(EXIT_FAILURE); } } //cout << endl; @@ -552,7 +580,6 @@ skeleton newGA cout << "found sol lmao" << endl; } return fitness; - } char *Solution::to_String() const diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.req.o b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.req.o index 5870685a5daf0898db697bf8fad0813ac1df73ec..efc6ca1890255eb78b74611e83076191427cb970 100644 GIT binary patch delta 9736 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 delta 9250 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 Z5z$xfmHHBKN7C-sEGN~&<&HTb_5a#8Rk#2E diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/res/sol.txt b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/res/sol.txt index f5ffab3..9b72163 100644 --- a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/res/sol.txt +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/res/sol.txt @@ -3,14 +3,14 @@ STATISTICS OF TRIALS ------------------------------------------------------------------ -1 14000 51100 1960 19 11244 56560 -2 14200 56400 1460 14 7515 52727 -3 9000 55200 2460 24 10842 44523 -4 12200 56400 2060 20 8742 43456 -5 11000 52200 9660 96 48456 50138 -6 15100 54300 3960 39 17263 47436 -7 14400 52200 1760 17 12878 56495 -8 18100 63500 1960 19 8947 50044 -9 10100 51200 1260 12 5809 44501 -10 14300 58300 7560 75 34227 44742 +1 9200 59800 2600 25 27064 589222 +2 2600 63700 4300 42 21797 493408 +3 5200 58000 11400 113 52831 481602 +4 5900 59300 13900 138 83146 531894 +5 7300 52800 49400 493 287669 550838 +6 2600 54500 21500 214 115742 534893 +7 5900 58100 11000 109 60535 527605 +8 7800 58100 1900 18 10128 489493 +9 2600 58500 4400 43 27452 515218 +10 12400 61600 32900 328 184002 544424 ------------------------------------------------------------------ diff --git a/malva/inc/Mallba b/malva/inc/Mallba deleted file mode 120000 index 5cd551c..0000000 --- a/malva/inc/Mallba +++ /dev/null @@ -1 +0,0 @@ -../src \ No newline at end of file diff --git a/malva/inc/Mallba/Makefile b/malva/inc/Mallba/Makefile new file mode 100644 index 0000000..b6d64fb --- /dev/null +++ b/malva/inc/Mallba/Makefile @@ -0,0 +1,14 @@ +include ../environment + +OBJS = States.o netstream.o + +all: $(OBJS) + +States.o: States.cc States.hh + $(CXX) $(CPPFLAGS) States.cc -c + +netstream.o: netstream.cc netstream.hh + $(CXX) $(CPPFLAGS) netstream.cc -c + +clean: + rm -f *.o *~ *% diff --git a/malva/inc/Mallba/Matrix.hh b/malva/inc/Mallba/Matrix.hh new file mode 100644 index 0000000..cc30ae7 --- /dev/null +++ b/malva/inc/Mallba/Matrix.hh @@ -0,0 +1,337 @@ +/***************************************************************************** +*** *** +*** Este fichero decribe el template Matrix, para el manejo de matrices. *** +*** Tambien permite el manejo de vectores, los que trata como matrices cuya*** +*** primera dimension es 1. *** +*** *** +*****************************************************************************/ +#ifndef _MATRIX +#define _MATRIX + +#include "Messages.h" +#include <assert.h> + +template <class T> class Matrix +{ + private: + T *_matrix; + T nulo,neutro,inverso; + int _dimX,_dimY; + + public: + Matrix() + { + _dimX = _dimY = 0; + _matrix = NULL; + } + + Matrix(const int x,const int y,const T nulo = 0.0,const T neutro = 1.0,const T inverso = -1.0) + { + assert(x >= 1); + assert(y >= 1); + + int k = 0; + + _dimX = x; + _dimY = y; + + this->nulo = nulo; + this->neutro = neutro; + this->inverso = inverso; + + _matrix = new T [_dimX*_dimY]; + if(!_matrix) show_message(7); + + for(int i = 0; i < x; i++) + { + for(int j = 0; j < y ; j++) + { + _matrix[k] = (i!=j?nulo:neutro); + k++; + } + + } + } + + Matrix(const int y,const T nulo = 0.0,const T neutro = 1.0,const T inverso = -1.0) + { + assert(y >= 1); + + _dimX = 1; + _dimY = y; + + this->nulo = nulo; + this->neutro = neutro; + this->inverso = inverso; + + _matrix = new T [_dimY]; + if(!_matrix) show_message(7); + + _matrix[0] = neutro; + for(int j = 1; j < y ; j++) + _matrix[j] = nulo; + } + + Matrix(const Matrix<T> &m) + { + + _dimX = m.dimX(); + _dimY = m.dimY(); + + nulo = m.nulo; + neutro = m.neutro; + inverso = m.inverso; + + _matrix = new T [_dimX*_dimY]; + if(!_matrix) show_message(7); + + for(int i = 0; i < (_dimX*_dimY); i++) + { + _matrix[i] = m[i]; + } + } + + + ~Matrix() + { + remove(); + } + + T &operator()(const int x,const int y) const + { + if((x >= _dimX) || (y >= _dimY)) + show_message(14); + + return (T&)(*(_matrix + (x*_dimX) + y)); + } + + T &operator[](const int y) const + { + if(y >= (_dimX*_dimY)) + show_message(14); + + return (T&)(*(_matrix + y)); + } + + T &operator()(const int y) const + { + if(y >= (_dimX*_dimY)) + show_message(14); + + return (T&)(*(_matrix + y)); + } + + Matrix<T> &operator=(const Matrix<T> &m) + { + remove(); + + _dimX = m.dimX(); + _dimY = m.dimY(); + + _matrix = new T [_dimX*_dimY]; + if(!_matrix) show_message(7); + + for(int i = 0; i < (_dimX*_dimY); i++) + { + _matrix[i] = m[i]; + } + + return (*this); + } + + bool operator==(const Matrix<T> &m) const + { + if((_dimX != m.dimX()) || (_dimY != m.dimY())) + return false; + + for(int i = 0; i < (_dimX*_dimY); i++) + if(_matrix[i] != m[i]) return false; + + return true; + } + + bool operator!=(const Matrix<T> &m) const + { + return !((*this) == m); + } + + Matrix<T> operator*(const Matrix<T> &m) + { + int x = (m.dimX()!=_dimY?0:_dimX); + int y = (x!=0?m.dimY():0); + T acum = nulo; + + Matrix<T> res(x,y); + + for(int i = 0; i < _dimX; i++) + for(int j = 0; j < m.dimY(); j++) + { + acum = nulo; + for( int k = 0; k < _dimY; k++) + acum += (*this)(i,k)* m(k,j); + res(i,j) = acum; + } + + return Matrix<T>(res); + + } + + Matrix<T> &operator*=(const Matrix<T> &m) + { + int x = (m.dimX()!=_dimY?0:_dimX); + int y = (x!=0?0:m.dimY()); + T acum = nulo; + + Matrix<T> res(x,y); + + for(int i = 0; i < _dimX; i++) + for(int j = 0; j < m.dimY(); j++) + { + acum = nulo; + for( int k = 0; k < _dimY; k++) + acum += (*this)(i,k)*m(k,j); + res(i,j) = acum; + } + + (*this) = res; + + return (*this); + + } + + Matrix<T> operator*(const T &elem) + { + Matrix<T> res(_dimX,_dimY); + + for(int i = 0; i < (_dimX*_dimY); i++) + res[i] = _matrix[i] * elem; + + return Matrix(res); + } + + Matrix<T> &operator*=(const T &elem) + { + for(int i = 0; i < (_dimX*_dimY); i++) + _matrix[i] *= elem; + + return (*this); + } + + Matrix<T> operator+(const Matrix<T> &m) + { + int x = (m.dimX()!=_dimX?0:_dimX); + int y = (m.dimY()!=_dimY?0:_dimY); + + Matrix<T> res(x,y); + + for(int i = 0; i < (x*y); i++) + res[i] = _matrix[i] + m[i]; + + return Matrix<T>(res); + } + + Matrix<T> &operator+=(const Matrix<T> &m) + { + int x = (m.dimX()!=_dimX?0:_dimX); + int y = (m.dimY()!=_dimY?0:_dimY); + + for(int i = 0; i < (x*y); i++) + _matrix[i] += m[i]; + + return (*this); + } + + Matrix<T> operator-(const Matrix<T> &m) + { + Matrix<T> res(); + + res = m * inverso; + return (*this) + res; + } + + + Matrix<T> &operator-=(const Matrix<T> &m) + { + Matrix<T> res(); + + res = m * inverso; + (*this) += res; + + return (*this); + } + + Matrix<T> Traspuesta() + { + Matrix<T> res(_dimY,_dimX); + + for(int i = 0; i < _dimX; i++) + for(int j = 0; j < _dimY; j++) + res(j,i) = (*this)(i,j); + + return Matrix<T>(res); + } + + Matrix<T> &nula() + { + for(int i = 0; i < (_dimX*dimY); i++) + _matrix[i] = nulo; + + return (*this); + } + + Matrix<T> &identity() + { + register int k = 0; + + for(int i = 0; i < _dimX; i++) + for(int j = 0; j < _dimY; j++) + { + _matrix[k] = (i!=j?nulo:neutro); + k++; + } + + return (*this); + } + + unsigned int size() const + { + return (sizeof(T)*_dimX*_dimY); + } + + char *to_string() const + { + return (char *) _matrix; + } + + Matrix<T> &to_Matrix(char *_cadena) + { + T *ptr = (T *)_cadena; + + for(int i = 0; i < (_dimX*_dimY) ; i++) + { + _matrix[i] = *ptr; + ptr++; + } + + return (*this); + } + + + int dimX() const + { + return _dimX; + } + + int dimY() const + { + return _dimY; + } + + void remove() + { + if(_matrix != NULL) + delete [] _matrix; + } +}; + +#endif diff --git a/malva/inc/Mallba/Messages.h b/malva/inc/Mallba/Messages.h new file mode 100644 index 0000000..e46b1d8 --- /dev/null +++ b/malva/inc/Mallba/Messages.h @@ -0,0 +1,112 @@ +/*****************************************************************************/ +/*** ***/ +/*** Modificado por G.J.L.P. ***/ +/*** Añadidos nuevos mensajes que indican falta de algún ***/ +/*** Fichero de Configuración (No específico para ningún ***/ +/*** problema) o nuevos errores. ***/ +/*** ***/ +/*****************************************************************************/ + +#ifndef RLFAP_MESSAGES +#define RLFAP_MESSAGES + +#ifndef MAX_BUFFER +#define MAX_BUFFER 200 +#endif + +#include <iostream> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +using namespace std; + +inline void show_message(int value) +{ + switch (value) + { + case 1: cout << endl << "Error: number of arguments in the execution call is incorrect !!" + << endl; break; + case 2: cout << endl << "Error: It's imposible find Configuration file !!" << endl; + break; + /* Específicos de RLFAP */ + case 3: cout << endl << "Error: It is imposible find the Celar problem definition file (cst.txt) !!" + << endl; break; + case 4: cout << endl << "Error: It is imposible find the Celar domains file (dom.txt) !!" + << endl; break; + case 5: cout << endl << "Error: It is imposible find the Celar links file (var.txt) !!" + << endl; break; + case 6: cout << endl << "Error: It is imposible find the Celar constraints file (ctr.txt) !!" + << endl; break; + /* Fallos de Memoria */ + case 7: cout << endl << "Error: No avalible memory for \"malloc\" operation !!" << endl; + break; + case 8: cout << endl << "Error: in \"free\" operation !!" << endl; + break; + /* Específicos del MaxCut */ + case 9: cout << endl << "Error: It is imposible find the Maxcut file (Maxcut.txt) !!" + << endl; break; + /* Genéricos de Falta de ficheros de configuracion adicionales al mensaje 2 */ + case 10: cout << endl << "Error: It's imposible find Configuration file (Config.cfg) !!" + << endl; break; + case 11: cout << endl << "Error: It's imposible find Skeleton Configuration File (Ske.cfg) !!" + << endl; break; + case 12: cout << endl << "Error: It's imposible find Instance Problem File !!" << endl; + break; + case 13: cout << endl << "Error: It's imposible find Resultate File !!" << endl; + break; + case 14: cout << endl << "Error: Index out of Range !!" << endl; + break; + default: cout << endl << "Unkown Error !!" << endl; + } + + cout << endl << " " << endl; + exit(-1); +} + +inline void continue_question() +{ + fflush(stdout); + cout << endl << "Press any key to continue..." << endl; + fflush(stdin); + getc(stdin); +} + +inline void get_path(const char *source,char *target) +{ + int last = 0; + + for(int i = 0; i < strlen(source); i++) + { + target[i] = source[i]; + if(target[i] == '/') + last = i; + } + target[last+1] = '\0'; +} + +inline unsigned count_lines(char *file_name) // returns the number of lines of a file +{ + char line[MAX_BUFFER]; + FILE *file; + int count=0; + + if ((file=fopen(file_name,"r"))==NULL) + { + fflush(stdout); + printf("File not found !"); + } + + while (!feof(file)) + { + if (fgets(line,MAX_BUFFER,file)) count++; + else + { + fclose(file); + break; + } + } + return count; +} + +#endif diff --git a/malva/inc/Mallba/Rarray.h b/malva/inc/Mallba/Rarray.h new file mode 100644 index 0000000..5d1a1c2 --- /dev/null +++ b/malva/inc/Mallba/Rarray.h @@ -0,0 +1,145 @@ +/****************************************************************************** +*** *** +*** Template para el manejo dinámico de arrays *** +*** Añadido métodos para invertir todo o parte del array. *** +*** *** +******************************************************************************/ + +#ifndef ARRAY_INC +#define ARRAY_INC 1 +#include <iostream> +#include <assert.h> + +using namespace std; + +template<class E1> class Rarray +{ + private: + E1 *first; + int count; + + public: + Rarray() + { + first = NULL; + count = 0; + } + + ~Rarray() + { + remove(); + } + + E1* get_first() const + { + return first; + } + + void message_a(int cod) const + { + switch (cod) + { + case 1: cout << endl << "The size of array must be upper that 0 !!!" ; + } + } + + Rarray(const int size_a) + { + if (size_a<0) message_a(1); + first = new E1[size_a]; + count=size_a; + } + + void remove() + { + if (count!=0) + delete [] first; + } + + int size() const + { + return count; + } + + E1& operator[](int pos) const + { + return (E1&)(*(first + pos)); + } + + friend ostream& operator<< (ostream& os,const Rarray<E1>& a) + { + for (int i=0;i<a.size();i++) + os << endl << a[i]; + return os; + } + + Rarray<E1>& operator=(const Rarray<E1>& source) + { + remove(); + count = source.size(); + first = new E1[count]; + + for (int i=0;i<count;i++) + (*this)[i] = source[i]; + + return (*this); + } + + + Rarray<E1>& invert() + { + return invert(0,count-1); + } + + Rarray<E1>& invert(const int pos1, const int pos2) + { + int max,min,half,i,j; + E1 aux; + + if(pos1 > pos2) + { + max = pos1; + min = pos2; + } + else + { + max = pos2; + min = pos1; + } + + assert((min > 0) || (min < count-1)); + half = ((max-min)/2) + 1; + + for(i = min,j=max; i< half; i++,j--) + { + aux = first[min]; + first[min] = first[max]; + first[max] = aux; + } + + return (*this); + } + + Rarray<E1>& sort(int (*comp)(const E1 &,const E1 &)) + { + E1 aux; + int j; + + for (int i=1; i < count ; i++) + { + aux = first[i]; + j = i - 1; + while ( (comp(aux,first[j])) && (j >= 0) ) + { + first[j+1]= first[j]; + j--; + } + first[j+1] = aux; + } + + return (*this); + } + +}; // end of class + +#endif diff --git a/malva/inc/Mallba/Rlist.h b/malva/inc/Mallba/Rlist.h new file mode 100644 index 0000000..f561d0b --- /dev/null +++ b/malva/inc/Mallba/Rlist.h @@ -0,0 +1,415 @@ +/****************************************************************************** +*** *** +*** Este template sirve para el manejo de listas din�micas *** +*** *** +******************************************************************************/ + +#ifndef LIST_INC +#define LIST_INC 1 +#include <iostream> +#include <stdlib.h> +#include <Messages.h> + +using namespace std; + +template<class E> class Rlist_item +{ + public: + E *useful_data; // pointer to the structure stored in the list + Rlist_item<E> *next; + Rlist_item<E> *previous; + + Rlist_item(E& new_data) + { + useful_data=&new_data; + next=NULL; + previous=NULL; + } + + Rlist_item(E *new_data) + { + useful_data=new_data; + next=NULL; + previous=NULL; + } + + ~Rlist_item() + { + } + + Rlist_item<E>& next_item() + { + return *(next); + } + + Rlist_item<E>& previous_item() + { + return *(previous); + } + + bool is_last() + { + return (next==NULL); + } + + bool is_first() + { + return (previous==NULL); + } + + E& data() + { + return *(useful_data); + } +}; + +template<class E> class Rlist +{ + private: + Rlist_item<E> *first; // first item in the list + Rlist_item<E> *last; // last item un the list + int count; // number of items in the list + + public: + // constructor + Rlist() + { + first=NULL; + last=NULL; + count=0; + } + + // destructor + ~Rlist() + { + remove(); + } + + // Return the size of the list + int size() const + { return count; } + + // Go back to the initial state of the list + void reset() + { + first=NULL; + last=NULL; + count=0; + } + + // Add a item at the final of the list + Rlist<E>& append(E& new_item) + { + Rlist_item<E> *new_Rlist_item=new Rlist_item<E>(new_item); + if (first==NULL) + { + first=new_Rlist_item; + new_Rlist_item->next=NULL; + new_Rlist_item->previous=NULL; + } + else + { + last->next=new_Rlist_item; + new_Rlist_item->previous=last; + } + last=new_Rlist_item; + count++; + return *this; + } + + Rlist<E>& append(E *new_item) + { + append(*new_item); + return (*this); + } + + // Add a item in a position ( pos ) of the list + Rlist<E>& add_pos(E& new_item, const int pos) + { + if (pos==size()-1) + return append(new_item); + + if (pos==-1) + return add(new_item,NULL); + else + return add(new_item,get_at(pos).useful_data); + } + + // Add a item in the list in the position next to "previous item" + Rlist<E>& add(E& new_item,E *previous_item) + { + if (first==NULL) + return append(new_item); + + Rlist_item<E> *new_Rlist_item=new Rlist_item<E>(new_item); + + if (previous_item==NULL) // Add the item like the first of the list + { + new_Rlist_item->next=first; + new_Rlist_item->previous=NULL; + first->previous=new_Rlist_item; + first=new_Rlist_item; + } + else + { + int previous_position=get_position(*previous_item); + if (previous_position==-1) return(*this); + Rlist_item<E> *previous_Rlist_item = &( get_at(previous_position)); + new_Rlist_item->next=previous_Rlist_item->next; + new_Rlist_item->previous=previous_Rlist_item; + if (previous_Rlist_item->next!=NULL) + (previous_Rlist_item->next)->previous=new_Rlist_item; + else last=new_Rlist_item; + previous_Rlist_item->next=new_Rlist_item; + } + count++; + return *this; + } + + // Return a pointer to the first item of the list + Rlist_item<E> *get_first() const + { return first; } + + // Assign a item like the first item in the list + void set_first(Rlist_item<E> *new_first) + { first=new_first; } + + // Return a pointer to the last item of the list + Rlist_item<E> *get_last() const + { return last; } + + // Assign a item like the last item in the list + void set_last(Rlist_item<E> *new_last) + { last=new_last; } + + // Return the item at position "pos" + E& operator[](int pos) const + { + return *(get_at(pos).useful_data); + } + + // Return the Rlist_item at position "pos" + Rlist_item<E>& get_at(int pos) const + { + Rlist_item<E> *present=first; + for (int k=0;k<size();k++) + if (k==pos) return *present; + else present=present->next; + } + + // Return the item position in the list + int get_position(const E& item) const // probado + { + Rlist_item<E> *present=first; + int i=0; + + while(present!=NULL) + { + if (present->useful_data==&item) return i; + i++; + present=present->next; + } + return -1; // the object has not been found + } + + // Delete a item of the list + Rlist<E>& delete_item(E& item) + { + int position = get_position(item); + + if (position==-1) return *this; + Rlist_item<E> *present=&(get_at(position)); + + if (&item==first->useful_data) // is the first + { + if (&item==last->useful_data) + { + delete(first->useful_data); + delete(first); + first=NULL; + last=NULL; + count=0; + } + else + { + first=first->next; + first->previous=NULL; + delete(present->useful_data); + delete(present); + count--; + } + } + else + { + if (&item==last->useful_data) + { + last=present->previous; + last->next=NULL; + delete(present->useful_data); + delete(present); + count--; + } + else + { + (present->next)->previous=present->previous; + (present->previous)->next=present->next; + delete(present->useful_data); + delete(present); + count--; + } + } + return *this; + } + + // Delete a item of the list without free the useful_data + Rlist<E>& delete_item_1(E& item) + { + int position = get_position(item); + + if (position==-1) return *this; + Rlist_item<E> *present=&(get_at(position)); + + if (&item==first->useful_data) // is the first + { + if (&item==last->useful_data) + { + delete(first); + first=NULL; + last=NULL; + count=0; + } + else + { + first=first->next; + first->previous=NULL; + delete(present); + count--; + } + } + else + { + if (&item==last->useful_data) + { + last=present->previous; + last->next=NULL; + delete(present); + count--; + } + else + { + (present->next)->previous=present->previous; + (present->previous)->next=present->next; + delete(present); + count--; + } + } + return *this; + } + + // Delete item at position "pos" + Rlist<E>& delete_item_by_position(const int pos) + { return delete_item(*(get_at(pos).useful_data)); } + + // Delete the last item in the list + Rlist<E>& delete_last() + { return delete_item(*(last->useful_data)); } + + // delete all items in the list + Rlist<E>& remove() + { + Rlist_item<E> *next,*present=first; + while (present!=NULL) + { + next=present->next; + delete(present->useful_data); + delete(present); + present=next; + } + first=NULL; + last=NULL; + count=0; + return *this; + } + + // Join a new list to this list + Rlist<E>& join(Rlist<E>& new_list) + { + if (new_list.size()==0) + return *this; + + if (first==NULL) + { + first=new_list.get_first(); + last=new_list.get_last(); + } + else + { + last->next=new_list.get_first(); + (new_list.get_first())->previous=last; + last = new_list.get_last(); + } + count += new_list.size(); + new_list.reset(); + return *this; + } + + // Show items of the list + friend ostream& operator<<(ostream& os, const Rlist<E>& list) + { + Rlist_item<E> *present=list.get_first(); + if (list.get_first()==NULL) os << endl << "THE LIST IS EMPTY !!"; + while (present!=NULL) + { + os << endl << (*(present->useful_data)); + // Falta el operador para stat. + // (habra que ver) + present=present->next; + } + return os; + } + + // Copy the list passed + Rlist<E>& operator=(const Rlist<E>& source) + { + E *new_item; + remove(); + if (source.first==NULL && source.last==NULL) + { + first=NULL; + last=NULL; + count=0; + } + else + { + for (int i=0;i<source.size();i++) + { + if ((new_item=(E *)malloc(sizeof(E)))==NULL) + show_message(7); + (*new_item)=*(source.get_at(i).useful_data); + append(*new_item); + } + } + return *this; + } + + // Invert the order of items in the list + Rlist<E>& invert() + { + Rlist_item<E> *present,*interchange; + + present=first; + + for (int i=0;i<size();i++) + { + interchange=present->next; + present->next=present->previous; + present->previous=interchange; + present=interchange; + } + interchange=first; + first=last; + last=interchange; + return (*this); + } +}; // end of class +#endif diff --git a/malva/inc/Mallba/States.cc b/malva/inc/Mallba/States.cc new file mode 100644 index 0000000..f36d197 --- /dev/null +++ b/malva/inc/Mallba/States.cc @@ -0,0 +1,228 @@ +/****************************************************************************** + Modified by Carlos Cotta Porras + April 2001 + + Modified by G.J.L.P +******************************************************************************/ + + +#include <string.h> +#include "States.hh" + +// Methods of class State_Vble + + // constructors + State_Vble ::State_Vble () + { + name=NULL; + nitems=0; + length=0; + content=NULL; + } + + State_Vble ::State_Vble (const char *st_name) + { + name=strdup(st_name); + nitems=0; + length=0; + content=NULL; + } + + State_Vble::State_Vble (const char *st_name,StateCenter& sc) + { + name=strdup(st_name); + nitems=0; + length=0; + content=NULL; + sc.add(*this); + } + + State_Vble ::State_Vble (const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length) + { + name=strdup(st_name); + nitems=0; + length=0; + content=NULL; + set_contents(new_contents,new_nitems,new_length); + } + + State_Vble ::State_Vble (const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length,StateCenter& sc) + { + name=strdup(st_name); + nitems=0; + length=0; + content=NULL; + set_contents(new_contents,new_nitems,new_length); + sc.add(*this); + } + + + // Set the name of a state vble. + void State_Vble ::set_name (const char* st_name) // Set the name of a state vble. + { + if (name!=NULL) + free(name); + name=strdup(st_name); + } + + // Get the name of a state vble. + char* State_Vble ::get_name () const // Get the name of a state vble. + { + return name; + } + + // Number of basic items + unsigned long State_Vble ::get_nitems() const // Number of basic items + { + return nitems; + } + + // Get the total number of bytes + unsigned long State_Vble ::get_length () const // Get the total number of bytes + { + return length; + } + + // Fill up a state vble. + void State_Vble ::set_contents (const char *new_contents, unsigned long new_nitems, unsigned long new_length) + { + if (content!=NULL) + free(content); + content=(char *)malloc(new_nitems * new_length); + memcpy(content,new_contents,(new_nitems*new_length)); + nitems=new_nitems; + length=new_length; + } + + // Obtain the contents of a state vble. + void *State_Vble ::get_contents (char *read_contents, unsigned long& read_nitems, unsigned long& read_length) const + { + memcpy(read_contents,content,nitems * length); + read_nitems=nitems; + read_length=length; + return NULL; + } + + ostream& operator<< (ostream& os,const State_Vble& st) + { + os << endl << st.name + << endl << st.nitems + << endl << st.length + << endl << st.content; + + return os; + } + + State_Vble ::~State_Vble () + { + free(content); + free(name); + } + +// Methods of class StateCenter + + StateCenter::StateCenter():state_variables() + {} + + // searchs a state variable + State_Vble *StateCenter::find(const char *st_name) const + { + Rlist_item<State_Vble> *current_state=state_variables.get_first(); + + for (int i=0;i<state_variables.size();i++) + { + if (!(strcmp(current_state->data().get_name(),st_name))) + return &(current_state->data()); + current_state=¤t_state->next_item(); + } + return NULL; + } + + // Add one state variable + void StateCenter::add(State_Vble& st) + { + State_Vble *found_state=find(st.get_name()); + if (found_state==NULL) + state_variables.append(st); + else + cout << endl << "You are trying to introduce a state variable that is yet used in the skeleton !!" << st.get_name(); + } + + void StateCenter::add(State_Vble *st) + { + State_Vble *found_state=find(st->get_name()); + if (found_state==NULL) + state_variables.append(*st); + else + cout << endl << "You are trying to introduce a state variable that is yet used in the skeleton !!" << st->get_name(); + } + + // Remove one state variable + void StateCenter::remove(const char* st_name) + { + State_Vble *found_state=find(st_name); + if (found_state!=NULL) + state_variables.delete_item_1(*found_state); + } + + // Update the contents of one vble. + void StateCenter::update(const char* st_name, const State_Vble& st) const // Update the contents of one vble. + { + State_Vble *found_state=find(st_name); + if (found_state!=NULL) + { + char *a=(char *)malloc(found_state->get_nitems() * found_state->get_length()); + unsigned long nitems,length; + st.get_contents(a,nitems,length); + found_state->set_contents(a,nitems,length); + free(a); + } + } + + // Get a vble. with a given name + State_Vble& StateCenter::get(const char* st_name) const // Get a vble. with a given name + { + State_Vble *found_state=find(st_name); + return *found_state; + } + + // Allows an easy iterated extraction + State_Vble* StateCenter::get_next(const State_Vble& st) const + { + State_Vble *found_state=find(st.get_name()); + if (found_state==NULL) return NULL; + if ( state_variables.get_at(state_variables.get_position(*found_state)).is_last()) return NULL; + else return &(state_variables.get_at(state_variables.get_position(*found_state)).next_item().data()); + } + + // returns the number of state variables + unsigned int StateCenter::size() const + { + return state_variables.size(); + } + + // Obtain the contents of a state vble. of name st_name + void StateCenter::get_contents_state_variable(const char *st_name,char *read_contents, unsigned long& read_nitems, unsigned long& read_length) const + { + get(st_name).get_contents(read_contents,read_nitems,read_length); + } + + // Fill up a state vble.of name st_name + void StateCenter::set_contents_state_variable(const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length) const + { + get(st_name).set_contents(new_contents,new_nitems,new_length); + } + + void StateCenter::removeAll() + { + while(state_variables.get_first()) + { + Rlist_item<State_Vble>* v = state_variables.get_first(); + remove(v->useful_data->get_name()); + } + } + + StateCenter::~StateCenter() + { + removeAll(); + } diff --git a/malva/inc/Mallba/States.hh b/malva/inc/Mallba/States.hh new file mode 100644 index 0000000..e3a215f --- /dev/null +++ b/malva/inc/Mallba/States.hh @@ -0,0 +1,64 @@ +/******************************************************************************************************** +*** *** +*** Class StateCenter: Pool of state variables for skeletons *** +*** *** +*** Class State_Vble: State Variable of a skeleton *** +*** *** +*********************************************************************************************************/ + +#ifndef STATE_CENTER +#define STATE_CENTER 1 + +#include "Rlist.h" +#include <iostream> + +class StateCenter; + +class State_Vble +{ + private: + char *name; + unsigned long nitems; + unsigned long length; + char *content; + + public: + // constructors + State_Vble (); + State_Vble (const char *st_name); + State_Vble (const char *st_name,StateCenter& sc); + State_Vble (const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length); + State_Vble (const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length,StateCenter& sc); + + void set_name (const char* st_name); // Set the name of a state vble. + char* get_name () const; // Get the name of a state vble. + unsigned long get_nitems() const; + unsigned long get_length () const; // Get the total number of bytes + void set_contents (const char *new_contents, unsigned long new_nitems, unsigned long new_length); // Fill up a state vble. + void *get_contents (char *read_contents, unsigned long& read_nitems, unsigned long& read_length) const; // Obtain the contents of a state vble. + friend ostream& operator<< (ostream& os,const State_Vble& st); + ~State_Vble (); +}; + +class StateCenter +{ + private: + Rlist<State_Vble> state_variables; + + public: + StateCenter(); + State_Vble *find(const char *st_name) const; // search a state variable + void add(State_Vble& st); // Add one state variable + void add(State_Vble *st); // Add one state variable + void remove(const char* st_name); // Remove one state variable + void removeAll(); // Removes all variables + void update(const char* st_name, const State_Vble& st) const; // Update the contents of one vble. + State_Vble& get(const char* st_name) const; // Get a vble. with a given name + State_Vble* get_next(const State_Vble& st) const; // Allows an easy iterated extraction + unsigned int size() const; // returns the number of state variables + void get_contents_state_variable(const char *st_name,char *read_contents, unsigned long& read_nitems, unsigned long& read_length) const; // Obtain the contents of a state vble. of name st_name + void set_contents_state_variable(const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length) const; // Fill up a state vble.of name st_name + ~StateCenter(); +}; + +#endif diff --git a/malva/inc/Mallba/States.o b/malva/inc/Mallba/States.o new file mode 100644 index 0000000000000000000000000000000000000000..f5e95c8928fb22e26363c12820d0e56fd98709d2 GIT binary patch literal 12968 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 literal 0 HcmV?d00001 diff --git a/malva/inc/Mallba/mallba.hh b/malva/inc/Mallba/mallba.hh new file mode 100644 index 0000000..e022ff8 --- /dev/null +++ b/malva/inc/Mallba/mallba.hh @@ -0,0 +1,26 @@ +/***************************************************************************** +*** *** +*** Este fichero hace algunas declaraciones y declara algunos tipos comu- *** +*** nes a todos los algoritmos implementados. *** +*** *** +*****************************************************************************/ + +#ifndef INC_mallba_hh +#define INC_mallba_hh + +#define skeleton namespace +#define requires +#define provides +#define hybridizes(x) +#define inherits typedef +#define as + +enum Direction { minimize=-1,maximize=1}; + +extern const double plus_infinity; +extern const double minus_infinity; + +#define false 0 +#define true 1 + +#endif diff --git a/malva/inc/Mallba/netstream.cc b/malva/inc/Mallba/netstream.cc new file mode 100644 index 0000000..932e89e --- /dev/null +++ b/malva/inc/Mallba/netstream.cc @@ -0,0 +1,380 @@ +/*************************************************************************** + *** netstream.cc *** + *** v1.6 - July 2001 *** + ** *** + *** v1.5 - March 2001 *** + *** v1.0 - November 2000 *** + *** *** + *** v1.5 extends v1.0: *** + *** .- Changes metods init() and finalize() to be static *** + *** .- Incorporates process group management *** + *** .- Do not consider LEDA anymore *** + *** .- Contains a method "int my_pid()" for easy invokations *** + *** .- Adds "unsigned" and "long double" input/output *** + *** *** + *** v1.6 extends v1.5: *** + ** .- Internal in/out buffers for packed separated *** + *** *** + *** Communication services for LAN/WAN use following the message *** + *** passing paradigm. *** + *** STREAM C++ VERSION *** + *** MPI implementation *** + *** Developed by Erique Alba *** + ***************************************************************************/ +#include "netstream.hh" +// Default constructor +NetStream::NetStream() +{ + this->reset(); // Reset to default values member variables + packin_buffer = new char[MAX_PACK_BUFFER_SIZE]; + packout_buffer = new char[MAX_PACK_BUFFER_SIZE]; +} +// Init the underlying communication library (MPI) +NetStream::NetStream (int argc, char ** argv) +{ + init(argc,argv); + this->reset(); + packin_buffer = new char[MAX_PACK_BUFFER_SIZE]; + packout_buffer = new char[MAX_PACK_BUFFER_SIZE]; +} +// Default destructor +NetStream::~NetStream() +{ + delete [] packin_buffer; delete [] packout_buffer; + this->reset(); +} +// Give default values to member variables +void NetStream::reset(void) +{ + default_target = default_source = 0; + pack_in_progress = false; + packin_index = packout_index = 0; + pending_input_packet = false; + pack_in = pack_out = false; + broadcast = false; + my_communicator = MPI_COMM_WORLD; +} +// Init the communication system. Invoke it only ONCE +void NetStream::init(int argc, char** argv) +{ + static bool system_up = false; // Is MPI already running? + if (!system_up) + { MPI_Init(&argc,&argv); + system_up = true; + } +} +// Shutdown the communication system. Invoke it ONCE +void NetStream::finalize(void) +{ + MPI_Finalize(); // Unconditional Finalization +} +// BASIC INPUT/OUTPUT SERVICES +// =================================================================================== + +NetStream& NetStream::operator>> (bool& d) +{ rcv(&d,1,NET_BOOL,default_source); return(*this); } + +NetStream& NetStream::operator<< (bool d) +{ send(&d,1,NET_BOOL,default_target); return(*this); } +NetStream& NetStream::operator>> (char& d) +{ rcv(&d,1,NET_CHAR,default_source); return(*this); } +NetStream& NetStream::operator<< (char d) +{ send(&d,1,NET_CHAR,default_target); return(*this); } +NetStream& NetStream::operator>> (short& d) +{ rcv(&d,1,NET_SHORT,default_source); return(*this); } +NetStream& NetStream::operator<< (short d) +{ send(&d,1,NET_SHORT,default_target); return(*this); } +NetStream& NetStream::operator>> (int& d) +{ rcv(&d,1,NET_INT,default_source); return(*this); } +NetStream& NetStream::operator<< (int d) +{ send(&d,1,NET_INT,default_target); return(*this); } +NetStream& NetStream::operator>> (long& d) +{ rcv(&d,1,NET_LONG,default_source); return(*this); } +NetStream& NetStream::operator<< (long d) +{ send(&d,1,NET_LONG,default_target); return(*this); } +NetStream& NetStream::operator>> (float& d) +{ rcv(&d,1,NET_FLOAT,default_source); return(*this); } +NetStream& NetStream::operator<< (float d) +{ send(&d,1,NET_FLOAT,default_target); return(*this); } +NetStream& NetStream::operator>> (double& d) +{ rcv(&d,1,NET_DOUBLE,default_source); return(*this); } +NetStream& NetStream::operator<< (double d) +{ send(&d,1,NET_DOUBLE,default_target); return(*this); } +NetStream& NetStream::operator>> (char* d) +{ rcv(d,MAX_MSG_LENGTH,NET_CHAR,default_source); return(*this); } +NetStream& NetStream::operator<< (char* d) +{ send(d,strlen(d)+1,NET_CHAR,default_target); return(*this); } +NetStream& NetStream::operator>> (void* d) +{ rcv(d,MAX_MSG_LENGTH,NET_CHAR,default_source); return(*this); } +NetStream& NetStream::operator<< (void* d) +{ send(d,strlen((char*)d)+1,NET_CHAR,default_target); return(*this); } +// Extended data types from version 1.5 on +NetStream& NetStream::operator>> (unsigned char& d) +{ rcv(&d,MAX_MSG_LENGTH,NET_UNSIGNED_CHAR,default_source);return(*this); } + +NetStream& NetStream::operator<< (unsigned char d) +{ send(&d,1,NET_UNSIGNED_CHAR,default_target); return(*this); } +NetStream& NetStream::operator>> (unsigned short int& d) +{ rcv(&d,MAX_MSG_LENGTH,NET_UNSIGNED_SHORT,default_source);return(*this); } +NetStream& NetStream::operator<< (unsigned short int d) +{ send(&d,1,NET_UNSIGNED_SHORT,default_target); return(*this); } +NetStream& NetStream::operator>> (unsigned int& d) +{ rcv(&d,MAX_MSG_LENGTH,NET_UNSIGNED,default_source); return(*this); } + +NetStream& NetStream::operator<< (unsigned int d) +{ send(&d,1,NET_UNSIGNED,default_target); return(*this); } +NetStream& NetStream::operator>> (unsigned long int& d) +{ rcv(&d,MAX_MSG_LENGTH,NET_UNSIGNED_LONG,default_source);return(*this); } + +NetStream& NetStream::operator<< (unsigned long int d) +{ send(&d,1,NET_UNSIGNED_LONG,default_target); return(*this); } +NetStream& NetStream::operator>> (long double& d) +{ rcv(&d,MAX_MSG_LENGTH,NET_LONG_DOUBLE,default_source); return(*this); } + +NetStream& NetStream::operator<< (long double d) +{ send(&d,1,NET_LONG_DOUBLE,default_target); return(*this); } +// SET-GET TARGET AND SOURCE PROCESSES +NetStream& __set_target(NetStream& n, const int p) { return n._set_target(p); } +NetStream& NetStream::_set_target(const int p) +{ assert(p>=0); default_target = p; return (*this); } +NetStream& __get_target(NetStream& n, int* p) { return n._get_target(p); } +NetStream& NetStream::_get_target(int* p) +{ *p = default_target; return (*this); } +NetStream& __set_source(NetStream& n, const int p) { return n._set_source(p); } +NetStream& NetStream::_set_source(const int p) +{ /*assert(p>=0);*/ default_source = p; return (*this); } +NetStream& __get_source(NetStream& n, int* p) { return n._get_source(p); } +NetStream& NetStream::_get_source(int* p) +{ *p = default_source; return (*this); } +// Get the number of processes involved in the communications +int NetStream::pnumber(void) +{ int numprocs, rvalue; + rvalue = MPI_Comm_size(my_communicator,&numprocs); + assert(rvalue==MPI_SUCCESS); + return numprocs; +} +// MANIPULATORS: SYNCHRONIZATION AND PACKING SERVICES +// =================================================================================== +// Get the process ID [0, 1, 2, ...] fro the calling process +NetStream& __my_pid(NetStream& n, int* pid) +{ + return n._my_pid(pid); +} +NetStream& NetStream::_my_pid(int* pid) +{ + MPI_Comm_rank(my_communicator,pid); + return (*this); +} +// EASY access to rank - Returns the process ID of the calling process +int NetStream::my_pid(void) +{ int pid; + this->_my_pid(&pid); + return pid; +} +// Sit and wait until all processes are in the same barrier +// Can be used as a MANIPULATOR +NetStream& barrier(NetStream& n) +{ + return n._barrier(); +} +NetStream& NetStream::_barrier(void) +{ int status; + status = MPI_Barrier(my_communicator); + assert(status==MPI_SUCCESS); + return (*this); +} +// Wait for an incoming message in any input stream +NetStream& NetStream::_wait(const int stream_type) // class +{ + int rvalue; + MPI_Status status; + assert(stream_type==regular||stream_type==packed||stream_type==any); + if( ((stream_type==packed) || (stream_type==any) )&& (pending_input_packet) ) + //if( (stream_type==packed) && (pending_input_packet) ) + return (*this); // wait befor packet_begin when already received + rvalue = MPI_Probe(default_source,stream_type,my_communicator,&status); + assert(rvalue==MPI_SUCCESS); + return (*this); +} + +NetStream& NetStream::_wait2(const int stream_type, int& tipo) // class +{ + int rvalue; + MPI_Status status; + assert(stream_type==regular||stream_type==packed||stream_type==any); + if( ((stream_type==packed) || (stream_type==any) )&& (pending_input_packet) ) + //if( (stream_type==packed) && (pending_input_packet) ) + return (*this); // wait befor packet_begin when already received + rvalue = MPI_Probe(default_source,stream_type,my_communicator,&status); + assert(rvalue==MPI_SUCCESS); + if (status.MPI_SOURCE == 0){ + tipo = 1; + } + return (*this); +} +NetStream& __wait(NetStream& n, const int stream_type) // helper +{ + return n._wait(stream_type); +} +// Marks the beginning of a packed information +NetStream& pack_begin(NetStream& n) +{ + return n._pack_begin(); +} +NetStream& NetStream::_pack_begin(void) +{ + int rvalue=MPI_SUCCESS; + MPI_Status status; + if(!pack_in_progress) + { pack_in_progress = true; + packin_index = packout_index = 0; + pack_in = false; + pack_out = false; + if (!pending_input_packet) + { _probe(packed,pending_input_packet); + if(pending_input_packet) + rvalue = MPI_Recv(packin_buffer, MAX_PACK_BUFFER_SIZE, NET_PACKED, + default_source, PACKED_STREAM_TAG, my_communicator, &status); + } + } + return (*this); +} +// Marks the end of a packed and flush it to the net +NetStream& pack_end(NetStream& n) +{ + return n._pack_end(); +} +NetStream& NetStream::_pack_end(void) +{ + int rvalue, mypid; + if (pack_in_progress) + { + if(pack_out) + { if(broadcast) // Packet broadcast + { broadcast = false; + _my_pid(&mypid); + rvalue = MPI_Bcast(packout_buffer,packout_index,NET_PACKED, + mypid,my_communicator); + assert(rvalue==MPI_SUCCESS); + } + else + { rvalue = MPI_Send(packout_buffer, packout_index, NET_PACKED, + default_target,PACKED_STREAM_TAG,my_communicator); + assert(rvalue==MPI_SUCCESS); + } + } + pack_in_progress = false; + pack_in = pack_out = false; + packin_index = packout_index = 0 ; + } + return (*this); +} +// Check whether there are awaiting data +NetStream& probe(NetStream& n, const int stream_type, int& pending) +{ + return n._probe(stream_type, pending); +} +NetStream& NetStream::_probe(const int stream_type, int& pending) +{ + MPI_Status status; + int rvalue; + assert(stream_type==regular||stream_type==packed||stream_type==any); + rvalue = MPI_Iprobe(default_source,stream_type,my_communicator,&pending,&status); + assert(rvalue==MPI_SUCCESS); + return (*this); +} +// Broadcast a message to all the processes +NetStream& broadcast(NetStream& n) +{ + return n._broadcast(); +} +NetStream& NetStream::_broadcast(void) +{ + broadcast = true; + return (*this); +} +// PRIVATE SERVICES +// =================================================================================== +// Usually, the length is the number of bytes for every net type +// When packing we must use in the pack calls the numer of items (length divided by type size) +// Any char is encoded with a leading field of length +void NetStream::send(void* d, const int len, const NET_TYPE type, const int target) +{ + int rvalue = MPI_SUCCESS, length = len; + // PACKING SERVICE + if(pack_in_progress) + { + pack_out = true; + assert(pack_out!=pack_in); // Error condition + if(type==NET_CHAR) + send(&length,sizeof(NET_INT),NET_INT,target); // Recursive call to store string length + else + length = 1; + rvalue = MPI_Pack(d,length,type,packout_buffer,MAX_PACK_BUFFER_SIZE,&packout_index,my_communicator); + assert(rvalue==MPI_SUCCESS); + return; + } + if(broadcast) // Regular broadcast, packed broadcast managed in _pack_end() + { int mypid; + + broadcast = false; + _my_pid(&mypid); + rvalue = MPI_Bcast(d,len,type,mypid,my_communicator); + assert(rvalue==MPI_SUCCESS); + return; + } + rvalue = MPI_Send(d,len,type,target,REGULAR_STREAM_TAG,my_communicator); + assert(rvalue==MPI_SUCCESS); +} +void NetStream::rcv (void* d, const int len, const NET_TYPE type, const int source) +{ MPI_Status status; + int rvalue = MPI_SUCCESS, length=len; + if(pack_in_progress) + { +// if(!pack_in && !pending_input_packet) +// rvalue = MPI_Recv(packin_buffer, MAX_PACK_BUFFER_SIZE, NET_PACKED, +// default_source, PACKED_STREAM_TAG, my_communicator, &status); + pack_in = true; + pending_input_packet = false; + assert(pack_out!=pack_in); + if(type==NET_CHAR) + rcv(&length,sizeof(NET_INT),NET_INT,source); // Gets the string length + else + length = 1; + rvalue = MPI_Unpack(packin_buffer, MAX_PACK_BUFFER_SIZE, &packin_index, d, + length, type, my_communicator); + assert(rvalue==MPI_SUCCESS); + return; + } + + rvalue=MPI_Recv(d,len,type,source,REGULAR_STREAM_TAG,my_communicator,&status); + assert(status.MPI_ERROR==MPI_SUCCESS); + assert(rvalue==MPI_SUCCESS); +} +/////////////////////////////////////// GROUP MANAGEMENT //////////////////////////////// +// Set the netstream to a new communicator +void NetStream::set_communicator(NET_Comm comm) +{ + my_communicator = comm; +} +// Get the present communicator in this netstream +NET_Comm NetStream::get_communicator(void) +{ + return my_communicator; +} +// Create a new group inside the present communicator +NET_Comm NetStream::create_group(NET_Comm comm, int color, int key) +{ int rvalue; + NET_Comm newcomm; + rvalue=MPI_Comm_split(comm,color,key,&newcomm); + assert(rvalue==MPI_SUCCESS); + return newcomm; +} +// Create a bridge between local and remote MATCHING call +NET_Comm NetStream::create_inter_group(NET_Comm lcomm, int lrank, NET_Comm bcomm, int rrank, int strtype) +{ int rvalue; + NET_Comm newcomm; + rvalue=MPI_Intercomm_create(lcomm,lrank,bcomm,rrank,strtype,&newcomm); + assert(rvalue==MPI_SUCCESS); + return newcomm; +} diff --git a/malva/inc/Mallba/netstream.hh b/malva/inc/Mallba/netstream.hh new file mode 100644 index 0000000..5c24a3d --- /dev/null +++ b/malva/inc/Mallba/netstream.hh @@ -0,0 +1,161 @@ +/*************************************************************************** + *** netstream.cc *** + *** v1.6 - July 2001 *** + ** *** + *** v1.5 - March 2001 *** + *** v1.0 - November 2000 *** + *** *** + *** v1.5 extends v1.0: *** + *** .- Changes metods init() and finalize() to be static *** + *** .- Incorporates process group management *** + *** .- Do not consider LEDA anymore *** + *** .- Contains a method "int my_pid()" for easy invokations *** + *** .- Adds "unsigned" and "long double" input/output *** + *** *** + *** v1.6 extends v1.5: *** + ** .- Internal in/out buffers for packed separated *** + *** *** + *** Communication services for LAN/WAN use following the message *** + *** passing paradigm. *** + *** STREAM C++ VERSION *** + *** MPI implementation *** + *** Developed by Erique Alba *** + ***************************************************************************/ +#ifndef INC_netstream +#define INC_netstream +#include "mpi.h" +#include <assert.h> +#include <string.h> +// Class NetStream allows to define and use network streams trhough LAN and WAN +#define REGULAR_STREAM_TAG 0 // Used for tagging MPI regular messages +#define PACKED_STREAM_TAG 1 // Used for tagging MPI packet messages +#define NET_TYPE MPI_Datatype // Network allowable data types +#define NET_BOOL MPI_CHAR // Bools like chars +#define NET_CHAR MPI_CHAR +#define NET_SHORT MPI_SHORT +#define NET_INT MPI_INT +#define NET_LONG MPI_LONG +#define NET_UNSIGNED_CHAR MPI_UNSIGNED_CHAR +#define NET_UNSIGNED_SHORT MPI_UNSIGNED_SHORT +#define NET_UNSIGNED MPI_UNSIGNED +#define NET_UNSIGNED_LONG MPI_UNSIGNED_LONG +#define NET_FLOAT MPI_FLOAT +#define NET_DOUBLE MPI_DOUBLE +#define NET_LONG_DOUBLE MPI_LONG_DOUBLE +#define NET_BYTE MPI_BYTE +#define NET_PACKED MPI_PACKED +#define NET_Comm MPI_Comm +#define MAX_MSG_LENGTH 204800 // Max length of a message +#define MAX_PACK_BUFFER_SIZE 204800 // Max length of a packed message +// Help structure for manipulators having one int& argument +class NetStream; +struct smanip1c // "const int" +{ NetStream& (*f)(NetStream&, const int); // The ONE argument function + int i; // The argument + smanip1c( NetStream&(*ff)(NetStream&,const int), int ii) : f(ff), i(ii) {} // Constuctor +}; +struct smanip1 // "int*" note: references do not work! "int&" +{ NetStream& (*f)(NetStream&, int*); // The ONE argument function + int* i; // The argument + smanip1( NetStream&(*ff)(NetStream&, int*), int* ii) : f(ff), i(ii) {} // Constuctor +}; +// Tags for the available streams +const int any = MPI_ANY_TAG; // Tag value valid for any stream +const int regular = REGULAR_STREAM_TAG; // Tag value for regular stream of data +const int packed = PACKED_STREAM_TAG; // Tag value for packed stream of data +// Tags for sources +const int any_source = MPI_ANY_SOURCE; // Tag value valid for any source +class NetStream +{ + public: + NetStream (); // Default constructor + // Constructor with source integer left unchanged + NetStream (int, char **); // Init the communications + ~NetStream (); // Default destructor + static void init(int,char**); // Init the communication system. Invoke it only ONCE + static void finalize(void); // Shutdown the communication system. Invoke it ONCE + // GROUP management + void set_communicator(NET_Comm comm); // Set the netstream to a new communicator + NET_Comm get_communicator(void); // Get the present communicator in this netstream + static NET_Comm create_group(NET_Comm comm, int color, int key); // Create a new group inside the present communicator + // Create a bridge between local and remote MATCHING call + static NET_Comm create_inter_group(NET_Comm lcomm, int lrank, NET_Comm bcomm, int rrank, int strtrype); + +// BASIC INPUT SERVICES <comments> BASIC OUTPUT SERVICES +// ============================================================================================================ + NetStream& operator>> (bool& d); NetStream& operator<< (bool d); + NetStream& operator>> (char& d); NetStream& operator<< (char d); + NetStream& operator>> (short& d); NetStream& operator<< (short d); + NetStream& operator>> (int& d); NetStream& operator<< (int d); + NetStream& operator>> (long& d); NetStream& operator<< (long d); + NetStream& operator>> (float& d); NetStream& operator<< (float d); + NetStream& operator>> (double& d); NetStream& operator<< (double d); + NetStream& operator>> (char* d); /*NULL terminated*/ NetStream& operator<< (char* d); + NetStream& operator>> (void* d); /*NULL terminated*/ NetStream& operator<< (void* d); + // Extended data types from version 1.5 on + NetStream& operator>> (unsigned char& d); NetStream& operator<< (unsigned char d); + NetStream& operator>> (unsigned short int& d); NetStream& operator<< (unsigned short int d); + NetStream& operator>> (unsigned int& d); NetStream& operator<< (unsigned int d); + NetStream& operator>> (unsigned long int& d); NetStream& operator<< (unsigned long int d); + NetStream& operator>> (long double& d); NetStream& operator<< (long double d); + int pnumber(void); // Returns the number of processes + bool broadcast; // Determines whether the next sent message is for broadcasting + // Input MANIPULATORS for modifying the behavior of the channel on the fly + // NO ARGUMENTS + NetStream& operator<< (NetStream& (*f)(NetStream& n)) { return f(*this); } // NO arguments + NetStream& _barrier(void); // Sit and wait until all processes are in barrier + NetStream& _pack_begin(void); // Marks the beginning of a packed information + NetStream& _pack_end(void); // Marks the end of a packed and flush it to the net + NetStream& _probe(const int stream_type, int& pending); // Check whether there are awaiting data + NetStream& _broadcast(void); // Broadcast a message to all the processes + // ONE ARGUMENT + // "const int" + NetStream& operator<< (smanip1c m) { return m.f((*this),m.i); }// ONE int& argument constant + // "int*" + NetStream& operator<< (smanip1 m) { return m.f((*this),m.i); }// ONE int& argument + // BASIC CLASS METHODS FOR MANIPULATORS + NetStream& _my_pid(int* pid); // Returns the process ID of the calling process + NetStream& _wait(const int stream_type); // Wait for an incoming message in the specified stream + NetStream& _wait2(const int stream_type, int& tipo); + NetStream& _set_target(const int p); // Stablish "p" as the default receiver + NetStream& _get_target(int* p); // Get into "p" the default receiver + NetStream& _set_source(const int p); // Stablish "p" as the default transmitter + NetStream& _get_source(int* p); // Get into "p" the default transmitter + // AUXILIAR PUBLIC METHODS FOR ALLOWING EASY MANAGEMENTS OF NETSTREAMS + int my_pid(void); // Returns the process ID of the calling process + private: + int default_target, default_source; // Default process IDs to send-recv data to-from + bool pack_in_progress; // Defines whether a packet is being defined with "pack_begin-pack_end" + int packin_index; // Index to be used for extracting from a IN packed message - v1.6 + int packout_index; // Index to be used for adding to an OUT packed message - v1.6 + int pending_input_packet;//Is there a pending packet already read into the IN buffer? - v1.6 + char* packin_buffer; // Buffer to temporary storage of the IN packed being defined - v1.6 + char* packout_buffer; // Buffer to temporary storage of the OUT packed being defined - v1.6 + bool pack_in, pack_out; // Define whether input-output packed message is being used + void reset(void); // Reset member variables of this class + NET_Comm my_communicator; // Communicator of this netstream + void send(void* d, const int len, const NET_TYPE type, const int target); + void rcv (void* d, const int len, const NET_TYPE type, const int source); +}; // class NetStream + // MANIPULATORS (must be static or non-member methods in C++ -mpiCC only allows non-member!-) + // NO ARGUMENTS + NetStream& barrier(NetStream& n); // Sit and wait until all processes are in barrier + NetStream& broadcast(NetStream& n); // Broadcast a message to all the processes + NetStream& pack_begin(NetStream& n); // Marks the beginning of a packed information + NetStream& pack_end(NetStream& n); // Marks the end of a packed and flush it to the net + // ONE ARGUMENT + NetStream& __my_pid(NetStream& n, int* pid); // Returns the process ID of the calling process + inline smanip1 my_pid(int* pid){ return smanip1(__my_pid,pid); } // manipulator + NetStream& __wait(NetStream& n, const int stream_type);// Wait for an incoming message - helper + inline smanip1c wait(const int stream_type){ return smanip1c(__wait,stream_type); } // manipulator + NetStream& __set_target(NetStream& n, const int p); // Stablish "p" as the default receiver + inline smanip1c set_target(const int p){ return smanip1c(__set_target,p); } // manipulator + NetStream& __get_target(NetStream& n, int* p); // Get into "p" the default receiver + inline smanip1 get_target(int* p){ return smanip1(__get_target,p); } // manipulator + NetStream& __set_source(NetStream& n, const int p); // Stablish "p" as the default transmitter + inline smanip1c set_source(const int p){ return smanip1c(__set_source,p); } // manipulator + NetStream& __get_source(NetStream& n, int* p); // Get into "p" the default transmitter + inline smanip1 get_source(int* p){ return smanip1(__get_source,p); } // manipulator + // TWO ARGUMENTS - not used yet + NetStream& probe(NetStream& n, const int stream_type, int& pending); // Check whether there are awaiting data +#endif diff --git a/malva/inc/Mallba/netstream.o b/malva/inc/Mallba/netstream.o new file mode 100644 index 0000000000000000000000000000000000000000..fb40ece360fb739d83d40beffbf1b01c031a15aa GIT binary patch literal 18752 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 WPq&ZTAtmkCLk1+?U$LKx<M;m{=Bs=F literal 0 HcmV?d00001 diff --git a/malva/inc/Mallba/random.hh b/malva/inc/Mallba/random.hh new file mode 100644 index 0000000..ae6bde6 --- /dev/null +++ b/malva/inc/Mallba/random.hh @@ -0,0 +1,50 @@ +/****************************************************************************** +*** *** +*** Este fichero contiene funciones (en general inlines) para generar núme- *** +*** ros aleatorios y otras funciones relacionadas con ello *** +*** *** +*******************************************************************************/ + +#ifndef INC_random_hh +#define INC_random_hh + +#include <stdlib.h> + + +inline double undefined () +{ + double zero = 0; + return zero/zero; +} + +// Returns a valeu greater than any other +inline double infinity () +{ + double one=1.0; + double zero=0.0; + return one/zero; +} + +// Returns a random number in [0,1]. +inline double rand01 () +{ + return drand48(); +} + +// Returns a random number +inline int rand_int (float min,float max) +{ + int value=rand(); + int range= (int)(max - min); + int order = value % (range+1); + return ((int)min + order); +} + +// selects a seed +inline void random_seed(long int seed) +{ + srand48(seed); + srand(seed); +} + +#endif diff --git a/malva/inc/Mallba/time.hh b/malva/inc/Mallba/time.hh new file mode 100644 index 0000000..2dcb9a7 --- /dev/null +++ b/malva/inc/Mallba/time.hh @@ -0,0 +1,43 @@ +/****************************************************************************** +*** *** +*** Este fichero incluye algunas funciones útiles para la medicion de tiem- *** +*** pos. *** +*** *** +******************************************************************************/ + +#ifndef INC_time_hh +#define INC_time_hh + +#define MAXTIME 4294 + +#include <time.h> +#include <sys/time.h> +#include <unistd.h> + +// return time in microseconds +inline float _used_time() +{ + struct timeval tv ; + static long tiempo = -1; + float u_clock; + + gettimeofday(&tv,NULL); + + if(tiempo < 0) tiempo = tv.tv_sec; + + u_clock = ((float)(tv.tv_sec - tiempo)*1000000.0) + ((float)tv.tv_usec); + return u_clock; + +} + + +inline float _used_time(float time) +{ + float dif=_used_time() - time; + if (dif<0) dif = 0; + return dif; +} + + + +#endif -- GitLab