Guest User

Untitled

a guest
Dec 12th, 2018
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.77 KB | None | 0 0
  1. #include <iostream>
  2. #include <cassert>
  3. #include <map>
  4. #include <sstream>
  5. #include <algorithm>
  6. #include <cstring>
  7. #include <set>
  8. #include <fstream>
  9. #include <cmath>
  10. #include <queue>
  11. #include <cstdlib>
  12.  
  13. using namespace std;
  14.  
  15. int gx, gy; // goal x, goal y
  16.  
  17. // 50.0 on kävelynopeus, koska yksi yksikkö on 100m
  18. const double WALK_SPEED = 50.0;
  19. double max_speed = WALK_SPEED; // jossei nopeampia tule
  20.  
  21. const int MAXX = 100;
  22. const int MAXY = 100;
  23.  
  24. struct sit;
  25. struct transit;
  26.  
  27. sit* ptrs[MAXX+1][MAXY+1] = {}; // 100, 100 on sallittu, joten siksi "yhtä isompi"
  28.  
  29. int md(int x1, int y1, int x2, int y2);
  30. double ed(int x1, int y1, int x2, int y2);
  31. double normalize_time(double time);
  32.  
  33. typedef vector<transit> mtype;
  34. mtype TR[MAXX+1][MAXY+1];
  35.  
  36. struct sit {
  37. int x, y;
  38. double time_spent;
  39. sit* prev;
  40. char prevtran;
  41.  
  42. double cmp() const {
  43. return time_spent + ed(x,y,gx,gy)/max_speed;
  44. }
  45. };
  46.  
  47. struct transit {
  48. char type; // matkanteon tyyppi, '0' on kävely
  49. int dx, dy; // destination x, destination y
  50. double time; // kauanko tällä matkustusvälineellä menee aikaa
  51. vector<double> times; // milloin tämä matkustusväline lähtee (tunteja tasatunnin jälkeen)
  52. };
  53.  
  54. int md(int x1, int y1, int x2, int y2) { // Manhattan distance
  55. return abs(x1-x2) + abs(y1-y2);
  56. }
  57.  
  58. double ed(int x1, int y1, int x2, int y2) { // Euclidean distance
  59. double xd = x1-x2, yd = y1-y2;
  60. return sqrt(xd*xd+yd*yd);
  61. }
  62.  
  63. // siirtymävektorit kaikkiin neljään pääilmansuuntaan
  64. int dx[4] = {1,-1,0,0};
  65. int dy[4] = {0,0,1,-1};
  66.  
  67. // onko ehdotettu paikka enää kartalla?
  68. bool in_range(sit* s) {
  69. return s->x >= 0 && s->y >= 0 && s->x <= MAXX && s->y <= MAXY;
  70. }
  71.  
  72. // vertailuluokka, jolla järjestetään tilanteet setissä
  73. struct cmp {
  74. bool operator ()(sit* s1, sit* s2) {
  75. if(s1->cmp() == s2->cmp()) {
  76. if(s1->x == s2->x) return s1->y < s2->y;
  77. return s1->x < s2->x;
  78. }
  79. return s1->cmp() < s2->cmp();
  80. }
  81. };
  82.  
  83.  
  84. // lisäysfunktio; katsotaan onko tähän paikkaan päästy jo nopeammin
  85. // jos ei -> lisätään uusi arvo ja pistetään pointteri muistiin
  86. // muistista voidaan löytää nopeasti onko tähän ruutuun löydetty jo
  87. // joku reitti ja paljonko aikaa oli kulutettu tuolloin
  88.  
  89. bool add(multiset<sit*,cmp>& pq, sit* ns) {
  90. if(ptrs[ns->x][ns->y] == 0) {
  91. ptrs[ns->x][ns->y] = ns;
  92. pq.insert(ns);
  93. return true;
  94. } else {
  95. if(ptrs[ns->x][ns->y]->cmp() > ns->cmp()) {
  96. sit* old = ptrs[ns->x][ns->y];
  97. ptrs[ns->x][ns->y] = ns;
  98. pq.erase(old);
  99. pq.insert(ns);
  100. return true;
  101. }
  102. }
  103. return false;
  104. }
  105.  
  106. // kuinka kauan liikennevälinettä pitää odottaa?
  107. double time_to_wait(double cur, double leaving_time) {
  108. cur = normalize_time(cur);
  109. leaving_time = normalize_time(leaving_time);
  110. // epsilontarkastus, jos lähtöajan ja nykyisen ajan erotus
  111. // on tarpeeksi pieni, on kyseessä sama aika -> ei myöhästytä
  112. // jatkoyhteydestä
  113. if(abs(leaving_time - cur) < 0.00001) return 0;
  114. if(leaving_time < cur) leaving_time++;
  115. double ret = leaving_time - cur;
  116. return ret;
  117. }
  118.  
  119. void astar(multiset<sit*,cmp>& pq) {
  120. // prioriteettijonon ensimmäinen alkio
  121. sit* cur = *pq.begin();
  122. bool ok = false;
  123. while(!pq.empty()) {
  124. cur = *pq.begin(); pq.erase(cur);
  125. // ollaanko jo maalissa
  126. if(cur->x == gx && cur->y == gy) {
  127. ok = true;
  128. break;
  129. }
  130.  
  131. // kävellään kaikkiin pääilmansuuntiin
  132. for(int i = 0; i < 4; ++i) {
  133. sit* ns = new sit;
  134. ns->x = cur->x + dx[i];
  135. ns->y = cur->y + dy[i];
  136. ns->time_spent = cur->time_spent + 1.0/WALK_SPEED;
  137. ns->prev = cur;
  138. ns->prevtran = '0';
  139. if(in_range(ns)) {
  140. if(!add(pq,ns)) delete ns;
  141. } else delete ns;
  142. }
  143.  
  144. // sitten käydään läpi kaikki kulkuvälineet, jotka pysähtyvät tällä
  145. // pysäkillä, ja hypätään niiden kaikkien kyytiin ja työnnetään
  146. // mukaan prioriteettijonoon
  147.  
  148. for(int i = 0; i < (int)TR[cur->x][cur->y].size(); ++i) {
  149. double min_wait = 1e9;
  150. for(int j = 0; j < (int)TR[cur->x][cur->y][i].times.size(); ++j) {
  151. min_wait = min(min_wait,time_to_wait(cur->time_spent,
  152. TR[cur->x][cur->y][i].times[j]));
  153. }
  154. sit* ns = new sit;
  155. ns->x = TR[cur->x][cur->y][i].dx;
  156. ns->y = TR[cur->x][cur->y][i].dy;
  157. ns->prev = cur;
  158. ns->prevtran = TR[cur->x][cur->y][i].type;
  159.  
  160. ns->time_spent = cur->time_spent + TR[cur->x][cur->y][i].time
  161. + min_wait;
  162. if(!add(pq,ns)) delete ns;
  163. }
  164. }
  165.  
  166. // tätä ei pitäisi tapahtua, mutta kertookin lähinnä jostain hölmöstä
  167. // virhetilanteesta jos tällainen ilmoitus tulee
  168. if(!ok) cout<<"Did not find a route :o"<<endl;
  169.  
  170. cout<<"Time spent: "<<cur->time_spent<<" hours"<<endl;
  171.  
  172. // ja sitten lopullinen reitti, "väärässä" järjestyksessä kylläkin
  173. while(cur != NULL) {
  174. cout<<cur->x<<" "<<cur->y<<" "<<cur->time_spent<<" "<<cur->prevtran<<endl;
  175. cur = cur->prev;
  176. }
  177.  
  178. }
  179.  
  180. // emme ole kiinnostuneita tunneista, kun haluamme tietää,
  181. // milloin lähtee seuraava bussi/juna, johon ehdimme
  182. double normalize_time(double time) {
  183. return time - floor(time);
  184. }
  185.  
  186. int main(int argc, char** argv) {
  187. // argumentteina annetaan nykyiset x ja y, ja uudet x ja y,
  188. // joihin pyritään, eli siis muodossa x1 y1 x2 y2
  189. if(argc < 5) {
  190. cout<<"Liian vähän argumentteja"<<endl;
  191. return -1;
  192. }
  193.  
  194. // käydään junat läpi, ja merkataan ylös kaikki pysäkit,
  195. // joilta junaan voi hypätä ja minne sieltä pääsee;
  196. // todella pitkä funktio täynnä mekaanista vääntöä,
  197. // tämä jos mikä me halutaan kyllä antaa opiskelijoille
  198. // valmiina, todella rasittava kirjoittaa
  199.  
  200. for(int i = 'A'; i <= 'D'; ++i) {
  201. string filename = "";
  202. filename += i; filename += ".train";
  203. ifstream fin(filename.c_str());
  204.  
  205. double speed;
  206.  
  207. string str;
  208. getline(fin,str);
  209. istringstream s1(str);
  210. s1>>speed;
  211.  
  212. speed *= 10;
  213. max_speed = max(speed,max_speed);
  214. getline(fin,str);
  215. istringstream ss(str);
  216.  
  217. vector<double> T;
  218.  
  219. int stime;
  220. while(ss>>stime) {
  221. T.push_back(stime);
  222. T.back() /= 60.0;
  223. }
  224.  
  225. vector<pair<int,int> > S;
  226.  
  227. int x, y;
  228. while(fin>>x>>y) {
  229. S.resize(S.size() + 1);
  230. S.back().first = x;
  231. S.back().second = y;
  232. }
  233.  
  234. fin.close();
  235.  
  236. double curtime = 0;
  237.  
  238. for(int j = 0; j < (int)S.size() - 1; ++j) {
  239. transit tr;
  240. tr.type = i;
  241. tr.dx = S[j+1].first; tr.dy = S[j+1].second;
  242. tr.time = ed(S[j].first,S[j].second,tr.dx,tr.dy) / speed;
  243. for(int k = 0; k < (int)T.size(); ++k) {
  244. tr.times.push_back(normalize_time(T[k] + curtime));
  245. }
  246. TR[S[j].first][S[j].second].push_back(tr);
  247. curtime += tr.time;
  248. }
  249.  
  250. for(int j = S.size() - 1; j >= 1; --j) {
  251. transit tr;
  252. tr.type = i;
  253. tr.dx = S[j-1].first; tr.dy = S[j-1].second;
  254. tr.time = ed(S[j].first,S[j].second,tr.dx,tr.dy) / speed;
  255. for(int k = 0; k < (int)T.size(); ++k) {
  256. tr.times.push_back(normalize_time(T[k] + curtime));
  257. }
  258. TR[S[j].first][S[j].second].push_back(tr);
  259. curtime += tr.time;
  260. }
  261. }
  262.  
  263. // ja sama busseille, aika paljon rasittavampi kirjoittaa,
  264. // vaikka onkin suurimmaksi osaksi copy pastea
  265.  
  266. for(char i = '1'; i <= '6'; ++i) {
  267. string busfile = "";
  268. busfile += i; busfile += ".bus";
  269. ifstream fin(busfile.c_str());
  270.  
  271. double speed;
  272.  
  273. string str;
  274. getline(fin,str);
  275. istringstream s1(str);
  276. s1>>speed;
  277. speed *= 10;
  278.  
  279. max_speed = max(speed,max_speed);
  280. getline(fin,str);
  281. istringstream ss(str);
  282.  
  283. vector<double> T;
  284.  
  285. int stime;
  286. while(ss>>stime) {
  287. T.push_back(stime);
  288. T.back() /= 60.0;
  289. }
  290.  
  291. vector<pair<int,int> > S;
  292.  
  293. int x, y;
  294. while(fin>>x>>y) {
  295. S.resize(S.size() + 1);
  296. S.back().first = x;
  297. S.back().second = y;
  298. }
  299.  
  300. fin.close();
  301.  
  302. busfile = ""; busfile += i; busfile += ".broute";
  303. fin.open(busfile.c_str());
  304.  
  305. vector<pair<int,int> > R;
  306. while(fin>>x>>y) {
  307. R.resize(R.size() + 1);
  308. R.back().first = x;
  309. R.back().second = y;
  310. }
  311. fin.close();
  312.  
  313.  
  314. vector<int> index_table(S.size());
  315.  
  316. int cur_route = 0;
  317. for(int j = 0; j < (int)S.size(); ++j) {
  318. while(R[cur_route] != S[j]) {
  319. ++cur_route;
  320. }
  321. index_table[j] = cur_route;
  322. }
  323.  
  324. double curtime = 0;
  325.  
  326. for(int j = 0; j < (int)S.size() - 1; ++j) {
  327. transit tr;
  328. tr.type = i;
  329. tr.dx = S[j+1].first; tr.dy = S[j+1].second;
  330. tr.time = (index_table[j+1] - index_table[j]) / speed;
  331. for(int k = 0; k < (int)T.size(); ++k) {
  332. tr.times.push_back(normalize_time(T[k] + curtime));
  333. }
  334. TR[S[j].first][S[j].second].push_back(tr);
  335. curtime += tr.time;
  336. }
  337.  
  338. for(int j = (int)S.size() - 1; j >= 1; --j) {
  339. transit tr;
  340. tr.type = i;
  341. tr.dx = S[j-1].first; tr.dy = S[j-1].second;
  342. tr.time = (index_table[j] - index_table[j-1]) / speed;
  343. for(int k = 0; k < (int)T.size(); ++k) {
  344. tr.times.push_back(normalize_time(T[k] + curtime));
  345. }
  346. TR[S[j].first][S[j].second].push_back(tr);
  347. curtime += tr.time;
  348. }
  349. }
  350.  
  351. // luetaan input, current x ja y, goal x ja y
  352.  
  353. int cx, cy;
  354. cx = atoi(argv[1]);
  355. cy = atoi(argv[2]);
  356. gx = atoi(argv[3]);
  357. gy = atoi(argv[4]);
  358.  
  359. // nollataan pointteritaulukko
  360. memset(ptrs,0,(MAXX+1)*(MAXY+1));
  361.  
  362. // pistetään ensimmäinen alkio prioriteettijonoon
  363. sit* s1 = new sit;
  364. s1->x = cx; s1->y = cy; s1->time_spent = 0;
  365. s1->prev = NULL;
  366.  
  367. multiset<sit*,cmp> pq;
  368. add(pq,s1);
  369.  
  370. // ja sitten ajetaan itse A* prioriteettijonolle
  371. astar(pq);
  372.  
  373. return 0;
  374. }
Add Comment
Please, Sign In to add comment