Files
ADS/P4/main.cpp
2025-02-21 13:17:35 +01:00

297 lines
8.6 KiB
C++
Executable File

#define CATCH_CONFIG_RUNNER
#include "catch.h"
#include <iostream>
#include "EdgeWeightedGraph.h"
#include "PrimMST.h"
#include "Graphsearch.h"
#include "KruskalMST.h"
#include "DijkstraSP.h"
using namespace std;
bool isInGrapf(EdgeWeightedGraph gr, int v) {
if (v > gr.getV())
return false;
return true;
}
void PrintGrapf(EdgeWeightedGraph g) {
vector<vector<Edge> > adj = g.getAdj();
cout << endl;
for (int i = 0; i < g.getV(); i++) {
cout << i << " -> ";
for (int j = 0; j < adj[i].size(); j++) {
cout << adj[i][j].other(i) << "[" << adj[i][j].weight() << "]";
if (j < adj[i].size() - 1) {
cout << " -> ";
}
}
cout << endl;
}
}
void print_digraph(EdgeWeightedDigraph graph) {
int prev = -1;
for (DirectedEdge e: graph.edges()) {
if (e.from() != prev)
cout << endl << e.from();
cout << " -> " << e.to() << " [" << e.weight() << "] ";
prev = e.from();
}
cout << endl << endl;
}
void print_mst(vector<Edge> mst) {
vector<int> v;
cout << endl;
for (Edge e: mst) {
int vorhanden = 0;
for (int i: v) {
if (e.either() == i)
vorhanden++;
}
if (vorhanden == 0) {
cout << e.either();
for (Edge z: mst) {
if (z.either() == e.either()) {
cout << " -> " << z.other(z.either()) << " [" << z.weight() << "] ";
}
}
cout << endl;
}
v.push_back(e.either());
}
}
void search(EdgeWeightedGraph gra, int type) {
int search;
cout << endl << "Suche nach ?> ";
cin >> search;
vector<bool> marked;
vector<int> edgeTo;
bool zsm;
if (!isInGrapf(gra, search))
cout << search << " ist nicht im Graphen" << endl;
if (type == 2) {
cout << "Tiefensuche(Depth - First - Search(DFS)) - Startknoten: " << search << endl << "Besuchsreihenfolge :"
<< endl;
zsm = Graphsearch::DFS(gra, search, marked, edgeTo);
} else {
cout << "Breitensuche(Breadth - First - Search(BFS)) - Startknoten: " << search << endl <<
"Besuchsreihenfolge :"
<< endl;
zsm = Graphsearch::BFS(gra, search, marked, edgeTo);
}
cout << endl << "Marked Array:";
for (int i = 0; i < marked.size(); i++)
cout << endl << i << " -> " << marked[i];
cout << endl << "Edge To Array:";
for (int i = 0; i < edgeTo.size(); i++)
cout << endl << i << " -> " << edgeTo[i];
if (zsm)
cout << endl << "Graph ist zusammenhaengend" << endl;
else
cout << endl << "Graph ist nicht zusammenhaengend" << endl;
}
bool get_edge_values(EdgeWeightedGraph &gra, int &from, int &to) {
cout << endl << "Start Knoten ?>";
cin >> from;
if (!isInGrapf(gra, from)) {
cout << from << " ist nicht im Graphen" << endl;
return false;
}
cout << endl << "Ziel Knoten ?>";
cin >> to;
if (!isInGrapf(gra, to)) {
cout << to << " ist nicht im Graphen" << endl;
return false;
}
return true;
}
int main() {
// Starte Unit-Tests
Catch::Session().run();
int selection;
string graph;
EdgeWeightedGraph gra(graph);
EdgeWeightedDigraph wgra(graph);
while (true) {
if (graph == "")
cout << endl << "Graph nicht gefunden" << endl;
cout << endl
<< "Praktikum 4: Graphenalgorithem:" << endl
<< "1) Graph einlesen" << endl
<< "2) Tiefensuche" << endl
<< "3) Breitensuche" << endl
<< "4) MST nach Prim" << endl
<< "5) MST nach Kruskal" << endl
<< "6) Kuerzeste Wege nach Dijkstra" << endl
<< "7) Ausgabe der Adjazenzliste" << endl
<< "8) Kante löschen" << endl
<< "9) Kante hinzufügen" << endl
<< "10) Programm beenden" << endl
<< "? > ";
cin >> selection;
switch (selection) {
case 1: {
int auswahl;
cout << endl << "Graph einlesen" << endl
<< "1) Graph1" << endl
<< "2) Graph2" << endl
<< "3) Graph3" << endl
<< "?> ";
cin >> auswahl;
switch (auswahl) {
case 1:
graph = "graph1.txt";
break;
case 2:
graph = "graph2.txt";
break;
case 3:
graph = "graph3.txt";
break;
}
if (graph != "") {
gra = EdgeWeightedGraph(graph);
wgra = EdgeWeightedDigraph(graph);
cout << endl << "Graph " << auswahl << " wurde eingelesen" << endl;
} else
cout << endl << "Graph nicht gefunden" << endl;
break;
}
case 2: {
search(gra, selection);
break;
}
case 3: {
search(gra, selection);
break;
}
case 4: {
int start = 0;
cout << endl << "Start Knoten ?> ";
cin >> start;
if (!isInGrapf(gra, start)) {
cout << start << " ist nicht im Graphen" << endl;
break;
}
PrimMST test(gra, start);
cout << "Minimaler Spannbaum(MST) nach Prim :" << endl;
cout << "Gewicht: " << test.weight();
vector<Edge> mst = test.edges();
print_mst(mst);
break;
}
case 5: {
KruskalMST test(gra);
cout << "Minimaler Spannbaum(MST) nach Kruskal :" << endl;
cout << "Gewicht: " << test.weight();
vector<Edge> mst = test.edges();
print_mst(mst);
break;
}
case 6: {
int start, ziel = 0;
cout << endl << "Start Knoten ?> ";
cin >> start;
if (!isInGrapf(gra, start)) {
cout << start << " ist nicht im Graphen" << endl;
continue;
}
cout << endl << "Ziel Knoten ?>";
cin >> ziel;
if (!isInGrapf(gra, ziel)) {
cout << ziel << " ist nicht im Graphen" << endl;
continue;
}
DijkstraSP dijkstra(wgra, start);
vector<DirectedEdge> path = dijkstra.pathTo(ziel);
print_digraph(wgra);
double kosten = 0.0;
string out = "";
cout << "Pfad: ";
for (DirectedEdge de: path) {
kosten += de.weight();
out += to_string(de.from()) + " [" + to_string(de.weight()) + "] " + " -> ";
}
if (kosten == 0.0) {
cout << "Kein Weg gefunden" << endl;
continue;
}
cout << out;
cout << path[path.size() - 1].to() << endl;
cout << "Kosten: " << kosten << endl;
break;
}
case 7: {
PrintGrapf(gra);
break;
}
case 8: {
int from, to;
if (get_edge_values(gra, from, to)) {
Edge n(from, to, 0);
DirectedEdge m(from, to, 0);
gra.del_Edge(n);
wgra.del_Edge(m);
cout << "Die Kante (" << from << " ; " << to << ") wurde gelöscht." << endl;
break;
}
break;
}
case 9: {
int from, to, weight;
bool a = get_edge_values(gra, from, to);
cout << endl << "Gewicht ?>";
cin >> weight;
if (a) {
Edge n(from, to, weight);
DirectedEdge m(from, to, weight);
gra.add(n);
wgra.add(m);
cout << "Die Kante (" << from << " ; " << to << " ; " << weight << ") wurde hinzugefügt." << endl;
}
break;
}
case 10: {
}
}
}
return 0;
}