first commit

This commit is contained in:
2025-06-04 17:33:13 +02:00
commit d2324d1020
15 changed files with 129837 additions and 0 deletions

200
src/Algo.cpp Normal file
View File

@@ -0,0 +1,200 @@
#include "Algo.h"
#include <algorithm>
#include <limits>
static constexpr int I_INFINITY = std::numeric_limits<int>::max();
static constexpr float F_INFINITY = std::numeric_limits<float>::infinity();
std::map<Vertex*, int> PlusCourtCheminNbArcs(Graphe& g, Vertex* s) {
std::vector<Vertex*> f;
std::map<Vertex*, int> longueurs;
std::map<Vertex*, bool> atteints;
for (Vertex& v : g.getVertecies()) {
longueurs.insert({&v, I_INFINITY});
atteints.insert({&v, false});
}
atteints[s] = true;
longueurs[s] = 0;
f.push_back(s);
while (!f.empty()) {
Vertex* v = f.back();
for (Edge* edge : v->m_Edges) {
Vertex* y = edge->m_End;
if (atteints[y] == true)
continue;
atteints[y] = true;
longueurs[y] = longueurs[v] + 1;
f.push_back(y);
}
f.erase(std::remove(f.begin(), f.end(), v));
}
return longueurs;
}
std::map<Vertex*, Path> PlusCourtCheminsNbArcs(Graphe& g, Vertex* s) {
std::vector<Vertex*> f;
std::map<Vertex*, bool> atteints;
std::map<Vertex*, Vertex*> parents;
for (Vertex& v : g.getVertecies()) {
atteints.insert({&v, false});
}
atteints[s] = true;
f.push_back(s);
while (!f.empty()) {
Vertex* v = f.back();
for (Edge* edge : v->m_Edges) {
Vertex* y = edge->m_End;
if (atteints[y] == true)
continue;
atteints[y] = true;
parents[y] = v;
f.push_back(y);
}
f.erase(std::remove(f.begin(), f.end(), v));
}
std::map<Vertex*, Path> chemins;
for (Vertex& v : g.getVertecies()) {
Path path;
path.push_back(&v);
auto parent_it = parents.find(&v);
while (parent_it != parents.end()) {
Vertex* parent = parent_it->second;
path.push_back(parent);
parent_it = parents.find(parent);
}
std::reverse(path.begin(), path.end());
chemins.insert({&v, path});
}
return chemins;
}
Path PlusCourtChemin(Graphe& g, Vertex* s, Vertex* arrivee) {
std::vector<Vertex*> f;
std::map<Vertex*, bool> atteints;
std::map<Vertex*, Vertex*> parents;
for (Vertex& v : g.getVertecies()) {
atteints.insert({&v, false});
}
atteints[s] = true;
f.push_back(s);
bool trouve = false;
while (!f.empty() && !trouve) {
Vertex* v = f.back();
for (Edge* edge : v->m_Edges) {
Vertex* y = edge->m_End;
if (atteints[y] == true)
continue;
atteints[y] = true;
parents[y] = v;
f.push_back(y);
if (y == arrivee) {
trouve = true;
break;
}
}
f.erase(std::remove(f.begin(), f.end(), v));
}
Path path;
path.push_back(arrivee);
auto parent_it = parents.find(arrivee);
while (parent_it != parents.end()) {
Vertex* parent = parent_it->second;
path.push_back(parent);
parent_it = parents.find(parent);
}
std::reverse(path.begin(), path.end());
return path;
}
struct DjikstraData {
std::map<Vertex*, int> d;
std::map<Vertex*, Vertex*> p;
};
std::map<Vertex*, float> PlusCourtCheminDjikstra(Graphe& g, Vertex* s) {
std::vector<Vertex*> z;
std::map<Vertex*, float> distances;
std::map<Vertex*, Vertex*> prev;
for (Vertex& v : g.getVertecies()) {
distances.insert({&v, F_INFINITY});
z.push_back(&v);
}
distances[s] = 0;
while (!z.empty()) {
Vertex* u = z.front();
float minimum = distances[u];
for (Vertex* vertex : z) {
float distance = distances[vertex];
if (distance < minimum) {
u = vertex;
minimum = distance;
}
}
z.erase(std::remove(z.begin(), z.end(), u));
for (Edge& e : g.getEdges()) {
if (e.m_Start != u)
continue;
float alt = distances[u] + e.m_Values[0];
Vertex* v = e.m_End;
if (alt < distances[v]) {
distances[v] = alt;
// prev[v] = u
}
}
}
return distances;
}

