RepastHPC  2.3.1
Graph.h
1 /*
2  * Repast for High Performance Computing (Repast HPC)
3  *
4  * Copyright (c) 2010 Argonne National Laboratory
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with
8  * or without modification, are permitted provided that the following
9  * conditions are met:
10  *
11  * Redistributions of source code must retain the above copyright notice,
12  * this list of conditions and the following disclaimer.
13  *
14  * Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * Neither the name of the Argonne National Laboratory nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE TRUSTEES OR
26  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
32  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  *
35  * Graph.h
36  *
37  * Created on: Dec 23, 2008
38  * Author: nick
39  */
40 
41 #ifndef GRAPH_H_
42 #define GRAPH_H_
43 
44 #include "AgentId.h"
45 #include "Projection.h"
46 #include "Edge.h"
47 #include "DirectedVertex.h"
48 #include "UndirectedVertex.h"
49 
50 #include <vector>
51 #include <utility>
52 #include <map>
53 #include <iostream>
54 #include <boost/unordered_map.hpp>
55 #include <boost/smart_ptr.hpp>
56 #include <boost/serialization/access.hpp>
57 #include <boost/iterator/transform_iterator.hpp>
58 
59 namespace repast {
60 
71 template<typename V, typename E, typename Ec, typename EcM>
72 class Graph: public Projection<V> {
73 
74 protected:
75  typedef boost::unordered_map<AgentId, Vertex<V, E>*, HashId> VertexMap;
76  typedef typename VertexMap::iterator VertexMapIterator;
77 
78  typedef typename Projection<V>::RADIUS RADIUS;
79 
80  int edgeCount_;
81  bool isDirected;
82  VertexMap vertices;
83 
84  EcM* edgeContentManager;
85 
86  void cleanUp();
87  void init(const Graph& graph);
88 
89  virtual bool addAgent(boost::shared_ptr<V> agent);
90  virtual void removeAgent(V* agent);
91 
92  virtual void doAddEdge(boost::shared_ptr<E> edge, bool allowOverwrite = true);
93 
94 public:
95 
96 
100  typedef typename boost::transform_iterator<NodeGetter<V, E> , typename VertexMap::const_iterator> vertex_iterator;
101 
102  std::set<int> ranksToSendProjInfoTo; // Set these if the ranks for exchanging projection info are known
103  std::set<int> ranksToReceiveProjInfoFrom;
104 
105  std::set<int> ranksToSendAgentStatusInfoTo; // Set these if the ranks for exchanging agent status info are known
106  std::set<int> ranksToReceiveAgentStatusInfoFrom;
107 
108  bool keepsAgents; // Set this to false if you are CERTAIN that this projection will never 'keep' an agent during a proj info sync
109  bool sendsSecondaryAgents; // Set this to false if you are CERTAIN that this projection will never send secondary agents during an agent status sync (VERY RARE)
110 
117  Graph(std::string name, bool directed, EcM* edgeContentMgr) :
118  Projection<V> (name), edgeCount_(0), isDirected(directed), edgeContentManager(edgeContentMgr), keepsAgents(true), sendsSecondaryAgents(true) {
119  }
120 
124  Graph(const Graph<V, E, Ec, EcM>& graph);
125  virtual ~Graph();
126 
127  // assignment
128  Graph& operator=(const Graph& graph);
129 
138  virtual boost::shared_ptr<E> addEdge(V* source, V* target);
139 
149  virtual boost::shared_ptr<E> addEdge(V* source, V* target, double weight);
150 
160  virtual boost::shared_ptr<E> findEdge(V* source, V* target);
161 
169  virtual void successors(V* vertex, std::vector<V*>& out);
170 
178  virtual void predecessors(V* vertex, std::vector<V*>& out);
179 
186  virtual void adjacent(V* vertex, std::vector<V*>& out);
187 
194  virtual void removeEdge(V* source, V* target);
195 
202  virtual void removeEdge(const AgentId& source, const AgentId& target);
203 
209  virtual int inDegree(V* vertex);
210 
216  virtual int outDegree(V* vertex);
217 
223  int edgeCount() const {
224  return edgeCount_;
225  }
226 
232  int vertexCount() const {
233  return vertices.size();
234  }
235 
243  return vertex_iterator(vertices.begin());
244  }
245 
253  return vertex_iterator(vertices.end());
254  }
255 
256  void showEdges();
257 
258 
259  // Beta
260  virtual bool isMaster(E* e) = 0;
261 
262  virtual bool keepsAgentsOnSyncProj(){ return keepsAgents; }
263 
264  virtual bool sendsSecondaryAgentsOnStatusExchange(){ return sendsSecondaryAgents; }
265 
266  virtual void getInfoExchangePartners(std::set<int>& psToSendTo, std::set<int>& psToReceiveFrom);
267 
268  virtual void getAgentStatusExchangePartners(std::set<int>& psToSendTo, std::set<int>& psToReceiveFrom);
269 
270  virtual void getProjectionInfo(std::vector<AgentId>& agents, std::vector<ProjectionInfoPacket*>& packets,
271  bool secondaryInfo = false, std::set<AgentId>* secondaryIds = 0, int destProc = -1);
272 
273  virtual ProjectionInfoPacket* getProjectionInfo(AgentId id, bool secondaryInfo = false, std::set<AgentId>* secondaryIds = 0, int destProc = -1 );
274 
275  virtual void updateProjectionInfo(ProjectionInfoPacket* pip, Context<V>* context);
276 
277  virtual void getRequiredAgents(std::set<AgentId>& agentsToTest, std::set<AgentId>& agentsRequired, RADIUS radius =Projection<V>::PRIMARY);
278 
279  virtual void getAgentsToPush(std::set<AgentId>& agentsToTest, std::map<int, std::set<AgentId> >& agentsToPush);
280 
281  virtual void cleanProjectionInfo(std::set<AgentId>& agentsToKeep);
282 
283  void clearConflictedEdges();
284 
285  void getConflictedEdges(std::set<boost::shared_ptr<E> >& conflictedEdges);
286 
287 };
288 
289 template<typename V, typename E, typename Ec, typename EcM>
290 Graph<V, E, Ec, EcM>::~Graph() {
291  cleanUp();
292 }
293 
294 template<typename V, typename E, typename Ec, typename EcM>
295 void Graph<V, E, Ec, EcM>::cleanUp() {
296  for (VertexMapIterator iter = vertices.begin(); iter != vertices.end(); ++iter) {
297  delete iter->second;
298  }
299  vertices.clear();
300 }
301 
302 template<typename V, typename E, typename Ec, typename EcM>
304  init(graph);
305 }
306 
307 template<typename V, typename E, typename Ec, typename EcM>
309  edgeCount_ = graph.edgeCount_;
310  isDirected = graph.isDirected;
311  edgeContentManager = graph.edgeContentManager;
312 
313  // create new vertices from the old ones
314  for (VertexMapIterator iter = graph.vertices.begin(); iter != graph.vertices.end(); ++iter) {
315  Vertex<V, E>* vertex = iter->second;
316  if (isDirected) {
317  vertices[iter->first] = new DirectedVertex<V, E> (vertex->item());
318  } else {
319  vertices[iter->first] = new UndirectedVertex<V, E> (vertex->item());
320  }
321  }
322 
323  // fill adj list maps using the new vertex info.
324  // create new vertices from the old ones
325  for (VertexMapIterator iter = graph.vertices.begin(); iter != graph.vertices.end(); ++iter) {
326  Vertex<V, E>* vertex = iter->second;
327  Vertex<V, E>* newVert = vertices[iter->first];
328  std::vector<boost::shared_ptr<E> > edges;
329 
330  vertex->edges(Vertex<V, E>::OUTGOING, edges);
331  for (typename std::vector<boost::shared_ptr<E> >::iterator iter = edges.begin(); iter != edges.end(); ++iter) {
332  // create new edge and add it
333  boost::shared_ptr<E> newEdge(new E(**iter));
334  doAddEdge(newEdge);
335  }
336  }
337 }
338 
339 template<typename V, typename E, typename Ec, typename EcM>
340 Graph<V, E, Ec, EcM>& Graph<V, E, Ec, EcM>::operator=(const Graph<V, E, Ec, EcM>& graph) {
341  if (this != &graph) {
342  cleanUp();
343  init(graph);
344  }
345 
346  return *this;
347 }
348 
349 template<typename V, typename E, typename Ec, typename EcM>
350 boost::shared_ptr<E> Graph<V, E, Ec, EcM>::addEdge(V* source, V* target) {
351  boost::shared_ptr<E> ret;
352 
353  const VertexMapIterator notFound = Graph<V, E, Ec, EcM>::vertices.end();
354 
355  VertexMapIterator srcIter = vertices.find(source->getId());
356  if (srcIter == notFound) return ret;
357 
358  VertexMapIterator targetIter = vertices.find(target->getId());
359  if (targetIter == notFound) return ret;
360 
361  boost::shared_ptr<E> edge(new E(srcIter->second->item(), targetIter->second->item()));
362  doAddEdge(edge);
363  return edge;
364 }
365 
366 template<typename V, typename E, typename Ec, typename EcM>
367 boost::shared_ptr<E> Graph<V, E, Ec, EcM>::addEdge(V* source, V* target, double weight) {
368  boost::shared_ptr<E> ret;
369 
370  const VertexMapIterator notFound = Graph<V, E, Ec, EcM>::vertices.end();
371 
372  VertexMapIterator srcIter = vertices.find(source->getId());
373  if (srcIter == notFound) return ret;
374 
375  VertexMapIterator targetIter = vertices.find(target->getId());
376  if (targetIter == notFound) return ret;
377 
378  boost::shared_ptr<E> edge(new E(srcIter->second->item(), targetIter->second->item(), weight));
379  doAddEdge(edge);
380  return edge;
381 }
382 
383 template<typename V, typename E, typename Ec, typename EcM>
384 void Graph<V, E, Ec, EcM>::successors(V* vertex, std::vector<V*>& out) {
385  VertexMapIterator iter = Graph<V, E, Ec, EcM>::vertices.find(vertex->getId());
386  if (iter != Graph<V, E, Ec, EcM>::vertices.end()) iter->second->successors(out);
387 }
388 
389 template<typename V, typename E, typename Ec, typename EcM>
390 void Graph<V, E, Ec, EcM>::predecessors(V* vertex, std::vector<V*>& out) {
391  VertexMapIterator iter = Graph<V, E, Ec, EcM>::vertices.find(vertex->getId());
392  if (iter != vertices.end()) iter->second->predecessors(out);
393 }
394 
395 template<typename V, typename E, typename Ec, typename EcM>
396 void Graph<V, E, Ec, EcM>::adjacent(V* vertex, std::vector<V*>& out) {
397  VertexMapIterator iter = Graph<V, E, Ec, EcM>::vertices.find(vertex->getId());
398  if (iter != vertices.end()) iter->second->adjacent(out);
399 }
400 
401 template<typename V, typename E, typename Ec, typename EcM>
403  VertexMapIterator iter = Graph<V, E, Ec, EcM>::vertices.find(vertex->getId());
404  return (iter != vertices.end() ? iter->second->inDegree() : 0);
405 }
406 
407 template<typename V, typename E, typename Ec, typename EcM>
409  VertexMapIterator iter = Graph<V, E, Ec, EcM>::vertices.find(vertex->getId());
410  return (iter != vertices.end() ? iter->second->outDegree() : 0);
411 }
412 
413 template<typename V, typename E, typename Ec, typename EcM>
414 void Graph<V, E, Ec, EcM>::removeEdge(const AgentId& sourceId, const AgentId& targetId) {
415  const VertexMapIterator vertexNotFound = Graph<V, E, Ec, EcM>::vertices.end();
416 
417  VertexMapIterator iter = Graph<V, E, Ec, EcM>::vertices.find(sourceId);
418  if (iter == vertexNotFound) return;
419  Vertex<V, E>* sVert = iter->second;
420 
421  iter = Graph<V, E, Ec, EcM>::vertices.find(targetId);
422  if (iter == vertexNotFound) return;
423  Vertex<V, E>* tVert = iter->second;
424 
425  boost::shared_ptr<E> edgeNotFound;
426  if(sVert->removeEdge(tVert, Vertex<V, E>::OUTGOING) != edgeNotFound) edgeCount_--;
427  tVert->removeEdge(sVert, Vertex<V, E>::INCOMING);
428 
429 }
430 
431 template<typename V, typename E, typename Ec, typename EcM>
432 void Graph<V, E, Ec, EcM>::removeEdge(V* source, V* target) {
433  removeEdge(source->getId(), target->getId());
434 }
435 
436 template<typename V, typename E, typename Ec, typename EcM>
437 void Graph<V, E, Ec, EcM>::removeAgent(V* vertex) {
438  VertexMapIterator iter = Graph<V, E, Ec, EcM>::vertices.find(vertex->getId());
439  if (iter != vertices.end()) {
440  Vertex<V, E>* iVert = iter->second;
441  std::vector<V*> adjacentVertices;
442  iVert->adjacent(adjacentVertices);
443  for(typename std::vector<V*>::iterator adjIter = adjacentVertices.begin(), adjIterEnd = adjacentVertices.end(); adjIter != adjIterEnd; ++adjIter){
444  removeEdge(vertex->getId(), (*adjIter)->getId());
445  removeEdge((*adjIter)->getId(), vertex->getId());
446  }
447 
448  delete iVert;
449  vertices.erase(iter);
450  }
451 }
452 
453 template<typename V, typename E, typename Ec, typename EcM>
454 bool Graph<V, E, Ec, EcM>::addAgent(boost::shared_ptr<V> agent) {
455  if(!Projection<V>::agentCanBeAdded(agent)) return false;
456  if (vertices.find(agent->getId()) != vertices.end()) return false;
457 
458  if(isDirected) vertices[agent->getId()] = new DirectedVertex<V, E> (agent);
459  else vertices[agent->getId()] = new UndirectedVertex<V, E> (agent);
460 
461  return true;
462 }
463 
464 template<typename V, typename E, typename Ec, typename EcM>
465 boost::shared_ptr<E> Graph<V, E, Ec, EcM>::findEdge(V* source, V* target) {
466  boost::shared_ptr<E> ret;
467 
468  const VertexMapIterator notFound = Graph<V, E, Ec, EcM>::vertices.end();
469 
470  VertexMapIterator sIter = vertices.find(source->getId());
471  if (sIter == notFound) return ret;
472 
473  VertexMapIterator tIter = vertices.find(target->getId());
474  if (tIter == notFound) return ret;
475 
476  return sIter->second->findEdge(tIter->second, Vertex<V, E>::OUTGOING);
477 }
478 
479 template<typename V, typename E, typename Ec, typename EcM>
480 void Graph<V, E, Ec, EcM>::doAddEdge(boost::shared_ptr<E> edge, bool allowOverwrite) {
481  V* source = edge->source();
482  V* target = edge->target();
483 
484  Vertex<V, E>* vSource = vertices[source->getId()];
485  Vertex<V, E>* vTarget = vertices[target->getId()];
486 
487  boost::shared_ptr<E> notFound;
488  boost::shared_ptr<E> extant = vSource->findEdge(vTarget, Vertex<V, E>::OUTGOING);
489  if(extant == notFound){
490  vSource->addEdge(vTarget, edge, Vertex<V, E>::OUTGOING);
491  vTarget->addEdge(vSource, edge, Vertex<V, E>::INCOMING);
492  edgeCount_++;
493  }
494  else{
495  if(allowOverwrite){
496  vSource->removeEdge(vTarget, Vertex<V, E>::OUTGOING);
497  vTarget->removeEdge(vSource, Vertex<V, E>::INCOMING);
498 
499  vSource->addEdge(vTarget, edge, Vertex<V, E>::OUTGOING);
500  vTarget->addEdge(vSource, edge, Vertex<V, E>::INCOMING);
501  }
502  else extant->markConflicted();
503  }
504 }
505 
506 template<typename V, typename E, typename Ec, typename EcM>
507 void Graph<V, E, Ec, EcM>::showEdges(){
508  std::set<boost::shared_ptr<E> > edgeSet;
509  for(typename VertexMap::iterator iter = vertices.begin(), iterEnd = vertices.end(); iter != iterEnd; ++iter){
510  std::vector<boost::shared_ptr<E> > edges;
511  (*iter).second->edges(repast::Vertex<V, E>::INCOMING, edges);
512  (*iter).second->edges(repast::Vertex<V, E>::OUTGOING, edges);
513  for(typename std::vector<boost::shared_ptr<E> >::iterator EI = edges.begin(), EIEnd = edges.end(); EI != EIEnd; ++EI) edgeSet.insert(*EI);
514  }
515  for(typename std::set<boost::shared_ptr<E> >::iterator ei = edgeSet.begin(), eiEnd = edgeSet.end(); ei != eiEnd; ++ei){
516  std::cout << "SOURCE: " << (*ei)->source()->getId() << " TARGET: " << (*ei)->target()->getId() << " " << (isMaster(&**ei) ? "MASTER" : "NONLOCAL") << " Weight = " << (*ei)->weight() << std::endl;
517  }
518 }
519 
520 
521 
522 // Beta
523 
524 template<typename V, typename E, typename Ec, typename EcM>
525 void Graph<V, E, Ec, EcM>::getInfoExchangePartners(std::set<int>& psToSendTo, std::set<int>& psToReceiveFrom){
526  psToSendTo.insert(ranksToSendProjInfoTo.begin(), ranksToSendProjInfoTo.end());
527  psToReceiveFrom.insert(ranksToReceiveProjInfoFrom.begin(), ranksToReceiveProjInfoFrom.end());
528 }
529 
530 template<typename V, typename E, typename Ec, typename EcM>
531 void Graph<V, E, Ec, EcM>::getAgentStatusExchangePartners(std::set<int>& psToSendTo, std::set<int>& psToReceiveFrom){
532  psToSendTo.insert(ranksToSendAgentStatusInfoTo.begin(), ranksToSendAgentStatusInfoTo.end());
533  psToReceiveFrom.insert(ranksToReceiveAgentStatusInfoFrom.begin(), ranksToReceiveAgentStatusInfoFrom.end());
534 }
535 
536 
537 template<typename V, typename E, typename Ec, typename EcM>
538 void Graph<V, E, Ec, EcM>::getProjectionInfo(std::vector<AgentId>& agents, std::vector<ProjectionInfoPacket*>& packets,
539  bool secondaryInfo, std::set<AgentId>* secondaryIds, int destProc){
540  if(secondaryInfo == false) return; // Can be skipped entirely for graphs
541  // If not, call the superclass's implementation
542  Projection<V>::getProjectionInfo(agents, packets, secondaryInfo, secondaryIds, destProc);
543 }
544 
545 
546 template<typename V, typename E, typename Ec, typename EcM>
547 ProjectionInfoPacket* Graph<V, E, Ec, EcM>::getProjectionInfo(AgentId id, bool secondaryInfo, std::set<AgentId>* secondaryIds, int destProc ){
548  if(secondaryInfo == false) return 0; // All graph projection info is secondary; if not returning it, done.
549 
550  VertexMapIterator agent = vertices.find(id);
551  if(agent == vertices.end()) return 0; // The requested agent is not in this graph
552 
553  std::vector<Ec> edgeContent;
554 
555  std::vector<boost::shared_ptr<E> > edges;
556  agent->second->edges(Vertex<V, E>::INCOMING, edges);
557  agent->second->edges(Vertex<V, E>::OUTGOING, edges);
558  // Sometimes the incoming and outgoing edges are the same; purge duplicates
559  std::set<boost::shared_ptr<E> > edgeSet;
560  edgeSet.insert(edges.begin(), edges.end());
561  // Make all four instances of the loop to optimize for each case
562  AgentId sourceId;
563  AgentId targetId;
564  AgentId otherId;
565 
566  if(secondaryIds == 0){
567  if(destProc > -1){
568  for(typename std::set<boost::shared_ptr<E> >::iterator iter = edgeSet.begin(), iterEnd = edgeSet.end(); iter != iterEnd; ++iter){
569  sourceId = (*iter)->source()->getId();
570  targetId = (*iter)->target()->getId();
571  otherId = (sourceId != id ? sourceId : targetId);
572  if(otherId.currentRank() == destProc) edgeContent.push_back(*(edgeContentManager->provideEdgeContent(iter->get())));
573  }
574  }
575  else{
576  for(typename std::set<boost::shared_ptr<E> >::iterator iter = edgeSet.begin(), iterEnd = edgeSet.end(); iter != iterEnd; ++iter){
577  sourceId = (*iter)->source()->getId();
578  targetId = (*iter)->target()->getId();
579  otherId = (sourceId != id ? sourceId : targetId);
580  edgeContent.push_back(*(edgeContentManager->provideEdgeContent(iter->get())));
581  }
582  }
583  }
584  else{
585  if(destProc > -1){
586  for(typename std::set<boost::shared_ptr<E> >::iterator iter = edgeSet.begin(), iterEnd = edgeSet.end(); iter != iterEnd; ++iter){
587  sourceId = (*iter)->source()->getId();
588  targetId = (*iter)->target()->getId();
589  otherId = (sourceId != id ? sourceId : targetId);
590  if(otherId.currentRank() == destProc){
591  secondaryIds->insert(otherId);
592  edgeContent.push_back(*(edgeContentManager->provideEdgeContent(iter->get())));
593  }
594  }
595  }
596  else{
597  for(typename std::set<boost::shared_ptr<E> >::iterator iter = edgeSet.begin(), iterEnd = edgeSet.end(); iter != iterEnd; ++iter){
598  sourceId = (*iter)->source()->getId();
599  targetId = (*iter)->target()->getId();
600  otherId = (sourceId != id ? sourceId : targetId);
601  secondaryIds->insert(otherId);
602  edgeContent.push_back(*(edgeContentManager->provideEdgeContent(iter->get())));
603  }
604  }
605  }
606 
607  return new SpecializedProjectionInfoPacket<Ec>(id, edgeContent);
608 }
609 
610 template<typename V, typename E, typename Ec, typename EcM>
611 void Graph<V, E, Ec, EcM>::updateProjectionInfo(ProjectionInfoPacket* pip, Context<V>* context){
612  SpecializedProjectionInfoPacket<Ec>* spip = static_cast<SpecializedProjectionInfoPacket<Ec>*>(pip);
613  std::vector<Ec> &edges = spip->data;
614  for(int i = 0; i < edges.size(); i++){
615  boost::shared_ptr<E> newEdge(edgeContentManager->createEdge(edges[i], context));
616  doAddEdge(newEdge, false);
617  }
618 }
619 
620 
621 
622 template<typename V, typename E, typename Ec, typename EcM>
623 void Graph<V, E, Ec, EcM>::getRequiredAgents(std::set<AgentId>& agentsToTest, std::set<AgentId>& agentsRequired, RADIUS radius){
624  switch(radius){
625  case Projection<V>::PRIMARY: {// Keep only the nonlocal ends of MASTER edges
626  std::set<AgentId>::iterator iter = agentsToTest.begin();
627  while(iter != agentsToTest.end()){
628  VertexMapIterator vertex = Graph<V, E, Ec, EcM>::vertices.find(*iter);
629  if(vertex != vertices.end()){
630  std::vector<boost::shared_ptr<E> > edges;
631  vertex->second->edges(Vertex<V, E>::INCOMING, edges);
632  vertex->second->edges(Vertex<V, E>::OUTGOING, edges);
633  std::set<boost::shared_ptr<E> > edgeSet;
634  edgeSet.insert(edges.begin(), edges.end());
635  edges.clear();
636  edges.assign(edgeSet.begin(), edgeSet.end());
637  bool keep = false;
638  for(typename std::vector<boost::shared_ptr<E> >::iterator edgeIter = edges.begin(), edgeIterEnd = edges.end(); edgeIter != edgeIterEnd; edgeIter++){
639  if(isMaster(&**edgeIter)){
640  agentsRequired.insert(*iter);
641  keep = true;
642  break;
643  }
644  }
645  if(keep){
646  std::set<AgentId>::iterator iterTEMP = iter;
647  iter++;
648  agentsToTest.erase(*iterTEMP);
649  }
650  else iter++;
651  }
652  else iter++;
653  }
654  break;
655  }
656  case Projection<V>::SECONDARY: {// Keep any nonlocal agent that is in any edge
657  std::set<AgentId>::iterator iter = agentsToTest.begin();
658  while(iter != agentsToTest.end()){
659  VertexMapIterator vertex = Graph<V, E, Ec, EcM>::vertices.find(*iter);
660  if(vertex != vertices.end()){
661  std::vector<boost::shared_ptr<E> > edges;
662  vertex->second->edges(Vertex<V, E>::INCOMING, edges);
663  vertex->second->edges(Vertex<V, E>::OUTGOING, edges);
664  if(edges.size() > 0){
665  std::set<AgentId>::iterator iterTEMP = iter;
666  iter++;
667  agentsToTest.erase(*iterTEMP);
668  }
669  else iter++;
670  }
671  else iter++;
672  }
673  break;
674  }
675  }
676 }
677 
678 template<typename V, typename E, typename Ec, typename EcM>
679 void Graph<V, E, Ec, EcM>::getAgentsToPush(std::set<AgentId>& agentsToTest, std::map<int, std::set<AgentId> >& agentsToPush){
680  if(agentsToTest.size() == 0) return;
681  // The local agent ends of master edges must be pushed to the process of the non-local end
682  std::set<AgentId>::iterator iter = agentsToTest.begin();
683  while(iter != agentsToTest.end()){
684  VertexMapIterator vertexMapEntry = Graph<V, E, Ec, EcM>::vertices.find(*iter);
685  if(vertexMapEntry != vertices.end()){
686  int localRank = vertexMapEntry->second->item()->getId().currentRank();
687  std::vector<boost::shared_ptr<E> > edges;
688  vertexMapEntry->second->edges(Vertex<V, E>::INCOMING, edges);
689  vertexMapEntry->second->edges(Vertex<V, E>::OUTGOING, edges);
690  for(typename std::vector<boost::shared_ptr<E> >::iterator edgeIter = edges.begin(), edgeIterEnd = edges.end(); edgeIter != edgeIterEnd; ++edgeIter){
691  boost::shared_ptr<E> e = *edgeIter;
692  if(isMaster(&**edgeIter)){
693  AgentId sourceId = (*edgeIter)->source()->getId();
694  AgentId targetId = (*edgeIter)->target()->getId();
695  AgentId otherAgentId = (sourceId != *iter ? sourceId : targetId);
696  int destRank = otherAgentId.currentRank();
697  if(destRank != localRank){
698  agentsToPush[destRank].insert(*iter);
699  }
700  }
701  }
702  }
703  iter++;
704  }
705 }
706 
707 template<typename V, typename E, typename Ec, typename EcM>
708 void Graph<V, E, Ec, EcM>::cleanProjectionInfo(std::set<AgentId>& agentsToKeep){
709  for(std::set<AgentId>::iterator iter = agentsToKeep.begin(), iterEnd = agentsToKeep.end(); iter != iterEnd; ++iter){
710  VertexMapIterator vertexMapEntry = Graph<V, E, Ec, EcM>::vertices.find(*iter);
711  if(vertexMapEntry != vertices.end()){
712  std::vector<boost::shared_ptr<E> > edges;
713  vertexMapEntry->second->edges(Vertex<V, E>::INCOMING, edges);
714  for(typename std::vector<boost::shared_ptr<E> >::iterator edgeIter = edges.begin(), edgeIterEnd = edges.end(); edgeIter != edgeIterEnd; ++edgeIter){
715  if(!isMaster(&**edgeIter)) removeEdge((*edgeIter)->source(), (*edgeIter)->target());
716  }
717  edges.clear();
718  vertexMapEntry->second->edges(Vertex<V, E>::OUTGOING, edges);
719  for(typename std::vector<boost::shared_ptr<E> >::iterator edgeIter = edges.begin(), edgeIterEnd = edges.end(); edgeIter != edgeIterEnd; ++edgeIter){
720  if(!isMaster(&**edgeIter)) removeEdge((*edgeIter)->source(), (*edgeIter)->target());
721  }
722  }
723  }
724 }
725 
726 template<typename V, typename E, typename Ec, typename EcM>
727 void Graph<V, E, Ec, EcM>::clearConflictedEdges(){
728  for(typename VertexMap::iterator iter = vertices.begin(), iterEnd = vertices.end(); iter != iterEnd; ++iter){
729  std::vector<boost::shared_ptr<E> > edges;
730  (*iter).second->edges(repast::Vertex<V, E>::INCOMING, edges);
731  (*iter).second->edges(repast::Vertex<V, E>::OUTGOING, edges);
732  for(typename std::vector<boost::shared_ptr<E> >::iterator EI = edges.begin(), EIEnd = edges.end(); EI != EIEnd; ++EI){
733  (*EI)->clearConflicted();
734  }
735  }
736 }
737 
738 template<typename V, typename E, typename Ec, typename EcM>
739 void Graph<V, E, Ec, EcM>::getConflictedEdges(std::set<boost::shared_ptr<E> >& conflictedEdges){
740  for(typename VertexMap::iterator iter = vertices.begin(), iterEnd = vertices.end(); iter != iterEnd; ++iter){
741  std::vector<boost::shared_ptr<E> > edges;
742  (*iter).second->edges(repast::Vertex<V, E>::INCOMING, edges);
743  (*iter).second->edges(repast::Vertex<V, E>::OUTGOING, edges);
744  for(typename std::vector<boost::shared_ptr<E> >::iterator EI = edges.begin(), EIEnd = edges.end(); EI != EIEnd; ++EI){
745  if((*EI)->isConflicted()) conflictedEdges.insert(*EI);
746  }
747  }
748 }
749 
750 
751 }
752 
753 #endif /* GRAPH_H_ */
repast::Vertex::removeEdge
virtual boost::shared_ptr< E > removeEdge(Vertex *other, EdgeType type)=0
Removes the edge of the specified type between this Vertex and the specified Vertex.
repast::Context
Collection of agents of type T with set semantics.
Definition: Context.h:82
repast::Graph::verticesEnd
vertex_iterator verticesEnd()
Gets the end of an iterator over all the vertices in this graph.
Definition: Graph.h:252
repast::ProjectionInfoPacket
Serializable packet that can contain projection information regardless of the type of projection (net...
Definition: Projection.h:64
repast::Graph::successors
virtual void successors(V *vertex, std::vector< V * > &out)
Gets the sucessors of the specified vertex and puts them in out.
Definition: Graph.h:384
repast::Vertex::edges
virtual void edges(EdgeType type, std::vector< boost::shared_ptr< E > > &out)=0
Gets all the edges of the specified type in which this Vertex participates and return them in out.
repast::Vertex::addEdge
virtual void addEdge(Vertex< V, E > *other, boost::shared_ptr< E > edge, EdgeType type)=0
Adds an edge of the specified type between this Vertex and the specified vertex.
repast::Graph::findEdge
virtual boost::shared_ptr< E > findEdge(V *source, V *target)
Gets the edge between the source and target or 0 if no such edge is found.
Definition: Graph.h:465
repast::Graph::outDegree
virtual int outDegree(V *vertex)
Gets the out-degree of the specified vertex.
Definition: Graph.h:408
repast::Graph::vertex_iterator
boost::transform_iterator< NodeGetter< V, E >, typename VertexMap::const_iterator > vertex_iterator
An iterator over the agents that are the vertices in this Graph.
Definition: Graph.h:100
repast::Graph::verticesBegin
vertex_iterator verticesBegin()
Gets the start of an iterator over all the vertices in this graph.
Definition: Graph.h:242
repast::AgentId
Agent identity information.
Definition: AgentId.h:60
repast::Graph::predecessors
virtual void predecessors(V *vertex, std::vector< V * > &out)
Gets the predecessors of the specified vertex and puts them in out.
Definition: Graph.h:390
repast::Graph::addEdge
virtual boost::shared_ptr< E > addEdge(V *source, V *target)
Adds an edge between source and target to this Graph.
Definition: Graph.h:350
repast::Vertex::adjacent
virtual void adjacent(std::vector< V * > &out)=0
Gets the Vertices adjacent to this Vertex.
repast::Graph::inDegree
virtual int inDegree(V *vertex)
Gets the in-degree of the specified vertex.
Definition: Graph.h:402
repast::Graph::Graph
Graph(std::string name, bool directed, EcM *edgeContentMgr)
Creates a Graph with the specified name.
Definition: Graph.h:117
repast::AgentId::currentRank
int currentRank() const
Gets the current process rank of this AgentId.
Definition: AgentId.h:135
repast::Graph::removeEdge
virtual void removeEdge(V *source, V *target)
Removes the edge between source and target from this Graph.
Definition: Graph.h:432
repast::Graph::adjacent
virtual void adjacent(V *vertex, std::vector< V * > &out)
Gets all the agent adjacent to the specified vertex.
Definition: Graph.h:396
repast::Projection
Abstract base class for all Projections.
Definition: Projection.h:125
repast::Graph::getInfoExchangePartners
virtual void getInfoExchangePartners(std::set< int > &psToSendTo, std::set< int > &psToReceiveFrom)
Gets the set of processes with which this Projection exchanges projection info.
Definition: Graph.h:525
repast::Vertex
Used internally by repast graphs / networks to encapsulate Vertices.
Definition: Vertex.h:52
repast::Graph::sendsSecondaryAgentsOnStatusExchange
virtual bool sendsSecondaryAgentsOnStatusExchange()
Should return true if the Projection implemented will send secondary agents during a status exchange.
Definition: Graph.h:264
repast::Graph::edgeCount
int edgeCount() const
Gets the number of edges in this Graph.
Definition: Graph.h:223
repast::Graph::getAgentStatusExchangePartners
virtual void getAgentStatusExchangePartners(std::set< int > &psToSendTo, std::set< int > &psToReceiveFrom)
Gets the set of processes with which this Projection exchanges agent status info- that is,...
Definition: Graph.h:531
repast::DirectedVertex
Used internally by repast graphs / networks to encapsulate the vertices of a directed graph.
Definition: DirectedVertex.h:56
repast::Graph::keepsAgentsOnSyncProj
virtual bool keepsAgentsOnSyncProj()
Should return true if the Projection implemented can 'keep' some (non-local) agents during a projecti...
Definition: Graph.h:262
repast::Graph::vertexCount
int vertexCount() const
Gets the number of vertices in this Graph.
Definition: Graph.h:232
repast::Vertex::findEdge
virtual boost::shared_ptr< E > findEdge(Vertex *other, EdgeType type)=0
Finds the edge of the specified type between this Vertex and the specified vertex.
repast::Graph::getProjectionInfo
virtual void getProjectionInfo(std::vector< AgentId > &agents, std::vector< ProjectionInfoPacket * > &packets, bool secondaryInfo=false, std::set< AgentId > *secondaryIds=0, int destProc=-1)
Convenience wrapper that gets all of the projection information for the agents specified (calls imple...
Definition: Graph.h:538
repast::Vertex::item
boost::shared_ptr< V > item() const
Gets the item that this Vertex contains.
Definition: Vertex.h:192
repast::HashId
operator() implementation that returns the hashcode of an AgentId.
Definition: AgentId.h:185
repast::Graph::getAgentsToPush
virtual void getAgentsToPush(std::set< AgentId > &agentsToTest, std::map< int, std::set< AgentId > > &agentsToPush)
Given a set of agents, gets the agents that this projection implementation must 'push' to other proce...
Definition: Graph.h:679
repast::Graph
Graph / Network implementation where agents are vertices in the graph.
Definition: Graph.h:72
repast::Projection< V >::name
const std::string name() const
Gets the name of this projection.
Definition: Projection.h:164
repast::Projection< V >::agentCanBeAdded
bool agentCanBeAdded(boost::shared_ptr< V > agent)
Returns true if the agent can be added to the projection, which will be the case if the filter list i...
Definition: Projection.h:207