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 ;
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
00142 if ( i != first_node )
00143 {neighbors.push_back(i-1);}
00144 else
00145 neighbors.push_back(last_node) ;
00146
00147 if ( i != last_node )
00148 {neighbors.push_back(i+1);}
00149 else
00150 neighbors.push_back(first_node) ;
00151
00152 break;
00153 }
00154 }
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;
00236 else
00237 return (int)y;
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 );
00283 else
00284 return rect_dist( (int)x1, (int)y1, (int)x2, (int)y2 );
00285 };
00286
00287
00288 void OneDT::Save( TMatrix tsp_result , string nick , int number_of_neurons ) {
00289 ofstream fout(nick.c_str());
00290
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]);
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]);
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
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] );
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) {
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
00350 result_path[tsp_count][1] = cities[strtoint(rem_id(neurons_labels[i][j]))][1] ;
00351
00352 result_path[tsp_count][2] = cities[strtoint(rem_id(neurons_labels[i][j]))][2] ;
00353
00354 tsp_count++ ;
00355 }
00356 }
00357 else {
00358 if (number_of_labels == 1) {
00359
00360 result_path[tsp_count][1] = cities[strtoint(rem_id(neurons_labels[i][0]))][1] ;
00361
00362 result_path[tsp_count][2] = cities[strtoint(rem_id(neurons_labels[i][0]))][2] ;
00363
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