11
src/Algo.h Normal file
View File

@@ -0,0 +1,11 @@
#pragma once
#include "Graphe.h"
std::map<Vertex*, int> PlusCourtCheminNbArcs(Graphe& g, Vertex* depart);
std::map<Vertex*, Path> PlusCourtCheminsNbArcs(Graphe& g, Vertex* depart);
Path PlusCourtChemin(Graphe& g, Vertex* depart, Vertex* arrivee);
std::map<Vertex*, float> PlusCourtCheminDjikstra(Graphe& g, Vertex* s);

145
src/Graphe.cpp Normal file
View File

@@ -0,0 +1,145 @@
#include "Graphe.h"
#include <fstream>
#include <iostream>
#include <regex>
using namespace std;
std::ostream& operator<<(std::ostream& os, const Graphe& g) {
os << "Graphe: " << g.file_name << "\n";
os << "Comment: " << g.comment << "\n";
os << "Directed: " << (g.directed ? "true" : "false") << "\n";
os << "Number of vertices: " << g.nb_vertices << "\n";
os << "Number of edges: " << g.nb_edges << "\n";
os << "Vertices:\n";
for (const auto& vertex : g.m_Vertecies) {
os << " ID: " << vertex.m_Name << ", Values: " << vertex.m_Values << "\n";
}
os << "Edges:\n";
for (const auto& edge : g.m_Edges) {
os << " Start: " << edge.m_Start->m_Name
<< ", End: " << edge.m_End->m_Name
<< ", Values: " << edge.m_Values << "\n";
}
return os;
}
Graphe::Graphe(const string& fileName) {
// load the graph from the file
ifstream file(fileName);
if (!file.is_open()) {
// cerr << "Error opening file: " << fileName << endl;
return;
}
string line;
bool isSettingsSection = true;
bool verticesSection = false;
bool edgesSection = false;
while (getline(file, line)) {
if (line.empty()) {
if (isSettingsSection) {
isSettingsSection = false;
verticesSection = true;
// cout << "Settings section ended, now reading vertices." << endl;
continue;
}
if (verticesSection) {
verticesSection = false;
edgesSection = true;
// cout << "Vertices section ended, now reading edges." << endl;
continue;
}
}
if (isSettingsSection) {
// cout << "Settings :" << line << endl;
regex settingRegex(R"(^([A-Z_]+):\s([\w\d\.]+)$)");
smatch match;
if (regex_match(line, match, settingRegex)) {
string key = match[1].str();
string value = match[2].str();
if (key == "NAME") {
file_name = value;
} else if (key == "COMMENT") {
comment = value;
} else if (key == "ORIENTED") {
directed = (value == "true");
} else if (key == "NB_VERTICES") {
nb_vertices = stoi(value);
} else if (key == "NB_EDGES") {
nb_edges = stoi(value);
} else if (key == "NB_VALUES_BY_VERTEX") {
nb_values_by_vertex = stoi(value);
} else if (key == "NB_VALUES_BY_EDGE") {
nb_values_by_edge = stoi(value);
} else {
cerr << "Unknown setting: " << key << endl;
}
}
}
m_Vertecies.reserve(nb_vertices);
m_Edges.reserve(nb_edges);
if(verticesSection) {
// cout << "Reading vertices : " << line << endl;
if(line.starts_with("VER")) {
continue;
}
regex vertexRegex(R"(^(\d+)\s(\w+)\s?(.*)$)");
smatch match;
if (regex_match(line, match, vertexRegex)) {
Vertex v;
int id = stoi(match[1].str());
v.m_Name = match[2].str();
string valuesStr = match[3].str();
regex valueRegex(R"((\d+))");
auto valuesBegin = sregex_iterator(valuesStr.begin(), valuesStr.end(), valueRegex);
auto valuesEnd = sregex_iterator();
for (sregex_iterator i = valuesBegin; i != valuesEnd; ++i) {
v.m_Values.push_back(stof((*i).str()));
}
m_Vertecies.push_back(v);
m_VertexMap[v.m_Name] = &m_Vertecies[id];
} else {
cerr << "Invalid vertex line: " << line << endl;
}
}
if (edgesSection) {
// cout << "Reading edges : " << line << endl;
if(line.starts_with("EDG")) {
continue;
}
regex edgeRegex(R"(^(\d+)\s(\d+)\s?(.*)$)");
smatch match;
if (regex_match(line, match, edgeRegex)) {
Edge e;
e.m_Start = &m_Vertecies[stoi(match[1].str())];
e.m_End = &m_Vertecies[stoi(match[2].str())];
string valuesStr = match[3].str();
regex valueRegex(R"((\d+))");
auto valuesBegin = sregex_iterator(valuesStr.begin(), valuesStr.end(), valueRegex);
auto valuesEnd = sregex_iterator();
for (sregex_iterator i = valuesBegin; i != valuesEnd; ++i) {
e.m_Values.push_back(stof((*i).str()));
}
std::size_t edgeID = m_Edges.size();
m_Edges.push_back(e);
e.m_Start->m_Edges.push_back(&m_Edges[edgeID]);
if (!directed) {
Edge reverseEdge;
reverseEdge.m_Start = e.m_End;
reverseEdge.m_End = e.m_Start;
reverseEdge.m_Values = e.m_Values;
std::size_t index = m_Edges.size();
m_Edges.push_back(reverseEdge);
reverseEdge.m_Start->m_Edges.push_back(&m_Edges[index]);
}
} else {
cerr << "Invalid edge line: " << line << endl;
}
}
}
}

