45 #include "Projection.h"
47 #include "DirectedVertex.h"
48 #include "UndirectedVertex.h"
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>
71 template<
typename V,
typename E,
typename Ec,
typename EcM>
75 typedef boost::unordered_map<AgentId, Vertex<V, E>*,
HashId> VertexMap;
76 typedef typename VertexMap::iterator VertexMapIterator;
84 EcM* edgeContentManager;
87 void init(
const Graph& graph);
89 virtual bool addAgent(boost::shared_ptr<V> agent);
90 virtual void removeAgent(V* agent);
92 virtual void doAddEdge(boost::shared_ptr<E> edge,
bool allowOverwrite =
true);
100 typedef typename boost::transform_iterator<NodeGetter<V, E> ,
typename VertexMap::const_iterator>
vertex_iterator;
102 std::set<int> ranksToSendProjInfoTo;
103 std::set<int> ranksToReceiveProjInfoFrom;
105 std::set<int> ranksToSendAgentStatusInfoTo;
106 std::set<int> ranksToReceiveAgentStatusInfoFrom;
109 bool sendsSecondaryAgents;
117 Graph(std::string
name,
bool directed, EcM* edgeContentMgr) :
118 Projection<V> (
name), edgeCount_(0), isDirected(directed), edgeContentManager(edgeContentMgr), keepsAgents(true), sendsSecondaryAgents(true) {
138 virtual boost::shared_ptr<E>
addEdge(V* source, V* target);
149 virtual boost::shared_ptr<E>
addEdge(V* source, V* target,
double weight);
160 virtual boost::shared_ptr<E>
findEdge(V* source, V* target);
169 virtual void successors(V* vertex, std::vector<V*>& out);
178 virtual void predecessors(V* vertex, std::vector<V*>& out);
186 virtual void adjacent(V* vertex, std::vector<V*>& out);
194 virtual void removeEdge(V* source, V* target);
233 return vertices.size();
260 virtual bool isMaster(E* e) = 0;
270 virtual void getProjectionInfo(std::vector<AgentId>& agents, std::vector<ProjectionInfoPacket*>& packets,
271 bool secondaryInfo =
false, std::set<AgentId>* secondaryIds = 0,
int destProc = -1);
277 virtual void getRequiredAgents(std::set<AgentId>& agentsToTest, std::set<AgentId>& agentsRequired, RADIUS radius =
Projection<V>::PRIMARY);
279 virtual void getAgentsToPush(std::set<AgentId>& agentsToTest, std::map<
int, std::set<AgentId> >& agentsToPush);
281 virtual void cleanProjectionInfo(std::set<AgentId>& agentsToKeep);
283 void clearConflictedEdges();
285 void getConflictedEdges(std::set<boost::shared_ptr<E> >& conflictedEdges);
289 template<
typename V,
typename E,
typename Ec,
typename EcM>
290 Graph<V, E, Ec, EcM>::~Graph() {
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) {
302 template<
typename V,
typename E,
typename Ec,
typename EcM>
307 template<
typename V,
typename E,
typename Ec,
typename EcM>
309 edgeCount_ = graph.edgeCount_;
310 isDirected = graph.isDirected;
311 edgeContentManager = graph.edgeContentManager;
314 for (VertexMapIterator iter = graph.vertices.begin(); iter != graph.vertices.end(); ++iter) {
319 vertices[iter->first] =
new UndirectedVertex<V, E> (vertex->
item());
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;
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) {
333 boost::shared_ptr<E> newEdge(
new E(**iter));
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) {
349 template<
typename V,
typename E,
typename Ec,
typename EcM>
351 boost::shared_ptr<E> ret;
355 VertexMapIterator srcIter = vertices.find(source->getId());
356 if (srcIter == notFound)
return ret;
358 VertexMapIterator targetIter = vertices.find(target->getId());
359 if (targetIter == notFound)
return ret;
361 boost::shared_ptr<E> edge(
new E(srcIter->second->item(), targetIter->second->item()));
366 template<
typename V,
typename E,
typename Ec,
typename EcM>
368 boost::shared_ptr<E> ret;
372 VertexMapIterator srcIter = vertices.find(source->getId());
373 if (srcIter == notFound)
return ret;
375 VertexMapIterator targetIter = vertices.find(target->getId());
376 if (targetIter == notFound)
return ret;
378 boost::shared_ptr<E> edge(
new E(srcIter->second->item(), targetIter->second->item(), weight));
383 template<
typename V,
typename E,
typename Ec,
typename EcM>
389 template<
typename V,
typename E,
typename Ec,
typename EcM>
392 if (iter != vertices.end()) iter->second->
predecessors(out);
395 template<
typename V,
typename E,
typename Ec,
typename EcM>
398 if (iter != vertices.end()) iter->second->
adjacent(out);
401 template<
typename V,
typename E,
typename Ec,
typename EcM>
404 return (iter != vertices.end() ? iter->second->inDegree() : 0);
407 template<
typename V,
typename E,
typename Ec,
typename EcM>
410 return (iter != vertices.end() ? iter->second->outDegree() : 0);
413 template<
typename V,
typename E,
typename Ec,
typename EcM>
418 if (iter == vertexNotFound)
return;
422 if (iter == vertexNotFound)
return;
425 boost::shared_ptr<E> edgeNotFound;
431 template<
typename V,
typename E,
typename Ec,
typename EcM>
433 removeEdge(source->getId(), target->getId());
436 template<
typename V,
typename E,
typename Ec,
typename EcM>
439 if (iter != vertices.end()) {
441 std::vector<V*> 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());
449 vertices.erase(iter);
453 template<
typename V,
typename E,
typename Ec,
typename EcM>
454 bool Graph<V, E, Ec, EcM>::addAgent(boost::shared_ptr<V> agent) {
456 if (vertices.find(agent->getId()) != vertices.end())
return false;
458 if(isDirected) vertices[agent->getId()] =
new DirectedVertex<V, E> (agent);
459 else vertices[agent->getId()] =
new UndirectedVertex<V, E> (agent);
464 template<
typename V,
typename E,
typename Ec,
typename EcM>
466 boost::shared_ptr<E> ret;
470 VertexMapIterator sIter = vertices.find(source->getId());
471 if (sIter == notFound)
return ret;
473 VertexMapIterator tIter = vertices.find(target->getId());
474 if (tIter == notFound)
return ret;
479 template<
typename V,
typename E,
typename Ec,
typename EcM>
481 V* source = edge->source();
482 V* target = edge->target();
487 boost::shared_ptr<E> notFound;
489 if(extant == notFound){
496 vSource->
removeEdge(vTarget, Vertex<V, E>::OUTGOING);
497 vTarget->
removeEdge(vSource, Vertex<V, E>::INCOMING);
499 vSource->
addEdge(vTarget, edge, Vertex<V, E>::OUTGOING);
500 vTarget->
addEdge(vSource, edge, Vertex<V, E>::INCOMING);
502 else extant->markConflicted();
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;
513 for(
typename std::vector<boost::shared_ptr<E> >::iterator EI = edges.begin(), EIEnd = edges.end(); EI != EIEnd; ++EI) edgeSet.insert(*EI);
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;
524 template<
typename V,
typename E,
typename Ec,
typename EcM>
526 psToSendTo.insert(ranksToSendProjInfoTo.begin(), ranksToSendProjInfoTo.end());
527 psToReceiveFrom.insert(ranksToReceiveProjInfoFrom.begin(), ranksToReceiveProjInfoFrom.end());
530 template<
typename V,
typename E,
typename Ec,
typename EcM>
532 psToSendTo.insert(ranksToSendAgentStatusInfoTo.begin(), ranksToSendAgentStatusInfoTo.end());
533 psToReceiveFrom.insert(ranksToReceiveAgentStatusInfoFrom.begin(), ranksToReceiveAgentStatusInfoFrom.end());
537 template<
typename V,
typename E,
typename Ec,
typename EcM>
539 bool secondaryInfo, std::set<AgentId>* secondaryIds,
int destProc){
540 if(secondaryInfo ==
false)
return;
546 template<
typename V,
typename E,
typename Ec,
typename EcM>
548 if(secondaryInfo ==
false)
return 0;
550 VertexMapIterator agent = vertices.find(
id);
551 if(agent == vertices.end())
return 0;
553 std::vector<Ec> edgeContent;
555 std::vector<boost::shared_ptr<E> > edges;
559 std::set<boost::shared_ptr<E> > edgeSet;
560 edgeSet.insert(edges.begin(), edges.end());
566 if(secondaryIds == 0){
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())));
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())));
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);
591 secondaryIds->insert(otherId);
592 edgeContent.push_back(*(edgeContentManager->provideEdgeContent(iter->get())));
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())));
607 return new SpecializedProjectionInfoPacket<Ec>(
id, edgeContent);
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);
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){
625 case Projection<V>::PRIMARY: {
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());
636 edges.assign(edgeSet.begin(), edgeSet.end());
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);
646 std::set<AgentId>::iterator iterTEMP = iter;
648 agentsToTest.erase(*iterTEMP);
656 case Projection<V>::SECONDARY: {
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;
667 agentsToTest.erase(*iterTEMP);
678 template<
typename V,
typename E,
typename Ec,
typename EcM>
680 if(agentsToTest.size() == 0)
return;
682 std::set<AgentId>::iterator iter = agentsToTest.begin();
683 while(iter != agentsToTest.end()){
685 if(vertexMapEntry != vertices.end()){
686 int localRank = vertexMapEntry->second->item()->getId().currentRank();
687 std::vector<boost::shared_ptr<E> > 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);
697 if(destRank != localRank){
698 agentsToPush[destRank].insert(*iter);
707 template<
typename V,
typename E,
typename Ec,
typename EcM>
709 for(std::set<AgentId>::iterator iter = agentsToKeep.begin(), iterEnd = agentsToKeep.end(); iter != iterEnd; ++iter){
711 if(vertexMapEntry != vertices.end()){
712 std::vector<boost::shared_ptr<E> > 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());
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());
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;
732 for(
typename std::vector<boost::shared_ptr<E> >::iterator EI = edges.begin(), EIEnd = edges.end(); EI != EIEnd; ++EI){
733 (*EI)->clearConflicted();
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;
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);