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 #include <Graph.h>
00035 #include <Vertex.h>
00036 #include <VertexIter.h>
00037 #include <MapOfTaggedObjects.h>
00038 #include <Channel.h>
00039 #include <FEM_ObjectBroker.h>
00040 #include <Vector.h>
00041
00042 Graph::Graph()
00043 :myVertices(0), theVertexIter(0), numEdge(0), nextFreeTag(START_VERTEX_NUM)
00044 {
00045 myVertices = new MapOfTaggedObjects();
00046 theVertexIter = new VertexIter(myVertices);
00047 }
00048
00049
00050 Graph::Graph(int numVertices)
00051 :myVertices(0), theVertexIter(0), numEdge(0), nextFreeTag(START_VERTEX_NUM)
00052 {
00053 myVertices = new MapOfTaggedObjects();
00054 theVertexIter = new VertexIter(myVertices);
00055 }
00056
00057
00058 Graph::Graph(TaggedObjectStorage &theVerticesStorage)
00059 :myVertices(&theVerticesStorage), theVertexIter(0), numEdge(0), nextFreeTag(START_VERTEX_NUM)
00060 {
00061 TaggedObject *theObject;
00062 TaggedObjectIter &theObjects = theVerticesStorage.getComponents();
00063 while ((theObject = theObjects()) != 0)
00064 if (theObject->getTag() > nextFreeTag)
00065 nextFreeTag = theObject->getTag() + 1;
00066
00067 theVerticesStorage.clearAll();
00068 theVertexIter = new VertexIter(myVertices);
00069 }
00070
00071
00072 Graph::Graph(Graph &other)
00073 :myVertices(0), theVertexIter(0), numEdge(0), nextFreeTag(START_VERTEX_NUM)
00074 {
00075 myVertices = new MapOfTaggedObjects();
00076 theVertexIter = new VertexIter(myVertices);
00077
00078 VertexIter &otherVertices = other.getVertices();
00079 Vertex *vertexPtr;
00080
00081
00082 while ((vertexPtr = otherVertices()) != 0) {
00083 int vertexTag = vertexPtr->getTag();
00084 int vertexRef = vertexPtr->getRef();
00085 vertexPtr = new Vertex(vertexTag, vertexRef);
00086 if (vertexPtr == 0) {
00087 opserr << "Graph::Graph - out of memory\n";
00088 return;
00089 }
00090 this->addVertex(vertexPtr, false);
00091 }
00092
00093
00094 VertexIter &otherVertices2 = other.getVertices();
00095 while ((vertexPtr = otherVertices2()) != 0) {
00096 int vertexTag = vertexPtr->getTag();
00097 const ID &adjacency = vertexPtr->getAdjacency();
00098 for (int i=0; i<adjacency.Size(); i++) {
00099 if (this->addEdge(vertexTag, adjacency(i)) < 0) {
00100 opserr << "Graph::merge - could not add an edge!\n";
00101 return;
00102 }
00103 }
00104 }
00105 }
00106
00107 Graph::~Graph()
00108 {
00109
00110 myVertices->clearAll();
00111
00112 if (myVertices != 0)
00113 delete myVertices;
00114
00115 if (theVertexIter != 0)
00116 delete theVertexIter;
00117 }
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 bool
00128 Graph::addVertex(Vertex *vertexPtr, bool checkAdjacency)
00129 {
00130
00131 if (vertexPtr == 0) {
00132 opserr << "WARNING Graph::addVertex";
00133 opserr << " - attempting to add a NULL vertex*\n";
00134 return false;
00135 }
00136
00137 if (checkAdjacency == true) {
00138 if (vertexPtr->getDegree() != 0) {
00139 const ID &adjacency = vertexPtr->getAdjacency();
00140 int size = adjacency.Size();
00141 for (int i=0; i<size; i++) {
00142 Vertex *other = this->getVertexPtr(adjacency(i));
00143 if (other == 0) {
00144 opserr << "WARNING Graph::addVertex";
00145 opserr << " - vertex with adjacent vertex not in graph\n";
00146 return false;
00147 }
00148 }
00149 }
00150 }
00151
00152
00153 bool result = myVertices->addComponent(vertexPtr);
00154 if (result == false) {
00155 opserr << *this;
00156 opserr << "BAD VERTEX\n: " << *vertexPtr;
00157 opserr << "WARNING Graph::addVertex";
00158 opserr << " - vertex could not be stored in TaggedObjectStorage object\n";
00159 }
00160
00161
00162
00163 if (vertexPtr->getTag() >= nextFreeTag)
00164 nextFreeTag = vertexPtr->getTag() + 1;
00165
00166 return result;
00167 }
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 int
00179 Graph::addEdge(int vertexTag, int otherVertexTag)
00180 {
00181
00182
00183 Vertex *vertex1 = this->getVertexPtr(vertexTag);
00184 Vertex *vertex2 = this->getVertexPtr(otherVertexTag);
00185 if ((vertex1 == 0) || (vertex2 == 0)) {
00186 opserr << "WARNING Graph::addEdge() - one or both of the vertices ";
00187 opserr << vertexTag << " " << otherVertexTag << " not in Graph\n";
00188 return -1;
00189 }
00190
00191
00192 int result = vertex1->addEdge(otherVertexTag);
00193 if (result == 1)
00194 return 0;
00195 else if (result == 0) {
00196 if ((result = vertex2->addEdge(vertexTag)) == 0) {
00197 numEdge++;
00198 }
00199 else {
00200 opserr << " WARNING Graph::addEdge() - " << vertexTag;
00201 opserr << " added to " << otherVertexTag;
00202 opserr << " adjacency - but already there in otherVertexTag!.\n";
00203 opserr << *this; exit(0);
00204 return -2;
00205 }
00206 } else {
00207 opserr << " WARNING Graph::addEdge() - " << vertexTag;
00208 opserr << " added to " << otherVertexTag;
00209 opserr << " adjacency - but not vica versa!.\n";
00210 opserr << *this; exit(0);
00211 return -2;
00212 }
00213 return result;
00214 }
00215
00216
00217 Vertex *
00218 Graph::getVertexPtr(int vertexTag)
00219 {
00220 TaggedObject *res = myVertices->getComponentPtr(vertexTag);
00221 if (res == 0) return 0;
00222 Vertex *result = (Vertex *)res;
00223 return result;
00224 }
00225
00226
00227 VertexIter &
00228 Graph::getVertices(void)
00229 {
00230
00231 theVertexIter->reset();
00232 return *theVertexIter;
00233 }
00234
00235
00236 int
00237 Graph::getNumVertex(void) const
00238 {
00239 return myVertices->getNumComponents();
00240 }
00241
00242 int
00243 Graph::getNumEdge(void) const
00244 {
00245 return numEdge;
00246 }
00247
00248 int
00249 Graph::getFreeTag(void)
00250 {
00251 return nextFreeTag;
00252 }
00253
00254 Vertex *
00255 Graph::removeVertex(int tag, bool flag)
00256 {
00257 TaggedObject *mc = myVertices->removeComponent(tag);
00258 if (mc == 0) return 0;
00259 Vertex *result = (Vertex *)mc;
00260
00261 if (flag == true) {
00262 opserr << "Graph::removeVertex(int tag, bool flag = true)";
00263 opserr << " - no code to remove edges yet\n";
00264 return 0;
00265 }
00266 return result;
00267 }
00268
00269
00270 int
00271 Graph::merge(Graph &other) {
00272
00273 int result =0;
00274 VertexIter &otherVertices = other.getVertices();
00275 Vertex *vertexPtrOther;
00276
00277
00278 while ((vertexPtrOther = otherVertices()) != 0) {
00279 int vertexTag = vertexPtrOther->getTag();
00280 Vertex *vertexPtr = this->getVertexPtr(vertexTag);
00281 if (vertexPtr == 0) {
00282 int vertexRef = vertexPtrOther->getRef();
00283 vertexPtr = new Vertex(vertexTag, vertexRef);
00284 if (vertexPtr == 0) {
00285 opserr << "Graph::merge - out of memory\n";
00286 return -1;
00287 }
00288 this->addVertex(vertexPtr, false);
00289 }
00290 }
00291
00292
00293
00294 VertexIter &otherVertices2 = other.getVertices();
00295 while ((vertexPtrOther = otherVertices2()) != 0) {
00296 int vertexTag = vertexPtrOther->getTag();
00297 const ID &adjacency = vertexPtrOther->getAdjacency();
00298 for (int i=0; i<adjacency.Size(); i++) {
00299 if (this->addEdge(vertexTag, adjacency(i)) < 0) {
00300 opserr << "Graph::merge - could not add an edge!\n";
00301 return -2;
00302 }
00303 }
00304 }
00305
00306 return result;
00307 }
00308
00309
00310 void
00311 Graph::Print(OPS_Stream &s, int flag)
00312 {
00313 myVertices->Print(s, flag);
00314 }
00315
00316
00317 OPS_Stream &operator<<(OPS_Stream &s, Graph &M)
00318 {
00319 M.Print(s);
00320 return s;
00321 }
00322
00323
00324 int
00325 Graph::sendSelf(int commitTag, Channel &theChannel)
00326 {
00327
00328 if (theChannel.isDatastore() != 0) {
00329 opserr << "Graph::sendSelf() - does not at present send to a database\n";
00330 return -1;
00331 }
00332
00333 int numVertex = this->getNumVertex();
00334
00335
00336 static ID idData(2);
00337 idData(0) = numEdge;
00338 idData(1) = numVertex;
00339 if (theChannel.sendID(0, commitTag, idData) < 0) {
00340 opserr << "Graph::sendSelf() - failed to send the id\n";
00341 return -3;
00342 }
00343
00344 if (numVertex != 0) {
00345 int *vertexData = new int[5 * numVertex + 2 * numEdge];
00346 Vector vertexWeights(numVertex);
00347 if (vertexData != 0) {
00348 VertexIter &theVertices = this->getVertices();
00349 Vertex *vertexPtr;
00350 int adjacencyLocation = 5 * numVertex;
00351 int vertexLocation = 0;
00352 int weightLoc = 0;
00353 while ((vertexPtr = theVertices()) != 0) {
00354 int tag = vertexPtr->getTag();
00355 int color = vertexPtr->getColor();
00356 int ref = vertexPtr->getRef();
00357 int tmp = vertexPtr->getTmp();
00358 const ID &adjacency = vertexPtr->getAdjacency();
00359 int adjSize = adjacency.Size();
00360 vertexData[vertexLocation++] = tag;
00361 vertexData[vertexLocation++] = ref;
00362 vertexData[vertexLocation++] = color;
00363 vertexData[vertexLocation++] = tmp;
00364 vertexData[vertexLocation++] = adjSize;
00365 for (int i=0; i<adjSize; i++)
00366 vertexData[adjacencyLocation++] = adjacency(i);
00367 vertexWeights[weightLoc++] = vertexPtr->getWeight();
00368
00369 }
00370
00371 ID verticesData(vertexData, adjacencyLocation, true);
00372 if (theChannel.sendID(0, commitTag, verticesData) < 0) {
00373 opserr << "Graph::sendSelf() - failed to send the id\n";
00374 return -3;
00375 }
00376 if (theChannel.sendVector(0, commitTag, vertexWeights) < 0) {
00377 opserr << "Graph::sendSelf() - failed to send the id\n";
00378 return -3;
00379 }
00380 }
00381 }
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 return 0;
00394 }
00395
00396
00397 int
00398 Graph::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00399 {
00400
00401 if (theChannel.isDatastore() != 0) {
00402 opserr << "Graph::recvSelf() - at present does not receive from a database\n";
00403 return -1;
00404 }
00405
00406
00407 if (this->getNumVertex() != 0) {
00408 opserr << "Graph::recvSelf() - can only receive to an empty graph at present\n";
00409
00410 numEdge = 0;
00411 myVertices->clearAll();
00412 }
00413
00414
00415 static ID idData(2);
00416 if (theChannel.recvID(0, commitTag, idData) < 0) {
00417 opserr << "Graph::recvSelf() - failed to receive the id\n";
00418 return -3;
00419 }
00420
00421 numEdge = idData(0);
00422 int numVertex = idData(1);
00423
00424 if (numVertex != 0) {
00425
00426 int *vertexData = new int[5 * numVertex + 2 * numEdge];
00427 if (vertexData != 0) {
00428 ID verticesData(vertexData, 5*numVertex + 2 * numEdge, true);
00429 if (theChannel.recvID(0, commitTag, verticesData) < 0) {
00430 opserr << "Graph::sendSelf() - failed to send the id\n";
00431 return -3;
00432 }
00433 Vector vertexWeights(numVertex);
00434 if (theChannel.recvVector(0, commitTag, vertexWeights) < 0) {
00435 opserr << "Graph::sendSelf() - failed to send the id\n";
00436 return -3;
00437 }
00438
00439 int adjacencyLocation = 5 * numVertex;
00440 int vertexLocation = 0;
00441 for (int i=0; i<numVertex; i++) {
00442 int tag = vertexData[vertexLocation++];
00443 int ref = vertexData[vertexLocation++];
00444 int color = vertexData[vertexLocation++];
00445 int tmp = vertexData[vertexLocation++];
00446 int adjSize = vertexData[vertexLocation++];
00447 Vertex *theVertex = new Vertex(tag, ref);
00448 if (theVertex == 0) {
00449 opserr << "Graph::recvSelf() - out of memory\n";
00450 return -4;
00451 }
00452 theVertex->setColor(color);
00453 theVertex->setTmp(tmp);
00454 theVertex->setWeight(vertexWeights(i));
00455 for (int i=0; i<adjSize; i++) {
00456 int edge = vertexData[adjacencyLocation++];
00457 theVertex->addEdge(edge);
00458 }
00459 this->addVertex(theVertex, false);
00460 }
00461 } else {
00462 opserr << "Graph::recvSelf() - out of memory\n";
00463 return -5;
00464 }
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 return 0;
00483
00484 }