00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "Beobot/Graph.H"
00039 #include "Image/Image.H"
00040 #include "Image/MathOps.H"
00041 #include <unistd.h>
00042
00043 #include "Raster/Raster.H"
00044
00045
00046 Graph::Graph():
00047 itsNodes(),
00048 itsEdges(),
00049 itsDirectedAdjecencyList(),
00050 itsDirectedAdjecencyCostList(),
00051 itsDirectedAdjecencyInEdgeList(),
00052 itsDirectedAdjecencyOutEdgeList(),
00053 itsUndirectedAdjecencyList(),
00054 itsUndirectedAdjecencyCostList(),
00055 itsUndirectedAdjecencyEdgeList(),
00056 itsDirectedPathList(),
00057 itsUndirectedPathList()
00058 {
00059 itsDistanceMatrixComputed = false;
00060 }
00061
00062
00063 Graph::Graph(std::vector<rutz::shared_ptr<Node> > nodes,
00064 std::vector<rutz::shared_ptr<Edge> > edges):
00065 itsNodes(),
00066 itsEdges(),
00067 itsDirectedAdjecencyList(),
00068 itsDirectedAdjecencyCostList(),
00069 itsDirectedAdjecencyInEdgeList(),
00070 itsDirectedAdjecencyOutEdgeList(),
00071 itsUndirectedAdjecencyList(),
00072 itsUndirectedAdjecencyCostList(),
00073 itsUndirectedAdjecencyEdgeList(),
00074 itsDirectedPathList(),
00075 itsUndirectedPathList()
00076 {
00077 for(uint i = 0; i < nodes.size(); i++)
00078 itsNodes.push_back(nodes[i]);
00079
00080 for(uint i = 0; i < edges.size(); i++)
00081 itsEdges.push_back(edges[i]);
00082
00083 itsDistanceMatrixComputed = false;
00084 }
00085
00086
00087 Graph::~Graph()
00088 { }
00089
00090
00091 void Graph::addNode(rutz::shared_ptr<Node> node)
00092 {
00093 itsNodes.push_back(node);
00094 }
00095
00096
00097 void Graph::addEdge(rutz::shared_ptr<Edge> edge)
00098 {
00099 itsEdges.push_back(edge);
00100 }
00101
00102
00103 void Graph::computeAdjecencyList()
00104 {
00105 itsDirectedAdjecencyList.resize(itsNodes.size());
00106 itsDirectedAdjecencyCostList.resize(itsNodes.size());
00107 itsDirectedAdjecencyInEdgeList.resize(itsNodes.size());
00108 itsDirectedAdjecencyOutEdgeList.resize(itsNodes.size());
00109
00110 itsUndirectedAdjecencyList.resize(itsNodes.size());
00111 itsUndirectedAdjecencyCostList.resize(itsNodes.size());
00112 itsUndirectedAdjecencyEdgeList.resize(itsNodes.size());
00113
00114
00115 for(uint i = 0; i < itsEdges.size(); i++)
00116 {
00117 uint sind = itsEdges[i]->getSourceNode()->getIndex();
00118 uint dind = itsEdges[i]->getDestNode()->getIndex();
00119 float cost = itsEdges[i]->getCost();
00120 LINFO("[%d -> %d]: %f", sind, dind, cost);
00121
00122
00123
00124
00125 itsDirectedAdjecencyList[sind].push_back(dind);
00126 itsDirectedAdjecencyCostList[sind].push_back(cost);
00127
00128 itsDirectedAdjecencyInEdgeList[dind].push_back(i);
00129 itsDirectedAdjecencyOutEdgeList[sind].push_back(i);
00130
00131
00132 itsUndirectedAdjecencyList[sind].push_back(dind);
00133 itsUndirectedAdjecencyList[dind].push_back(sind);
00134 itsUndirectedAdjecencyCostList[sind].push_back(cost);
00135 itsUndirectedAdjecencyCostList[dind].push_back(cost);
00136
00137 itsUndirectedAdjecencyEdgeList[dind].push_back(i);
00138 itsUndirectedAdjecencyEdgeList[sind].push_back(i);
00139 }
00140 }
00141
00142
00143 void Graph::computeDistances()
00144 {
00145
00146 itsDistanceMatrixComputed = false;
00147 uint nnode = itsNodes.size();
00148
00149
00150 itsDirectedDistanceMatrix.resize(nnode, nnode);
00151 itsDirectedPathList.resize(nnode);
00152 itsUndirectedDistanceMatrix.resize(nnode, nnode);
00153 itsUndirectedPathList.resize(nnode);
00154 for(uint i = 0; i < nnode; i++)
00155 {
00156 itsDirectedPathList[i].resize(nnode);
00157 itsUndirectedPathList[i].resize(nnode);
00158 }
00159
00160 for(uint i = 0; i < nnode; i++)
00161 {
00162 for(uint j = 0; j < nnode; j++)
00163 {
00164
00165 std::vector<uint> dedges;
00166 float ddist = getDirectedDistance(i,j, dedges);
00167 itsDirectedDistanceMatrix.setVal(i,j, ddist);
00168 itsDirectedPathList[i][j] = dedges;
00169
00170
00171 std::vector<uint> uedges;
00172 float udist = getUndirectedDistance(i,j, uedges);
00173 itsUndirectedDistanceMatrix.setVal(i,j, udist);
00174 itsUndirectedPathList[i][j] = uedges;
00175 }
00176 }
00177 itsDistanceMatrixComputed = true;
00178 }
00179
00180
00181 float Graph::getDirectedDistance(uint a, uint b)
00182 {
00183 std::vector<uint> edges;
00184 return getDirectedDistance(a, b, edges);
00185 }
00186
00187
00188 float Graph::getDirectedDistance
00189 (uint a, uint b, std::vector<uint> &edges)
00190 {
00191 ASSERT(a < itsNodes.size() && b < itsNodes.size());
00192 if(a == b) return 0.0F;
00193
00194 if(itsDistanceMatrixComputed)
00195 {
00196 edges.clear();
00197 for(uint i = 0; i < itsDirectedPathList[a][b].size(); i++)
00198 edges.push_back(itsDirectedPathList[a][b][i]);
00199 return itsDirectedDistanceMatrix[Point2D<int>(a,b)];
00200 }
00201
00202 uint nnode = itsNodes.size();
00203 std::vector<float> edist(nnode);
00204 std::vector<uint> epath(nnode);
00205
00206
00207
00208 for(uint i = 0; i < nnode; i++) edist[i] = -1.0F;
00209 std::vector<bool> selected(nnode);
00210 for(uint i = 0; i < nnode; i++) selected[i] = false;
00211
00212
00213 uint nsadj = itsDirectedAdjecencyList[a].size();
00214 for(uint i = 0; i < nsadj; i++)
00215 {
00216 uint adjnode = itsDirectedAdjecencyList[a][i];
00217 edist[adjnode] = itsDirectedAdjecencyCostList[a][i];
00218 epath[adjnode] = itsDirectedAdjecencyOutEdgeList[a][i];
00219 }
00220 edist[a] = 0.0F; selected[a] = true;
00221
00222
00223
00224
00225
00226
00227
00228 uint mindex = a; bool end = false;
00229 while(mindex != b && !end)
00230 {
00231
00232 float mindist = -1.0F;
00233 for(uint i = 0; i < nnode; i++)
00234 if(!selected[i] && edist[i] != -1.0F &&
00235 (mindist == -1.0F || mindist > edist[i]))
00236 {
00237 mindist = edist[i]; mindex = i;
00238
00239 }
00240
00241
00242
00243
00244 if(mindist != -1.0F)
00245 {
00246 selected[mindex] = true;
00247
00248 uint nadj = itsDirectedAdjecencyList[mindex].size();
00249 for(uint i = 0; i < nadj; i++)
00250 {
00251 uint eindex = itsDirectedAdjecencyOutEdgeList[mindex][i];
00252 uint adjindex = itsDirectedAdjecencyList[mindex][i];
00253 float cost = itsDirectedAdjecencyCostList[mindex][i];
00254
00255
00256
00257 if(edist[adjindex] == -1.0F ||
00258 edist[adjindex] > edist[mindex] + cost)
00259 {
00260
00261
00262 edist[adjindex] = edist[mindex] + cost;
00263 epath[adjindex] = eindex;
00264
00265
00266
00267
00268 }
00269 }
00270 }
00271 else { end = true; }
00272
00273
00274
00275 }
00276
00277
00278 edges.clear();
00279
00280
00281 if(edist[b] != -1.0F)
00282 {
00283 std::vector<uint> tEdges;
00284
00285 uint index = b;
00286 while(index != a)
00287 {
00288 tEdges.push_back(epath[index]);
00289
00290 index = getEdge(epath[index])->getSourceNode()->getIndex();
00291 }
00292 for(int i = tEdges.size()-1; i >= 0; i--)
00293 edges.push_back(tEdges[i]);
00294 }
00295
00296 return edist[b];
00297 }
00298
00299
00300 float Graph::getUndirectedDistance(uint a, uint b)
00301 {
00302 std::vector<uint> edges;
00303 return getUndirectedDistance(a, b, edges);
00304 }
00305
00306
00307 float Graph::getUndirectedDistance
00308 (uint a, uint b, std::vector<uint> &edges)
00309 {
00310 ASSERT(a < itsNodes.size() && b < itsNodes.size());
00311 if(a == b) return 0.0F;
00312
00313
00314 if(itsDistanceMatrixComputed)
00315 {
00316 edges.clear();
00317 for(uint i = 0; i < itsUndirectedPathList[a][b].size(); i++)
00318 {
00319 edges.push_back(itsUndirectedPathList[a][b][i]);
00320
00321 }
00322 return itsUndirectedDistanceMatrix[Point2D<int>(a,b)];
00323 }
00324
00325 uint nnode = itsNodes.size();
00326 std::vector<float> edist(nnode);
00327 std::vector<uint> epath(nnode);
00328
00329
00330
00331 for(uint i = 0; i < nnode; i++) edist[i] = -1.0F;
00332 std::vector<bool> selected(nnode);
00333 for(uint i = 0; i < nnode; i++) selected[i] = false;
00334
00335
00336 uint nsadj = itsUndirectedAdjecencyList[a].size();
00337
00338 for(uint i = 0; i < nsadj; i++)
00339 {
00340 uint adjnode = itsUndirectedAdjecencyList[a][i];
00341 edist[adjnode] = itsUndirectedAdjecencyCostList[a][i];
00342 epath[adjnode] = itsUndirectedAdjecencyEdgeList[a][i];
00343 }
00344 edist[a] = 0.0F; selected[a] = true;
00345
00346
00347
00348
00349
00350
00351
00352
00353 uint mindex = a; bool end = false;
00354 while(mindex != b && !end)
00355 {
00356
00357 float mindist = -1.0F;
00358 for(uint i = 0; i < nnode; i++)
00359 if(!selected[i] && edist[i] != -1.0F &&
00360 (mindist == -1.0F || mindist > edist[i]))
00361 {
00362 mindist = edist[i]; mindex = i;
00363
00364 }
00365
00366
00367
00368
00369 if(mindist != -1.0F)
00370 {
00371 selected[mindex] = true;
00372
00373 uint nadj = itsUndirectedAdjecencyList[mindex].size();
00374 for(uint i = 0; i < nadj; i++)
00375 {
00376 uint eindex = itsUndirectedAdjecencyEdgeList[mindex][i];
00377 uint adjindex = itsUndirectedAdjecencyList[mindex][i];
00378 float cost = itsUndirectedAdjecencyCostList[mindex][i];
00379
00380 if(edist[adjindex] == -1.0F ||
00381 edist[adjindex] > edist[mindex] + cost)
00382 {
00383
00384
00385 edist[adjindex] = edist[mindex] + cost;
00386 epath[adjindex] = eindex;
00387 }
00388 }
00389 }
00390 else { end = true; }
00391
00392
00393
00394 }
00395
00396
00397 edges.clear();
00398
00399
00400 if(edist[b] != -1.0F)
00401 {
00402 std::vector<uint> tEdges;
00403
00404 uint index = b;
00405 while(index != a)
00406 {
00407 tEdges.push_back(epath[index]);
00408 uint is = getEdge(epath[index])->getSourceNode()->getIndex();
00409 uint id = getEdge(epath[index])->getDestNode()->getIndex();
00410 if(index == is) index = id;
00411 else index = is;
00412
00413 }
00414
00415 for(int i = tEdges.size()-1; i >= 0; i--)
00416 edges.push_back(tEdges[i]);
00417 }
00418 return edist[b];
00419 }
00420
00421
00422 float Graph::getMaxDirectedDistance()
00423 {
00424 float min, max;
00425 getMinMax(itsDirectedDistanceMatrix, min, max);
00426 if(min == -1.0F) return -1.0F;
00427 else return max;
00428 }
00429
00430
00431 float Graph::getMaxUndirectedDistance()
00432 {
00433 float min, max;
00434 getMinMax(itsUndirectedDistanceMatrix, min, max);
00435 if(min == -1.0F) return -1.0F;
00436 else return max;
00437 }
00438
00439
00440 std::vector<uint> Graph::getDirectedPath(uint a, uint b)
00441 {
00442 std::vector<uint> edges;
00443
00444
00445 if(itsDistanceMatrixComputed) return itsDirectedPathList[a][b];
00446 else
00447 {
00448 getDirectedDistance(a, b, edges);
00449 return edges;
00450 }
00451 }
00452
00453
00454 std::vector<uint> Graph::getUndirectedPath(uint a, uint b)
00455 {
00456 std::vector<uint> edges;
00457
00458
00459 if(itsDistanceMatrixComputed) return itsUndirectedPathList[a][b];
00460 else
00461 {
00462 getUndirectedDistance(a, b, edges);
00463 return edges;
00464 }
00465 }
00466
00467
00468 std::vector<uint> Graph::getEdges(rutz::shared_ptr<Node> n)
00469 {
00470 std::vector<uint> res;
00471
00472
00473 for(uint i = 0; i < itsEdges.size(); i++)
00474 {
00475
00476
00477 }
00478 LFATAL("not yet implemented");
00479
00480 return res;
00481 }
00482
00483
00484 float Graph::getAngle
00485 (rutz::shared_ptr<Edge> e1, rutz::shared_ptr<Edge> e2)
00486 {
00487
00488 Point2D<int> s1 = e1->getSourceNode()->getCoordinate();
00489 Point2D<int> d1 = e1->getDestNode()->getCoordinate();
00490 Point2D<int> s2 = e2->getSourceNode()->getCoordinate();
00491 Point2D<int> d2 = e2->getDestNode()->getCoordinate();
00492 LDEBUG("(s1(%d,%d)-d1(%d,%d))-----(s2(%d,%d)-d2(%d,%d))",
00493 s1.i, s1.j,d1.i, d1.j, s2.i, s2.j,d2.i, d2.j);
00494
00495
00496 float xD1 = d1.i - s1.i;
00497 float xD2 = d2.i - s2.i;
00498 float yD1 = d1.j - s1.j;
00499 float yD2 = d2.j - s2.j;
00500
00501
00502 float len1 = sqrt(xD1*xD1+yD1*yD1);
00503 float len2 = sqrt(xD2*xD2+yD2*yD2);
00504
00505 float dot = (xD1*xD2+yD1*yD2);
00506 float cross = (xD1*yD2-xD2*yD1);
00507
00508
00509 float ang = atan2(cross/(len1*len2), dot/(len1*len2));
00510 return ang;
00511 }
00512
00513
00514
00515
00516
00517