Skip to content

Nasedkin Ivan's tasks #30

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,8 @@ _deps

.cache/*
.vscode/*
build/*
build/*
.vs
WeightedGraph.i
out
CMakeSettings.json
5 changes: 4 additions & 1 deletion lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ project(Utils)

set(CMAKE_CXX_STANDARD 23)

file(GLOB_RECURSE lib_source_list "src/*.cpp" "src/*.hpp")
file(GLOB_RECURSE lib_source_list "src/*.cpp")

SET(BASEPATH "${CMAKE_SOURCE_DIR}")
INCLUDE_DIRECTORIES("${BASEPATH}")

add_library(${PROJECT_NAME} ${lib_source_list})

Expand Down
35 changes: 35 additions & 0 deletions lib/src/BellmanFordAlgorithm.cpp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

имена файлов должны быть в стиле переменных, а расширение hpp( bellman_ford.hpp

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include <cfloat>

#include "BellmanForlAlgorithm.h"

std::vector<double> BellmanFordAlgorithm(const WeightedGraph& graph,
int start_id) {
int n = graph.GetVerts();
std::vector<double> pathLength(n, DBL_MAX);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

не по кодстайлу( path_length правильно, ни и везде

pathLength[start_id] = 0;
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
for (int k = 0; k < n; ++k)
if (graph[j][k] && pathLength[j] != DBL_MAX &&
pathLength[j] + graph[j][k] < pathLength[k]) {
if (i == n - 1) return std::vector<double>(0);
pathLength[k] = pathLength[j] + graph[j][k];
}
return pathLength;
}

std::vector<double> BellmanFordAlgorithm(
const OrientedWeightedGraphWithZeroWeight& graph, int start_id) {
int n = graph.GetVerts();
std::vector<double> pathLength(n, DBL_MAX);
pathLength[start_id] = 0;
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
for (int k = 0; k < n; ++k)
if (graph[j][k] && pathLength[j] != DBL_MAX &&
pathLength[j] + graph.GetWeight(j, k) < pathLength[k]) {
if (i == n - 1) return std::vector<double>(0);
pathLength[k] = pathLength[j] + graph.GetWeight(j, k);
}
return pathLength;
}
8 changes: 8 additions & 0 deletions lib/src/BellmanForlAlgorithm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once

#include <includes.h>

std::vector<double> BellmanFordAlgorithm(const WeightedGraph& graph,
int start_id);
std::vector<double> BellmanFordAlgorithm(
const OrientedWeightedGraphWithZeroWeight& graph, int start_id);
131 changes: 131 additions & 0 deletions lib/src/DeikstraAlgorithm.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#include "DeikstraAlgorithm.h"

#include <cfloat>

double DeikstraAlgorithm(const WeightedGraph& graph, int start_id, int end_id) {
int n = graph.GetVerts();
std::vector<bool> ended(n);
std::vector<double> pathLength(n, DBL_MAX);
pathLength[start_id] = 0;
int this_id = start_id;
int counter = 0;
for (; true;) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

тогда уж for (;;)

if (counter >= n) break;
for (int i = 0; i < n; ++i) {
if (graph[this_id][i])
pathLength[i] =
std::min(pathLength[i], pathLength[this_id] + graph[this_id][i]);
}
ended[this_id] = true;
double min = DBL_MAX;
for (int j = 0; j < n; ++j) {
if (!ended[j])
if (min > pathLength[j]) {
min = pathLength[j];
this_id = j;
}
}
if (this_id == end_id) return pathLength[end_id];
++counter;
}
return pathLength[end_id];
}

double DeikstraAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph,
int start_id, int end_id) {
int n = graph.GetVerts();
std::vector<bool> ended(n);
std::vector<double> pathLength(n, DBL_MAX);
pathLength[start_id] = 0;
int this_id = start_id;
int counter = 0;
for (; true;) {
if (counter >= n) break;
for (int i = 0; i < n; ++i) {
if (graph[this_id][i])
pathLength[i] = std::min(
pathLength[i], pathLength[this_id] + graph.GetWeight(this_id, i));
}
ended[this_id] = true;
double min = DBL_MAX;
for (int j = 0; j < n; ++j) {
if (!ended[j])
if (min > pathLength[j]) {
min = pathLength[j];
this_id = j;
}
}
if (this_id == end_id) return pathLength[end_id];
++counter;
}
return pathLength[end_id];
}

DeikstraReturn DeikstraPathAlgorithm(const WeightedGraph& graph, int start_id,
int end_id) {
int n = graph.GetVerts();
std::vector<bool> ended(n);
std::vector<double> pathLength(n, DBL_MAX);
std::vector<int> prevs(n, -1);
pathLength[start_id] = 0;
int this_id = start_id;
for (int counter = 0; counter < n && this_id != end_id; ++counter) {
for (int i = 0; i < n; ++i) {
if (graph[this_id][i] &&
pathLength[i] > pathLength[this_id] + graph[this_id][i]) {
pathLength[i] = pathLength[this_id] + graph[this_id][i];
prevs[i] = this_id;
}
}
ended[this_id] = true;
double min = DBL_MAX;
for (int j = 0; j < n; ++j) {
if (!ended[j])
if (min > pathLength[j]) {
min = pathLength[j];
this_id = j;
}
}
}
std::vector<int> path;
for (int i = end_id; i != start_id; i = prevs[i]) path.push_back(prevs[i]);
for (int i = 0; i < path.size() / 2; ++i)
std::swap(path[i], path[path.size() - 1 - i]);
return DeikstraReturn(path, pathLength[end_id]);
}

DeikstraReturn DeikstraPathAlgorithm(
const OrientedWeightedGraphWithZeroWeight& graph, int start_id,
int end_id) {
if (start_id == end_id) return DeikstraReturn(std::vector<int>(), 0);
int n = graph.GetVerts();
std::vector<bool> ended(n);
std::vector<double> pathLength(n, DBL_MAX);
std::vector<int> prevs(n, -1);
pathLength[start_id] = 0;
int this_id = start_id;
for (int counter = 0; counter < n && this_id != end_id; ++counter) {
for (int i = 0; i < n; ++i) {
if (graph[this_id][i] &&
pathLength[i] > pathLength[this_id] + graph.GetWeight(this_id, i)) {
pathLength[i] = pathLength[this_id] + graph.GetWeight(this_id, i);
prevs[i] = this_id;
}
}
ended[this_id] = true;
double min = DBL_MAX;
for (int j = 0; j < n; ++j) {
if (!ended[j])
if (min > pathLength[j]) {
min = pathLength[j];
this_id = j;
}
}
}
std::vector<int> path;
path.push_back(end_id);
for (int i = end_id; i != start_id; i = prevs[i]) path.push_back(prevs[i]);
for (int i = 0; i < path.size() / 2; ++i)
std::swap(path[i], path[path.size() - 1 - i]);
return DeikstraReturn(path, pathLength[end_id]);
}
16 changes: 16 additions & 0 deletions lib/src/DeikstraAlgorithm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

#include <includes.h>

struct DeikstraReturn {
std::vector<int> path;
double pathLength;
};

double DeikstraAlgorithm(const WeightedGraph& graph, int start_id, int end_id);
double DeikstraAlgorithm(const OrientedWeightedGraphWithZeroWeight& graph,
int start_id, int end_id);
DeikstraReturn DeikstraPathAlgorithm(const WeightedGraph& graph, int start_id,
int end_id);
DeikstraReturn DeikstraPathAlgorithm(
const OrientedWeightedGraphWithZeroWeight& graph, int start_id, int end_id);
14 changes: 14 additions & 0 deletions lib/src/Graph.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

#include <WeightedGraph.h>
#include <util.h>

#include <vector>

class Graph : public WeightedGraph {
int GetEdges() {
int result = 0;
for (int i = 0; i < graph.size(); ++i) result += sum(graph[i]);
return result;
}
};
31 changes: 31 additions & 0 deletions lib/src/GraphDFSIterator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include <GraphDFSIterator.h>

GraphDFSIterator::GraphDFSIterator(const WeightedGraph* const graph,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

красивее было бы вот так:
GraphDFSIterator::GraphDFSIterator(...) : start_id(start_id), graph(),... {}

int start_id) {
this->start_id = start_id;
this->graph = graph;
this->is_end = false;
this_id = start_id;
visited.resize(graph->GetVerts());
visited[start_id] = true;
parent.resize(graph->GetVerts(), -1);
}

int GraphDFSIterator::Next() {
for (int i = 0; i < graph->GetVerts(); ++i) {
if ((*graph)[this_id][i] != 0 && !visited[i]) {
visited[i] = true;
parent[i] = this_id;
this_id = i;
return i;
}
}
if (parent[this_id] == -1) {
is_end = true;
return this_id;
}
this_id = parent[this_id];
return Next();
}

bool GraphDFSIterator::IsEnd() { return is_end; }
27 changes: 27 additions & 0 deletions lib/src/GraphDFSIterator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#pragma once

#include <WeightedGraph.h>
#include <util.h>

#include <vector>

class WeightedGraph;

class GraphDFSIterator {
const WeightedGraph* graph;
int start_id;
int this_id;
bool is_end;
std::vector<bool> visited;
std::vector<int> parent;

int Next();

public:
GraphDFSIterator() = delete;
GraphDFSIterator(const WeightedGraph* const graph, int start_id);

int operator++() { return Next(); }
int operator()() { return this_id; }
bool IsEnd();
};
27 changes: 27 additions & 0 deletions lib/src/JonsonAlgorithm.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "JonsonAlgorithm.h"

double GetPathLength(const WeightedGraph& graph, const std::vector<int>& path) {
if (path.size() == 0) return 0;
double result = 0;
for (int i = 0; i < path.size() - 1; ++i)
result += graph[path[i]][path[i + 1]];
return result;
}

OrientedWeightedGraphWithZeroWeight JonsonAlgorithm(
const WeightedGraph& graph) {
int n = graph.GetVerts();
OrientedWeightedGraphWithZeroWeight new_graph(graph);
for (int i = 0; i < n; ++i) new_graph.AddEdge(n, i, 0);
auto h = BellmanFordAlgorithm(new_graph, n);
if (h.size() == 0) return WeightedGraph();
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j) new_graph.GetWeight(i, j) += h[i] - h[j];
OrientedWeightedGraphWithZeroWeight resultGraph;
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
resultGraph.AddEdge(
i, j,
GetPathLength(graph, DeikstraPathAlgorithm(new_graph, i, j).path));
return resultGraph;
}
8 changes: 8 additions & 0 deletions lib/src/JonsonAlgorithm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#pragma once

#include <includes.h>

#include "BellmanForlAlgorithm.h"
#include "DeikstraAlgorithm.h"

OrientedWeightedGraphWithZeroWeight JonsonAlgorithm(const WeightedGraph& graph);
19 changes: 19 additions & 0 deletions lib/src/Lca.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

struct Node {
int data;
Node* left;
Node* right;
Node(int val) {
data = val;
left = nullptr;
right = nullptr;
}
};

Node* LCA(Node* root, int n1, int n2) {
if (root == nullptr) return nullptr;
if (root->data > n1 && root->data > n2) return LCA(root->left, n1, n2);
if (root->data < n1 && root->data < n2) return LCA(root->right, n1, n2);
return root;
}
Loading
Loading