Commit ec515f3f by Xinfu L

Final project

parent 5cc1ba70
#include<iostream>
#include<algorithm>
#include<thread>
#include<chrono>
#include<mutex>
#include<atomic>
#include<fstream>
#include<string>
#include<regex>
#include"graph2D.h"
using namespace std;
using namespace chrono_literals;
using namespace graph2D;
mutex m;
void task(Graph & g, Point s, double c) {
m.lock();
g.ShortestPathBFS(s, c);
m.unlock();
}
int main() {
Graph g;
cout << N << " * " << N << " map with BFS:" << endl;
Point source(0, 0);
Point target(10, 10);
ifstream inp("data.dat");
regex rgx0("\\((\\d{1,}), (\\d{1,})\\):");
regex rgx1(" \\((\\d{1,}), (\\d{1,})\\)");
smatch r;
for(string line; getline(inp, line);) {
if(regex_search(line, r, rgx0)) {
Point p00(stoi(r[1]), stoi(r[2]));
g.addPoint(p00);
sregex_iterator it(line.begin(), line.end(), rgx1);
sregex_iterator rgx_end;
for (; it != rgx_end; ++it) {
Point p01(stoi((*it)[1]), stoi((*it)[2]));
g.addPoint(p01);
g.addEdge(Edge(p00, p01));
}
}
}
/*
Point p1(2, 3);
Point p2(4, 5);
Point p3(1, 4);
Point p4(3, 3);
g.addPoint(p0, p1, p2, p3, p4);
g.addEdge(Edge(p0, p1), Edge(p0, p2), Edge(p1, p4), Edge(p2, p3), Edge(p2, p4));
*/
/*
auto begin = chrono::high_resolution_clock::now();
g.ShortestPathBFS(source, 0);
auto end = chrono::high_resolution_clock::now();
cout << g.dist[target] << endl;
chrono::duration<double, milli> elapsed = end - begin;
cout << elapsed.count() << " ms" << endl;
*/
auto begin = chrono::high_resolution_clock::now();
vector<thread> ts;
int N = g.m[source].size();
for(int i=0; i<N; i++) {
ts.push_back(thread(task, std::ref(g), g.m[source][i], Distance(source, g.m[source][i])));
}
auto end = chrono::high_resolution_clock::now();
chrono::duration<double, milli> elapsed = end - begin;
cout << N << " threads loaded: "<< elapsed.count() << " ms" << endl;
begin = chrono::high_resolution_clock::now();
for(auto & i : ts) {
i.join();
}
end = chrono::high_resolution_clock::now();
elapsed = end - begin;
cout << "Shortest path found: " << elapsed.count() << " ms" << endl;
cout << "The shortest path from " << source << " to " << target << " is " << g.dist[target] << '.' << endl;
return 0;
}
\ No newline at end of file
(0, 0): (1, 1) (2, 2)
(1, 1): (2, 3) (3, 10)
(2, 3): (3, 3) (4, 4) (4, 5) (4, 6)
(4, 4): (5, 6) (7, 7) (7, 7) (10, 10)
\ No newline at end of file
#include<iostream>
#include<unordered_map>
#include<vector>
#include<list>
#include<string>
#include <limits>
namespace graph2D {
class Point {
public:
Point(int a, int b): x(a), y(b) {}
bool operator==(const Point & p) const {
return (x == p.x) && (y == p.y);
}
int x;
int y;
};
std::ostream & operator << (std::ostream & os, const Point & p) {
os << "Point(" << p.x << ", " << p.y << ')';
return os;
}
double Distance(Point p1, Point p2) {
return sqrt((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y));
}
class Edge {
public:
Edge(Point p1, Point p2): start_point(p1), end_point(p2) {}
bool operator==(const Edge & e) const {
return (start_point == e.start_point) && (end_point == e.end_point);
}
Point start_point;
Point end_point;
};
int dim = 2;
int N = 20;
double M = std::numeric_limits<double>::infinity();
}
namespace std {
template<>
class hash<graph2D :: Point> {
public:
size_t operator()(const graph2D :: Point & p) const {
using graph2D :: N;
return hash<int> {} (p.x * N + p.y);
}
};
}
namespace graph2D {
class Graph {
public:
void addPoint(Point p) {
m.insert(std::pair<Point, std::vector<Point>>(p, {}));
dist.insert(std::pair<Point, double>(p, M));
}
template<typename ... Ts>
void addPoint(Point p, Ts ... args) {
m.insert(std::pair<Point, std::vector<Point>>(p, {}));
dist.insert(std::pair<Point, double>(p, M));
addPoint(args...);
}
void addEdge(Edge e) {
if(!ifDup(m[e.start_point].begin(), m[e.start_point].end(), e.end_point)) {
m[e.start_point].push_back(std::move(e.end_point));
}
}
template<typename ... Ts>
void addEdge(Edge e, Ts ... args) {
if(!ifDup(m[e.start_point].begin(), m[e.start_point].end(), e.end_point)) {
m[e.start_point].push_back(std::move(e.end_point));
}
addEdge(args...);
}
/*
template<class P>
bool ifDup(std::vector<P> v, P p) {
for(auto i : v) {
if(i == p) {
return true;
}
}
return false;
}
*/
template<typename Iterator>
bool ifDup(Iterator begin, Iterator end, typename std::iterator_traits<Iterator>::value_type p) {
for(Iterator it = begin; it != end; it++) {
if(*it == p) {
return true;
}
}
return false;
}
void ShortestPathBFS(Point s, double c) {
dist[s] = c;
std::list<Point> q;
q.push_back(s);
while(!q.empty()) {
Point v = q.front();
q.pop_front();
for(auto i : m[v]) {
double d = Distance(v, i);
if(dist[i] > dist[v] + d) {
dist[i] = dist[v] + d;
q.push_back(i);
}
}
}
}
std::unordered_map<Point, std::vector<Point>> m;
std::unordered_map<Point, double> dist;
};
}
\ No newline at end of file
My idea is to write a simplified "Google Map".
We can set up a map with grid points, for example, 100 by 100. Then we connect adjacent(up/down/left/right) points with "road" with weight(1/2/.5). So we can choose a start point A and an end point B to calculate the shortest path using many algorithms(Dijkstra's algorithm, BFS and so on). Here I hope to use multithread technique which interests me a lot since last quarter for some algorithms. I am not sure if I can make a user interface since I have no experience with user interface/graphics using C++. If you can give me some examples, I would like to try. In my mind, this little project will include a lot of knowledge I learned from the three quarters in MPCS. I am not sure if this is too easy for a final project. If so, I can choose to take the final exam.
1. grid map
2. algorithms
2.1 BFS
3. multithread
4. interface
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment