Skip to content
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
Binary file added D-кучи.doc
Binary file not shown.
42 changes: 42 additions & 0 deletions include/DHBPQ.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#pragma once
#include "priority_queue.h"
#include "dheap.h"

template <typename T>
class DHBPQ : public priority_queue<T>
{
dheap<T> heap;
public:
DHBPQ() = default;
DHBPQ(vector<T> elems, int d);
bool is_full() const override;
bool is_empty() const override;
void push(T a) override;
T pop() override;
};

template <typename T>
DHBPQ<T>::DHBPQ(vector<T> elems, int d) {
heap = dheap<T>(elems, d);
}

template <typename T>
bool DHBPQ<T>::is_full() const {
return false;
}

template <typename T>
bool DHBPQ<T>::is_empty() const {
return heap.is_empty();
}

template <typename T>
void DHBPQ<T>::push(T a) {
heap.insert(a);
}

template <typename T>
T DHBPQ<T>::pop() {
T a = heap.get_min_value();
return a;
}
111 changes: 111 additions & 0 deletions include/dheap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#pragma once
#include <algorithm>
#include <vector>
using namespace std;

template <typename T>
class dheap
{
vector<T> keys;
int d;
public:
dheap();
dheap(vector<T> keys, int d);
dheap(const dheap& heap) = default;
void sink(int idx);
void rise(int idx);
void transpose(int idx1, int idx2);
void hilling();
void insert(T key);
void remove(int idx);
T get_min_value();
int minchild(int idx);
bool is_empty() const;
};

template <typename T>
dheap<T>::dheap() : d(3) {
}

template <typename T>
dheap<T>::dheap(vector<T> keys, int d) {
this->d = d;
this->keys = keys;
hilling();
}

template <typename T>
void dheap<T>::sink(int idx) {
int c = minchild(idx);
while (c != -1 && keys[c] < keys[idx]) {
transpose(c, idx);
idx = c;
c = minchild(idx);
}
}

template <typename T>
void dheap<T>::rise(int idx) {
int p = (idx - 1) / d;
while (p > 0) {
if (keys[idx] < keys[p]) {
transpose(p, idx);
}
idx = p;
p = (idx - 1) / d;
}
}

template <typename T>
void dheap<T>::transpose(int idx1, int idx2) {
swap(keys[idx1], keys[idx2]);
}

template <typename T>
void dheap<T>::hilling() {
for (int i = keys.size() - 1; i >= 0; i--) {
sink(i);
}
}

template <typename T>
void dheap<T>::insert(T key) {
keys.push_back(key);
rise(keys.size() - 1);
}

template <typename T>
void dheap<T>::remove(int idx) {
if (idx < 0 || idx >= keys.size()) throw "Index error";

swap(keys.back(), keys[idx]);
keys.pop_back();
sink(idx);
}

template <typename T>
T dheap<T>::get_min_value() {
T tmp = keys.front();
swap(keys.front(), keys.back());
keys.pop_back();
sink(0);
return tmp;
}

template <typename T>
int dheap<T>::minchild(int idx) {
if (idx * d + 1 >= keys.size()) return -1;
int minidx = idx * d + 1;
int idx1 = idx * d + 1;
int idx2 = min(idx * d + d, (int)keys.size() - 1);
for (int i = idx1; i <= idx2; i++) {
if (keys[i] < keys[minidx])
minidx = i;
}
return minidx;
}

template <typename T>
bool dheap<T>::is_empty() const {
return keys.empty();
}
32 changes: 32 additions & 0 deletions include/edge.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#pragma once
#include <iostream>
using namespace std;

struct edge
{
int begin;
int end;
double weight;

bool operator <(const edge& A) const {
return weight < A.weight;
}

edge() = default;

edge(int begin, int end, double weight) {
this->begin = begin;
this->end = end;
this->weight = weight;
}

friend ostream& operator<<(ostream& o, const edge& e) {
o << "start = " << e.begin << ", weight = " << e.weight << ", finish = " << e.end;
return o;
}

bool operator ==(const edge& a) const {
return begin == a.begin && end == a.end ||
end == a.begin && begin == a.end;
}
};
33 changes: 33 additions & 0 deletions include/graph.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#pragma once
#include"edge.h"
#include <vector>
using namespace std;

struct vertex
{
int point_index = 0;
double distance = 0;
int from = -1;

vertex(int point_index, double distance, int from)
: point_index(point_index), distance(distance), from(from) {
}

bool operator<(const vertex& p) const { return distance < p.distance; }
};


class graph
{
void generate(int n, int m);
vector<edge> edges;
vector<int> points;
public:
graph(int n, int m);
graph(vector<edge> edges);
int points_size() const;
int edges_size() const;
vector<edge> get_edges() const;
vector<int> get_points() const;
void print();
};
10 changes: 10 additions & 0 deletions include/priority_queue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once
template <typename T>
class priority_queue
{
public:
virtual bool is_full() const = 0;
virtual bool is_empty() const = 0;
virtual void push(T a) = 0;
virtual T pop() = 0;
};
90 changes: 90 additions & 0 deletions src/deikstra.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#include <DHBPQ.h>
#include <graph.h>
#include <vector>

using namespace std;

vector<vertex> alg_deikstra(const graph& g, const int start) {
vector<int> points = g.get_points();
int n = points.size();
vector<vector<double>> matrix = vector<vector<double>>(n);
for (int i = 0; i < n; i++) {
matrix[i] = vector<double>(n, 0);
}

vector<edge> edges = g.get_edges();
int m = edges.size();
for (int i = 0; i < m; i++) {
matrix[edges[i].begin][edges[i].end] = edges[i].weight;
matrix[edges[i].end][edges[i].begin] = edges[i].weight;
}

vector<double> distance = vector<double>(g.points_size(), numeric_limits<double>::infinity());
vector<int> from = vector<int>(g.points_size(), -1);

distance[start] = 0;

DHBPQ<vertex> queue = DHBPQ<vertex>();
queue.push(vertex(start, distance[start], from[start]));

while (!queue.is_empty()) {
const vertex p = queue.pop();
vector<double>& weight = matrix[p.point_index];
for (unsigned int i = 0; i < weight.size(); i++) {
if (weight[i] == 0)
continue;

const double new_dist = distance[p.point_index] + weight[i];
if (new_dist < distance[i]) {
distance[i] = new_dist;
from[i] = p.point_index;
queue.push(vertex(i, distance[i], from[i]));
}
}
}

vector<vertex> result = vector<vertex>();
result.reserve(n);
for (int i = 0; i < n; i++) {
result.push_back(vertex(points[i], distance[i], from[i]));
}
return result;
}


int main() {
char IsEnded = 'y';
int n, m;
while (IsEnded == 'Y' || IsEnded == 'y')
{
cout << "Enter n,m" << endl;
cin >> n >> m;
try {
graph g = graph(n, m);
g.print();
vector<vertex> v = alg_deikstra(g, 0);


cout << "Point: ";
for (int i = 0; i < v.size(); i++) {
cout.width(4);
cout << v[i].point_index;
}
cout << endl << "Distance: ";
for (int i = 0; i < v.size(); i++) {
cout.width(4);
cout << v[i].distance;
}
cout << endl << "From: ";
for (int i = 0; i < v.size(); i++) {
cout.width(4);
cout << v[i].from;
}
}
catch (exception& l) { cout << l.what() << endl; }
cout << endl;
cout << "Do u wanna try again (Y/N)" << endl;
cin >> IsEnded;
}
return 0;
}
Loading