void dumpGraph(Graph* graph) { int i,j; int nVertices; int nLinks; Vertex* vertex; VertexNode* current; VertexNode* child; /* Dump dos vértices */ /* Número de vertices */ nVertices = sizeGraph(graph); printf("vertices %d\n",nVertices); /* Recria o index */ createGraphIndex(&graph); /* id e nome dos vértices */ nLinks = 0; current = graph->vertices->first; while (current!=NULL) { vertex = current->vertex; printf("%d %s\n",vertex->id,vertex->name); nLinks = nLinks + length(vertex->children); current = current->next; } /* Dump dos arcs (ou links) */ /* Número de arcs (ou links) */ if (isDirected(graph)) { printf("%s %d\n",ARCS,nLinks); } else { nLinks = nLinks/2; printf("%s %d\n",LINKS,nLinks); } /* Conexões */ current = graph->vertices->first; while (current!=NULL) { vertex = current->vertex; child = vertex->children->first; while (child!=NULL) { if (isDirected(graph) || child->vertex->id > vertex->id) { printf("%d %d\n",vertex->id,child->vertex->id); } child = child->next; } current = current->next; } }
edge_id Network::addEdge(vertex_id vid1, vertex_id vid2) { if (!containsVertex(vid1)) throw ElementNotFoundException("Vertex " + std::to_string(vid1)); if (!containsVertex(vid2)) throw ElementNotFoundException("Vertex " + std::to_string(vid2)); if (out_edges[vid1].count(vid2)>0) throw DuplicateElementException("Edge (" + std::to_string(vid1) + "," + std::to_string(vid2) + ") already exists"); //max_edge_id++; out_edges[vid1].insert(vid2); in_edges[vid2].insert(vid1); if (!isDirected() && vid1!=vid2) { out_edges[vid2].insert(vid1); in_edges[vid1].insert(vid2); } if (isWeighted()) setNumericEdgeAttribute(vid1,vid2,"weight",MULTIPLENETWORK_DEFAULT_WEIGHT); // this value will be replaced if this method has been called inside addEdge(vertex_id, vertex_id, double) num_edges++; return edge_id(vid1, vid2, isDirected()); }
std::set<edge_id> Network::getEdges() const { std::set<edge_id> edges; std::map<vertex_id,std::set<vertex_id> >::const_iterator from_edge_iterator; //std::cout << "Getting edges..." << std::endl; for (from_edge_iterator=out_edges.begin(); from_edge_iterator!=out_edges.end(); ++from_edge_iterator) { vertex_id from = from_edge_iterator->first; for (vertex_id to: from_edge_iterator->second) { if (isDirected() || from<=to) { edge_id e(from,to,isDirected()); edges.insert(e); //std::cout << e << " done!" << std::endl; } } } return edges; }
TEST_F(GraphToolsGTest, testGetCompactedGraphUndirectedWeighted1) { Graph G(10,true,false); G.removeNode(0); G.removeNode(2); G.removeNode(4); G.removeNode(6); G.removeNode(8); G.addEdge(1,3,0.2); G.addEdge(5,3,2132.351); G.addEdge(7,5,3.14); G.addEdge(7,9,2.7); G.addEdge(1,9,0.12345); auto nodeMap = GraphTools::getContinuousNodeIds(G); auto Gcompact = GraphTools::getCompactedGraph(G,nodeMap); EXPECT_EQ(G.totalEdgeWeight(),Gcompact.totalEdgeWeight()); EXPECT_NE(G.upperNodeIdBound(),Gcompact.upperNodeIdBound()); EXPECT_EQ(G.numberOfNodes(),Gcompact.numberOfNodes()); EXPECT_EQ(G.numberOfEdges(),Gcompact.numberOfEdges()); EXPECT_EQ(G.isDirected(),Gcompact.isDirected()); EXPECT_EQ(G.isWeighted(),Gcompact.isWeighted()); // TODOish: find a deeper test to check if the structure of the graphs are the same, // probably compare results of some algorithms or compare each edge with a reference node id map. }
TEST_F(GraphToolsGTest, testRestoreGraph) { Graph G(10,false,true); G.removeNode(0); G.removeNode(2); G.removeNode(4); G.removeNode(6); G.removeNode(8); G.addEdge(1,3); G.addEdge(5,3); G.addEdge(7,5); G.addEdge(7,9); G.addEdge(1,9); auto nodeMap = GraphTools::getContinuousNodeIds(G); auto invertedNodeMap = GraphTools::invertContinuousNodeIds(nodeMap,G); std::vector<node> reference = {1,3,5,7,9,10}; EXPECT_EQ(6,invertedNodeMap.size()); EXPECT_EQ(reference,invertedNodeMap); auto Gcompact = GraphTools::getCompactedGraph(G,nodeMap); Graph Goriginal = GraphTools::restoreGraph(invertedNodeMap,Gcompact); EXPECT_EQ(Goriginal.totalEdgeWeight(),Gcompact.totalEdgeWeight()); EXPECT_NE(Goriginal.upperNodeIdBound(),Gcompact.upperNodeIdBound()); EXPECT_EQ(Goriginal.numberOfNodes(),Gcompact.numberOfNodes()); EXPECT_EQ(Goriginal.numberOfEdges(),Gcompact.numberOfEdges()); EXPECT_EQ(Goriginal.isDirected(),Gcompact.isDirected()); EXPECT_EQ(Goriginal.isWeighted(),Gcompact.isWeighted()); }
void Network::setStringEdgeAttribute(vertex_id vid1, vertex_id vid2, const std::string& attribute_name, const std::string& val) { if (!containsVertex(vid1)) throw ElementNotFoundException("Vertex " + std::to_string(vid1)); if (!containsVertex(vid2)) throw ElementNotFoundException("Vertex " + std::to_string(vid2)); if (!containsEdge(vid1, vid2)) throw ElementNotFoundException("Edge (" + std::to_string(vid2) + ", " + std::to_string(vid2) + ")"); if (edge_string_attribute.count(attribute_name)==0) throw ElementNotFoundException("Attribute " + attribute_name); edge_id eid(vid1, vid2, isDirected()); edge_string_attribute.at(attribute_name)[eid] = val; }
bool Network::deleteEdge(vertex_id vid1, vertex_id vid2) { if (!containsEdge(vid1,vid2)) return false; edge_id eid(vid1,vid2,isDirected()); out_edges[vid1].erase(vid2); in_edges[vid2].erase(vid1); if (!isDirected()) { out_edges[vid2].erase(vid1); in_edges[vid1].erase(vid2); } // remove attribute values (including WEIGHT, if present, which is treated as any other numeric attribute) for (std::map<std::string,std::map<edge_id,std::string> >::iterator it=edge_string_attribute.begin(); it!=edge_string_attribute.end(); it++) edge_string_attribute[it->first].erase(eid); for (std::map<std::string,std::map<edge_id,double> >::iterator it=edge_numeric_attribute.begin(); it!=edge_numeric_attribute.end(); it++) edge_numeric_attribute[it->first].erase(eid); num_edges--; return true; }
std::string Network::getStringEdgeAttribute(vertex_id vid1, vertex_id vid2, const std::string& attribute_name) const { if (!containsVertex(vid1)) throw ElementNotFoundException("Vertex " + std::to_string(vid1)); if (!containsVertex(vid2)) throw ElementNotFoundException("Vertex " + std::to_string(vid2)); if (!containsEdge(vid1, vid2)) throw ElementNotFoundException("Edge (" + std::to_string(vid1) + ", " + std::to_string(vid2) + ")"); if (edge_string_attribute.count(attribute_name)==0) throw ElementNotFoundException("Attribute " + attribute_name); edge_id eid(vid1, vid2, isDirected()); if (edge_string_attribute.at(attribute_name).count(eid)==0) throw ElementNotFoundException("No attribute value for attribute " + attribute_name + " on edge (" + std::to_string(vid1) + "," + std::to_string(vid2) + ")"); return edge_string_attribute.at(attribute_name).at(eid); }
std::set<vertex_id> Network::getNeighbors(vertex_id vid) const { std::set<vertex_id> neighbors; if (!containsVertex(vid)) throw ElementNotFoundException("Vertex " + std::to_string(vid)); std::set<vertex_id>::iterator it; if (out_edges.count(vid)!=0) for (it=out_edges.at(vid).begin(); it!=out_edges.at(vid).end(); it++) neighbors.insert(*it); if (isDirected() && in_edges.count(vid)!=0) for (it=in_edges.at(vid).begin(); it!=in_edges.at(vid).end(); it++) neighbors.insert(*it); return neighbors; }
std::set<std::string> Network::getNeighbors(const std::string& vertex_name) const { if (!isNamed()) throw OperationNotSupportedException("Cannot reference a named vertex in an unnamed network"); if (!containsVertex(vertex_name)) throw ElementNotFoundException("Vertex " + vertex_name); std::set<std::string> neighbors; std::set<vertex_id> tmp_id_result = getOutNeighbors(vertex_name_to_id.at(vertex_name)); for (std::set<vertex_id>::iterator it=tmp_id_result.begin(); it!=tmp_id_result.end(); it++) neighbors.insert(vertex_id_to_name.at(*it)); if (isDirected()) { std::set<vertex_id> tmp_id_result = getInNeighbors(vertex_name_to_id.at(vertex_name)); for (std::set<vertex_id>::iterator it=tmp_id_result.begin(); it!=tmp_id_result.end(); it++) neighbors.insert(vertex_id_to_name.at(*it)); } return neighbors; }
bool statisticsNetwork::isConnected() { if( isDirected() ) { cout << "Warning! This network is directed. This function cannout make a statement about connectivity."; cout << "\n"; return false; } network::nodeList vl; network::nodeIterator vi; verticesMatching(vl, _dynNode_ ); unsigned int n,i; n = vl.size(); vector<unsigned int> connect; connect.resize(n); nodeDescriptor v,t; for (vi=vl.begin(); vi!=vl.end(); vi++) { connect[0]=1; for( i=1; i<n; i++) { connect[i]=0; } vector<unsigned int> Sub; Sub.push_back(*vi+1); // Knotennummern um +1 verschoben um nicht 0 zu pushen for( i=0; i<Sub.size(); i++) { v = Sub[i]-1; for( node::edgeDescriptor l=0; l<node::theNodes[v]->degree() ; l++) { t = node::theNodes[v]->getTarget(l)->getNumber(); if (connect[ t - *vl.begin()] == 0) { connect[ t - *vl.begin() ] = 1; Sub.push_back(t+1); } } } if( n!=Sub.size() ) return false; } return true; }
TEST_F(GraphToolsGTest, testGetCompactedGraphUndirectedUnweighted1) { Graph G(10,false,false); G.addEdge(0,1); G.addEdge(2,1); G.addEdge(0,3); G.addEdge(2,4); G.addEdge(3,6); G.addEdge(4,8); G.addEdge(5,9); G.addEdge(3,7); G.addEdge(5,7); auto nodeMap = GraphTools::getContinuousNodeIds(G); auto Gcompact = GraphTools::getCompactedGraph(G,nodeMap); EXPECT_EQ(G.numberOfNodes(),Gcompact.numberOfNodes()); EXPECT_EQ(G.numberOfEdges(),Gcompact.numberOfEdges()); EXPECT_EQ(G.isDirected(),Gcompact.isDirected()); EXPECT_EQ(G.isWeighted(),Gcompact.isWeighted()); // TODOish: find a deeper test to check if the structure of the graphs are the same, // probably compare results of some algorithms or compare each edge with a reference node id map. }
edge_id Network::addEdge(vertex_id vid1, vertex_id vid2, double weight) { if (!isWeighted()) throw OperationNotSupportedException("Cannot add a weight: network is unweighed"); addEdge(vid1,vid2); setNumericEdgeAttribute(vid1, vid2, "weight", weight); return edge_id(vid1, vid2, isDirected()); }
long Network::getDegree(vertex_id vid) const { long tmp_degree = getInDegree(vid); if (isDirected()) tmp_degree += getOutDegree(vid); return tmp_degree; }
int getVertexDegree(Vertex* vertex) { return (isDirected((Graph*)vertex->graph)?(length(vertex->parents)+length(vertex->children)):length((vertex->parents))); }