bool GraphUtils::isGraphConnected(GraphIF* const graph, EdgeSetIF* const notHiddenEdges) { graph->hideAllEdges(); notHiddenEdges->begin(); while (notHiddenEdges->hasNext()) { notHiddenEdges->next()->show(); } INFO(logger, LogBundleKey::GU_CHECK_GRAPH_CONNECTIVITY_WITH_EDGE_SET, LogStringUtils::graphBasicDescription(graph, "\t").c_str(), LogStringUtils::edgeSetVisualization(notHiddenEdges, "\t").c_str()); return isGraphConnected(graph); }
void Graph<T>::generateRandomGraph(int numVertices,double density) { int numEdges = ceil((density *(numVertices*numVertices - numVertices))/200); if(numEdges < (numVertices-1) || density >100) { cout<<"Error: Density not enough for Graph to be connected"<<endl; return; } srand(time(NULL)); do { graph = new std::map<T,VertexNode<T>*>(); for(int i=0;i<numVertices;i++) addVertex(i); while(numEdges > 0) { addRandomEdge(numVertices); numEdges--; } }while(!isGraphConnected()); }
EdgeSetIF* GraphUtils::getRandomSpanningTree(GraphIF* const graph) throw (GraphExceptions::DisconnectedGraphException) { EdgeSetIF * spanningTreeEdges { }; VertexCount numberOfVertices { }; EdgeCount numberOfEdgesInMST { }; std::vector<bool> discoveryArray { }; std::list<VertexIF*> vertexStack { }; VertexIF* vertex { }; VertexIdx idx { }; INFO(logger, LogBundleKey::GU_RND_MST_SEARCH_INIT, LogStringUtils::graphBasicDescription(graph, "\t").c_str()); if (isGraphConnected(graph)) { spanningTreeEdges = new EdgeSetImpl { }; numberOfVertices = graph->getNumberOfVertices(); numberOfEdgesInMST = numberOfVertices - 1; discoveryArray = std::vector<bool>(numberOfVertices, false); idx = std::rand() % numberOfVertices; discoveryArray[idx] = true; //root INFO(logger, LogBundleKey::GU_RND_MST_SEARCH_ROOT, idx); for (idx = 0; idx < numberOfVertices; idx += 1) { if (spanningTreeEdges->size() == numberOfEdgesInMST) { INFO(logger, LogBundleKey::GU_RND_MST_SEARCH_BREAK, idx); break; } INFO(logger, LogBundleKey::GU_RND_MST_SEARCH_CONSTRUCT_PATH, idx); vertexStack.clear(); vertex = graph->getVertexByIdx(idx); if (discoveryArray.at(vertex->getVertexIdx()) == false) { INFO(logger, LogBundleKey::GU_RND_MST_SEARCH_NOT_DISCOVERED, idx); vertexStack.push_back(vertex); do { INFO(logger, LogBundleKey::GU_RND_MST_SEARCH_BUILD_PATH, vertex->getVertexIdx(), LogStringUtils::vertexOutputEdges(vertex, "\t").c_str()); vertex = vertex->getRandomSuccessor(); INFO(logger, LogBundleKey::GU_RND_MST_SEARCH_ADD_TO_PATH, vertex->getVertexIdx()); vertexStack.push_back(vertex); } while (discoveryArray.at(vertex->getVertexIdx()) == false); INFO(logger, LogBundleKey::GU_RND_MST_SEARCH_ADD_EDGES_FROM_PATH, vertexStack.back()->getVertexIdx(), idx, vertexStack.size() - 1); vertex = vertexStack.back(); vertexStack.pop_back(); while (!vertexStack.empty()) { if (spanningTreeEdges->size() == numberOfEdgesInMST) { vertexStack.clear(); break; } if (discoveryArray[vertexStack.back()->getVertexIdx()] == false) { discoveryArray[vertexStack.back()->getVertexIdx()] = true; INFO(logger, LogBundleKey::GU_RND_MST_SEARCH_ADD_EDGE_FROM_PATH, vertexStack.back()->getVertexIdx(), vertex->getVertexIdx(), LogStringUtils::edgeVisualization( vertexStack.back()->findOutputEdge( vertex), "\t").c_str()); spanningTreeEdges->push_back( vertex->findOutputEdge(vertexStack.back())); } vertex = vertexStack.back(); vertexStack.pop_back(); } } INFO(logger, LogBundleKey::GU_RND_MST_SEARCH_CONSTRUCT_PATH_END, idx); } INFO(logger, LogBundleKey::GU_RND_MST_FOUND, LogStringUtils::edgeSetVisualization(spanningTreeEdges, "\t").c_str()); return spanningTreeEdges; } else { WARN_NOARG(logger, LogBundleKey::GU_RND_MST_GRAPH_DISCONNECTED); throw GraphExceptions::DisconnectedGraphException(); } }