Init from KnyfSky
This commit is contained in:
commit
bd81d402be
24
CPP.cpp.snip
Normal file
24
CPP.cpp.snip
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// #define NDEBUG
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
// #include <string>
|
||||||
|
#include <vector>
|
||||||
|
// #include <array>
|
||||||
|
// #include <queue>
|
||||||
|
#include <iostream>
|
||||||
|
// #include <map>
|
||||||
|
// #include <math.h>
|
||||||
|
// #include <numeric>
|
||||||
|
// #include <tuple>
|
||||||
|
// #include <set>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
<cursor>;
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
#endif
|
105
CPP/TODO/foo.cpp
Normal file
105
CPP/TODO/foo.cpp
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/* #define NDEBUG */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
/* #include <string> */
|
||||||
|
#include <vector>
|
||||||
|
/* #include <array> */
|
||||||
|
/* #include <queue> */
|
||||||
|
#include <iostream>
|
||||||
|
/* #include <map> */
|
||||||
|
/* #include <math.h> */
|
||||||
|
/* #include <numeric> */
|
||||||
|
/* #include <tuple> */
|
||||||
|
/* #include <set> */
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class adjacency_list {
|
||||||
|
public:
|
||||||
|
size_t N;
|
||||||
|
std::vector<std::vector<T>> adj;
|
||||||
|
|
||||||
|
adjacency_list (size_t n) {
|
||||||
|
N = n;
|
||||||
|
adj(N, std::vector<T>());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<T> operator[](T i) { adj[i]; };
|
||||||
|
void add_directed_edge(size_t i, size_t j) {
|
||||||
|
adj[i].push_back(j);
|
||||||
|
};
|
||||||
|
void add_undirected_edge(size_t i, size_t j) {
|
||||||
|
adj[i].push_back(j);
|
||||||
|
adj[j].push_back(i);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T = long>
|
||||||
|
std::vector<std::vector<T>> floyd_warshall(std::vector<std::vector<T>> adj);
|
||||||
|
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
vector<vector<int>> adj_matrix;
|
||||||
|
auto foo = floyd_warshall(adj_matrix);
|
||||||
|
/* floyd_warshall<int>(adj_matrix); */
|
||||||
|
;
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// NOTE: !!!UNTESTED!!!
|
||||||
|
// Time complexity: O(n^3)
|
||||||
|
// Memory complexity: O(n^2) - only for n ~ 10^3 (n ~ 10^4 results in 1524 MB of memory)
|
||||||
|
// Input: Graph as an adjancency matrix (weight 0 => no edge)
|
||||||
|
// Output: A distance matrix (distance std::numeric_limits<T>::max() => no path)
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <limits>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
template <typename T>
|
||||||
|
std::vector<std::vector<T>> floyd_warshall(std::vector<std::vector<T>> adj) {
|
||||||
|
size_t n = adj.size();
|
||||||
|
std::vector<std::vector<long>> distance(n, std::vector<T>(n, 0));
|
||||||
|
|
||||||
|
// Initialize distance
|
||||||
|
for (size_t i = 0; i < n; i++) {
|
||||||
|
for (size_t j = 0; j < n; j++) {
|
||||||
|
if (i == j) distance[i][j] = 0;
|
||||||
|
else if (adj[i][j]) distance[i][j] = adj[i][j];
|
||||||
|
else distance[i][j] = std::numeric_limits<T>::max();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find shortest distances
|
||||||
|
for (size_t k = 0; k < n; k++) {
|
||||||
|
for (size_t i = 0; i < n; i++) {
|
||||||
|
for (size_t j = 0; j < n; j++) {
|
||||||
|
if (distance[i][k] == std::numeric_limits<T>::max() || distance[k][j] == std::numeric_limits<T>::max())
|
||||||
|
continue;
|
||||||
|
distance[i][j] = std::min(distance[i][j],
|
||||||
|
distance[i][k] + distance[k][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T = long>
|
||||||
|
class 1D_sum_queries {
|
||||||
|
vector<vector<T>> array;
|
||||||
|
public:
|
||||||
|
1D_sum_queries(size_t n) {
|
||||||
|
|
||||||
|
}
|
||||||
|
std::vector<T> operator[](T i) { adj[i]; };
|
||||||
|
}
|
37
CPP/graph_theory/floyd_warshall.cpp.snip
Normal file
37
CPP/graph_theory/floyd_warshall.cpp.snip
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// NOTE: Check the input graph for multiple edges between the same vertices! You will want to keep the shortest one
|
||||||
|
// Time complexity: O(n^3)
|
||||||
|
// Memory complexity: O(n^2) - only for n ~ 10^3 (n ~ 10^4 results in 1524 MB of memory)
|
||||||
|
// Input: Graph as an adjancency matrix (weight __LONG_MAX__ => no edge)
|
||||||
|
// Output: A distance matrix (distance __LONG_MAX__ => no path)
|
||||||
|
vector<vector<long>> floyd_warshall(vector<vector<long>> adj) {
|
||||||
|
size_t n = adj.size();
|
||||||
|
vector<vector<long>> distance(n, vector<long>(n, 0));
|
||||||
|
|
||||||
|
// Initialize distance
|
||||||
|
for (size_t i = 0; i < n; i++) {
|
||||||
|
for (size_t j = 0; j < n; j++) {
|
||||||
|
// Original floyd-warshall
|
||||||
|
// if (i == j) distance[i][j] = 0;
|
||||||
|
// else if (adj[i][j]) distance[i][j] = adj[i][j];
|
||||||
|
// else distance[i][j] = __LONG_MAX__;
|
||||||
|
|
||||||
|
// My version
|
||||||
|
if (i == j) distance[i][j] = 0;
|
||||||
|
else distance[i][j] = adj[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find shortest distances
|
||||||
|
for (size_t k = 0; k < n; k++) {
|
||||||
|
for (size_t i = 0; i < n; i++) {
|
||||||
|
for (size_t j = 0; j < n; j++) {
|
||||||
|
if (distance[i][k] == __LONG_MAX__ || distance[k][j] == __LONG_MAX__)
|
||||||
|
continue;
|
||||||
|
distance[i][j] = min(distance[i][j],
|
||||||
|
distance[i][k] + distance[k][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return distance;
|
||||||
|
}
|
267
CPP/graph_theory/graph.cpp.snip
Normal file
267
CPP/graph_theory/graph.cpp.snip
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
// #define NDEBUG
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
#include <queue>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
template <typename T = long> class Graph;
|
||||||
|
template <typename T = long> class WeightedGraph;
|
||||||
|
template <typename T, typename EDGE> class BaseGraph;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class Graph : public BaseGraph<T, int> {
|
||||||
|
virtual int construct_edge(int v, T w) {
|
||||||
|
w; // Remove warning
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int get_edge_vertex(int e) {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual T get_edge_weight(int e) {
|
||||||
|
e; // Remove warning
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Graph(size_t N, size_t min_index) : BaseGraph<T, int>(N, min_index) {};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class WeightedGraph : public BaseGraph<T, std::pair<T, int>> {
|
||||||
|
virtual std::pair<T, int> construct_edge(int v, T w) {
|
||||||
|
return {w, v};
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int get_edge_vertex(std::pair<T, int> e) {
|
||||||
|
return e.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual T get_edge_weight(std::pair<T, int> e) {
|
||||||
|
return e.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool min_cut_max_flow_dfs(std::vector<std::vector<std::pair<std::pair<T, int>&, std::pair<T, int>&>>> &edge_pairs, std::vector<std::pair<std::pair<T, int>&, std::pair<T, int>&>>& path, std::vector<bool>& visited, int v, int sink, T threshold) {
|
||||||
|
if (v == sink)
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
visited[v] = true;
|
||||||
|
for (auto e : edge_pairs[v]) {
|
||||||
|
int u = get_edge_vertex(e.first);
|
||||||
|
int w = get_edge_weight(e.first);
|
||||||
|
if (!visited[u] && w >= threshold) {
|
||||||
|
bool res = min_cut_max_flow_dfs(edge_pairs, path, visited, u, sink, threshold);
|
||||||
|
if (res == EXIT_SUCCESS) {
|
||||||
|
path.push_back(e);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
WeightedGraph(size_t N, size_t min_index) : BaseGraph<T, std::pair<T, int>>(N, min_index) {};
|
||||||
|
|
||||||
|
Graph<T> get_shortest_path_graph(int from) {
|
||||||
|
std::vector<T> best_distance = this->dijkstra(from);
|
||||||
|
Graph<T> G(this->N, this->min_index);
|
||||||
|
for (size_t i = this->min_index; i < this->N; i++) {
|
||||||
|
for (auto e : this->adj[i]) {
|
||||||
|
T w = get_edge_weight(e);
|
||||||
|
int v = get_edge_vertex(e);
|
||||||
|
if (best_distance[i] + w == best_distance[v])
|
||||||
|
G.add_directed_edge(i, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return G;
|
||||||
|
}
|
||||||
|
|
||||||
|
WeightedGraph<T> get_weighted_shortest_path_graph(int from) {
|
||||||
|
std::vector<T> best_distance = this->dijkstra(from);
|
||||||
|
WeightedGraph<T> G(this->N, this->min_index);
|
||||||
|
for (size_t i = this->min_index; i < this->N; i++) {
|
||||||
|
for (auto e : this->adj[i]) {
|
||||||
|
T w = get_edge_weight(e);
|
||||||
|
int v = get_edge_vertex(e);
|
||||||
|
if (best_distance[i] + w == best_distance[v])
|
||||||
|
G.add_directed_edge(i, v, w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return G;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Running time: O(m^2n)
|
||||||
|
T min_cut_max_flow(int source, int sink) {
|
||||||
|
// TODO: Implement non-destructive version?
|
||||||
|
// Ford-Fulkerson - "scaling algorithm" version
|
||||||
|
std::vector<std::vector<std::pair<std::pair<T, int>&, std::pair<T, int>&>>> edge_pairs(this->N, std::vector<std::pair<std::pair<T, int>&, std::pair<T, int>&>>());
|
||||||
|
T threshold = 0;
|
||||||
|
for (size_t v = this->min_index; v < this->N; v++) {
|
||||||
|
for (auto& e : this->adj[v]) {
|
||||||
|
if (get_edge_weight(e) == 0) continue;
|
||||||
|
threshold = threshold > get_edge_weight(e) ? threshold : get_edge_weight(e); // max(threshold, get_edge_weight(e));
|
||||||
|
int u = get_edge_vertex(e);
|
||||||
|
this->adj[u].push_back(construct_edge(v, 0));
|
||||||
|
edge_pairs[v].push_back({e, this->adj[u][this->adj[u].size()-1]});
|
||||||
|
edge_pairs[u].push_back({this->adj[u][this->adj[u].size()-1], e});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<bool> visited(this->N, false);
|
||||||
|
std::vector<std::pair<std::pair<T, int>&, std::pair<T, int>&>> path;
|
||||||
|
while (true) {
|
||||||
|
bool res = min_cut_max_flow_dfs(edge_pairs, path, visited, source, sink, threshold);
|
||||||
|
if (res == EXIT_SUCCESS) {
|
||||||
|
T path_max_flow = std::numeric_limits<T>::max();
|
||||||
|
for (auto e : path)
|
||||||
|
path_max_flow = path_max_flow < get_edge_weight(e.first) ? path_max_flow : get_edge_weight(e.first);
|
||||||
|
// min(path_max_flow, get_edge_weight(e.first));
|
||||||
|
for (auto e : path) {
|
||||||
|
e.first = construct_edge(get_edge_vertex(e.first), get_edge_weight(e.first)-threshold);
|
||||||
|
e.second = construct_edge(get_edge_vertex(e.second), get_edge_weight(e.second)+threshold);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (threshold == 1)
|
||||||
|
break; // Done!
|
||||||
|
threshold /= 2;
|
||||||
|
}
|
||||||
|
std::fill(visited.begin(), visited.end(), false);
|
||||||
|
path.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
T max_flow = 0;
|
||||||
|
for (auto e : this->adj[sink]) {
|
||||||
|
max_flow += get_edge_weight(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return max_flow;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename EDGE>
|
||||||
|
class BaseGraph {
|
||||||
|
std::vector<int> top_sort;
|
||||||
|
int contains_cycles = 0; // 0 = unknown, 1 = yes, 2 = no
|
||||||
|
bool contains_negative_edge_weight = false;
|
||||||
|
|
||||||
|
virtual int get_edge_vertex(EDGE) = 0;
|
||||||
|
virtual T get_edge_weight(EDGE) = 0;
|
||||||
|
virtual EDGE construct_edge(int vertex, T w) = 0;
|
||||||
|
|
||||||
|
bool topological_sort_dfs(std::vector<int8_t>& status, int v, std::vector<int>& top_sort) {
|
||||||
|
if (status[v] == 1)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
if (status[v] == 0) {
|
||||||
|
status[v] = 1;
|
||||||
|
for (auto e : adj[v]) {
|
||||||
|
bool res = topological_sort_dfs(status, get_edge_vertex(e), top_sort);
|
||||||
|
if (res == EXIT_FAILURE)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
status[v] = 2;
|
||||||
|
top_sort.push_back(v);
|
||||||
|
}
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_topological_sort() {
|
||||||
|
std::vector<int8_t> status(N, 0);
|
||||||
|
std::vector<int> top_sort = std::vector<int>();
|
||||||
|
for (size_t i = min_index; i < N; i++) {
|
||||||
|
bool res = topological_sort_dfs(status, i, top_sort);
|
||||||
|
if (res == EXIT_FAILURE) {
|
||||||
|
contains_cycles = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contains_cycles = 2;
|
||||||
|
std::reverse(top_sort.begin(), top_sort.end());
|
||||||
|
this->top_sort = top_sort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
size_t N;
|
||||||
|
size_t min_index;
|
||||||
|
std::vector<std::vector<EDGE>> adj;
|
||||||
|
|
||||||
|
BaseGraph(size_t N, size_t min_index) {
|
||||||
|
N += min_index;
|
||||||
|
this->N = N;
|
||||||
|
this->min_index = min_index;
|
||||||
|
adj = std::vector<std::vector<EDGE>>(N, std::vector<EDGE>());
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_directed_edge(int from, int to, T w = 1) {
|
||||||
|
adj[from].push_back(construct_edge(to, w));
|
||||||
|
contains_cycles = 0;
|
||||||
|
if (w < 0)
|
||||||
|
contains_negative_edge_weight = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_undirected_edge(size_t a, size_t b, T w = 1) {
|
||||||
|
adj[a].push_back(construct_edge(b, w));
|
||||||
|
adj[b].push_back(construct_edge(a, w));
|
||||||
|
contains_cycles = 0;
|
||||||
|
if (w < 0)
|
||||||
|
contains_negative_edge_weight = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<EDGE> get(int v) {
|
||||||
|
return adj[v];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int> topological_sort() {
|
||||||
|
if (contains_cycles != 2)
|
||||||
|
std::cerr << "Check for cycles first!" << std::endl;
|
||||||
|
return top_sort;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has_cycles() {
|
||||||
|
if (contains_cycles == 0)
|
||||||
|
do_topological_sort();
|
||||||
|
return contains_cycles == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<T> count_paths(int from) {
|
||||||
|
if (contains_cycles != 2)
|
||||||
|
std::cerr << "Check for cycles first!" << std::endl;
|
||||||
|
std::vector<T> paths(N, 0);
|
||||||
|
for (auto v : top_sort) {
|
||||||
|
T p = 0;
|
||||||
|
if (v == from) p++;
|
||||||
|
for (auto e : adj[v])
|
||||||
|
p += paths[get_edge_vertex(e)];
|
||||||
|
paths[v] = p;
|
||||||
|
}
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<T> dijkstra(int from) {
|
||||||
|
if (contains_negative_edge_weight)
|
||||||
|
std::cerr << "Dijkstra only works if the graph doesn't contain any negative edge weights" << std::endl;
|
||||||
|
std::vector<T> distance(N, std::numeric_limits<T>::max());
|
||||||
|
distance[from] = 0;
|
||||||
|
std::vector<bool> processed(N, false);
|
||||||
|
std::priority_queue<std::pair<T, int>> q;
|
||||||
|
q.push({0, from});
|
||||||
|
while (!q.empty()) {
|
||||||
|
int v = q.top().second; q.pop();
|
||||||
|
if (processed[v]) continue;
|
||||||
|
processed[v] = true;
|
||||||
|
for (auto e : adj[v]) {
|
||||||
|
int u = get_edge_vertex(e);
|
||||||
|
T w = get_edge_weight(e);
|
||||||
|
if (distance[v] + w < distance[u]) {
|
||||||
|
distance[u] = distance[v] + w;
|
||||||
|
q.push({-distance[u], u});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
|
};
|
BIN
CPP/graph_theory/test/test
Normal file
BIN
CPP/graph_theory/test/test
Normal file
Binary file not shown.
372
CPP/graph_theory/test/test.cpp
Normal file
372
CPP/graph_theory/test/test.cpp
Normal file
@ -0,0 +1,372 @@
|
|||||||
|
// #define NDEBUG
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
// #include <string>
|
||||||
|
#include <vector>
|
||||||
|
// #include <array>
|
||||||
|
// #include <queue>
|
||||||
|
#include <iostream>
|
||||||
|
// #include <map>
|
||||||
|
// #include <math.h>
|
||||||
|
// #include <numeric>
|
||||||
|
// #include <tuple>
|
||||||
|
// #include <set>
|
||||||
|
|
||||||
|
|
||||||
|
// #define NDEBUG
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
#include <queue>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
template <typename T = long> class Graph;
|
||||||
|
template <typename T = long> class WeightedGraph;
|
||||||
|
template <typename T, typename EDGE> class BaseGraph;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class Graph : public BaseGraph<T, int> {
|
||||||
|
virtual int construct_edge(int v, T w) {
|
||||||
|
w; // Remove warning
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int get_edge_vertex(int e) {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual T get_edge_weight(int e) {
|
||||||
|
e; // Remove warning
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Graph(size_t N, size_t min_index) : BaseGraph<T, int>(N, min_index) {};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class WeightedGraph : public BaseGraph<T, std::pair<T, int>> {
|
||||||
|
virtual std::pair<T, int> construct_edge(int v, T w) {
|
||||||
|
return {w, v};
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int get_edge_vertex(std::pair<T, int> e) {
|
||||||
|
return e.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual T get_edge_weight(std::pair<T, int> e) {
|
||||||
|
return e.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool min_cut_max_flow_dfs(std::vector<std::vector<std::pair<std::pair<T, int>&, std::pair<T, int>&>>> &edge_pairs, std::vector<std::pair<std::pair<T, int>&, std::pair<T, int>&>>& path, std::vector<bool>& visited, int v, int sink, T threshold) {
|
||||||
|
if (v == sink)
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
visited[v] = true;
|
||||||
|
for (auto e : edge_pairs[v]) {
|
||||||
|
int u = get_edge_vertex(e.first);
|
||||||
|
int w = get_edge_weight(e.first);
|
||||||
|
if (!visited[u] && w >= threshold) {
|
||||||
|
bool res = min_cut_max_flow_dfs(edge_pairs, path, visited, u, sink, threshold);
|
||||||
|
if (res == EXIT_SUCCESS) {
|
||||||
|
path.push_back(e);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
WeightedGraph(size_t N, size_t min_index) : BaseGraph<T, std::pair<T, int>>(N, min_index) {};
|
||||||
|
|
||||||
|
Graph<T> get_shortest_path_graph(int from) {
|
||||||
|
std::vector<T> best_distance = this->dijkstra(from);
|
||||||
|
Graph<T> G(this->N, this->min_index);
|
||||||
|
for (size_t i = this->min_index; i < this->N; i++) {
|
||||||
|
for (auto e : this->adj[i]) {
|
||||||
|
T w = get_edge_weight(e);
|
||||||
|
int v = get_edge_vertex(e);
|
||||||
|
if (best_distance[i] + w == best_distance[v])
|
||||||
|
G.add_directed_edge(i, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return G;
|
||||||
|
}
|
||||||
|
|
||||||
|
WeightedGraph<T> get_weighted_shortest_path_graph(int from) {
|
||||||
|
std::vector<T> best_distance = this->dijkstra(from);
|
||||||
|
WeightedGraph<T> G(this->N, this->min_index);
|
||||||
|
for (size_t i = this->min_index; i < this->N; i++) {
|
||||||
|
for (auto e : this->adj[i]) {
|
||||||
|
T w = get_edge_weight(e);
|
||||||
|
int v = get_edge_vertex(e);
|
||||||
|
if (best_distance[i] + w == best_distance[v])
|
||||||
|
G.add_directed_edge(i, v, w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return G;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Running time: O(m^2n)
|
||||||
|
T min_cut_max_flow(int source, int sink) {
|
||||||
|
// TODO: Implement non-destructive version?
|
||||||
|
// Ford-Fulkerson - "scaling algorithm" version
|
||||||
|
std::vector<std::vector<std::pair<std::pair<T, int>&, std::pair<T, int>&>>> edge_pairs(this->N, std::vector<std::pair<std::pair<T, int>&, std::pair<T, int>&>>());
|
||||||
|
T threshold = 0;
|
||||||
|
for (size_t v = this->min_index; v < this->N; v++) {
|
||||||
|
for (auto& e : this->adj[v]) {
|
||||||
|
if (get_edge_weight(e) == 0) continue;
|
||||||
|
threshold = threshold > get_edge_weight(e) ? threshold : get_edge_weight(e); // max(threshold, get_edge_weight(e));
|
||||||
|
int u = get_edge_vertex(e);
|
||||||
|
this->adj[u].push_back(construct_edge(v, 0));
|
||||||
|
edge_pairs[v].push_back({e, this->adj[u][this->adj[u].size()-1]});
|
||||||
|
edge_pairs[u].push_back({this->adj[u][this->adj[u].size()-1], e});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<bool> visited(this->N, false);
|
||||||
|
std::vector<std::pair<std::pair<T, int>&, std::pair<T, int>&>> path;
|
||||||
|
while (true) {
|
||||||
|
bool res = min_cut_max_flow_dfs(edge_pairs, path, visited, source, sink, threshold);
|
||||||
|
if (res == EXIT_SUCCESS) {
|
||||||
|
T path_max_flow = std::numeric_limits<T>::max();
|
||||||
|
for (auto e : path)
|
||||||
|
path_max_flow = path_max_flow < get_edge_weight(e.first) ? path_max_flow : get_edge_weight(e.first);
|
||||||
|
// min(path_max_flow, get_edge_weight(e.first));
|
||||||
|
for (auto e : path) {
|
||||||
|
e.first = construct_edge(get_edge_vertex(e.first), get_edge_weight(e.first)-threshold);
|
||||||
|
e.second = construct_edge(get_edge_vertex(e.second), get_edge_weight(e.second)+threshold);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (threshold == 1)
|
||||||
|
break; // Done!
|
||||||
|
threshold /= 2;
|
||||||
|
}
|
||||||
|
std::fill(visited.begin(), visited.end(), false);
|
||||||
|
path.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
T max_flow = 0;
|
||||||
|
for (auto e : this->adj[sink]) {
|
||||||
|
max_flow += get_edge_weight(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return max_flow;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename EDGE>
|
||||||
|
class BaseGraph {
|
||||||
|
std::vector<int> top_sort;
|
||||||
|
int contains_cycles = 0; // 0 = unknown, 1 = yes, 2 = no
|
||||||
|
bool contains_negative_edge_weight = false;
|
||||||
|
|
||||||
|
virtual int get_edge_vertex(EDGE) = 0;
|
||||||
|
virtual T get_edge_weight(EDGE) = 0;
|
||||||
|
virtual EDGE construct_edge(int vertex, T w) = 0;
|
||||||
|
|
||||||
|
bool topological_sort_dfs(std::vector<int8_t>& status, int v, std::vector<int>& top_sort) {
|
||||||
|
if (status[v] == 1)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
if (status[v] == 0) {
|
||||||
|
status[v] = 1;
|
||||||
|
for (auto e : adj[v]) {
|
||||||
|
bool res = topological_sort_dfs(status, get_edge_vertex(e), top_sort);
|
||||||
|
if (res == EXIT_FAILURE)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
status[v] = 2;
|
||||||
|
top_sort.push_back(v);
|
||||||
|
}
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_topological_sort() {
|
||||||
|
std::vector<int8_t> status(N, 0);
|
||||||
|
std::vector<int> top_sort = std::vector<int>();
|
||||||
|
for (size_t i = min_index; i < N; i++) {
|
||||||
|
bool res = topological_sort_dfs(status, i, top_sort);
|
||||||
|
if (res == EXIT_FAILURE) {
|
||||||
|
contains_cycles = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contains_cycles = 2;
|
||||||
|
std::reverse(top_sort.begin(), top_sort.end());
|
||||||
|
this->top_sort = top_sort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
size_t N;
|
||||||
|
size_t min_index;
|
||||||
|
std::vector<std::vector<EDGE>> adj;
|
||||||
|
|
||||||
|
BaseGraph(size_t N, size_t min_index) {
|
||||||
|
N += min_index;
|
||||||
|
this->N = N;
|
||||||
|
this->min_index = min_index;
|
||||||
|
adj = std::vector<std::vector<EDGE>>(N, std::vector<EDGE>());
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_directed_edge(int from, int to, T w = 1) {
|
||||||
|
adj[from].push_back(construct_edge(to, w));
|
||||||
|
contains_cycles = 0;
|
||||||
|
if (w < 0)
|
||||||
|
contains_negative_edge_weight = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_undirected_edge(size_t a, size_t b, T w = 1) {
|
||||||
|
adj[a].push_back(construct_edge(b, w));
|
||||||
|
adj[b].push_back(construct_edge(a, w));
|
||||||
|
contains_cycles = 0;
|
||||||
|
if (w < 0)
|
||||||
|
contains_negative_edge_weight = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<EDGE> get(int v) {
|
||||||
|
return adj[v];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int> topological_sort() {
|
||||||
|
if (contains_cycles != 2)
|
||||||
|
std::cerr << "Check for cycles first!" << std::endl;
|
||||||
|
return top_sort;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has_cycles() {
|
||||||
|
if (contains_cycles == 0)
|
||||||
|
do_topological_sort();
|
||||||
|
return contains_cycles == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<T> count_paths(int from) {
|
||||||
|
if (contains_cycles != 2)
|
||||||
|
std::cerr << "Check for cycles first!" << std::endl;
|
||||||
|
std::vector<T> paths(N, 0);
|
||||||
|
for (auto v : top_sort) {
|
||||||
|
T p = 0;
|
||||||
|
if (v == from) p++;
|
||||||
|
for (auto e : adj[v])
|
||||||
|
p += paths[get_edge_vertex(e)];
|
||||||
|
paths[v] = p;
|
||||||
|
}
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<T> dijkstra(int from) {
|
||||||
|
if (contains_negative_edge_weight)
|
||||||
|
std::cerr << "Dijkstra only works if the graph doesn't contain any negative edge weights" << std::endl;
|
||||||
|
std::vector<T> distance(N, std::numeric_limits<T>::max());
|
||||||
|
distance[from] = 0;
|
||||||
|
std::vector<bool> processed(N, false);
|
||||||
|
std::priority_queue<std::pair<T, int>> q;
|
||||||
|
q.push({0, from});
|
||||||
|
while (!q.empty()) {
|
||||||
|
int v = q.top().second; q.pop();
|
||||||
|
if (processed[v]) continue;
|
||||||
|
processed[v] = true;
|
||||||
|
for (auto e : adj[v]) {
|
||||||
|
int u = get_edge_vertex(e);
|
||||||
|
T w = get_edge_weight(e);
|
||||||
|
if (distance[v] + w < distance[u]) {
|
||||||
|
distance[u] = distance[v] + w;
|
||||||
|
q.push({-distance[u], u});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
// TODO: SEGFAULT
|
||||||
|
// WeightedGraph G(6, 1);
|
||||||
|
// G.add_directed_edge(1, 2, 5);
|
||||||
|
// G.add_directed_edge(1, 4, 4);
|
||||||
|
// G.add_directed_edge(4, 2, 3);
|
||||||
|
// G.add_directed_edge(2, 3, 6);
|
||||||
|
// G.add_directed_edge(4, 5, 1);
|
||||||
|
// G.add_directed_edge(3, 5, 8);
|
||||||
|
// G.add_directed_edge(3, 6, 5);
|
||||||
|
// G.add_directed_edge(5, 6, 2);
|
||||||
|
|
||||||
|
// cout << "foo" << endl;
|
||||||
|
// cout << G.min_cut_max_flow(1, 6) << endl;
|
||||||
|
|
||||||
|
// // Works! (Probably)
|
||||||
|
// WeightedGraph G(6, 1);
|
||||||
|
// G.add_directed_edge(1, 2, 5);
|
||||||
|
// G.add_directed_edge(4, 1, 4);
|
||||||
|
// G.add_directed_edge(4, 5, 4);
|
||||||
|
// G.add_directed_edge(5, 2, 4);
|
||||||
|
// G.add_directed_edge(5, 3, 4);
|
||||||
|
// G.add_directed_edge(2, 3, 4);
|
||||||
|
// G.add_directed_edge(3, 6, 4);
|
||||||
|
|
||||||
|
// cout << "foo" << endl;
|
||||||
|
// bool cycles = G.has_cycles();
|
||||||
|
// cout << "Has cycles: " << cycles << endl;
|
||||||
|
// vector<int> top = G.topological_sort();
|
||||||
|
// for (auto i : top)
|
||||||
|
// cout << i << " ";
|
||||||
|
// cout << endl;
|
||||||
|
|
||||||
|
// // Works! (Probably)
|
||||||
|
// WeightedGraph G(6, 1);
|
||||||
|
// G.add_directed_edge(1, 2, 5);
|
||||||
|
// G.add_directed_edge(1, 4, 4);
|
||||||
|
// G.add_directed_edge(5, 1, 4);
|
||||||
|
// G.add_directed_edge(4, 5, 4);
|
||||||
|
// G.add_directed_edge(5, 2, 4);
|
||||||
|
// G.add_directed_edge(5, 3, 4);
|
||||||
|
// G.add_directed_edge(2, 3, 4);
|
||||||
|
// G.add_directed_edge(3, 6, 4);
|
||||||
|
|
||||||
|
// cout << "foo" << endl;
|
||||||
|
// bool cycles = G.has_cycles();
|
||||||
|
// cout << "Has cycles: " << cycles << endl;
|
||||||
|
|
||||||
|
// // Works! (Probably)
|
||||||
|
// Graph G(6, 1);
|
||||||
|
// G.add_directed_edge(1, 2);
|
||||||
|
// G.add_directed_edge(4, 1);
|
||||||
|
// G.add_directed_edge(4, 5);
|
||||||
|
// G.add_directed_edge(5, 2);
|
||||||
|
// G.add_directed_edge(5, 3);
|
||||||
|
// G.add_directed_edge(2, 3);
|
||||||
|
// G.add_directed_edge(3, 6);
|
||||||
|
|
||||||
|
// cout << "foo" << endl;
|
||||||
|
// bool cycles = G.has_cycles();
|
||||||
|
// cout << "Has cycles: " << cycles << endl;
|
||||||
|
// vector<int> top = G.topological_sort();
|
||||||
|
// for (auto i : top)
|
||||||
|
// cout << i << " ";
|
||||||
|
// cout << endl;
|
||||||
|
|
||||||
|
// Works! (Probably)
|
||||||
|
WeightedGraph G(6, 1);
|
||||||
|
G.add_directed_edge(1, 2, 5);
|
||||||
|
G.add_directed_edge(4, 1, 4);
|
||||||
|
G.add_directed_edge(4, 5, 4);
|
||||||
|
G.add_directed_edge(5, 2, 4);
|
||||||
|
G.add_directed_edge(5, 3, 4);
|
||||||
|
G.add_directed_edge(2, 3, 4);
|
||||||
|
G.add_directed_edge(3, 6, 4);
|
||||||
|
|
||||||
|
cout << "foo" << endl;
|
||||||
|
bool cycles = G.has_cycles();
|
||||||
|
cout << "Has cycles: " << cycles << endl;
|
||||||
|
vector<long> dist = G.dijkstra(1);
|
||||||
|
for (int i = 1; i <= 6; i++)
|
||||||
|
cout << i << " " << dist[i] << endl;
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
25
CPP/hpc/dmalloc_2d.c.snip
Normal file
25
CPP/hpc/dmalloc_2d.c.snip
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
double** dmalloc_2d(int m, int n);
|
||||||
|
void dfree_2d(double **A);
|
||||||
|
|
||||||
|
// allocate a double-precision m x n matrix
|
||||||
|
double** dmalloc_2d(int m, int n) {
|
||||||
|
if (m <= 0 || n <= 0) return NULL;
|
||||||
|
double **A = malloc(m * sizeof(double *));
|
||||||
|
if (A == NULL) return NULL;
|
||||||
|
A[0] = malloc(m*n*sizeof(double));
|
||||||
|
if (A[0] == NULL) {
|
||||||
|
free(A);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for (int i = 1; i < m; i++)
|
||||||
|
A[i] = A[0] + i * n;
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
// de-allocating memory, allocated with dmalloc_2d
|
||||||
|
void dfree_2d(double **A) {
|
||||||
|
free(A[0]);
|
||||||
|
free(A);
|
||||||
|
}
|
6
CPP/hpc/include_cblas.c.snip
Normal file
6
CPP/hpc/include_cblas.c.snip
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#if defined(__MACH__) && defined(__APPLE__)
|
||||||
|
#include <Accelerate/Accelerate.h>
|
||||||
|
#else
|
||||||
|
#include <cblas.h>
|
||||||
|
#endif
|
142
CPP/range_queries/SegmentTree.cpp.snip
Normal file
142
CPP/range_queries/SegmentTree.cpp.snip
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
#define NDEBUG
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
template <typename T = long> class SegmentTree;
|
||||||
|
template <typename T = long> class SumSegmentTree;
|
||||||
|
template <typename T = long> class MinSegmentTree;
|
||||||
|
template <typename T = long> class MaxSegmentTree;
|
||||||
|
template <typename T = long> class DifferenceSegmentTree;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class SumSegmentTree : public SegmentTree<T> {
|
||||||
|
virtual T cmp (T a, T b) override {
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
SumSegmentTree(size_t N) : SegmentTree<T>(N, 0) {};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class MinSegmentTree : public SegmentTree<T> {
|
||||||
|
virtual T cmp (T a, T b) override {
|
||||||
|
return (a < b) ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
MinSegmentTree(size_t N) : SegmentTree<T>(N, std::numeric_limits<T>::max()) {};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class MaxSegmentTree : public SegmentTree<T> {
|
||||||
|
virtual T cmp (T a, T b) override {
|
||||||
|
return (a > b) ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
MaxSegmentTree(size_t N) : SegmentTree<T>(N, std::numeric_limits<T>::min()) {};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class DifferenceSegmentTree : public SegmentTree<T> {
|
||||||
|
virtual T cmp (T a, T b) override {
|
||||||
|
return a+b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void add(size_t i, T val) override {
|
||||||
|
this->set(i, this->get(i) + val);
|
||||||
|
if (i != this->N-1)
|
||||||
|
this->set(i+1, this->get(i+1) - val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_range(size_t i, size_t j, T val) {
|
||||||
|
this->set(i, this->get(i) + val);
|
||||||
|
if (j+1 != this->N)
|
||||||
|
this->set(j+1, this->get(j+1)-val);
|
||||||
|
}
|
||||||
|
|
||||||
|
DifferenceSegmentTree(size_t N) : SegmentTree<T>(N, 0) {};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class SegmentTree {
|
||||||
|
const T unit;
|
||||||
|
virtual T cmp (T a, T b) = 0;
|
||||||
|
std::vector<T> arr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
size_t N;
|
||||||
|
|
||||||
|
void print() {
|
||||||
|
size_t newline = 2;
|
||||||
|
for (size_t i = 1; i < 2*N; i++) {
|
||||||
|
std::cout << arr[i] << " ";
|
||||||
|
if (i == newline-1) {
|
||||||
|
std::cout << std::endl;
|
||||||
|
newline *= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SegmentTree(size_t N, T unit) : unit(unit) {
|
||||||
|
this->N = N;
|
||||||
|
// Initialize the array to the size of the smallest power of two greater than N
|
||||||
|
size_t exp = 0;
|
||||||
|
while (N != 0) {
|
||||||
|
N = N >> 1;
|
||||||
|
exp++;
|
||||||
|
}
|
||||||
|
if ((size_t)(1 << (exp-1)) == this->N)
|
||||||
|
arr = std::vector<T>(this->N*2, unit);
|
||||||
|
else
|
||||||
|
arr = std::vector<T>(1 << (exp+1), unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
T get(size_t i) {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (i >= N)
|
||||||
|
std::cerr << "Tried accessing index " << i << " out of " << N-1 << " (remember, 0-indexing)" << std::endl;
|
||||||
|
#endif
|
||||||
|
return arr[i+N];
|
||||||
|
}
|
||||||
|
/* T operator[](size_t i) { get(i); }; */
|
||||||
|
|
||||||
|
virtual void set(size_t i, T val) {
|
||||||
|
update_field(i, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_field(size_t i, T val) {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (i >= N)
|
||||||
|
std::cerr << "Tried updating index " << i << " out of " << N-1 << " (remember, 0-indexing)" << std::endl;
|
||||||
|
#endif
|
||||||
|
i += N; // Put the index at the leaf nodes/original array
|
||||||
|
arr[i] = val;
|
||||||
|
for (i /= 2; i >= 1; i /= 2)
|
||||||
|
arr[i] = cmp(arr[i*2], arr[i*2+1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void add(size_t i, T val) {
|
||||||
|
set(i, val + get(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
T query(size_t a, size_t b) {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (a > N || b > N || a > b)
|
||||||
|
std::cerr << "Tried querying the range: [" << a << ", " << b << "]" << " of max index " << N-1 << std::endl;
|
||||||
|
#endif
|
||||||
|
a += N; b += N;
|
||||||
|
size_t val = unit;
|
||||||
|
while (a <= b) {
|
||||||
|
if (a % 2 == 1) val = cmp(val, arr[a++]);
|
||||||
|
if (b % 2 == 0) val = cmp(val, arr[b--]);
|
||||||
|
a /= 2; b /= 2;
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
};
|
12
CPP/utility/prime_sieve.cpp.snip
Normal file
12
CPP/utility/prime_sieve.cpp.snip
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
vector<int> prime_sieve(int n) {
|
||||||
|
vector<bool> is_prime(n+1, true);
|
||||||
|
is_prime[0] = is_prime[1] = false;
|
||||||
|
vector<int> primes;
|
||||||
|
for (int i = 2; i <= n; i++) {
|
||||||
|
if (!is_prime[i]) continue;
|
||||||
|
primes.push_back(i);
|
||||||
|
for (int j = i; j <= n; j += i)
|
||||||
|
is_prime[j] = false;
|
||||||
|
}
|
||||||
|
return primes;
|
||||||
|
}
|
8
HTML.html.snip
Normal file
8
HTML.html.snip
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
18
Markdown.md.snip
Normal file
18
Markdown.md.snip
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<style>
|
||||||
|
.markdown-body { overflow: visible }
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div style="overflow: visible">
|
||||||
|
|
||||||
|
<div style="position: sticky; float: right; top: 90%; z-index: 1000; font-size: 80px"><a href="#table-of-contents">⮉</a></div>
|
||||||
|
|
||||||
|
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||||
|
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||||
|
# Table of Contents
|
||||||
|
|
||||||
|
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Keep this div at the bottom of the document -->
|
||||||
|
</div>
|
4
install_configfiles.sh
Normal file
4
install_configfiles.sh
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
mkdir -p ~/.config/nvim;
|
||||||
|
rm -df ~/.config/nvim/snippets;
|
||||||
|
ln -s ~/Nextcloud/configfiles/vim/snippets ~/.config/nvim/snippets;
|
29
julia_OR.jl.snip
Normal file
29
julia_OR.jl.snip
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using JuMP, GLPK
|
||||||
|
|
||||||
|
profit = [5, 3, 2, 7, 4]
|
||||||
|
weight = [2, 8, 4, 2, 5]
|
||||||
|
capacity = 10
|
||||||
|
|
||||||
|
model = Model(GLPK.Optimizer)
|
||||||
|
|
||||||
|
n = 5
|
||||||
|
@variable(model, x[1:n], Bin) # Binary
|
||||||
|
@variable(model, y[1:n], Int) # Integer
|
||||||
|
@variable(model, z[1:n]) # Continuous
|
||||||
|
|
||||||
|
@objective(model, Max, sum(profit[i]*x[i] for i=1:n))
|
||||||
|
@constraint(model, sum(weight[i]*x[i] for i=1:n) <= capacity)
|
||||||
|
@constraint(model, [i=1:n], x[i] <= 1) # unnecessary, just to include this syntax in the example
|
||||||
|
|
||||||
|
JuMP.optimize!(model)
|
||||||
|
|
||||||
|
if termination_status(model) == MOI.OPTIMAL
|
||||||
|
println("Objective is: ", JuMP.objective_value(model))
|
||||||
|
print("Solution is:")
|
||||||
|
for i=1:n
|
||||||
|
print(" ", JuMP.value(x[i]))
|
||||||
|
end
|
||||||
|
println()
|
||||||
|
else
|
||||||
|
println("Optimise was not successful. Return code ", termination_status(model))
|
||||||
|
end
|
17
latex.tex.snip
Normal file
17
latex.tex.snip
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
\documentclass[11pt]{article}
|
||||||
|
\usepackage{../../../Texpreambles/JRPreamble}
|
||||||
|
\DTMsavedate{mydate}{2022-9-5}% chktex 8
|
||||||
|
|
||||||
|
\usepackage{listings}
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
\selectlanguage{british}
|
||||||
|
|
||||||
|
\begin{center}
|
||||||
|
\Huge My Course: Assignment 1 \\
|
||||||
|
\Large Jonas Ryssel \\
|
||||||
|
\Large s184009 \\
|
||||||
|
\Large \DTMusedate{mydate}
|
||||||
|
\end{center}
|
||||||
|
|
||||||
|
\end{document}
|
9
rust/unit_test.rs.snip
Normal file
9
rust/unit_test.rs.snip
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn my_test() {
|
||||||
|
assert_eq!(add(1, 2), 3);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user