86
src/Graphe.h Normal file
View File

@@ -0,0 +1,86 @@
#pragma once
#include <map>
#include <string>
#include <vector>
#include <iostream>
struct Edge;
struct Vertex {
std::vector<float> m_Values;
std::vector<Edge*> m_Edges;
std::size_t getWeight() {
return m_Edges.size();
}
std::string m_Name;
};
struct Edge {
Vertex* m_Start;
Vertex* m_End;
std::vector<float> m_Values;
};
using VertexMap = std::map<std::string, Vertex*>;
using Path = std::vector<Vertex*>;
class Graphe {
private:
VertexMap m_VertexMap;
std::vector<Vertex> m_Vertecies;
std::vector<Edge> m_Edges;
std::string file_name;
std::string comment;
bool directed;
int nb_vertices;
int nb_edges;
int nb_values_by_vertex;
int nb_values_by_edge;
public:
Graphe(const std::string& fileName);
std::vector<Vertex>& getVertecies() {
return m_Vertecies;
}
Vertex* getVertex(const std::string& name) {
return m_VertexMap.at(name);
}
std::vector<Edge>& getEdges() {
return m_Edges;
}
friend std::ostream& operator<<(std::ostream& os, const Graphe& graphe);
};
inline std::ostream& operator<<(std::ostream& os, const Path& p) {
os << "[";
for (size_t i = 0; i < p.size(); i++) {
os << p[i]->m_Name;
if (i < p.size() - 1) {
os << ", ";
}
}
return os << "]";
}
template<typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& value) {
os << "[";
for (size_t i = 0; i < value.size(); i++)
{
os << value[i];
if (i < value.size() - 1) {
os << ", ";
}
}
os << "]";
return os;
}

15
src/PrettyPrint.h Normal file
View File

@@ -0,0 +1,15 @@
#pragma once
#include <iostream>
void printYellow(const std::string& text) {
std::cout << "\033[33m" << text << "\033[0m";
}
void printRed(const std::string& text) {
std::cout << "\033[31m" << text << "\033[0m";
}
void printGreen(const std::string& text) {
std::cout << "\033[32m" << text << "\033[0m";
}
void printBlue(const std::string& text) {
std::cout << "\033[34m" << text << "\033[0m";
}

33
src/main.cpp Normal file
View File

@@ -0,0 +1,33 @@
#include <iostream>
#include "Algo.h"
#include "Graphe.h"
int main(int argc, char** argv) {
Graphe graphe("graphe-oriente-01.gra");
std::cout << graphe << std::endl;
auto result = PlusCourtCheminNbArcs(graphe, graphe.getVertex("a"));
std::cout << "Résultat :\n";
for (auto& [vertex, longueur] : result) {
std::cout << vertex->m_Name << " " << longueur << "\n";
}
auto result2 = PlusCourtCheminsNbArcs(graphe, graphe.getVertex("a"));
std::cout << "Résultat :\n";
for (auto& [vertex, chemin] : result2) {
std::cout << vertex->m_Name << " " << chemin << "\n";
}
auto result3 = PlusCourtChemin(graphe, graphe.getVertex("a"), graphe.getVertex("e"));
std::cout << "Résultat :\n";
std::cout << result3 << std::endl;
auto result4 = PlusCourtCheminDjikstra(graphe, graphe.getVertex("a"));
std::cout << "Résultat :\n";
for (auto& [vertex, longueur] : result4) {
std::cout << vertex->m_Name << " " << longueur << "\n";
}
}