Data Structures | |
| class | checkedVector |
| class | dynamic_priority_queue |
| struct | Empty |
| class | Graph |
| struct | IterGreater |
Enumerations | |
| enum | VertStatus { notVisited, visited, processed } |
Functions | |
| template<class EdgeType> | |
| void | connectNeighbors (Graph< Place, EdgeType > &G) |
| template<class EdgeType> | |
| void | create_vertex_set (Graph< Place, EdgeType > &G, int count, int maxX, int maxY) |
| template<class EdgeType> | |
| void | createMPfile (char *Filename, Graph< Place, EdgeType > &G, double ScalingFactor) |
| template<class EdgeType> | |
| void | createTeXfile (const char *Filename, Graph< Place, EdgeType > &G, double ScalingFactor, int xMax, int yMax) |
| template<class GraphType, class EdgeType> | |
| void | Dijkstra (GraphType &Gr, std::vector< EdgeType > &Dist, std::vector< int > &Pred, int Start) |
| std::string | i2string (unsigned int i) |
| template<class VertexType, class EdgeType> | |
| std::ostream & | operator<< (std::ostream &os, Graph< VertexType, EdgeType > &G) |
| std::ostream & | operator<< (std::ostream &os, const Empty &) |
| std::istream & | operator>> (std::istream &is, Empty &) |
| template<class Container> | |
| void | showSequence (const Container &s, const char *sep=" ", std::ostream &where=std::cout) |
| template<class GraphType> | |
| bool | topoSort (GraphType &G, std::vector< int > &Result) |
| template<class EdgeType> | |
| void | writeMPpath (char *Filename, Graph< Place, EdgeType > &G, std::vector< int > &V, double ScalingFactor, int Start) |
| enum br_stl::VertStatus |
| void br_stl::connectNeighbors | ( | Graph< Place, EdgeType > & | G | ) | [inline] |
Definition at line 47 of file gra_util.h.
References br_stl::Graph< VertexType, EdgeType >::connectVertices(), and br_stl::Graph< VertexType, EdgeType >::size().
00047 { 00048 for(size_t i = 0; i < G.size(); ++i) { 00049 Place iPlace = G[i].first; 00050 00051 for(size_t j = i+1; j < G.size(); ++j) { 00052 Place jPlace = G[j].first; 00053 00054 Place MidPoint((iPlace.X()+jPlace.X())/2, 00055 (iPlace.Y()+jPlace.Y())/2); 00056 00057 /* The following loop is not run-time optimized. A possible 00058 optimization could be to sort the places by their x 00059 coordinates so that only a small relevant range must be 00060 searched. The relevant range results from the fact that 00061 the places to be compared must lie inside a circle around 00062 the mid-point whose diameter is equal to the distance 00063 between the places i and j. */ 00064 00065 size_t k = 0; 00066 unsigned long int e2 = DistSquare(iPlace, MidPoint); 00067 00068 while(k < G.size()) { // not run-time optimized 00069 if(k != j && k != i && 00070 DistSquare(G[k].first, MidPoint) < e2) 00071 break; 00072 ++k; 00073 } 00074 00075 if(k == G.size()) {// no nearer place found 00076 EdgeType dist = Distance(iPlace, jPlace); 00077 G.connectVertices(i, j, dist); 00078 } 00079 } 00080 } 00081 }
| void br_stl::create_vertex_set | ( | Graph< Place, EdgeType > & | G, | |
| int | count, | |||
| int | maxX, | |||
| int | maxY | |||
| ) | [inline] |
Definition at line 35 of file gra_util.h.
References i2string(), and br_stl::Graph< VertexType, EdgeType >::insert().
00036 { 00037 Random xRandom(maxX), 00038 yRandom(maxY); 00039 00040 // create vertices with random coordinates 00041 int i = -1; 00042 while(++i < count) 00043 G.insert(Place(xRandom(), yRandom(),i2string(i))); 00044 }
| void br_stl::createMPfile | ( | char * | Filename, | |
| Graph< Place, EdgeType > & | G, | |||
| double | ScalingFactor | |||
| ) | [inline] |
Definition at line 159 of file gra_util.h.
References br_stl::Graph< VertexType, EdgeType >::begin(), br_stl::Graph< VertexType, EdgeType >::end(), br_stl::Graph< VertexType, EdgeType >::isDirected(), and br_stl::Graph< VertexType, EdgeType >::size().
00161 { 00162 assert(!G.isDirected()); 00163 std::ofstream Output(Filename); 00164 00165 if(!Output) { 00166 std::cerr << Filename 00167 << " cannot be opened!\n"; 00168 exit(1); 00169 } 00170 00171 Output << "%%%% createMPfile(): This is a generated file!\n" 00172 << "input boxes\n\n" 00173 << "beginfig(1);\nu=1mm; % unitlength\n" 00174 << "defaultscale := 0.8; % small numbers\n"; 00175 00176 for(register size_t iv = 0; iv < G.size(); ++iv) { 00177 // Point 00178 Output << " drawdot( " 00179 << G[iv].first.X()*ScalingFactor 00180 << "u, " 00181 << G[iv].first.Y()*ScalingFactor 00182 << "u) withpen pencircle scaled 1mm;\n"; 00183 00184 // node name 00185 Output << " label.urt( \"" 00186 << G[iv].first << "\", ( " 00187 << G[iv].first.X()*ScalingFactor 00188 << "u, " 00189 << G[iv].first.Y()*ScalingFactor 00190 << "u) ); " << std::endl; 00191 00192 /* All edges are drawn. In order to prevent them from appearing 00193 twice in the undirected graph, they are only drawn in the 00194 direction of the greater index. */ 00195 00196 00197 typename Graph<Place, EdgeType>::Successor::const_iterator I = 00198 // std:: map<int, EdgeType>::const_iterator I = 00199 G[iv].second.begin(); 00200 00201 while(I != G[iv].second.end()) { 00202 size_t n = (*I).first; 00203 if(n > iv) { // otherwise, ignore 00204 Output << " draw ( " 00205 << G[iv].first.X()*ScalingFactor << "u, " 00206 << G[iv].first.Y()*ScalingFactor 00207 << "u ) -- ( " 00208 << G[n].first.X()*ScalingFactor << "u, " 00209 << G[n].first.Y()*ScalingFactor 00210 << "u );" << std::endl; 00211 } 00212 ++I; 00213 } 00214 } 00215 Output << "endfig;" << std::endl << "end." << std::endl; 00216 }
| void br_stl::createTeXfile | ( | const char * | Filename, | |
| Graph< Place, EdgeType > & | G, | |||
| double | ScalingFactor, | |||
| int | xMax, | |||
| int | yMax | |||
| ) | [inline] |
Definition at line 86 of file gra_util.h.
References br_stl::Graph< VertexType, EdgeType >::begin(), br_stl::Graph< VertexType, EdgeType >::end(), br_stl::Graph< VertexType, EdgeType >::isDirected(), and br_stl::Graph< VertexType, EdgeType >::size().
00089 { 00090 assert(!G.isDirected()); 00091 std::ofstream Output(Filename); 00092 00093 if(!Output) { 00094 std::cerr << Filename 00095 << " cannot be opened!\n"; 00096 exit(1); 00097 } 00098 00099 Output << "%% This is a generated file!\n" 00100 << "\\unitlength 1.00mm\n" 00101 << "\\begin{picture}(" 00102 << xMax << ',' 00103 << yMax << ")\n"; 00104 00105 for(size_t iv = 0; iv < G.size(); ++iv) { 00106 // Point 00107 Output << "\\put(" 00108 << G[iv].first.X()*ScalingFactor 00109 << ',' 00110 << G[iv].first.Y()*ScalingFactor 00111 << "){\\circle*{1.0}}\n"; 00112 00113 // node name 00114 Output << "\\put(" 00115 << (1.0 + G[iv].first.X()*ScalingFactor) 00116 << ',' 00117 << G[iv].first.Y()*ScalingFactor 00118 << "){\\makebox(0,0)[lb]{{\\tiny " 00119 << G[iv].first // name 00120 << "}}}\n"; 00121 00122 /* All edges are drawn. In order to prevent them from appearing 00123 twice in the undirected graph, they are only drawn in the 00124 direction of the greater index. */ 00125 00126 typename Graph<Place,EdgeType>::Successor::const_iterator I = 00127 // std::map< int, EdgeType >::const_iterator I = 00128 G[iv].second.begin(); 00129 00130 while(I != G[iv].second.end()) { 00131 size_t n = (*I).first; 00132 if(n > iv) { // otherwise, ignore 00133 double x1,x2,y1,y2,dx,dy; 00134 x1 = G[iv].first.X()*ScalingFactor; 00135 y1 = G[iv].first.Y()*ScalingFactor; 00136 x2 = G[n].first.X()*ScalingFactor; 00137 y2 = G[n].first.Y()*ScalingFactor; 00138 dx = x2-x1; dy = y2-y1; 00139 double dist = std::sqrt(dx*dx+dy*dy); 00140 int wdh = int(5*dist); 00141 dx = dx/wdh; dy = dy/wdh; 00142 Output << "\\multiput(" << x1 << "," << y1 << ")(" 00143 << dx << "," << dy << "){" << wdh 00144 << "}{\\circle*{0.1}}\n"; 00145 } 00146 ++I; 00147 } 00148 } 00149 Output << "\\end{picture}\n"; 00150 }
| void br_stl::Dijkstra | ( | GraphType & | Gr, | |
| std::vector< EdgeType > & | Dist, | |||
| std::vector< int > & | Pred, | |||
| int | Start | |||
| ) | [inline] |
Definition at line 35 of file Gra_algo.h.
References TeMAXFLOAT.
00039 { 00040 /* The algorithm proceeds in such a way that the distances are 00041 estimated and the estimates gradually improved. The distance to 00042 the starting point is known (0). For all other vertices, the 00043 worst possible estimate is entered.*/ 00044 00045 Dist = std::vector<EdgeType>(Gr.size(), 00046 TeMAXFLOAT); // as good as infinity 00047 Dist[Start] = (EdgeType)0; 00048 00049 /* The predecessor vector too is initialized with `impossible' 00050 values. Subsequently, a dynamic priority queue is defined and 00051 initialized with the distance vector: */ 00052 00053 Pred = std::vector<int>(Gr.size(), -1); 00054 dynamic_priority_queue<EdgeType> Q(Dist); 00055 00056 // In the next step, all vertices are extracted one by one from 00057 // the priority queue, and precisely in the order of the estimated 00058 // distance towards the starting vertex. Obviously, the starting 00059 //vertex is dealt with first. No vertex is looked at twice. 00060 00061 int u; 00062 while(!Q.empty()) { 00063 u = Q.topIndex(); // extract vertex with minimum 00064 Q.pop(); 00065 00066 // Now, the distance estimates for all neighboring vertices of 00067 // u are updated. If the previous estimate of the distance 00068 // between the current neighbor of u and the starting vertex 00069 // (Dist[Neighbor]) is worse than the distance between vertex u 00070 // and the starting vertex (Dist[u]) plus the distance between 00071 // u and the neighboring vertex (dist), the estimate is 00072 // improved: this process is called relaxation. In this case, 00073 // the path from the starting vertex to the neighbor cannot be 00074 // longer than (Dist[u] + dist). In this case, u would have to 00075 // be regarded as predecessor of the neighbor. 00076 00077 // improve estimates for all neighbors of u 00078 typename GraphType::Successor::const_iterator 00079 I = Gr[u].second.begin(); 00080 00081 while(I != Gr[u].second.end()) { 00082 int Neighbor = (*I).first; 00083 EdgeType dist = (*I).second; 00084 00085 // relaxation 00086 if(Dist[Neighbor] > Dist[u] + dist) { 00087 // improve estimate 00088 Q.changeKeyAt(Neighbor, Dist[u] + dist); 00089 // u is predecessor of the neighbor 00090 Pred[Neighbor] = u; 00091 } 00092 ++I; 00093 } 00094 } 00095 return; 00096 }
| std::string br_stl::i2string | ( | unsigned int | i | ) |
Definition at line 19 of file gra_util.h.
Referenced by create_vertex_set().
00019 { 00020 if(i==0) return std::string("0"); 00021 char buf[] = "0000000000000000"; 00022 char *pos = buf + sizeof(buf)-1; // point to end 00023 00024 do 00025 *--pos = i % 10 + '0'; 00026 while(i /=10); 00027 return std::string(pos); 00028 }
| std::ostream& br_stl::operator<< | ( | std::ostream & | os, | |
| Graph< VertexType, EdgeType > & | G | |||
| ) | [inline] |
Definition at line 354 of file graph.h.
00355 { 00356 // display of vertices with successors 00357 for(size_t i = 0; i < G.size(); ++i) 00358 { 00359 os << G[i].first << " <"; 00360 typename Graph<VertexType,EdgeType>::Successor::const_iterator 00361 startN = G[i].second.begin(), 00362 endN = G[i].second.end(); 00363 00364 while(startN != endN) 00365 { 00366 os << G[(*startN).first].first << ' ' // vertex 00367 << (*startN).second << ' '; // edge value 00368 ++startN; 00369 } 00370 os << ">" << std::endl; 00371 } 00372 return os; 00373 }
| std::ostream& br_stl::operator<< | ( | std::ostream & | os, | |
| const Empty & | ||||
| ) | [inline] |
| std::istream& br_stl::operator>> | ( | std::istream & | is, | |
| Empty & | ||||
| ) | [inline] |
| void br_stl::showSequence | ( | const Container & | s, | |
| const char * | sep = " ", |
|||
| std::ostream & | where = std::cout | |||
| ) | [inline] |
| bool br_stl::topoSort | ( | GraphType & | G, | |
| std::vector< int > & | Result | |||
| ) | [inline] |
Definition at line 99 of file Gra_algo.h.
00101 { 00102 assert(G.isDirected()); // let's play this safe! 00103 int ResCounter = 0; 00104 Result = std::vector<int>(G.size(), -1); 00105 00106 /* The vector Result takes the indices of the correspondingly 00107 distributed vertices. The counter ResCounter is the position in 00108 Result where the next entry belongs. */ 00109 00110 vector<int> PredecessorCount(G.size(), 0); 00111 int VerticesWithoutSuccessor = 0; 00112 00113 /* For each vertex, the vector PredecessorCount counts how many 00114 predecessors it has. There are vertices without successors, 00115 whose number is kept in VerticesWithoutSuccessor. Furthermore, 00116 the algorithm remains stable if the precondition that a graph 00117 must not have cycles is violated. The variable 00118 VerticesWithoutSuccessor is used to recognize this situation 00119 (see below). */ 00120 00121 /* 00122 for(size_t iv = 0; iv < G.size(); ++iv) { 00123 if(G[iv].second.size() > 0) { // is predecessor 00124 typename GraphType::Successor::const_iterator I = 00125 G[iv].second.begin(); 00126 while(I != G[iv].second.end()) 00127 // update number of predecessors 00128 ++PredecessorCount[(*I++).first]; 00129 } 00130 else { // Vertex is no predecessor, that is, without successor 00131 // an excessively high number of predecessors is used 00132 // for later recognition 00133 PredecessorCount[iv] = G.size(); // too many! 00134 ++VerticesWithoutSuccessor; 00135 } 00136 } 00137 */ 00138 00139 /* The dynamic priority queue is initialized with the vector of 00140 numbers of predecessors. At the beginning of the queue we find 00141 those vertices that have no predecessors and therefore are to 00142 be processed next. Only the vertices which are predecessors 00143 themselves, that is that have successors are processed. The 00144 subsequent loop is terminated when the queue only contains 00145 successor vertices which themselves are not predecessors. Their 00146 number of predecessors can never be 0 because further above 00147 they were initialized with too high a value.*/ 00148 00149 /* 00150 dynamic_priority_queue<int> Q(PredecessorCount); 00151 00152 // process all predecessors 00153 while(Q.topKey() == 0) { 00154 // determine vertex with predecessor number 0 00155 int oV = Q.topIndex(); 00156 Q.pop(); 00157 00158 Result[ResCounter++] = oV; 00159 00160 // In order to ensure that this vertex without predecessors oV 00161 // is no longer considered in the next cycle, the number of 00162 // predecessors of all its successors is decreased by 1. 00163 00164 typename GraphType::Successor::const_iterator 00165 I = G[oV].second.begin(); 00166 while(I != G[oV].second.end()) { 00167 // decrease number of predecessors with 00168 // changeKeyAt()}. Do not change directly! 00169 int V = (*I).first; 00170 Q.changeKeyAt(V, PredecessorCount[V] -1); 00171 ++I; 00172 } 00173 } 00174 00175 // Now, all vertices without successors are entered. As a 00176 // countercheck, the variable VerticesWithoutSuccessor is 00177 // decreased. If the queue contains too many vertices, an error 00178 // message is displayed. 00179 00180 while(!Q.empty()) { 00181 Result[ResCounter++] = Q.topIndex(); 00182 Q.pop(); 00183 --VerticesWithoutSuccessor; 00184 } 00185 00186 if(VerticesWithoutSuccessor < 0) 00187 std::cerr << "Error: graph contains a cycle!\n"; 00188 return VerticesWithoutSuccessor == 0; 00189 */ 00190 return; 00191 }
| void br_stl::writeMPpath | ( | char * | Filename, | |
| Graph< Place, EdgeType > & | G, | |||
| std::vector< int > & | V, | |||
| double | ScalingFactor, | |||
| int | Start | |||
| ) | [inline] |
Definition at line 222 of file gra_util.h.
00226 { 00227 std::ofstream Output(Filename); 00228 00229 if(!Output) { 00230 std::cerr << Filename 00231 << " cannot be opened!\n"; 00232 exit(1); 00233 } 00234 00235 Output << "%%%% writeMPpath(): This is a generated file!\n" 00236 << "beginfig( 1 );\nu=1mm; % unitlength" << std::endl 00237 << "pickup pencircle scaled 2pt;\n" // line width 00238 << " draw ( " 00239 << G[ Start ].first.X() * ScalingFactor 00240 << "u, " 00241 << G[ Start ].first.Y() * ScalingFactor 00242 << "u)"; 00243 00244 while ( V[ Start ] >= 0 ) { 00245 int Successor = V[ Start ]; 00246 Output << std::endl << " -- ( " 00247 << G[ Successor ].first.X() * ScalingFactor 00248 << "u, " 00249 << G[ Successor ].first.Y() * ScalingFactor 00250 << " u)"; 00251 Start = Successor; 00252 } 00253 Output << ";\n" << "endfig;\n" << "end." << std::endl; 00254 }
1.5.3