A simple students project implementing Dinic's Algorithm to compute the max flow/min cut of a network.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

76 lines
2.7 KiB

  1. #include <algorithm>
  2. #include <fstream>
  3. #include <iostream> // only debug
  4. #include <sstream>
  5. #include "GraphParser.h"
  6. #include "Vertex.h"
  7. void parseGraphInformation(const std::string &line, int &num_vertices, int &num_arcs, VertexID &source, VertexID &sink) {
  8. int num;
  9. std::vector<int> information;
  10. std::istringstream ss(line);
  11. for (; ss;) {
  12. if (ss >> num) {
  13. information.push_back(num);
  14. } else if (!ss.eof()) {
  15. ss.clear();
  16. ss.ignore(1);
  17. }
  18. }
  19. if(information.size() != 4) {
  20. std::cerr << "The graph information on line 0 is not well defined:\n";
  21. std::cerr << line << std::endl;
  22. throw std::runtime_error("The graph information on line 0 is not well defined.");
  23. }
  24. num_vertices = information.at(0);
  25. num_arcs = information.at(1);
  26. source = information.at(2);
  27. sink = information.at(3);
  28. }
  29. Arc parseArc(const std::string &line, const int &line_count) {
  30. try {
  31. int start, dest, capacity;
  32. std::istringstream(line) >> start >> dest >> capacity;
  33. return Arc{start, dest, capacity, capacity, 0}; // check sanity here
  34. } catch(const std::exception &e) {
  35. std::cerr << "Error on line " << line_count << ":\t" << line << std::endl;
  36. throw std::runtime_error("Error parsing the arc on line " + std::to_string(line_count));
  37. }
  38. }
  39. namespace parser {
  40. void parseString(const std::string &graph_string, std::vector<Arc> &arc_list, std::vector<Vertex> &vertices, VertexID &source_id, VertexID &sink_id, int &num_vertices, int &num_arcs) {
  41. int line_count = 0;
  42. std::set<Vertex> vertex_set;
  43. std::stringstream stream(graph_string);
  44. std::string line;
  45. std::getline(stream, line);
  46. parseGraphInformation(line, num_vertices, num_arcs, source_id, sink_id);
  47. line_count++;
  48. while (std::getline(stream, line)) {
  49. Arc arc = parseArc(line, line_count);
  50. arc_list.push_back(arc);
  51. vertex_set.insert(Vertex{arc.start});
  52. vertex_set.insert(Vertex{arc.end});
  53. line_count++;
  54. }
  55. vertices.resize(vertex_set.size());
  56. std::copy(vertex_set.begin(), vertex_set.end(), vertices.begin());
  57. for(auto &arc : arc_list) {
  58. auto it = std::find_if(vertices.begin(), vertices.end(), [&arc] (const Vertex &v) { return v.getID() == arc.start; }); // check if capacity is > 0
  59. it->addOutgoingArc(arc);
  60. }
  61. }
  62. void parseFile(const std::string &graph_filename, std::vector<Arc> &m_arc_list, std::vector<Vertex> &m_vertices, VertexID &source_id, VertexID &sink_id, int &m_num_vertices, int &m_num_arcs) {
  63. std::ifstream input_file(graph_filename);
  64. std::string content((std::istreambuf_iterator<char>(input_file)), (std::istreambuf_iterator<char>()));
  65. parseString(content, m_arc_list, m_vertices, source_id, sink_id, m_num_vertices, m_num_arcs);
  66. }
  67. }