ColPack
|
00001 /************************************************************************************ 00002 Copyright (C) 2005-2008 Assefaw H. Gebremedhin, Arijit Tarafdar, Duc Nguyen, 00003 Alex Pothen 00004 00005 This file is part of ColPack. 00006 00007 ColPack is free software: you can redistribute it and/or modify 00008 it under the terms of the GNU Lesser General Public License as published 00009 by the Free Software Foundation, either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 ColPack is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public License 00018 along with ColPack. If not, see <http://www.gnu.org/licenses/>. 00019 ************************************************************************************/ 00020 00021 #include "ColPackHeaders.h" 00022 00023 using namespace std; 00024 00025 namespace ColPack 00026 { 00027 //Private Function 2201;3201 00028 void BipartiteGraphInputOutput::CalculateVertexDegrees() 00029 { 00030 int i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); 00031 00032 int i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); 00033 00034 int i_TotalLeftVertexDegree = _FALSE; 00035 00036 int i_TotalRightVertexDegree = _FALSE; 00037 00038 i_TotalLeftVertexDegree = i_TotalRightVertexDegree = m_vi_Edges.size()/2; 00039 00040 for(int i = 0; i < i_LeftVertexCount; i++) 00041 { 00042 int i_VertexDegree = m_vi_LeftVertices[i + 1] - m_vi_LeftVertices[i]; 00043 00044 if(m_i_MaximumLeftVertexDegree < i_VertexDegree) 00045 { 00046 m_i_MaximumLeftVertexDegree = i_VertexDegree; 00047 } 00048 00049 if(m_i_MinimumLeftVertexDegree == _UNKNOWN) 00050 { 00051 m_i_MinimumLeftVertexDegree = i_VertexDegree; 00052 } 00053 else if(m_i_MinimumLeftVertexDegree > i_VertexDegree) 00054 { 00055 m_i_MinimumLeftVertexDegree = i_VertexDegree; 00056 } 00057 } 00058 00059 for(int i = 0; i < i_RightVertexCount; i++) 00060 { 00061 int i_VertexDegree = m_vi_RightVertices[i + 1] - m_vi_RightVertices[i]; 00062 00063 if(m_i_MaximumRightVertexDegree < i_VertexDegree) 00064 { 00065 m_i_MaximumRightVertexDegree = i_VertexDegree; 00066 } 00067 00068 if(m_i_MinimumRightVertexDegree == _UNKNOWN) 00069 { 00070 m_i_MinimumRightVertexDegree = i_VertexDegree; 00071 } 00072 else if(m_i_MinimumRightVertexDegree > i_VertexDegree) 00073 { 00074 m_i_MinimumRightVertexDegree = i_VertexDegree; 00075 } 00076 } 00077 00078 m_i_MaximumVertexDegree = m_i_MaximumLeftVertexDegree>m_i_MaximumRightVertexDegree?m_i_MaximumLeftVertexDegree:m_i_MaximumRightVertexDegree; 00079 m_i_MinimumVertexDegree = m_i_MinimumLeftVertexDegree<m_i_MinimumRightVertexDegree?m_i_MinimumLeftVertexDegree:m_i_MinimumRightVertexDegree; 00080 00081 m_d_AverageLeftVertexDegree = (double)i_TotalLeftVertexDegree/i_LeftVertexCount; 00082 m_d_AverageRightVertexDegree = (double)i_TotalRightVertexDegree/i_RightVertexCount; 00083 m_d_AverageVertexDegree = (double)(i_TotalLeftVertexDegree + i_TotalRightVertexDegree)/(i_LeftVertexCount + i_RightVertexCount); 00084 00085 return; 00086 00087 } 00088 00089 //Public Constructor 2251;3251 00090 BipartiteGraphInputOutput::BipartiteGraphInputOutput() 00091 { 00092 Clear(); 00093 } 00094 00095 //Public Destructor 2252;3252 00096 BipartiteGraphInputOutput::~BipartiteGraphInputOutput() 00097 { 00098 Clear(); 00099 } 00100 00101 //Virtual Function 2254;3254 00102 void BipartiteGraphInputOutput::Clear() 00103 { 00104 BipartiteGraphCore::Clear(); 00105 00106 return; 00107 } 00108 00109 int BipartiteGraphInputOutput::WriteMatrixMarket(string s_OutputFile) 00110 { 00111 ofstream out (s_OutputFile.c_str()); 00112 if(!out) { 00113 cout<<"Error creating file: \""<<s_OutputFile<<"\""<<endl; 00114 exit(1); 00115 } 00116 00117 int max = m_vi_LeftVertices.size()-1; 00118 00119 out<<"%%MatrixMarket matrix coordinate real general"<<endl; 00120 00121 out<<GetLeftVertexCount()<<" "<<GetRightVertexCount()<<" "<< GetEdgeCount()<<endl; 00122 00123 for(int i = 0; i<max;i++) { 00124 for(int j = m_vi_LeftVertices[i]; j < m_vi_LeftVertices[i+1]; j++) { 00125 out<<i+1<<" "<<m_vi_Edges[j]+1; 00126 out<<endl; 00127 } 00128 } 00129 00130 return 0; 00131 } 00132 00133 int BipartiteGraphInputOutput::ReadMatrixMarketBipartiteGraph(string s_InputFile) 00134 { 00135 bool b_symmetric; 00136 00137 istringstream in2; 00138 int entry_counter = 0, num_of_entries = 0, nz_counter=0; 00139 bool value_not_specified = false; 00140 int i_LineCount = _TRUE; 00141 00142 int i, j; 00143 00144 00145 int i_RowCount, i_ColumnCount; 00146 00147 int i_LeftVertex, i_RightVertex; 00148 double d_Value; 00149 00150 int i_LeftVertexCount, i_RightVertexCount; 00151 00152 int i_VertexDegree; 00153 00154 int i_EdgeCount; 00155 00156 string _GAP(" "); 00157 00158 string s_InputLine; 00159 00160 ifstream InputStream; 00161 00162 vector<string> vs_InputTokens; 00163 00164 vector< vector<int> > v2i_LeftVertexAdjacency, v2i_RightVertexAdjacency; 00165 00166 Clear(); 00167 00168 i_EdgeCount = _FALSE; 00169 00170 i_LeftVertexCount = i_RightVertexCount = _FALSE; 00171 00172 m_s_InputFile = s_InputFile; 00173 00174 00175 //READ IN BANNER 00176 MM_typecode matcode; 00177 FILE *f; 00178 if ((f = fopen(m_s_InputFile.c_str(), "r")) == NULL) { 00179 cout<<m_s_InputFile<<" not Found!"<<endl; 00180 exit(1); 00181 } 00182 else cout<<"Found file "<<m_s_InputFile<<endl; 00183 00184 if (mm_read_banner(f, &matcode) != 0) 00185 { 00186 printf("Could not process Matrix Market banner.\n"); 00187 exit(1); 00188 } 00189 00190 if(mm_is_symmetric(matcode)) { 00191 b_symmetric = true; 00192 } 00193 else b_symmetric = false; 00194 00195 //Check and make sure that the input file is supported 00196 char * result = mm_typecode_to_str(matcode); 00197 printf("Graph of Market Market type: [%s]\n", result); 00198 free(result); 00199 if( !( mm_is_coordinate(matcode) && (mm_is_symmetric(matcode) || mm_is_general(matcode) ) && ( mm_is_real(matcode) || mm_is_pattern(matcode) || mm_is_integer(matcode) ) ) ) { 00200 printf("Sorry, this application does not support this type."); 00201 exit(1); 00202 } 00203 00204 fclose(f); 00205 //DONE - READ IN BANNER 00206 00207 00208 InputStream.open(m_s_InputFile.c_str()); 00209 00210 if(!InputStream) 00211 { 00212 cout<<"File "<<m_s_InputFile<<" Not Found"<<endl; 00213 return _FALSE; 00214 } 00215 else 00216 { 00217 //cout<<"Found File "<<m_s_InputFile<<endl; 00218 } 00219 00220 do 00221 { 00222 getline(InputStream, s_InputLine); 00223 00224 if(!InputStream) 00225 { 00226 break; 00227 } 00228 00229 if(s_InputLine=="") 00230 { 00231 break; 00232 } 00233 00234 if(s_InputLine[0]=='%') 00235 { 00236 continue; 00237 } 00238 00239 if(i_LineCount == _TRUE) 00240 { 00241 in2.clear(); 00242 in2.str(s_InputLine); 00243 in2>>i_RowCount>>i_ColumnCount>>num_of_entries; 00244 i_EdgeCount = num_of_entries; 00245 00246 i_LeftVertexCount = i_RowCount; 00247 i_RightVertexCount = i_ColumnCount; 00248 00249 v2i_LeftVertexAdjacency.clear(); 00250 v2i_LeftVertexAdjacency.resize((unsigned) i_LeftVertexCount); 00251 00252 v2i_RightVertexAdjacency.clear(); 00253 v2i_RightVertexAdjacency.resize((unsigned) i_RightVertexCount); 00254 } 00255 00256 if((i_LineCount > _TRUE) && (i_LineCount <= STEP_UP(i_EdgeCount))) 00257 { 00258 //cout<<"i_LineCount = "<<i_LineCount<<endl; 00259 in2.clear(); 00260 in2.str(s_InputLine); 00261 d_Value =-999999999.; 00262 value_not_specified=false; 00263 in2>>i_LeftVertex>>i_RightVertex>>d_Value; 00264 entry_counter++; 00265 if(d_Value == -999999999. && in2.eof()) { 00266 // "d_Value" entry is not specified 00267 value_not_specified = true; 00268 } 00269 else if (d_Value == 0) { 00270 continue; 00271 } 00272 00273 //cout<<"\t i_LeftVertex = "<<i_LeftVertex<<"; i_RightVertex = "<<i_RightVertex<<endl; 00274 00275 v2i_LeftVertexAdjacency[STEP_DOWN(i_LeftVertex)].push_back(STEP_DOWN(i_RightVertex)); 00276 v2i_RightVertexAdjacency[STEP_DOWN(i_RightVertex)].push_back(STEP_DOWN(i_LeftVertex)); 00277 nz_counter++; 00278 00279 if(b_symmetric && (i_RightVertex != i_LeftVertex)) { 00280 //cout<<"\t i_LeftVertex = "<<i_LeftVertex<<"; i_RightVertex = "<<i_RightVertex<<endl; 00281 v2i_LeftVertexAdjacency[STEP_DOWN(i_RightVertex)].push_back(STEP_DOWN(i_LeftVertex)); 00282 v2i_RightVertexAdjacency[STEP_DOWN(i_LeftVertex)].push_back(STEP_DOWN(i_RightVertex)); 00283 nz_counter++; 00284 } 00285 } 00286 00287 i_LineCount++; 00288 00289 } 00290 while(InputStream); 00291 00292 InputStream.close(); 00293 00294 if(entry_counter < num_of_entries) { //entry_counter should be == num_of_entries 00295 cerr<<"* WARNING: BipartiteGraphInputOutput::ReadMatrixMarketBipartiteGraph()"<<endl; 00296 cerr<<"*\t entry_counter<num_of_entries. Wrong input format. Can't process."<<endl; 00297 cerr<<"\t # entries so far: "<<entry_counter<<"/"<<num_of_entries<<endl; 00298 exit(-1); 00299 } 00300 00301 for(i=0; i<i_LeftVertexCount; i++) 00302 { 00303 m_vi_LeftVertices.push_back((signed) m_vi_Edges.size()); 00304 00305 i_VertexDegree = (signed) v2i_LeftVertexAdjacency[i].size(); 00306 00307 for(j=0; j<i_VertexDegree; j++) 00308 { 00309 m_vi_Edges.push_back(v2i_LeftVertexAdjacency[i][j]); 00310 } 00311 } 00312 00313 m_vi_LeftVertices.push_back((signed) m_vi_Edges.size()); 00314 00315 for(i=0; i<i_RightVertexCount; i++) 00316 { 00317 m_vi_RightVertices.push_back((signed) m_vi_Edges.size()); 00318 00319 i_VertexDegree = (signed) v2i_RightVertexAdjacency[i].size(); 00320 00321 for(j=0; j<i_VertexDegree; j++) 00322 { 00323 m_vi_Edges.push_back(v2i_RightVertexAdjacency[i][j]); 00324 } 00325 } 00326 00327 m_vi_RightVertices.push_back((signed) m_vi_Edges.size()); 00328 00329 CalculateVertexDegrees(); 00330 00331 00332 #if DEBUG == 2255 || DEBUG == 3255 00333 00334 int k; 00335 00336 cout<<endl; 00337 cout<<"DEBUG 2255;3255 | Graph Coloring | Left Vertex Adjacency | "<<m_s_InputFile<<endl; 00338 cout<<endl; 00339 00340 for(i=0; i<i_LeftVertexCount; i++) 00341 { 00342 cout<<STEP_UP(i)<<"\t"<<" : "; 00343 00344 i_VertexDegree = mvi_LeftVertices[STEP_UP(i)] - mvi_LeftVertices[i]; 00345 00346 k = _FALSE; 00347 00348 for(j=mvi_LeftVertices[i]; j<mvi_LeftVertices[STEP_UP(i)]; j++) 00349 { 00350 if(k == STEP_DOWN(i_VertexDegree)) 00351 { 00352 cout<<STEP_UP(m_vi_Edges[j])<<" ("<<i_VertexDegree<<") "; 00353 } 00354 else 00355 { 00356 cout<<STEP_UP(m_vi_Edges[j])<<", "; 00357 } 00358 00359 k++; 00360 } 00361 00362 cout<<endl; 00363 } 00364 00365 cout<<endl; 00366 cout<<"DEBUG 2255;3255 | Graph Coloring | Right Vertex Adjacency | "<<m_s_InputFile<<endl; 00367 cout<<endl; 00368 00369 for(i=0; i<i_RightVertexCount; i++) 00370 { 00371 cout<<STEP_UP(i)<<"\t"<<" : "; 00372 00373 i_VertexDegree = mvi_RightVertices[STEP_UP(i)] - mvi_RightVertices[i]; 00374 00375 k = _FALSE; 00376 00377 for(j=mvi_RightVertices[i]; j<mvi_RightVertices[STEP_UP(i)]; j++) 00378 { 00379 if(k == STEP_DOWN(i_VertexDegree)) 00380 { 00381 cout<<STEP_UP(m_vi_Edges[j])<<" ("<<i_VertexDegree<<") "; 00382 } 00383 else 00384 { 00385 cout<<STEP_UP(m_vi_Edges[j])<<", "; 00386 } 00387 00388 k++; 00389 } 00390 00391 cout<<endl; 00392 } 00393 00394 cout<<endl; 00395 cout<<"[Left Vertices = "<<i_LeftVertexCount<<"; Right Vertices = "<<i_RightVertexCount<<"; Edges = "<<i_EdgeCount/2<<"]"<<endl; 00396 cout<<endl; 00397 00398 #endif 00399 00400 return(_TRUE); 00401 } 00402 00403 //Public Function 2256;3256 00404 int BipartiteGraphInputOutput::ReadMeTiSBipartiteGraph(string s_InputFile) 00405 { 00406 Clear(); 00407 00408 m_s_InputFile=s_InputFile; 00409 ifstream InputStream (m_s_InputFile.c_str()); 00410 00411 if(!InputStream) 00412 { 00413 cout<<"File "<<m_s_InputFile<<" Not Found"<<endl; 00414 return _FALSE; 00415 } 00416 else 00417 { 00418 cout<<"Found File "<<m_s_InputFile<<endl; 00419 } 00420 00421 //initialize local data 00422 int rowCounter=0, row=0, edges=0, num=0, numCount=0; 00423 istringstream in2; 00424 string line=""; 00425 map<int,vector<int> > colList; 00426 00427 getline(InputStream,line); 00428 rowCounter++; 00429 in2.str(line); 00430 in2>>row>>edges; 00431 m_vi_LeftVertices.push_back(m_vi_Edges.size()); 00432 00433 while(!InputStream.eof()) 00434 { 00435 getline(InputStream,line); 00436 if(line!="") 00437 { 00438 //cout<<"["<<lineCount<<"] \""<<line<<"\""<<endl; 00439 in2.clear(); 00440 in2.str(line); 00441 while(in2>>num) 00442 { 00443 num--; 00444 m_vi_Edges.push_back(num); 00445 colList[num].push_back(rowCounter-1); 00446 numCount++; 00447 //cout<<"\tpush_back "<<num<<endl; 00448 //cout<<"\tnumCount="<<numCount<<endl; 00449 } 00450 } 00451 rowCounter++; 00452 m_vi_LeftVertices.push_back(m_vi_Edges.size()); 00453 } 00454 rowCounter--; 00455 m_vi_LeftVertices.pop_back(); 00456 if(rowCounter!=row+1 || edges*2!=numCount) 00457 { 00458 cout<<"Read fail: rowCounter!=row+1 || edges*2!=numCount"<<endl; 00459 cout<<"Read fail: "<<rowCounter<<"!="<<row+1<<" || "<<edges*2<<"!="<<numCount<<endl; 00460 return _FALSE; 00461 } 00462 00463 //put together the right vertices 00464 m_vi_RightVertices.push_back(m_vi_Edges.size()); 00465 for(int i=0;i<row; i++) { 00466 m_vi_Edges.insert(m_vi_Edges.end(),colList[i].begin(),colList[i].end()); 00467 m_vi_RightVertices.push_back(m_vi_Edges.size()); 00468 } 00469 00470 /* 00471 cout<<"--------------------------------------------------------"<<endl; 00472 cout<<"numCount="<<numCount<<endl; 00473 cout<<"lineCount="<<lineCount<<endl; 00474 cout<<"Left vector:"; 00475 for(int i=0;i<m_vi_LeftVertices.size();i++) cout<<"["<<i<<"] "<<m_vi_LeftVertices[i]<<"; "; 00476 cout<<endl<<"Right vector:"; 00477 for(int i=0;i<m_vi_RightVertices.size();i++) cout<<"["<<i<<"] "<<m_vi_RightVertices[i]<<"; "; 00478 cout<<endl<<"Edges vector:"; 00479 for(int i=0;i<m_vi_Edges.size();i++) cout<<"["<<i<<"] "<<m_vi_Edges[i]<<"; "; 00480 cout<<endl<<"--------------------------------------------------------"<<endl; 00481 //*/ 00482 00483 CalculateVertexDegrees(); 00484 00485 return(_TRUE); 00486 } 00487 00488 int BipartiteGraphInputOutput::ReadHarwellBoeingBipartiteGraph(string s_InputFile) { 00489 Clear(); 00490 00491 m_s_InputFile=s_InputFile; 00492 ifstream in (m_s_InputFile.c_str()); 00493 00494 if(!in) 00495 { 00496 cout<<"File "<<m_s_InputFile<<" Not Found"<<endl; 00497 return _FALSE; 00498 } 00499 else 00500 { 00501 cout<<"Found File "<<m_s_InputFile<<endl; 00502 } 00503 00504 int i_Dummy, i, j; 00505 int num; 00506 int nnz; 00507 string line, num_string; 00508 istringstream iin; 00509 vector< vector<int> > vvi_LeftVertexAdjacency, vvi_RightVertexAdjacency; 00510 vector<int> vi_ColumnStartPointers; 00511 00512 //ignore the first line, which is the tittle and key 00513 getline(in, line); 00514 00515 // Get line 2 00516 int TOTCRD; // (ignored) Total number of lines excluding header 00517 int PTRCRD; // (ignored) Number of lines for pointers 00518 int INDCRD; // (ignored) Number of lines for row (or variable) indices 00519 int VALCRD; // (ignored) Number of lines for numerical values. VALCRD == 0 if no values is presented 00520 int RHSCRD; // (ignored) Number of lines for right-hand sides. RHSCRD == 0 if no right-hand side data is presented 00521 00522 getline(in, line); 00523 iin.clear(); 00524 iin.str(line); 00525 iin >> TOTCRD >> PTRCRD >> INDCRD >> VALCRD >> RHSCRD; 00526 00527 // Get line 3 00528 string MXTYPE; //Matrix type. We only accept: (R | P) (*) (A) 00529 int NROW; // Number of rows (or left vertices) 00530 int NCOL; // Number of columns (or right vertices) 00531 int NNZERO; // (ignored) Number of nonzeros 00532 // in case of symmetric matrix, it is the number of nonzeros IN THE UPPER TRIANGULAR including the diagonal 00533 int NELTVL; // (ignored) Number of elemental matrix entries (zero in the case of assembled matrices) 00534 bool b_symmetric; // true if this matrix is symmetric (MXTYPE[1] == 'S'), false otherwise. 00535 00536 getline(in, line); 00537 iin.clear(); 00538 iin.str(line); 00539 iin >> MXTYPE >> NROW >> NCOL >> NNZERO >> NELTVL; 00540 if(MXTYPE[2] == 'E') { 00541 cerr<<"ERR: Elemental matrices (unassembled) format is not supported"<<endl; 00542 exit(-1); 00543 } 00544 if(MXTYPE[1] == 'S') { 00545 if(NROW != NCOL) { 00546 cerr<<"ERR: The matrix is declared symmetric but NROW != NCOL"<<endl; 00547 exit(-1); 00548 } 00549 b_symmetric = true; 00550 } 00551 else b_symmetric = false; 00552 00553 // Ignore line 4 for now 00554 getline(in, line); 00555 00556 //If the right-hand side data is presented, ignore the 5th header line 00557 if(RHSCRD) getline(in, line); 00558 00559 m_vi_LeftVertices.clear(); 00560 m_vi_LeftVertices.resize(NROW+1, _UNKNOWN); 00561 m_vi_RightVertices.clear(); 00562 m_vi_RightVertices.resize(NCOL+1, _UNKNOWN); 00563 vvi_LeftVertexAdjacency.clear(); 00564 vvi_LeftVertexAdjacency.resize(NROW); 00565 vvi_RightVertexAdjacency.clear(); 00566 vvi_RightVertexAdjacency.resize(NCOL); 00567 vi_ColumnStartPointers.clear(); 00568 vi_ColumnStartPointers.resize(NCOL+1); 00569 00570 // get the 2nd data block: column start pointers 00571 for(int i=0; i<NCOL+1; i++) { 00572 in>> vi_ColumnStartPointers[i]; 00573 } 00574 00575 //populate vvi_LeftVertexAdjacency & vvi_RightVertexAdjacency 00576 nnz = 0; 00577 for(i=0; i<NCOL; i++) { 00578 for(j=vi_ColumnStartPointers[i]; j< vi_ColumnStartPointers[i+1]; j++) { 00579 in>> num; 00580 num--; 00581 vvi_RightVertexAdjacency[i].push_back(num); 00582 vvi_LeftVertexAdjacency[num].push_back(i); 00583 nnz++; 00584 00585 if(b_symmetric && num != i) { 00586 vvi_RightVertexAdjacency[num].push_back(i); 00587 vvi_LeftVertexAdjacency[i].push_back(num); 00588 nnz++; 00589 } 00590 } 00591 } 00592 00593 m_vi_Edges.clear(); 00594 m_vi_Edges.resize(2*nnz, _UNKNOWN); 00595 //populate the m_vi_LeftVertices and their edges at the same time 00596 m_vi_LeftVertices[0]=0; 00597 for(i=0; i<NROW; i++) { 00598 for(j=0; j<vvi_LeftVertexAdjacency[i].size();j++) { 00599 m_vi_Edges[m_vi_LeftVertices[i]+j] = vvi_LeftVertexAdjacency[i][j]; 00600 } 00601 00602 m_vi_LeftVertices[i+1] = m_vi_LeftVertices[i]+vvi_LeftVertexAdjacency[i].size(); 00603 } 00604 00605 //populate the m_vi_RightVertices and their edges at the same time 00606 m_vi_RightVertices[0]=m_vi_LeftVertices[NROW]; 00607 for(i=0; i<NCOL; i++) { 00608 for(j=0; j<vvi_RightVertexAdjacency[i].size();j++) { 00609 m_vi_Edges[m_vi_RightVertices[i]+j] = vvi_RightVertexAdjacency[i][j]; 00610 } 00611 00612 m_vi_RightVertices[i+1] = m_vi_RightVertices[i]+vvi_RightVertexAdjacency[i].size(); 00613 } 00614 00615 return 0; 00616 } 00617 00618 //Public Function 2258;3258 00619 int BipartiteGraphInputOutput::ReadGenericMatrixBipartiteGraph(string s_InputFile) 00620 { 00621 Clear(); 00622 00623 m_s_InputFile=s_InputFile; 00624 00625 //initialize local data 00626 int rowCounter=0, colCounter=0, row=0, col=0, tempNum=0; 00627 istringstream in2; 00628 string line=""; 00629 00630 map< int,vector<int> > colList; 00631 00632 ifstream InputStream (m_s_InputFile.c_str()); 00633 if(!InputStream) 00634 { 00635 cout<<"Not Found File "<<m_s_InputFile<<endl; 00636 } 00637 else 00638 { 00639 cout<<"Found File "<<m_s_InputFile<<endl; 00640 } 00641 00642 //now find the dimension of the matrix 00643 string sRow="", sCol=""; 00644 int tempCounter=s_InputFile.size()-1; 00645 bool getRow=0, firstTime=1; 00646 //read the file name from right to left, get number of rows and cols 00647 for(; tempCounter>-1;tempCounter--) 00648 { 00649 if(s_InputFile[tempCounter]=='\\') {tempCounter=0; continue;}//end of the filename 00650 if(getRow) 00651 { 00652 if(s_InputFile[tempCounter]<'0'||s_InputFile[tempCounter]>'9') 00653 { 00654 if(firstTime) continue; 00655 else break; 00656 } 00657 else firstTime=0; 00658 sRow=s_InputFile[tempCounter]+sRow; 00659 } 00660 else 00661 { 00662 //touch the "by", switch to getRow 00663 if(s_InputFile[tempCounter]<'0'||s_InputFile[tempCounter]>'9') 00664 { 00665 if(firstTime) continue; 00666 else {firstTime=1;getRow=1; continue;} 00667 } 00668 else firstTime=0; 00669 sCol=s_InputFile[tempCounter]+sCol; //finish with sCol, switch to sRow 00670 } 00671 } 00672 if (tempCounter==-1) 00673 { 00674 cout<<"Input file\""<<s_InputFile<<"\" has a wrong name format"<<endl; 00675 return _FALSE; 00676 } 00677 in2.clear();in2.str(sRow);in2>>row; 00678 in2.clear();in2.str(sCol);in2>>col; 00679 cout<<"Matrix: "<<row<<" x "<<col<<endl; 00680 00681 //Start reading the graph, row by row 00682 m_vi_LeftVertices.push_back(m_vi_Edges.size()); 00683 for(;rowCounter<row;rowCounter++) 00684 { 00685 colCounter=0; 00686 getline(InputStream,line); 00687 if(line=="") break; 00688 in2.clear(); in2.str(line); 00689 while(in2>>tempNum) 00690 { 00691 if(tempNum) 00692 { 00693 m_vi_Edges.push_back(colCounter); 00694 colList[colCounter].push_back(rowCounter); 00695 } 00696 colCounter++; 00697 } 00698 m_vi_LeftVertices.push_back(m_vi_Edges.size()); 00699 if (colCounter!=col) 00700 { 00701 cerr<<"WARNING: BipartiteGraphInputOutput::ReadGenericMatrixBipartiteGraph()"<<endl; 00702 cerr<<"Input file\""<<s_InputFile<<"\" has a wrong format. The number of entries in 1 column < # of columns"<<endl; 00703 return _FALSE; 00704 } 00705 } 00706 if (rowCounter!=row) 00707 { 00708 cerr<<"WARNING: BipartiteGraphInputOutput::ReadGenericMatrixBipartiteGraph()"<<endl; 00709 cout<<"Input file\""<<s_InputFile<<"\" has a wrong format. The number of rows is less than what it suppose to be"<<endl; 00710 return _FALSE; 00711 } 00712 //put together the right vertices 00713 m_vi_RightVertices.push_back(m_vi_Edges.size()); 00714 for(int i=0;i<col; i++) { 00715 m_vi_Edges.insert(m_vi_Edges.end(),colList[i].begin(),colList[i].end()); 00716 m_vi_RightVertices.push_back(m_vi_Edges.size()); 00717 } 00718 00719 CalculateVertexDegrees(); 00720 00721 return (_TRUE); 00722 } 00723 00724 //Public Function 2259;3259 00725 int BipartiteGraphInputOutput::ReadGenericSquareMatrixBipartiteGraph(string s_InputFile) 00726 { 00727 Clear(); 00728 00729 m_s_InputFile=s_InputFile; 00730 //initialize local data 00731 int rowCounter=0, colCounter=0, counter=0, row=0, col=0; 00732 istringstream in2; 00733 string line="", templ=""; 00734 00735 map< int,vector<int> > colList; 00736 00737 ifstream InputStream (m_s_InputFile.c_str()); 00738 if(!InputStream) 00739 { 00740 cout<<"Not Found File "<<m_s_InputFile<<endl; 00741 } 00742 else 00743 { 00744 cout<<"Found File "<<m_s_InputFile<<endl; 00745 } 00746 00747 //now find the dimension of the matrix 00748 string sRow="", sCol=""; 00749 int tempCounter=s_InputFile.size()-1; 00750 bool getRow=0, firstTime=1; 00751 //read the file name from right to left, get number of rows and cols 00752 for(; tempCounter>-1;tempCounter--) 00753 { 00754 if(s_InputFile[tempCounter]=='\\') {tempCounter=0; continue;}//end of the filename 00755 if(getRow) 00756 { 00757 if(s_InputFile[tempCounter]<'0'||s_InputFile[tempCounter]>'9') 00758 { 00759 if(firstTime) continue; 00760 else break; 00761 } 00762 else firstTime=0; 00763 sRow=s_InputFile[tempCounter]+sRow; 00764 } 00765 else 00766 { 00767 //touch the "by", switch to getRow 00768 if(s_InputFile[tempCounter]<'0'||s_InputFile[tempCounter]>'9') 00769 { 00770 if(firstTime) continue; 00771 else {firstTime=1;getRow=1; continue;} 00772 } 00773 else firstTime=0; 00774 sCol=s_InputFile[tempCounter]+sCol; //finish with sCol, switch to sRow 00775 } 00776 } 00777 if (tempCounter==-1) 00778 { 00779 cout<<"Input file\""<<s_InputFile<<"\" has a wrong name format"<<endl; 00780 return _FALSE; 00781 } 00782 in2.clear();in2.str(sRow);in2>>row; 00783 in2.clear();in2.str(sCol);in2>>col; 00784 if(row>col) row=col; else col=row; 00785 cout<<"Matrix: "<<row<<" x "<<col<<endl; 00786 00787 //get data 00788 while(!InputStream.eof()) 00789 { 00790 getline(InputStream,templ); 00791 line+=templ; 00792 } 00793 00794 //Start reading the graph, entry by entry 00795 m_vi_LeftVertices.push_back(m_vi_Edges.size()); 00796 counter=0; 00797 for(;rowCounter<row;rowCounter++) 00798 { 00799 for(colCounter=0;colCounter<row;colCounter++) 00800 { 00801 if(line[counter]=='1') 00802 { 00803 m_vi_Edges.push_back(colCounter); 00804 colList[colCounter].push_back(rowCounter); 00805 } 00806 counter++; 00807 } 00808 m_vi_LeftVertices.push_back(m_vi_Edges.size()); 00809 } 00810 00811 //put together the right vertices 00812 m_vi_RightVertices.push_back(m_vi_Edges.size()); 00813 for(int i=0;i<col; i++) { 00814 m_vi_Edges.insert(m_vi_Edges.end(),colList[i].begin(),colList[i].end()); 00815 m_vi_RightVertices.push_back(m_vi_Edges.size()); 00816 } 00817 00818 CalculateVertexDegrees(); 00819 00820 return (_TRUE); 00821 } 00822 00823 //Public Function 2260;3260 00824 void BipartiteGraphInputOutput::PrintBipartiteGraph() 00825 { 00826 int i, j, k; 00827 00828 int i_LeftVertexCount, i_RightVertexCount; 00829 00830 int i_EdgeCount; 00831 00832 int i_VertexDegree; 00833 00834 i_LeftVertexCount = STEP_DOWN((signed) m_vi_LeftVertices.size()); 00835 i_RightVertexCount = STEP_DOWN((signed) m_vi_RightVertices.size()); 00836 00837 i_EdgeCount = (signed) m_vi_Edges.size(); 00838 00839 cout<<endl; 00840 cout<<"Bipartite Graph | Left Vertex Adjacency | "<<m_s_InputFile<<endl; 00841 cout<<endl; 00842 00843 for(i=0; i<i_LeftVertexCount; i++) 00844 { 00845 cout<<STEP_UP(i)<<"\t"<<" : "; 00846 00847 i_VertexDegree = m_vi_LeftVertices[STEP_UP(i)] - m_vi_LeftVertices[i]; 00848 00849 k = _FALSE; 00850 00851 for(j=m_vi_LeftVertices[i]; j<m_vi_LeftVertices[STEP_UP(i)]; j++) 00852 { 00853 if(k == STEP_DOWN(i_VertexDegree)) 00854 { 00855 cout<<STEP_UP(m_vi_Edges[j])<<" ("<<i_VertexDegree<<") "; 00856 } 00857 else 00858 { 00859 cout<<STEP_UP(m_vi_Edges[j])<<", "; 00860 } 00861 00862 k++; 00863 } 00864 00865 cout<<endl; 00866 } 00867 00868 cout<<endl; 00869 cout<<"Bipartite Graph | Right Vertex Adjacency | "<<m_s_InputFile<<endl; 00870 cout<<endl; 00871 00872 for(i=0; i<i_RightVertexCount; i++) 00873 { 00874 cout<<STEP_UP(i)<<"\t"<<" : "; 00875 00876 i_VertexDegree = m_vi_RightVertices[STEP_UP(i)] - m_vi_RightVertices[i]; 00877 00878 k = _FALSE; 00879 00880 for(j=m_vi_RightVertices[i]; j<m_vi_RightVertices[STEP_UP(i)]; j++) 00881 { 00882 if(k == STEP_DOWN(i_VertexDegree)) 00883 { 00884 cout<<STEP_UP(m_vi_Edges[j])<<" ("<<i_VertexDegree<<") "; 00885 } 00886 else 00887 { 00888 cout<<STEP_UP(m_vi_Edges[j])<<", "; 00889 } 00890 00891 k++; 00892 } 00893 00894 cout<<endl; 00895 } 00896 00897 cout<<endl; 00898 cout<<"[Left Vertices = "<<i_LeftVertexCount<<"; Right Vertices = "<<i_RightVertexCount<<"; Edges = "<<i_EdgeCount/2<<"]"<<endl; 00899 cout<<endl; 00900 00901 return; 00902 } 00903 00904 //Public Function 2261;3261 00905 void BipartiteGraphInputOutput::PrintVertexDegrees() 00906 { 00907 cout<<endl; 00908 cout<<"Bipartite Graph | "<<m_s_InputFile<<" | Maximum Row Vertex Degree | "<<m_i_MaximumLeftVertexDegree<<endl; 00909 cout<<"Bipartite Graph | "<<m_s_InputFile<<" | Maximum Column Vertex Degree | "<<m_i_MaximumRightVertexDegree<<endl; 00910 cout<<"Bipartite Graph | "<<m_s_InputFile<<" | Maximum Vertex Degree | "<<m_i_MaximumVertexDegree<<endl; 00911 cout<<endl; 00912 cout<<"Bipartite Graph | "<<m_s_InputFile<<" | Minimum Row Vertex Degree | "<<m_i_MinimumLeftVertexDegree<<endl; 00913 cout<<"Bipartite Graph | "<<m_s_InputFile<<" | Minimum Column Vertex Degree | "<<m_i_MinimumRightVertexDegree<<endl; 00914 cout<<"Bipartite Graph | "<<m_s_InputFile<<" | Minimum Vertex Degree | "<<m_i_MinimumVertexDegree<<endl; 00915 cout<<endl; 00916 cout<<"Bipartite Graph | "<<m_s_InputFile<<" | Average Row Vertex Degree | "<<m_d_AverageLeftVertexDegree<<endl; 00917 cout<<"Bipartite Graph | "<<m_s_InputFile<<" | Average Column Vertex Degree | "<<m_d_AverageRightVertexDegree<<endl; 00918 cout<<"Bipartite Graph | "<<m_s_InputFile<<" | Average Vertex Degree | "<<m_d_AverageVertexDegree<<endl; 00919 cout<<endl; 00920 00921 return; 00922 } 00923 00924 int BipartiteGraphInputOutput::BuildBPGraphFromCSRFormat(int* ip_RowIndex, int i_RowCount, int i_ColumnCount, int* ip_ColumnIndex) { 00925 int i; 00926 unsigned int j; 00927 map< int,vector<int> > colList; 00928 00929 m_vi_LeftVertices.clear(); 00930 m_vi_LeftVertices.reserve(i_RowCount+1); 00931 m_vi_RightVertices.clear(); 00932 m_vi_RightVertices.reserve(i_RowCount+1); 00933 m_vi_Edges.clear(); 00934 m_vi_Edges.reserve(2*ip_RowIndex[i_RowCount]); //??? !!! 00935 00936 m_vi_LeftVertices.push_back(0); //equivalent to m_vi_LeftVertices.push_back(m_vi_Edges.size()); 00937 //PrintBipartiteGraph (); 00938 //Pause(); 00939 for(i=0; i < i_RowCount; i++) { 00940 for(j=ip_RowIndex[i]; j<ip_RowIndex[i+1]; j++) { 00941 m_vi_Edges.push_back(ip_ColumnIndex[j]); 00942 colList[ ip_ColumnIndex[j] ].push_back(i); 00943 } 00944 m_vi_LeftVertices.push_back(m_vi_Edges.size()); 00945 //PrintBipartiteGraph (); 00946 //Pause(); 00947 } 00948 00949 //for(i=0; i < i_RowCount; i++) { 00950 // for(j=1; j <= uip2_JacobianSparsityPattern[i][0]; j++) { 00951 // m_vi_Edges.push_back(uip2_JacobianSparsityPattern[i][j]); 00952 // colList[ uip2_JacobianSparsityPattern[i][j] ].push_back(i); 00953 // } 00954 // m_vi_LeftVertices.push_back(m_vi_Edges.size()); 00955 //} 00956 00957 //put together the right vertices 00958 map< int,vector<int> >::iterator curr; 00959 m_vi_RightVertices.push_back(m_vi_Edges.size()); 00960 for(int i=0; i <= i_ColumnCount; i++) { 00961 curr = colList.find(i); 00962 if(curr !=colList.end()) { 00963 m_vi_Edges.insert(m_vi_Edges.end(),curr->second.begin(),curr->second.end()); 00964 }//else We have an empty column 00965 m_vi_RightVertices.push_back(m_vi_Edges.size()); 00966 } 00967 00968 CalculateVertexDegrees(); 00969 00970 return (_TRUE); 00971 } 00972 00973 int BipartiteGraphInputOutput::BuildBPGraphFromADICFormat(std::list<std::set<int> > * lsi_SparsityPattern, int i_ColumnCount) { 00974 int i; 00975 unsigned int j; 00976 map< int,vector<int> > colList; 00977 int i_RowCount = (*lsi_SparsityPattern).size(); 00978 00979 m_vi_LeftVertices.clear(); 00980 m_vi_LeftVertices.reserve(i_RowCount+1); 00981 m_vi_RightVertices.clear(); 00982 m_vi_RightVertices.reserve(i_ColumnCount+1); 00983 m_vi_Edges.clear(); 00984 00985 m_vi_LeftVertices.push_back(0); // equivalent to m_vi_LeftVertices.push_back(m_vi_Edges.size()); 00986 00987 int rowIndex=-1, colIndex=-1; 00988 std::list<std::set<int> >::iterator valsetlistiter = (*lsi_SparsityPattern).begin(); 00989 00990 for (; valsetlistiter != (*lsi_SparsityPattern).end(); valsetlistiter++){ 00991 rowIndex++; 00992 std::set<int>::iterator valsetiter = (*valsetlistiter).begin(); 00993 00994 for (; valsetiter != (*valsetlistiter).end() ; valsetiter++) { 00995 colIndex = *valsetiter; 00996 m_vi_Edges.push_back(colIndex); 00997 colList[colIndex].push_back(rowIndex); 00998 } 00999 m_vi_LeftVertices.push_back(m_vi_Edges.size()); 01000 } 01001 m_vi_Edges.reserve(2*m_vi_Edges.size()); 01002 01003 //put together the right vertices 01004 map< int,vector<int> >::iterator curr; 01005 m_vi_RightVertices.push_back(m_vi_Edges.size()); 01006 for(int i=0; i < i_ColumnCount; i++) { 01007 curr = colList.find(i); 01008 if(curr !=colList.end()) { 01009 m_vi_Edges.insert(m_vi_Edges.end(),curr->second.begin(),curr->second.end()); 01010 }//else We have an empty column 01011 m_vi_RightVertices.push_back(m_vi_Edges.size()); 01012 } 01013 01014 CalculateVertexDegrees(); 01015 //cout<<"PrintBipartiteGraph()"<<endl; 01016 //PrintBipartiteGraph(); 01017 //Pause(); 01018 //cout<<"OUT BipartiteGraphInputOutput::RowCompressedFormat2BipartiteGraph"<<endl; 01019 return _TRUE; 01020 } 01021 01022 int BipartiteGraphInputOutput::BuildBPGraphFromRowCompressedFormat(unsigned int ** uip2_JacobianSparsityPattern, int i_RowCount, int i_ColumnCount) { 01023 return RowCompressedFormat2BipartiteGraph(uip2_JacobianSparsityPattern, i_RowCount, i_ColumnCount); 01024 } 01025 01026 int BipartiteGraphInputOutput::RowCompressedFormat2BipartiteGraph(unsigned int ** uip2_JacobianSparsityPattern, int i_RowCount, int i_ColumnCount) { 01027 //cout<<"IN BipartiteGraphInputOutput::RowCompressedFormat2BipartiteGraph"<<endl; 01028 //initialize local data 01029 int i; 01030 unsigned int j; 01031 map< int,vector<int> > colList; 01032 01033 m_vi_LeftVertices.clear(); 01034 m_vi_LeftVertices.reserve(i_RowCount+1); 01035 m_vi_RightVertices.clear(); 01036 m_vi_RightVertices.reserve(i_ColumnCount+1); 01037 m_vi_Edges.clear(); 01038 m_vi_LeftVertices.push_back(m_vi_Edges.size()); 01039 01040 for(i=0; i < i_RowCount; i++) { 01041 for(j=1; j <= uip2_JacobianSparsityPattern[i][0]; j++) { 01042 m_vi_Edges.push_back(uip2_JacobianSparsityPattern[i][j]); 01043 colList[ uip2_JacobianSparsityPattern[i][j] ].push_back(i); 01044 } 01045 m_vi_LeftVertices.push_back(m_vi_Edges.size()); 01046 } 01047 m_vi_Edges.reserve(2*m_vi_Edges.size()); 01048 01049 //put together the right vertices 01050 map< int,vector<int> >::iterator curr; 01051 m_vi_RightVertices.push_back(m_vi_Edges.size()); 01052 for(int i=0; i < i_ColumnCount; i++) { 01053 curr = colList.find(i); 01054 if(curr !=colList.end()) { 01055 m_vi_Edges.insert(m_vi_Edges.end(),curr->second.begin(),curr->second.end()); 01056 }//else We have an empty column 01057 m_vi_RightVertices.push_back(m_vi_Edges.size()); 01058 } 01059 01060 CalculateVertexDegrees(); 01061 //cout<<"PrintBipartiteGraph()"<<endl; 01062 //PrintBipartiteGraph(); 01063 //Pause(); 01064 //cout<<"OUT BipartiteGraphInputOutput::RowCompressedFormat2BipartiteGraph"<<endl; 01065 return _TRUE; 01066 } 01067 01068 int BipartiteGraphInputOutput::BipartiteGraph2RowCompressedFormat(unsigned int *** uip3_JacobianSparsityPattern, unsigned int * uip1_RowCount, unsigned int * uip1_ColumnCount) { 01069 //initialize local data 01070 unsigned int i = 0; 01071 unsigned int j = 0; 01072 unsigned int numOfNonZeros = 0; 01073 int offset = 0; 01074 01075 unsigned int i_RowCount = GetRowVertexCount(); 01076 (*uip1_RowCount) = i_RowCount; 01077 (*uip1_ColumnCount) = GetColumnVertexCount(); 01078 01079 // Allocate memory and populate (*uip3_JacobianSparsityPattern) 01080 (*uip3_JacobianSparsityPattern) = new unsigned int*[GetRowVertexCount()]; 01081 for(i=0; i < i_RowCount; i++) { 01082 numOfNonZeros = m_vi_LeftVertices[i + 1] - m_vi_LeftVertices[i]; 01083 (*uip3_JacobianSparsityPattern)[i] = new unsigned int[numOfNonZeros + 1]; // Allocate memory 01084 (*uip3_JacobianSparsityPattern)[i][0] = numOfNonZeros; // Populate the first entry, which contains the number of Non-Zeros 01085 01086 // Populate the entries 01087 offset = m_vi_LeftVertices[i] - 1; 01088 for(j=1; j <= numOfNonZeros; j++) { 01089 (*uip3_JacobianSparsityPattern)[i][j] = m_vi_Edges[offset + j]; 01090 } 01091 } 01092 01093 return _TRUE; 01094 } 01095 01096 int BipartiteGraphInputOutput::ReadBipartiteGraph(string s_InputFile, string s_fileFormat) { 01097 if (s_fileFormat == "AUTO_DETECTED" || s_fileFormat == "") { 01098 File file(s_InputFile); 01099 string fileExtension = file.GetFileExtension(); 01100 if (isHarwellBoeingFormat(fileExtension)) { 01101 cout<<"ReadHarwellBoeingBipartiteGraph"<<endl; 01102 ReadHarwellBoeingBipartiteGraph(s_InputFile); 01103 } 01104 else if (isMeTiSFormat(fileExtension)) { 01105 cout<<"ReadMeTiSBipartiteGraph"<<endl; 01106 ReadMeTiSBipartiteGraph(s_InputFile); 01107 } 01108 else if (fileExtension == "gen") { 01109 cout<<"ReadGenericMatrixBipartiteGraph"<<endl; 01110 ReadGenericMatrixBipartiteGraph(s_InputFile); 01111 } 01112 else if (fileExtension == "gens") { 01113 cout<<"ReadGenericSquareMatrixBipartiteGraph"<<endl; 01114 ReadGenericSquareMatrixBipartiteGraph(s_InputFile); 01115 } 01116 else if (isMatrixMarketFormat(fileExtension)) { 01117 cout<<"ReadMatrixMarketBipartiteGraph"<<endl; 01118 ReadMatrixMarketBipartiteGraph(s_InputFile); 01119 } 01120 else { //other extensions 01121 cout<<"unfamiliar extension, use ReadMatrixMarketBipartiteGraph"<<endl; 01122 ReadMatrixMarketBipartiteGraph(s_InputFile); 01123 } 01124 } 01125 else if (s_fileFormat == "MM") { 01126 cout<<"ReadMatrixMarketBipartiteGraph"<<endl; 01127 ReadMatrixMarketBipartiteGraph(s_InputFile); 01128 } 01129 else if (s_fileFormat == "HB") { 01130 cout<<"ReadHarwellBoeingBipartiteGraph"<<endl; 01131 ReadHarwellBoeingBipartiteGraph(s_InputFile); 01132 } 01133 else if (s_fileFormat == "MeTiS") { 01134 cout<<"ReadMeTiSBipartiteGraph"<<endl; 01135 ReadMeTiSBipartiteGraph(s_InputFile); 01136 } 01137 else if (s_fileFormat == "GEN") { 01138 cout<<"ReadGenericMatrixBipartiteGraph"<<endl; 01139 ReadGenericMatrixBipartiteGraph(s_InputFile); 01140 } 01141 else if (s_fileFormat == "GENS") { 01142 cout<<"ReadGenericSquareMatrixBipartiteGraph"<<endl; 01143 ReadGenericSquareMatrixBipartiteGraph(s_InputFile); 01144 } 01145 else { 01146 cerr<<"BipartiteGraphInputOutput::ReadBipartiteGraph s_fileFormat is not recognized"<<endl; 01147 exit(1); 01148 } 01149 01150 return(_TRUE); 01151 } 01152 }