void Graph::saveToFile(string path) { ofstream fs(path); if (fs.fail()) { throw GraphException("Error saving the graph!"); } fs << "Graph g {\r\n"; for(auto itr = nodeMap.begin(); itr != nodeMap.end(); itr++) { for (auto itrNeighbors = itr->second.begin(); itrNeighbors != itr->second.end(); itrNeighbors++) { fs << itr->first << " -- " << *itrNeighbors << ";\r\n"; } } fs << "}"; if (fs.fail()) { throw GraphException("Error while writing to file!"); } fs.flush(); fs.close(); if (fs.fail()) { throw GraphException("Error saving the graph!"); } }
Node *Graph::get_node(int i){ if(i > capacity){ FERROR("%s: element is out of bounds", __FUNCTION__); throw GraphException("element is out of bounds\n"); } return &nodes[i]; }
GraphWriter *GraphReaderWriterFactory::create_writer(string name, string outfile) { GraphWriter *w; if (name == "DIMACS" || name == "dimacs") { w = new DIMACSGraphWriter(outfile); } else if (name == "METIS" || name == "Metis" || name == "metis") { w = new MetisGraphWriter(); } else if (name == "AdjMatrix" || name == "ADJMATRIX" || name == "adjmatrix") { w = new AdjMatrixGraphWriter(outfile); } else if (name == "GraphViz" || name == "GRAPHVIZ" || name == "graphviz") { w = new GraphVizGraphWriter(outfile); } else { std::string desc = "Reader for file type " + name + " has not been implemented"; throw GraphException(desc); } return w; }
/** * Subdivides the edge (u,v) by placing a new vertex, numbered w * in the graph, deleting (u,v) and adding (u,w) and (w,v). * WARNING: If w is a current vertex, this function will remove * all its current edges, and may have unpredictable behavior. * */ int Graph::edge_subdivision(int u, int v, int w){ if((nodes[u].label == -1) || (nodes[v].label == -1) ){ fatal_error( "%s: Cannot remove edge (%d, %d) as one of its vertices is undefined!\n", __FUNCTION__, u, v); } list<int>::iterator it; // check that v is a neighbour of u bool foundv = false; for(it = nodes[u].nbrs.begin(); it != nodes[u].nbrs.end(); ++it){ if(*it == v){ foundv = true; } } if(foundv == false){ return false; } // if w provided, check that it is in bounds if(w >= capacity){ nodes.resize(2 * capacity); capacity *= 2; } nodes[w].nbrs.clear(); if(!nodes[w].nbrs.empty()){ FERROR("%s: node is not empty", __FUNCTION__); throw GraphException("node is not empty\n"); } else { nodes[w].label = w; degree[w] = 2; nodes[w].nbrs.push_back(u); nodes[w].nbrs.push_back(v); // remove u from v's nbrs list and vice versa for(it = nodes[u].nbrs.begin(); it != nodes[u].nbrs.end(); it++){ if(*it == v){ *it = w; break; } } for(it = nodes[v].nbrs.begin(); it != nodes[v].nbrs.end(); it++){ if(*it == u){ *it = w; break; } } } num_edges++; next_label++; num_nodes++; return w; } // Graph::edge_subdivision
/** * Loads a graph from a file * * @path path to the file */ Graph Graph::fromFile(string path) { ifstream fs(path); if (fs.fail()) { throw GraphException("Cannot open file."); } Graph g; string line; // ignore first line as it only contains "graph g {" getline(fs, line); getline(fs, line); if (fs.fail()) { throw GraphException("Error reading file."); } try { while (!fs.eof() && line.find("}") == string::npos) { int n1End = line.find(" "); string snode1 = line.substr(0, n1End); uint node1 = strtoul(snode1.c_str(), null, 10); if (node1 == 0 || errno == ERANGE) { fs.close(); throw GraphException("Error reading graph."); } string snode2 = line.substr(line.find("-- ") + 3, line.find(";")); uint node2 = strtoul(snode2.c_str(), null, 10); if (node2 == 0 || errno == ERANGE) { fs.close(); throw GraphException("Error reading graph."); } g.nodeMap[node1].push_back(node2); line.clear(); getline(fs, line); if (fs.fail()) { throw GraphException("Cannot open file."); } } } catch (const out_of_range& ex) { fs.close(); throw GraphException("Error reading graph."); } fs.close(); return g; }
/** * Generate a new graph. Neither the nodes nor the edges might be empty and we need more edges than nodes! * * @param n the number of nodes * @param m the number of edges */ Graph Graph::generate(const uint n, const uint m) { if (n == 0 || m == 0 || m <= n) { throw GraphException("Either n or m is 0 or m is less or equal than n."); } srand(time(null)); Graph g; uint currentEdges = 0; for (uint i = 1; i <= n; i++) { uint neighbor = (rand() % n) + 1; while (neighbor == i || find(g.nodeMap[neighbor].begin(), g.nodeMap[neighbor].end(), i) != g.nodeMap[neighbor].end()) { //we cannot be our own neighbor //and we don't want a double //choose new one neighbor = (rand() % n) + 1; } g.nodeMap[i].push_back(neighbor); currentEdges++; } while (currentEdges < m) { uint node1 = (rand() % n) + 1; uint node2 = (rand() % n) + 1; while (node1 == node2 || find(g.nodeMap[node1].begin(), g.nodeMap[node1].end(), node2) != g.nodeMap[node1].end() || find(g.nodeMap[node2].begin(), g.nodeMap[node2].end(), node1) != g.nodeMap[node2].end()) { //no ref to ourselves and no doubles node2 = (rand() % n) + 1; } g.nodeMap[node1].push_back(node2); currentEdges++; } return g; }
GraphReader *GraphReaderWriterFactory::create_reader(std::string name) { GraphReader *r; if (name == "DIMACS" || name == "dimacs") { r = new DIMACSGraphReader(); } else if (name == "AdjMatrix" || name == "ADJMATRIX" || name == "adjmatrix") { r = new AdjMatrixGraphReader(); } else if (name == "METIS" || name == "Metis" || name == "metis") { r = new MetisGraphReader(); } else { std::string desc = "Reader for file type " + name + " has not been implemented"; throw GraphException(desc); } return r; }