OneDT.h

00001 #ifndef OneDT_H
00002 #define OneDT_H
00003 #include "TopologyImp.h"
00004 
00005 
00006 #include <string>
00007 #include <iomanip.h>
00008 #include <fstream.h>
00009 #include <stdio.h>
00010 #include <string>
00011 
00012 #include "Som.h"
00013 #include "defs.h"
00014 #include "util.h"
00015 #include "TopolParams.h"
00016 
00024 class OneDT : public TopologyImp {
00025 public:
00027         Value_Type distance(int bmu, int i, int dimensions[MaxDimension], int type);    
00028 
00030         int Coord( int pos, int axis, int dimensions[MaxDimension] );
00031 
00033         TMatrix LinInitCoords(int mapsize, int dimensions[MaxDimension]);
00034 
00036         TMatrix CreateDelta( int dimensions[MaxDimension], int lattice, int mapsize );
00037 
00039         Value_Type H( const Value_Type delta, Value_Type radius,  int neighboor );
00040 
00042         vector<int> getNeighbors( int i, int neighbor, int dimensions[]  );
00043 
00045         OneDT(const TopolParams& par):TopologyImp(par) {};
00046         
00048         void Save(TMatrix tsp_result , string nick , int number_of_neurons );   
00049 
00052         void OneDT::Order_Labels(Value_Type city_x , Value_Type city_y , TvecLabel& cities_labels , int begin_city , int end_city , TMatrix cities_xy) ;
00053 
00056         TMatrix OneDT::Extract_Path(TLabel neurons_labels , TMatrix cities , int number_of_neurons) ;
00057         
00058 
00059 
00060 private:
00061         Value_Type hexa_dist(int bx, int by, int tx, int ty);
00062 
00063         Value_Type rect_dist(int bx, int by, int tx, int ty);
00064 };
00065 
00066 vector<int> OneDT::getNeighbors( int i, int neighbor, int dimensions[] ) {
00067   
00068         int L = dimensions[0] - 1;
00069         int C = dimensions[1] - 1;
00070         int y = Coord( i, 0, dimensions );
00071         int x = Coord( i, 1, dimensions );
00072         vector<int> neighbors;
00073         
00074 
00075         int last_node = dimensions[0]-1 ;
00076         int first_node = 0 ;  // <-- which is the initial index ?? 0 or 1 ??
00077 
00078 
00079         
00080         switch ( neighbor ) {
00081         
00082         case HEXA : {   if ( fmod( y, 2 ) != 0) {
00083   
00084                                 if ( ( x - 1 >= 0 ) )
00085                                         neighbors.push_back( ( (x-1)*(L+1) +y +1 ) );
00086   
00087                                 if ( (y + 1) <= L )
00088                                         neighbors.push_back(  (x)*(L+1) + y + 2 );
00089   
00090                                 if ( ((x + 1) <= C ) && ((y + 1) <= L) )
00091                                         neighbors.push_back( ( (x+1)*(L+1) + y + 2) );
00092                                                 
00093                                 if ( (x + 1) <= C ) 
00094                                         neighbors.push_back(  ( (x+1)*(L+1) + y + 1) );
00095   
00096                                 if ( ( (y - 1) >= 0 ) && ( x + 1 <= C ) )
00097                                         neighbors.push_back( ((x+1)*(L+1) + y ) );
00098   
00099                                 if ( (y - 1) >= 0 )
00100                                         neighbors.push_back( ( (x)*(L+1)+y ) );
00101                         }
00102                         else {
00103   
00104                                 if ( x - 1 >= 0)
00105                                         neighbors.push_back( (x-1)*(L+1) + y + 1 );
00106   
00107                                 if ((x-1>=0) && (y+1 <= L))
00108                                         neighbors.push_back( (x-1)*(L+1) + y + 2 );
00109 
00110                                 if ( y + 1 <= L )
00111                                         neighbors.push_back( x*(L+1) + y + 2 );
00112         
00113                                 if ( x + 1 <= C )
00114                                         neighbors.push_back( (x+1)*(L+1) + y + 1 );
00115 
00116                                 if ( y - 1 >= 0 )
00117                                         neighbors.push_back(  x*(L+1) + y );
00118 
00119                                 if ((x-1 >= 0) && (y-1) >= 0)
00120                                         neighbors.push_back( (x-1)*(L+1) + y );
00121                         }
00122                         break;
00123                 }
00124                 
00125         case RECT : {   if ( (y - 1) >= 0 )
00126                                 neighbors.push_back( ( (x-1)*L+y ) );
00127                 
00128                         if ( ( x - 1 >= 0 ) )
00129                                 neighbors.push_back( ( (x-2)*L +y +1 ) );
00130 
00131                         if ( (x + 1) <= C ) 
00132                                 neighbors.push_back( ( x*L + y + 1) );
00133 
00134                         if ( (y + 1) <= L )
00135                                 neighbors.push_back( (x-1)*L + y + 2 );
00136                         break;
00137                         }
00138                         
00139 
00140         case TORO : {
00141                 // left neighbor on the toros
00142                 if ( i != first_node )  // <--- Check the initial index of neurons on toros
00143                         {neighbors.push_back(i-1);}
00144                 else
00145                         neighbors.push_back(last_node) ;
00146                 // right neighbor on the toros
00147                 if ( i != last_node )
00148                         {neighbors.push_back(i+1);}
00149                 else
00150                         neighbors.push_back(first_node) ;
00151 
00152                 break;
00153                 }
00154         } // end of switch
00155 
00156 
00157         return neighbors;
00158 
00159 };
00160 
00161 Value_Type OneDT::H( const Value_Type delta, Value_Type radius, int neighboor ) {
00162                 
00163         switch(neighboor) {
00164                 case GAUSSIAN :         return exp( -delta*delta/2*radius*radius); break;
00165                                                         
00166                 case BUBBLE :           if (delta <= radius ) 
00167                                                                 return 1; 
00168                                                         else 
00169                                                                 return 0;
00170                                                         break;
00171                 case CUTGAUSS :         if (delta <= radius )
00172                                                                 return exp( -delta*delta/2*radius*radius);
00173                                                         else
00174                                                                 return 0;                                                       
00175                                                         break;
00176                 case EP :                       if (delta <= radius )
00177                                                                 return (1 - delta*delta/radius*radius);
00178                                                         else
00179                                                                 return 0;                                                       
00180                                                         break;
00181                 }       
00182         return 0;
00183 };
00184 
00185 TMatrix OneDT::CreateDelta(int dimensions[MaxDimension], int lattice, int mapsize ) {
00186         int i, j;
00187         TMatrix delta = create_matrix(1, mapsize, 1, mapsize);
00188         for (i=1; i<=mapsize ; i++) for (j=i; j<= mapsize; j++)  
00189                 delta[i][j] = delta[j][i] = distance( i, j, dimensions, lattice );              
00190         return delta;
00191 }
00192 
00193 TMatrix OneDT::LinInitCoords(int mapsize, int dimensions[MaxDimension]) {
00194         int i,k;
00195         int dimension = 2; 
00196         TMatrix LinInitCoords = create_matrix(1,mapsize,1,dimension);
00197         TVector Max = create_vector(1,2);
00198         TVector Min = create_vector(1,2);
00199 
00200         for (i=1;i<=2;i++) {Max[i] = 0.0; Min[i] = 100000.0;};
00201 
00202         for (i=1;i<=mapsize;i++) {              
00203                 LinInitCoords[i][1] = Coord(i, 2, dimensions );
00204                 LinInitCoords[i][2] = Coord(i, 1, dimensions );
00205                 if ( LinInitCoords[i][1] > Max[1] ) Max[1] = LinInitCoords[i][1];
00206                 if ( LinInitCoords[i][2] > Max[2] ) Max[2] = LinInitCoords[i][2];
00207                 if ( LinInitCoords[i][1] < Min[1] ) Min[1] = LinInitCoords[i][1];
00208                 if ( LinInitCoords[i][2] < Min[2] ) Min[2] = LinInitCoords[i][2];
00209         }
00210         for (i=1;i<=mapsize;i++)
00211                 for (k=1;k<=dimension;k++)
00212                         if (Max[k] > Min[k])
00213                                 LinInitCoords[i][k] = ((LinInitCoords[i][k] - Min[k])/(Max[k] - Min[k]) - 0.5)*2.0;
00214                         else
00215                                 LinInitCoords[i][k] = 0.0;
00216                 
00217         return LinInitCoords;
00218 };
00219 
00220 int OneDT::Coord( int pos, int axis, int dimensions[MaxDimension] ) {
00221 Value_Type x, y, tmp1, tmp2, N, M;
00222 
00223         N = dimensions[0];
00224         M = dimensions[1];
00225 
00226         tmp1 = pos % (int)N;
00227         tmp2 = floor(pos/(int)N);
00228 
00229         if (pos <= N) { x = 0; y = pos - 1; }
00230         else            
00231                 if (tmp1 == 0) { y = N - 1; x = tmp2 - 1; }                             
00232                 else {  y = tmp1 - 1;   x = tmp2; };
00233 
00234         if ( axis ==1 )
00235           return (int)x;//warning
00236         else
00237           return (int)y;//warning       
00238 };
00239 
00240 Value_Type OneDT::hexa_dist(int bx, int by, int tx, int ty){
00241   Value_Type ret, diff;
00242 
00243   diff = bx - tx;
00244 
00245   if (((by - ty) % 2) != 0) {
00246     if ((by % 2) == 0) {
00247       diff -= 0.5;
00248     }
00249     else {
00250       diff += 0.5;
00251     }
00252   }
00253   
00254   ret = diff * diff;
00255   diff = by - ty;
00256   ret += 0.75 * diff * diff;
00257   ret = (Value_Type) sqrt((Value_Type) ret);
00258 
00259   return(ret);
00260 }
00261 
00262 Value_Type OneDT::rect_dist(int bx, int by, int tx, int ty) {
00263   Value_Type ret, diff;
00264 
00265   diff = bx - tx;
00266   ret = diff * diff;
00267   diff = by - ty;
00268   ret += diff * diff;
00269   ret = (Value_Type) sqrt((Value_Type) ret);
00270 
00271   return(ret);
00272 }
00273 
00274 Value_Type OneDT::distance(int bmu, int i, int dimensions[MaxDimension], int type) {
00275         Value_Type x1, y1, x2, y2;
00276         
00277         x1 = Coord( bmu, 1, dimensions );
00278         y1 = Coord( bmu, 2, dimensions );
00279         x2 = Coord( i, 1, dimensions );
00280         y2 = Coord( i, 2, dimensions );
00281         if (type == HEXA) 
00282           return hexa_dist( (int)x1, (int)y1, (int)x2, (int)y2 );//warning
00283         else 
00284           return rect_dist( (int)x1, (int)y1, (int)x2, (int)y2 );//warning                      
00285 };
00286 
00287 
00288 void OneDT::Save( TMatrix tsp_result , string nick , int number_of_neurons ) {
00289         ofstream fout(nick.c_str()); // convert nick to the string used in c pure , and 
00290                                      // uses in function ofstream fout(c string);
00291         Value_Type ret, diff , dist = 0.0 ;
00292         int neurons = number_of_neurons ;
00293         cout << setiosflags(ios::fixed) << setprecision(2) ;
00294         fout << setiosflags(ios::fixed) << setprecision(2) ;
00295         for (int i = 1 ; i<neurons; i++)
00296                 {
00297                 fout << tsp_result[i][1] << " " << tsp_result[i][2] << "\n" ;
00298                 dist += rect_dist((int)tsp_result[i][1],(int)tsp_result[i][2],(int)tsp_result[i+1][1],(int)tsp_result[i+1][2]);//warning
00299                 }
00300         fout << tsp_result[neurons][1] << " " << tsp_result[neurons][2] << "\n" ;
00301         dist += rect_dist((int)tsp_result[neurons][1],(int)tsp_result[neurons][2],(int)tsp_result[1][1],(int)tsp_result[1][2]);//warning
00302         cout << nick << " -> length of the path : " << dist << "\n" ;
00303         fout << "% length of the path : " << dist << "\n" ;
00304         fout.close();
00305 }
00306 
00307 
00308 
00309 void OneDT::Order_Labels(Value_Type city_x , Value_Type city_y , TvecLabel& cities_labels , int begin_city , int end_city , TMatrix cities_xy) {
00310         TvecLabel new_order ;
00311         if (begin_city == end_city) {
00312         //end of recursive function
00313         } 
00314         else {
00315                 Value_Type min = 999999 ;
00316                 Value_Type min2 ;
00317                 int nearest = begin_city ;
00318                 if (city_x == city_y == -1){
00319                         city_x = cities_xy[strtoint(rem_id(cities_labels[begin_city]))][1] ;
00320                         city_y = cities_xy[strtoint(rem_id(cities_labels[begin_city]))][2] ;
00321                 }
00322                 for (int i = begin_city ; i <= end_city ; i++){
00323                   min2 = rect_dist( (int)city_x , (int)city_y , (int)cities_xy[strtoint(rem_id(cities_labels[i]))][1] , (int)cities_xy[strtoint(rem_id(cities_labels[i]))][2] );//warning
00324                         if (min2 < min) {
00325                                 nearest = i ;
00326                                 min = min2 ;
00327                                 }
00328                         }
00329                 Value_Type new_city_x = cities_xy[strtoint(rem_id(cities_labels[nearest]))][1];
00330                 Value_Type new_city_y = cities_xy[strtoint(rem_id(cities_labels[nearest]))][2];
00331                 string temp = cities_labels[begin_city] ;
00332                 cities_labels[begin_city] = cities_labels[nearest] ;
00333                 cities_labels[nearest] = temp ;
00334                 begin_city++ ;
00335                 Order_Labels(new_city_x , new_city_y , cities_labels , begin_city , end_city , cities_xy);
00336                 }
00337 }
00338 
00339 TMatrix OneDT::Extract_Path(TLabel neurons_labels , TMatrix cities , int number_of_neurons) {
00340         int tsp_count = 1 ;       
00341         TMatrix result_path = create_matrix(1,number_of_neurons,1,2);
00342         Value_Type begin_x = -1 ;
00343         Value_Type begin_y = -1 ;                       
00344           for (int i = 0; i < neurons_labels.size() ; i++) {
00345              int number_of_labels = neurons_labels[i].size() ;
00346              if (number_of_labels > 1) { // neuron labeled to more than 1 city
00347                 Order_Labels(begin_x , begin_y , neurons_labels[i] , 0 , neurons_labels[i].size()-1 , cities);
00348                 for (int j = 0; j < neurons_labels[i].size(); j++){
00349                         //cout << tsp_count << ": " << cities[strtoint(rem_id(neurons_labels[i][j]))][1] ;
00350                         result_path[tsp_count][1] = cities[strtoint(rem_id(neurons_labels[i][j]))][1] ;
00351                         //cout << "," << cities[strtoint(rem_id(neurons_labels[i][j]))][2] << " " ;
00352                         result_path[tsp_count][2] = cities[strtoint(rem_id(neurons_labels[i][j]))][2] ;
00353                         //cout << "\n";
00354                         tsp_count++ ;
00355                 }
00356              }
00357              else {
00358                   if (number_of_labels == 1) { // neuron labeled to more than 1 city
00359                   //cout << tsp_count << ": " << cities[strtoint(rem_id(neurons_labels[i][0]))][1] ;
00360                   result_path[tsp_count][1] = cities[strtoint(rem_id(neurons_labels[i][0]))][1] ;
00361                   //cout << "," << cities[strtoint(rem_id(neurons_labels[i][0]))][2] << " " ;
00362                   result_path[tsp_count][2] = cities[strtoint(rem_id(neurons_labels[i][0]))][2] ;
00363                   //cout << "\n";
00364                   begin_x = cities[strtoint(rem_id(neurons_labels[i][0]))][1] ;
00365                   begin_y = cities[strtoint(rem_id(neurons_labels[i][0]))][2] ;
00366                   tsp_count++ ;
00367                   }
00368              }
00369 
00370           }
00371         return result_path ;
00372 };
00373 
00374 #endif

Generated on Tue Aug 7 16:03:33 2007 for SOMCode by  doxygen 1.5.3