GlobeEngine
ReducableUndirectedGraph.h
Go to the documentation of this file.
1 //
2 // VBOVertex.h
3 // GlobeEngine
4 //
5 // Created by Mathias Thöny on 27.12.11.
6 // Copyright (c) 2011 University of Zurich. All rights reserved.
7 //
8 
9 #ifndef GlobeEngine_ReducableUndirectedGraph_h
10 #define GlobeEngine_ReducableUndirectedGraph_h
11 #include "VBOVertex.h"
12 #include "OpenGL_Includes.h"
13 #include <iostream>
14 
15 #include "UndirectedEdge.h"
16 #include "WeightedUndirectedEdge.h"
18 #include "GraphNode.h"
19 #include "Graph.h"
20 #include "UndirectedGraph.h"
21 
22 namespace geGraph {
23 
24  template <class NODETYPE, class EDGETYPE, class U> class ReducableUndirectedGraph : public UndirectedGraph < NODETYPE, EDGETYPE, U>
25  {
26  public:
28 
29  //
30  // reduces all edges so that just non-connector nodes are used.
31  //
32  void reduceEdges(){
33  // Start from Endpoints, not from edges
34  for (unsigned int i=0; i < this->nodes.size();i++)
35  {
36  if (this->nodes[i].isEndpoint()) {
38  }else{
39  if (this->nodes[i].isCrossing()) {
41  }
42  else{
43  // node is connector. No change
44  }
45  }
46  }
47  }
48 
49  void reduceFromEndpoint(unsigned int _nodeID){
50  unsigned int tmpEdgeID = this->nodes[_nodeID].getNeighbors()[0];
51  unsigned int tmpNodeID = this->edges[tmpEdgeID].getOppositeNode(_nodeID);
52  // weight of the edge
53  float weight = this->edges[tmpEdgeID].getWeight();
54 
55  if(this->edges[tmpEdgeID].isMarked()) {
56  return; // this route is already reduced;
57  }
58  std::vector< U > markedEdges;
59  while (this->nodes[tmpNodeID].isConnector())
60  {
61  this->edges[tmpEdgeID].mark();
62  markedEdges.push_back(tmpEdgeID);
63  tmpEdgeID = this->nodes[tmpNodeID].getOppositeEdge(tmpEdgeID);
64  tmpNodeID = this->edges[tmpEdgeID].getOppositeNode(tmpNodeID);
65  // add weight of this edge also
66  weight += this->edges[tmpEdgeID].getWeight();
67  }
68  // mark last segment
69  this->edges[tmpEdgeID].mark();
70  markedEdges.push_back(tmpEdgeID);
71 
72  EDGETYPE newUEdge(tmpEdgeID, _nodeID, tmpNodeID, weight);
73  unsigned int tmpRedEdgeID = this->reducedEdges.size();
74  reducedEdgeToGraphEdge.insert(std::pair< U , std::vector< U > >(tmpRedEdgeID, markedEdges));
75  this->reducedEdges.push_back(newUEdge);
76  // since the _nodeID is an endpoint there is just one
77  // associated reduced edge
78  std::vector< U > edgesAssociatedToNode;
79  edgesAssociatedToNode.push_back(tmpRedEdgeID);
80  nodeIDToReducedEdge.insert(std::pair< U , std::vector< U > >(_nodeID, edgesAssociatedToNode));
81 
82  // it is necessary to add this connection also to the new opposite node
83  typename std::map< U, std::vector< U > >::iterator nodeCheckItr = nodeIDToReducedEdge.find(tmpNodeID);
84  if(nodeCheckItr != nodeIDToReducedEdge.end()) {
85  nodeCheckItr->second.push_back(tmpRedEdgeID);
86  }else{
87  nodeIDToReducedEdge.insert(std::pair< U , std::vector< U > >(tmpNodeID, edgesAssociatedToNode));
88  }
89  }
90 
91  void reduceFromCrossing(unsigned int _nodeID){
92  //std::cout << "Neigbor count: " << this->nodes[_nodeID].getNeighborCount() << std::endl;
93  std::vector< U > edgesAssociatedToNode;
94  for (unsigned int i=0;i<this->nodes[_nodeID].getNeighborCount();i++)
95  {
96  unsigned int tmpEdgeID = this->nodes[_nodeID].getNeighbors()[i];
97  unsigned int tmpNodeID = this->edges[tmpEdgeID].getOppositeNode(_nodeID);
98  float weight = this->edges[tmpEdgeID].getWeight();
99 
100  if(this->edges[tmpEdgeID].isMarked()) {
101  // this route is already reduced;
102  }else{
103  std::vector< U > markedEdges;
104  while (this->nodes[tmpNodeID].isConnector())
105  {
106  this->edges[tmpEdgeID].mark();
107  markedEdges.push_back(tmpEdgeID);
108  tmpEdgeID = this->nodes[tmpNodeID].getOppositeEdge(tmpEdgeID);
109  tmpNodeID = this->edges[tmpEdgeID].getOppositeNode(tmpNodeID);
110  // add weight of this edge also
111  weight += this->edges[tmpEdgeID].getWeight();
112  }
113  this->edges[tmpEdgeID].mark();
114  markedEdges.push_back(tmpEdgeID);
115  unsigned int tmpRedEdgeID = this->reducedEdges.size();
116  EDGETYPE newUEdge(tmpEdgeID, _nodeID, tmpNodeID, weight);
117  this->reducedEdges.push_back(newUEdge);
118  reducedEdgeToGraphEdge.insert(std::pair< U , std::vector< U > >(tmpRedEdgeID, markedEdges));
119  edgesAssociatedToNode.push_back(tmpRedEdgeID);
120 
121  // it is necessary to add this connection also to the new opposite node
122  typename std::map< U, std::vector< U > >::iterator nodeCheckItr = nodeIDToReducedEdge.find(tmpNodeID);
123  if(nodeCheckItr != nodeIDToReducedEdge.end()) {
124  nodeCheckItr->second.push_back(tmpRedEdgeID);
125  }else{
126  nodeIDToReducedEdge.insert(std::pair< U , std::vector< U > >(tmpNodeID, edgesAssociatedToNode));
127  }
128  }
129  }
130  // it is necessary to add this connection also to the new opposite node
131  typename std::map< U, std::vector< U > >::iterator nodeCheckItr = nodeIDToReducedEdge.find(_nodeID);
132  if(nodeCheckItr != nodeIDToReducedEdge.end()) {
133  for(int i=0;i < edgesAssociatedToNode.size();i++) {
134  nodeCheckItr->second.push_back(edgesAssociatedToNode[i]);
135  }
136  }else{
137  nodeIDToReducedEdge.insert(std::pair< U , std::vector< U > >(_nodeID, edgesAssociatedToNode));
138  }
139  }
140 
141  std::vector< U > getEdgesForReducedEdge(unsigned int _redEdgeID) {
142  typename std::map< U, std::vector< U > >::const_iterator edgesByIDItr = reducedEdgeToGraphEdge.find(_redEdgeID);
143  if(edgesByIDItr != reducedEdgeToGraphEdge.end()) {
144  return edgesByIDItr->second;
145  }
146 
147  return std::vector<U>();
148  }
149 
150  std::vector< U > getReducedEdgesForNodeID(unsigned int _nodeID) {
151  typename std::map< U, std::vector< U > >::const_iterator edgesByIDItr = nodeIDToReducedEdge.find(_nodeID);
152  if(edgesByIDItr != nodeIDToReducedEdge.end()) {
153  return edgesByIDItr->second;
154  }
155 
156  return std::vector<U>();
157  }
158 
159  std::vector< U > getReducedNodesForNodeID(unsigned int _startNodeID, unsigned int _endNodeID) {
160  std::vector< U > nodeIDs;
161  typename std::map< U, std::vector< U > >::const_iterator edgeByIDItr = nodeIDToReducedEdge.find(_startNodeID);
162  if(edgeByIDItr != nodeIDToReducedEdge.end()) {
163  if(edgeByIDItr->second.size() == 0){
164  // no reduced nodes from this point
165  return nodeIDs;
166  }
167  if(edgeByIDItr->second.size() == 1){
168  return getReducedNodeIDsForReducedEdge(edgeByIDItr->second[0]);
169  }else{
170  // search the right connection first
171  for (unsigned int i = 0; i < edgeByIDItr->second.size();i++)
172  {
173 
174  if (_endNodeID == this->reducedEdges[edgeByIDItr->second[i]].getOppositeNode(_startNodeID) || _startNodeID == this->reducedEdges[edgeByIDItr->second[i]].getOppositeNode(_endNodeID))
175  {
176  return getReducedNodeIDsForReducedEdge(edgeByIDItr->second[i]);
177  }
178  }
179  std::cout << "Error: EndNode not found." << std::endl;
180  //return nodeIDs;
181  }
182  }else{
183  std::cout << "No reduced edge found." << std::endl;
184  }
185  return nodeIDs;
186  }
187 
188  std::vector< U > getReducedNodeIDsForReducedEdge(unsigned int _redEdgeID) {
189  std::vector< U > redNodeIds;
190  std::vector< U > edgeIds = getEdgesForReducedEdge(_redEdgeID);
191  if (edgeIds.size() > 0)
192  {
193  unsigned int prevNodeID = this->edges[edgeIds[0]].getNodes()[0];
194  if (this->nodes[prevNodeID].isConnector()) {
195  prevNodeID = this->edges[edgeIds[0]].getNodes()[1];
196  }
197 
198  redNodeIds.push_back(prevNodeID);
199  for (unsigned int i = 0; i < edgeIds.size();i++)
200  {
201  unsigned int tmpNodeID = this->edges[edgeIds[i]].getOppositeNode(prevNodeID);
202  redNodeIds.push_back(tmpNodeID);
203  prevNodeID = tmpNodeID;
204  }
205  }
206  return redNodeIds;
207  }
208 
209  EDGETYPE* getReducedEdge(unsigned int _redEdgeID) {
210  return &reducedEdges[_redEdgeID];
211  }
212 
213  unsigned int getReducedEdgesCount()
214  {
215  return reducedEdges.size();
216  }
217 
218  private:
219  std::vector< EDGETYPE > reducedEdges;
220  std::map< U, std::vector< U > > reducedEdgeToGraphEdge;
221  std::map< U, std::vector< U > > nodeIDToReducedEdge;
222  };
223 
224 
227 
230 
231 
232  template <class NODETYPE, class EDGETYPE, class U> class ReducableWeightedUndirectedGraph : public ReducableUndirectedGraph < NODETYPE, EDGETYPE, U>
233  {
234  public:
236 
237  void setReducedEdgeWheight(unsigned int _redEdgeID, float _weight)
238  {
239  this->reducedEdges[_redEdgeID].setWeight(_weight);
240  }
241 
242  void setReducedEdgeWheightByID(unsigned int _nodeID, float _weight)
243  {
244  //reducedEdges[_redEdgeID].setWeight(_weight);
245  }
246  };
247 
250 
253 
256 
257 }
258 #endif
unsigned int getReducedEdgesCount()
Definition: ReducableUndirectedGraph.h:213
std::vector< U > getReducedEdgesForNodeID(unsigned int _nodeID)
Definition: ReducableUndirectedGraph.h:150
ReducableWeightedUndirectedGraph()
Definition: ReducableUndirectedGraph.h:235
std::vector< U > getEdgesForReducedEdge(unsigned int _redEdgeID)
Definition: ReducableUndirectedGraph.h:141
void reduceEdges()
Definition: ReducableUndirectedGraph.h:32
ReducableWeightedUndirectedGraph< ge::Vertex3d, WeightedUndirectedEdgeui, unsigned int > ReducableWeightedUndirectedGraph3Dd
Definition: ReducableUndirectedGraph.h:252
ReducableWeightedUndirectedGraph< ge::Vertex3d, WeightedUndirectedPolylineEdgeui, unsigned int > ReducableWeightedUndirectedPolylineGraph3Dd
Definition: ReducableUndirectedGraph.h:255
ReducableUndirectedGraph< ge::Vertex3d, UndirectedEdgeui, unsigned int > ReducableGraph3Dd
Definition: ReducableUndirectedGraph.h:226
std::vector< U > getReducedNodeIDsForReducedEdge(unsigned int _redEdgeID)
Definition: ReducableUndirectedGraph.h:188
void setReducedEdgeWheight(unsigned int _redEdgeID, float _weight)
Definition: ReducableUndirectedGraph.h:237
ReducableWeightedUndirectedGraph< ge::Vertex2d, WeightedUndirectedEdgeui, unsigned int > ReducableWeightedGraph2Dd
Definition: ReducableUndirectedGraph.h:248
Definition: ReducableUndirectedGraph.h:232
ReducableWeightedUndirectedGraph< ge::Vertex3d, WeightedUndirectedEdgeui, unsigned int > ReducableWeightedGraph3Dd
Definition: ReducableUndirectedGraph.h:249
std::vector< U > getReducedNodesForNodeID(unsigned int _startNodeID, unsigned int _endNodeID)
Definition: ReducableUndirectedGraph.h:159
ReducableUndirectedGraph< ge::Vertex3d, UndirectedEdgeui, unsigned int > ReducableUndirectedGraph3Dd
Definition: ReducableUndirectedGraph.h:229
ReducableWeightedUndirectedGraph< ge::Vertex2d, WeightedUndirectedPolylineEdgeui, unsigned int > ReducableWeightedUndirectedPolylineGraph2Dd
Definition: ReducableUndirectedGraph.h:254
Definition: DirectedEdge.h:16
ReducableUndirectedGraph()
Definition: ReducableUndirectedGraph.h:27
std::vector< EDGETYPE > edges
Definition: Graph.h:147
void reduceFromEndpoint(unsigned int _nodeID)
Definition: ReducableUndirectedGraph.h:49
std::vector< GraphNode< U > > nodes
Definition: Graph.h:145
Definition: UndirectedGraph.h:21
void setReducedEdgeWheightByID(unsigned int _nodeID, float _weight)
Definition: ReducableUndirectedGraph.h:242
Definition: ReducableUndirectedGraph.h:24
ReducableUndirectedGraph< ge::Vertex2d, UndirectedEdgeui, unsigned int > ReducableGraph2Dd
Definition: ReducableUndirectedGraph.h:225
ReducableWeightedUndirectedGraph< ge::Vertex2d, WeightedUndirectedEdgeui, unsigned int > ReducableWeightedUndirectedGraph2Dd
Definition: ReducableUndirectedGraph.h:251
EDGETYPE * getReducedEdge(unsigned int _redEdgeID)
Definition: ReducableUndirectedGraph.h:209
ReducableUndirectedGraph< ge::Vertex2d, UndirectedEdgeui, unsigned int > ReducableUndirectedGraph2Dd
Definition: ReducableUndirectedGraph.h:228
void reduceFromCrossing(unsigned int _nodeID)
Definition: ReducableUndirectedGraph.h:91