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

#include <algorithm>
#include <fstream>
#include <iostream> // only debug
#include <sstream>
#include "GraphParser.h"
#include "Vertex.h"
void parseGraphInformation(const std::string &line, int &num_vertices, int &num_arcs, VertexID &source, VertexID &sink) {
int num;
std::vector<int> information;
std::istringstream ss(line);
for (; ss;) {
if (ss >> num) {
information.push_back(num);
} else if (!ss.eof()) {
ss.clear();
ss.ignore(1);
}
}
if(information.size() != 4) {
std::cerr << "The graph information on line 0 is not well defined:\n";
std::cerr << line << std::endl;
throw std::runtime_error("The graph information on line 0 is not well defined.");
}
num_vertices = information.at(0);
num_arcs = information.at(1);
source = information.at(2);
sink = information.at(3);
}
Arc parseArc(const std::string &line, const int &line_count) {
try {
int start, dest, capacity;
std::istringstream(line) >> start >> dest >> capacity;
return Arc{start, dest, capacity, capacity, 0}; // check sanity here
} catch(const std::exception &e) {
std::cerr << "Error on line " << line_count << ":\t" << line << std::endl;
throw std::runtime_error("Error parsing the arc on line " + std::to_string(line_count));
}
}
namespace parser {
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) {
int line_count = 0;
std::set<Vertex> vertex_set;
std::stringstream stream(graph_string);
std::string line;
std::getline(stream, line);
parseGraphInformation(line, num_vertices, num_arcs, source_id, sink_id);
line_count++;
while (std::getline(stream, line)) {
Arc arc = parseArc(line, line_count);
arc_list.push_back(arc);
vertex_set.insert(Vertex{arc.start});
vertex_set.insert(Vertex{arc.end});
line_count++;
}
vertices.resize(vertex_set.size());
std::copy(vertex_set.begin(), vertex_set.end(), vertices.begin());
for(auto &arc : arc_list) {
auto it = std::find_if(vertices.begin(), vertices.end(), [&arc] (const Vertex &v) { return v.getID() == arc.start; }); // check if capacity is > 0
it->addOutgoingArc(arc);
}
}
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) {
std::ifstream input_file(graph_filename);
std::string content((std::istreambuf_iterator<char>(input_file)), (std::istreambuf_iterator<char>()));
parseString(content, m_arc_list, m_vertices, source_id, sink_id, m_num_vertices, m_num_arcs);
}
}