├── .gitattributes
├── .idea
├── SpiderMenCome_V1.0.iml
├── libraries
│ └── R_User_Library.xml
├── misc.xml
├── modules.xml
├── other.xml
├── vcs.xml
└── workspace.xml
├── CodeCraft-2019
├── 2-map-exam-1
│ ├── .ipynb_checkpoints
│ │ └── PreProcessingCodeCraft-checkpoint.ipynb
│ ├── PreProcessingCodeCraft.ipynb
│ ├── answer.txt
│ ├── car.txt
│ ├── cross.txt
│ ├── presetAnswer.txt
│ ├── result.txt
│ └── road.txt
├── 2-map-exam-2
│ ├── answer.txt
│ ├── car.txt
│ ├── cross.txt
│ ├── presetAnswer.txt
│ ├── result.txt
│ └── road.txt
├── resource
│ └── CodeCraft2019RemFlowControl.png
└── src
│ ├── CodeCraft-2019.py
│ ├── CodeCraft-2019_judge.py
│ ├── VersionControl.md
│ ├── __pycache__
│ ├── base.cpython-37.pyc
│ ├── car.cpython-37.pyc
│ ├── core.cpython-37.pyc
│ ├── core_judge.cpython-37.pyc
│ ├── cross.cpython-37.pyc
│ ├── data.cpython-37.pyc
│ ├── road.cpython-37.pyc
│ ├── settings.cpython-37.pyc
│ └── utils.cpython-37.pyc
│ ├── base.py
│ ├── car.py
│ ├── core.py
│ ├── core_judge.py
│ ├── cross.py
│ ├── data.py
│ ├── road.py
│ ├── settings.py
│ ├── test.py
│ └── utils.py
├── CodeCraft_tar.sh
├── README.md
└── logs
└── CodeCraft-2019.log
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.py linguist-language=python
2 | *.ipynb linguist-language=python
3 |
--------------------------------------------------------------------------------
/.idea/SpiderMenCome_V1.0.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/libraries/R_User_Library.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/other.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
186 |
187 |
188 |
189 | -=
190 | life_span
191 | second
192 | delay
193 | 51321
194 | 37130
195 | Data
196 | road_use_arr
197 | CARS
198 | 'Priority':
199 | real_time
200 | 39681
201 | 66916
202 | 91237
203 | 46395
204 | 49659
205 | 74337
206 | (0, 18, 5340)
207 | 84726
208 | 55967
209 | 6703
210 | 21499
211 | 39962
212 | 21449
213 | 6253
214 | 5911
215 | [^\r\n]+\.+:
216 | self
217 | raise
218 | empty
219 |
220 |
221 | (G.$1)
222 | G.$1
223 | following_car
224 | ()
225 | .v6_move
226 |
227 | {}\t"
228 | 队列
229 | start_cars_in_garage
230 | C.
231 | Data.
232 | car.
233 | self
234 | c.
235 | self.
236 | CROSSES
237 | c
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 | true
307 | DEFINITION_ORDER
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 | 1554163589826
498 |
499 |
500 | 1554163589826
501 |
502 |
503 | 1555241344677
504 |
505 |
506 |
507 | 1555241344677
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 | file://$PROJECT_DIR$/CodeCraft-2019/old/CodeCraft-2019_old.py
569 | 856
570 |
571 |
572 | file://$PROJECT_DIR$/CodeCraft-2019/old/CodeCraft-2019_old.py
573 | 855
574 |
575 |
576 |
577 | file://$PROJECT_DIR$/CodeCraft-2019/src/JudgeMent.py
578 | 95
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 |
722 |
723 |
724 |
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 |
733 |
734 |
735 |
736 |
737 |
738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 |
746 |
747 |
748 |
749 |
750 |
751 |
752 |
753 |
754 |
755 |
756 |
757 |
758 |
759 |
760 |
761 |
762 |
763 |
764 |
765 |
766 |
767 |
768 |
769 |
770 |
771 |
772 |
773 |
774 |
775 |
776 |
777 |
778 |
779 |
780 |
781 |
782 |
783 |
784 |
785 |
786 |
787 |
788 |
789 |
790 |
791 |
792 |
793 |
794 |
795 |
796 |
797 |
798 |
799 |
800 |
801 |
802 |
803 |
804 |
805 |
806 |
807 |
808 |
809 |
810 |
811 |
--------------------------------------------------------------------------------
/CodeCraft-2019/2-map-exam-1/cross.txt:
--------------------------------------------------------------------------------
1 | #(id,roadId,roadId,roadId,roadId)
2 | (10, 6355, 5196, 5718, -1)
3 | (25, 6549, 6939, 6247, -1)
4 | (31, 6937, 6421, 6540, -1)
5 | (48, -1, 6317, 5634, 5029)
6 | (69, 5817, 5283, 5461, 6066)
7 | (74, -1, 5267, 5649, 6937)
8 | (90, 6308, 5196, 5725, 5509)
9 | (96, 6179, 6893, 5321, 5093)
10 | (97, 6177, 6795, 6366, 6469)
11 | (100, 5349, 5321, 6120, 6394)
12 | (109, -1, -1, 5695, 6811)
13 | (111, 6664, 5292, 5777, 6008)
14 | (112, 6345, 5093, 5023, 5526)
15 | (132, 5748, 6969, 5894, 5189)
16 | (152, 5275, 6789, 5687, 6236)
17 | (153, 6452, 6702, -1, 5335)
18 | (168, 5385, 6732, 6334, 5879)
19 | (179, 6492, 5280, 5526, 5981)
20 | (189, 6421, 5556, -1, 6852)
21 | (203, -1, 6035, 6543, 5231)
22 | (218, 6549, -1, 6332, 5923)
23 | (233, 6117, -1, 6008, 6513)
24 | (240, 6670, 6425, 6120, 6918)
25 | (247, 5375, 6331, -1, -1)
26 | (259, 5942, 5178, -1, -1)
27 | (269, 5204, 6492, 5779, 5418)
28 | (280, -1, 6918, 6893, 5544)
29 | (289, 5372, 6365, 6807, 6425)
30 | (297, 6703, 6301, 6644, 5420)
31 | (303, 6427, -1, 5029, 6805)
32 | (321, 6704, -1, 5978, 6252)
33 | (332, 5656, 5748, 5556, 5649)
34 | (335, 6469, 5015, 6956, -1)
35 | (345, 5687, 6334, 6956, 6271)
36 | (352, 5015, 5403, -1, 5137)
37 | (371, 6048, 5375, 5178, 6359)
38 | (375, -1, 6405, 5096, -1)
39 | (376, 5096, 6777, 6301, -1)
40 | (380, 6405, -1, 6042, 6112)
41 | (386, 6854, 6299, 5274, 6016)
42 | (391, 5549, 6999, 6811, 5275)
43 | (397, 5647, 6290, -1, -1)
44 | (405, -1, 5424, 6951, 6345)
45 | (419, 5461, 5700, 6048, -1)
46 | (421, 5023, 5349, -1, 5471)
47 | (428, 5877, 5443, 6223, 6623)
48 | (439, 6078, 5777, 6838, 6859)
49 | (450, 6909, 5597, 5803, 5486)
50 | (470, 6017, 6892, 5981, 5471)
51 | (471, -1, 6059, 6223, 6488)
52 | (473, 6734, 6979, -1, -1)
53 | (487, 5283, 5893, -1, 5844)
54 | (493, 6581, 5717, -1, 6897)
55 | (504, 5923, 6737, 5998, 6403)
56 | (505, 5779, 6892, 6467, 6673)
57 | (520, 6901, 5906, 6395, 5372)
58 | (554, 5695, -1, 5879, 6789)
59 | (600, -1, -1, 6835, 6487)
60 | (604, 6695, 6901, 6670, -1)
61 | (651, 5271, 5443, 6755, 5231)
62 | (674, 6299, -1, -1, 6703)
63 | (679, 6247, 5788, 6288, -1)
64 | (690, 6304, 5650, -1, 5248)
65 | (710, 6359, 6530, 5262, 5640)
66 | (731, 5700, 5844, -1, 6331)
67 | (744, 6137, 5680, 6836, 6355)
68 | (746, 6838, 6240, 5486, 5922)
69 | (766, 6954, 6984, 6464, -1)
70 | (776, 6542, 5805, 5386, -1)
71 | (800, 5552, 5257, 5634, 5118)
72 | (807, 5246, 6016, 6103, 5346)
73 | (837, 6366, 5473, -1, 5403)
74 | (841, 6465, 6513, 6078, 5998)
75 | (851, -1, -1, 5407, 5978)
76 | (857, 5788, 5781, 5922, 6517)
77 | (898, 6288, 5955, 5407, -1)
78 | (904, 5893, 5329, -1, -1)
79 | (915, 5054, 6137, 6488, 5271)
80 | (924, 6403, 6859, 5781, 6939)
81 | (935, 6014, -1, 6427, 6253)
82 | (964, 6732, 5495, 6088, -1)
83 | (979, 6581, 5335, 5329, 5817)
84 | (989, 5418, -1, 6240, 5292)
85 | (1011, 6467, 5699, -1, 5640)
86 | (1033, 6330, 5973, 6179, 6951)
87 | (1083, -1, -1, 6014, 6035)
88 | (1084, 5870, 6540, 6578, 5107)
89 | (1108, 6418, 5771, 6177, 6088)
90 | (1130, 6453, 6103, 5051, 5647)
91 | (1133, 5013, 5248, 6961, 6308)
92 | (1153, -1, 6659, 5399, 6317)
93 | (1218, 5552, 6326, 5725, 6836)
94 | (1222, -1, -1, 5807, 6954)
95 | (1240, 5314, 6465, 6730, 6236)
96 | (1242, 6623, 6458, 5656, 6678)
97 | (1245, 6673, 5262, 6909, -1)
98 | (1261, 6298, 6523, 6187, 5390)
99 | (1281, 5894, 6537, -1, 6187)
100 | (1302, 6517, 5803, 6252, 5955)
101 | (1320, 5717, 6066, 5699, 6017)
102 | (1337, -1, 6188, 5105, -1)
103 | (1340, 5509, 6930, -1, -1)
104 | (1393, 6067, 5659, 5592, 5495)
105 | (1408, 6042, -1, 6487, 5809)
106 | (1410, -1, 6999, 6197, -1)
107 | (1424, 6330, 6295, 5390, 5650)
108 | (1425, 6458, 6059, 5088, 6969)
109 | (1451, 5973, 6304, 6993, 5544)
110 | (1459, 5189, 6523, 5079, -1)
111 | (1490, 6708, 5204, 6664, -1)
112 | (1528, 6414, 6395, 6784, 5809)
113 | (1575, 5399, 5346, 6580, 5118)
114 | (1600, 6805, 5257, 5680, 6443)
115 | (1608, 6543, 6253, 6443, 5054)
116 | (1651, -1, 5386, 5659, 6734)
117 | (1672, 6784, 6698, 6777, 6112)
118 | (1673, 6124, 6785, 6678, 5267)
119 | (1675, 5931, 5051, 5274, 5420)
120 | (1696, -1, 5280, 6708, 5105)
121 | (1743, 6556, 6295, 5424, 6188)
122 | (1755, 6807, 6452, 6897, 6394)
123 | (1758, 6578, 6852, 6348, 5771)
124 | (1760, 6737, 5149, 5549, 6730)
125 | (1765, 6659, -1, 5703, 5246)
126 | (1804, 6785, 6984, 6568, 5877)
127 | (1805, 6429, 6298, 6556, 5473)
128 | (1815, 6854, 5703, -1, -1)
129 | (1836, 6695, 6290, 5931, 5716)
130 | (1837, -1, -1, 6993, 5013)
131 | (1844, 6332, -1, 6197, 5149)
132 | (1846, 6979, 6067, 5385, -1)
133 | (1875, 5807, -1, 6755, 6568)
134 | (1905, 6365, 6414, 6835, 6702)
135 | (1906, -1, -1, 6464, 6124)
136 | (1911, 6429, 6795, 6348, 5079)
137 | (1913, 5088, 5718, 6961, 6537)
138 | (1935, 6704, 5597, 6530, 5942)
139 | (1960, 5716, 6644, 6698, 5906)
140 | (1969, -1, 5870, 6542, -1)
141 | (1970, 5314, 6271, 5137, 6117)
142 | (1985, 6930, 6326, 6580, 6453)
143 | (1992, 5805, 5107, 6418, 5592)
--------------------------------------------------------------------------------
/CodeCraft-2019/2-map-exam-1/result.txt:
--------------------------------------------------------------------------------
1 |
2 | ====================
3 | {'MAX_COVERAGE': 0.16, 'MAX_TO_START': 200, 'K_PRIOR': 1.5, 'K_NON_PRIOR': 1.5, 'REFRESH_FREQUENCY': 4, 'M1': 10, 'M2': 10, 'MapName': '2-map-exam-1', 'TimeUsed': 122.978994846344}
4 | {'T_Prior': 243, 'T_Total': 244, 'T_Final': 557, 'S_Prior': 473036, 'S_Total': 1770987, 'S_Final': 4424253, 'Factor_A': 1.2880635, 'Factor_B': 5.609016}
5 | ===== FAILED !!! ======
6 |
7 | ====================
8 | {'MAX_COVERAGE': 0.14, 'MAX_TO_START': 200, 'K_PRIOR': 1.5, 'K_NON_PRIOR': 1.5, 'REFRESH_FREQUENCY': 4, 'M1': 10, 'M2': 10, 'MapName': '2-map-exam-1', 'TimeUsed': 35.60199189186096}
9 | {'T_Prior': 198, 'T_Total': 70, 'T_Final': 325, 'S_Prior': 3361, 'S_Total': 33802, 'S_Final': 52654, 'Factor_A': 1.2880635, 'Factor_B': 5.609016}
10 | ===== FAILED !!! ======
11 |
12 | ====================
13 | {'MAX_COVERAGE': 0.12, 'MAX_TO_START': 200, 'K_PRIOR': 1.5, 'K_NON_PRIOR': 1.5, 'REFRESH_FREQUENCY': 4, 'M1': 10, 'M2': 10, 'MapName': '2-map-exam-1', 'TimeUsed': 352.35450744628906}
14 | {'T_Prior': 498, 'T_Total': 1115, 'T_Final': 1756, 'S_Prior': 1598596, 'S_Total': 29058310, 'S_Final': 38024861, 'Factor_A': 1.2880635, 'Factor_B': 5.609016}
15 | ===== Succeeded!!! ======
16 |
--------------------------------------------------------------------------------
/CodeCraft-2019/2-map-exam-1/road.txt:
--------------------------------------------------------------------------------
1 | #(id,length,speed,channel,from,to,isDuplex)
2 | (5013, 50, 10, 1, 1133, 1837, 1)
3 | (5015, 50, 15, 5, 335, 352, 1)
4 | (5023, 40, 15, 2, 112, 421, 1)
5 | (5029, 50, 10, 2, 303, 48, 1)
6 | (5051, 24, 10, 3, 1130, 1675, 0)
7 | (5054, 20, 8, 1, 915, 1608, 1)
8 | (5079, 30, 15, 2, 1911, 1459, 1)
9 | (5088, 36, 15, 6, 1425, 1913, 1)
10 | (5093, 40, 15, 1, 112, 96, 1)
11 | (5096, 20, 10, 3, 376, 375, 1)
12 | (5105, 24, 12, 2, 1337, 1696, 1)
13 | (5107, 24, 12, 1, 1992, 1084, 1)
14 | (5118, 40, 10, 6, 800, 1575, 1)
15 | (5137, 24, 15, 5, 1970, 352, 1)
16 | (5149, 20, 15, 1, 1844, 1760, 1)
17 | (5178, 40, 10, 5, 259, 371, 1)
18 | (5189, 24, 10, 4, 1459, 132, 1)
19 | (5196, 30, 10, 3, 10, 90, 1)
20 | (5204, 50, 15, 1, 1490, 269, 1)
21 | (5231, 30, 8, 5, 651, 203, 1)
22 | (5246, 40, 15, 2, 807, 1765, 1)
23 | (5248, 20, 8, 3, 690, 1133, 1)
24 | (5257, 24, 15, 6, 1600, 800, 1)
25 | (5262, 40, 10, 6, 1245, 710, 1)
26 | (5267, 50, 8, 6, 74, 1673, 1)
27 | (5271, 40, 12, 1, 651, 915, 1)
28 | (5274, 40, 12, 4, 1675, 386, 1)
29 | (5275, 20, 10, 5, 391, 152, 1)
30 | (5280, 40, 10, 5, 1696, 179, 1)
31 | (5283, 30, 15, 3, 69, 487, 1)
32 | (5292, 40, 15, 2, 111, 989, 1)
33 | (5314, 40, 12, 3, 1240, 1970, 1)
34 | (5321, 24, 10, 1, 96, 100, 1)
35 | (5329, 20, 12, 5, 979, 904, 1)
36 | (5335, 20, 10, 2, 979, 153, 1)
37 | (5346, 50, 12, 6, 1575, 807, 0)
38 | (5349, 24, 12, 3, 421, 100, 1)
39 | (5372, 40, 8, 2, 289, 520, 0)
40 | (5375, 20, 8, 1, 371, 247, 1)
41 | (5385, 30, 15, 6, 1846, 168, 1)
42 | (5386, 20, 12, 4, 1651, 776, 1)
43 | (5390, 20, 12, 4, 1261, 1424, 1)
44 | (5399, 20, 12, 2, 1575, 1153, 1)
45 | (5403, 20, 10, 5, 352, 837, 1)
46 | (5407, 20, 8, 3, 898, 851, 1)
47 | (5418, 20, 10, 3, 989, 269, 1)
48 | (5420, 50, 10, 5, 1675, 297, 1)
49 | (5424, 36, 12, 3, 1743, 405, 1)
50 | (5443, 40, 8, 6, 428, 651, 1)
51 | (5461, 40, 12, 1, 419, 69, 1)
52 | (5471, 40, 10, 4, 470, 421, 1)
53 | (5473, 50, 10, 3, 837, 1805, 1)
54 | (5486, 20, 10, 2, 746, 450, 1)
55 | (5495, 30, 8, 2, 1393, 964, 1)
56 | (5509, 40, 10, 4, 90, 1340, 1)
57 | (5526, 40, 10, 2, 179, 112, 1)
58 | (5544, 20, 10, 4, 1451, 280, 1)
59 | (5549, 24, 8, 2, 391, 1760, 1)
60 | (5552, 36, 8, 3, 1218, 800, 1)
61 | (5556, 24, 12, 5, 189, 332, 1)
62 | (5592, 40, 8, 4, 1393, 1992, 0)
63 | (5597, 20, 10, 2, 450, 1935, 1)
64 | (5634, 30, 12, 6, 800, 48, 1)
65 | (5640, 40, 8, 5, 710, 1011, 1)
66 | (5647, 50, 12, 2, 397, 1130, 1)
67 | (5649, 30, 10, 5, 74, 332, 1)
68 | (5650, 24, 8, 3, 1424, 690, 1)
69 | (5656, 40, 15, 5, 332, 1242, 1)
70 | (5659, 24, 15, 2, 1651, 1393, 1)
71 | (5680, 30, 12, 4, 744, 1600, 1)
72 | (5687, 50, 8, 2, 152, 345, 1)
73 | (5695, 30, 10, 3, 109, 554, 1)
74 | (5699, 30, 8, 3, 1011, 1320, 1)
75 | (5700, 30, 12, 1, 419, 731, 1)
76 | (5703, 20, 10, 1, 1765, 1815, 1)
77 | (5716, 36, 10, 1, 1836, 1960, 1)
78 | (5717, 40, 8, 6, 1320, 493, 1)
79 | (5718, 30, 8, 1, 1913, 10, 1)
80 | (5725, 50, 15, 5, 90, 1218, 1)
81 | (5748, 36, 8, 1, 332, 132, 1)
82 | (5771, 36, 15, 5, 1108, 1758, 0)
83 | (5777, 24, 15, 6, 439, 111, 0)
84 | (5779, 30, 10, 2, 269, 505, 1)
85 | (5781, 20, 15, 1, 924, 857, 1)
86 | (5788, 36, 15, 1, 679, 857, 1)
87 | (5803, 20, 12, 6, 1302, 450, 1)
88 | (5805, 24, 8, 4, 776, 1992, 1)
89 | (5807, 50, 15, 1, 1222, 1875, 1)
90 | (5809, 30, 12, 5, 1528, 1408, 1)
91 | (5817, 50, 12, 2, 69, 979, 0)
92 | (5844, 20, 12, 6, 731, 487, 1)
93 | (5870, 30, 8, 5, 1969, 1084, 1)
94 | (5877, 36, 15, 2, 1804, 428, 1)
95 | (5879, 30, 8, 3, 554, 168, 1)
96 | (5893, 50, 15, 6, 487, 904, 1)
97 | (5894, 36, 15, 1, 132, 1281, 1)
98 | (5906, 36, 12, 4, 520, 1960, 1)
99 | (5922, 40, 15, 2, 857, 746, 1)
100 | (5923, 50, 15, 4, 218, 504, 1)
101 | (5931, 30, 12, 2, 1836, 1675, 1)
102 | (5942, 40, 8, 2, 1935, 259, 1)
103 | (5955, 30, 15, 5, 898, 1302, 1)
104 | (5973, 24, 12, 3, 1033, 1451, 1)
105 | (5978, 20, 10, 4, 851, 321, 1)
106 | (5981, 36, 15, 2, 179, 470, 1)
107 | (5998, 40, 8, 5, 504, 841, 1)
108 | (6008, 20, 8, 5, 233, 111, 1)
109 | (6014, 30, 10, 6, 1083, 935, 1)
110 | (6016, 50, 8, 5, 807, 386, 1)
111 | (6017, 36, 12, 5, 470, 1320, 1)
112 | (6035, 50, 10, 5, 203, 1083, 1)
113 | (6042, 40, 10, 6, 1408, 380, 1)
114 | (6048, 36, 12, 2, 371, 419, 1)
115 | (6059, 50, 12, 3, 1425, 471, 1)
116 | (6066, 24, 12, 6, 1320, 69, 1)
117 | (6067, 40, 8, 1, 1846, 1393, 1)
118 | (6078, 50, 15, 3, 841, 439, 1)
119 | (6088, 50, 12, 1, 964, 1108, 1)
120 | (6103, 30, 8, 4, 1130, 807, 1)
121 | (6112, 24, 8, 3, 1672, 380, 1)
122 | (6117, 30, 10, 4, 1970, 233, 1)
123 | (6120, 20, 15, 3, 100, 240, 1)
124 | (6124, 36, 12, 5, 1906, 1673, 1)
125 | (6137, 40, 15, 3, 915, 744, 1)
126 | (6177, 50, 10, 4, 1108, 97, 1)
127 | (6179, 30, 10, 4, 1033, 96, 1)
128 | (6187, 24, 10, 2, 1261, 1281, 1)
129 | (6188, 20, 8, 6, 1337, 1743, 1)
130 | (6197, 20, 8, 2, 1410, 1844, 1)
131 | (6223, 20, 12, 3, 428, 471, 1)
132 | (6236, 50, 10, 3, 152, 1240, 0)
133 | (6240, 36, 12, 1, 746, 989, 1)
134 | (6247, 50, 15, 2, 25, 679, 1)
135 | (6252, 50, 10, 2, 1302, 321, 1)
136 | (6253, 40, 15, 3, 1608, 935, 1)
137 | (6271, 36, 12, 2, 345, 1970, 1)
138 | (6288, 24, 8, 4, 679, 898, 1)
139 | (6290, 40, 10, 2, 397, 1836, 1)
140 | (6295, 30, 12, 3, 1743, 1424, 1)
141 | (6298, 30, 8, 2, 1805, 1261, 1)
142 | (6299, 24, 8, 4, 386, 674, 1)
143 | (6301, 30, 8, 4, 297, 376, 1)
144 | (6304, 40, 8, 6, 690, 1451, 1)
145 | (6308, 30, 12, 1, 1133, 90, 0)
146 | (6317, 24, 8, 3, 48, 1153, 1)
147 | (6326, 50, 10, 3, 1218, 1985, 1)
148 | (6330, 40, 8, 6, 1424, 1033, 0)
149 | (6331, 40, 8, 6, 247, 731, 1)
150 | (6332, 40, 10, 2, 1844, 218, 1)
151 | (6334, 50, 8, 6, 168, 345, 1)
152 | (6345, 24, 10, 3, 405, 112, 1)
153 | (6348, 30, 12, 2, 1758, 1911, 1)
154 | (6355, 40, 10, 5, 10, 744, 1)
155 | (6359, 36, 12, 5, 710, 371, 1)
156 | (6365, 20, 8, 4, 289, 1905, 1)
157 | (6366, 50, 12, 4, 97, 837, 1)
158 | (6394, 20, 10, 6, 100, 1755, 1)
159 | (6395, 20, 8, 3, 520, 1528, 1)
160 | (6403, 36, 10, 1, 504, 924, 1)
161 | (6405, 24, 8, 3, 380, 375, 1)
162 | (6414, 40, 15, 1, 1905, 1528, 1)
163 | (6418, 50, 15, 1, 1992, 1108, 1)
164 | (6421, 40, 10, 3, 31, 189, 1)
165 | (6425, 30, 15, 4, 240, 289, 1)
166 | (6427, 24, 12, 6, 935, 303, 1)
167 | (6429, 40, 15, 6, 1911, 1805, 1)
168 | (6443, 30, 15, 5, 1608, 1600, 0)
169 | (6452, 40, 8, 6, 1755, 153, 0)
170 | (6453, 36, 8, 3, 1985, 1130, 1)
171 | (6458, 24, 10, 2, 1242, 1425, 1)
172 | (6464, 24, 12, 4, 1906, 766, 1)
173 | (6465, 40, 8, 5, 1240, 841, 1)
174 | (6467, 40, 8, 3, 505, 1011, 1)
175 | (6469, 24, 15, 1, 335, 97, 1)
176 | (6487, 36, 8, 3, 600, 1408, 1)
177 | (6488, 20, 12, 1, 471, 915, 1)
178 | (6492, 30, 12, 2, 269, 179, 1)
179 | (6513, 24, 15, 2, 841, 233, 1)
180 | (6517, 30, 10, 1, 857, 1302, 1)
181 | (6523, 50, 12, 2, 1459, 1261, 1)
182 | (6530, 50, 12, 1, 1935, 710, 1)
183 | (6537, 30, 12, 3, 1281, 1913, 1)
184 | (6540, 20, 15, 3, 1084, 31, 1)
185 | (6542, 36, 10, 2, 776, 1969, 1)
186 | (6543, 40, 12, 5, 203, 1608, 1)
187 | (6549, 20, 12, 6, 218, 25, 1)
188 | (6556, 40, 12, 1, 1805, 1743, 1)
189 | (6568, 50, 12, 5, 1804, 1875, 1)
190 | (6578, 50, 8, 3, 1084, 1758, 1)
191 | (6580, 24, 12, 5, 1985, 1575, 1)
192 | (6581, 50, 10, 5, 493, 979, 1)
193 | (6623, 36, 15, 4, 1242, 428, 0)
194 | (6644, 36, 15, 2, 1960, 297, 1)
195 | (6659, 30, 12, 6, 1153, 1765, 1)
196 | (6664, 50, 12, 5, 111, 1490, 1)
197 | (6670, 24, 12, 4, 240, 604, 1)
198 | (6673, 36, 10, 6, 1245, 505, 0)
199 | (6678, 20, 15, 5, 1673, 1242, 1)
200 | (6695, 36, 12, 6, 604, 1836, 1)
201 | (6698, 20, 8, 3, 1960, 1672, 0)
202 | (6702, 24, 10, 1, 153, 1905, 1)
203 | (6703, 40, 8, 1, 297, 674, 1)
204 | (6704, 50, 10, 1, 321, 1935, 1)
205 | (6708, 40, 8, 6, 1490, 1696, 1)
206 | (6730, 36, 15, 5, 1760, 1240, 1)
207 | (6732, 20, 12, 1, 168, 964, 1)
208 | (6734, 50, 15, 3, 473, 1651, 1)
209 | (6737, 40, 15, 1, 1760, 504, 1)
210 | (6755, 50, 12, 2, 1875, 651, 1)
211 | (6777, 40, 8, 1, 1672, 376, 1)
212 | (6784, 50, 8, 1, 1528, 1672, 1)
213 | (6785, 20, 8, 3, 1673, 1804, 1)
214 | (6789, 20, 12, 3, 554, 152, 1)
215 | (6795, 50, 10, 2, 97, 1911, 1)
216 | (6805, 20, 15, 5, 1600, 303, 1)
217 | (6807, 36, 15, 3, 1755, 289, 1)
218 | (6811, 30, 8, 6, 109, 391, 1)
219 | (6835, 30, 8, 6, 1905, 600, 1)
220 | (6836, 40, 10, 5, 744, 1218, 1)
221 | (6838, 36, 10, 6, 439, 746, 1)
222 | (6852, 36, 12, 3, 1758, 189, 1)
223 | (6854, 30, 12, 4, 386, 1815, 1)
224 | (6859, 30, 8, 6, 924, 439, 1)
225 | (6892, 20, 8, 1, 505, 470, 1)
226 | (6893, 30, 8, 4, 96, 280, 1)
227 | (6897, 24, 12, 2, 493, 1755, 1)
228 | (6901, 20, 15, 2, 604, 520, 1)
229 | (6909, 30, 8, 4, 450, 1245, 1)
230 | (6918, 30, 8, 1, 280, 240, 1)
231 | (6930, 30, 10, 6, 1340, 1985, 1)
232 | (6937, 20, 15, 6, 31, 74, 1)
233 | (6939, 24, 12, 4, 25, 924, 1)
234 | (6951, 20, 12, 3, 405, 1033, 1)
235 | (6954, 40, 8, 4, 766, 1222, 1)
236 | (6956, 36, 12, 2, 345, 335, 1)
237 | (6961, 30, 15, 3, 1913, 1133, 1)
238 | (6969, 20, 15, 6, 132, 1425, 0)
239 | (6979, 40, 10, 6, 473, 1846, 1)
240 | (6984, 30, 10, 1, 766, 1804, 1)
241 | (6993, 40, 8, 3, 1451, 1837, 1)
242 | (6999, 50, 15, 3, 1410, 391, 1)
--------------------------------------------------------------------------------
/CodeCraft-2019/2-map-exam-2/cross.txt:
--------------------------------------------------------------------------------
1 | #(id,roadId,roadId,roadId,roadId)
2 | (5, 5457, -1, -1, 6528)
3 | (32, 6895, 6916, 6332, 5597)
4 | (33, 6134, 5706, 5998, 6551)
5 | (41, 5028, 5816, 5356, -1)
6 | (47, 6528, -1, 6991, 6625)
7 | (52, 6271, 5011, 5125, 6428)
8 | (62, 6809, 5749, 6695, 6442)
9 | (84, 5086, 6069, 5002, 5211)
10 | (93, 5028, -1, -1, 6849)
11 | (108, 6499, 5683, 5634, 6785)
12 | (110, 6894, 5553, 6005, 6974)
13 | (111, 5928, 6332, 6493, 5542)
14 | (112, 5382, 5617, 5873, -1)
15 | (130, 6465, 6677, 6585, 6762)
16 | (131, 6549, 5243, -1, -1)
17 | (148, 6980, 5837, 5664, 5384)
18 | (153, 5470, 6675, -1, -1)
19 | (157, 6988, 5090, 6736, 6445)
20 | (174, 6751, 6199, 6271, -1)
21 | (180, 5876, 5260, 6220, 6369)
22 | (197, -1, 5443, 5211, -1)
23 | (205, 5235, 6003, 6644, 6029)
24 | (217, -1, 5978, 5030, 5324)
25 | (256, 6422, 5630, 6831, 5637)
26 | (263, -1, -1, 5768, 5274)
27 | (283, 5358, 6971, -1, 6662)
28 | (291, 6692, 6371, -1, -1)
29 | (317, -1, 6091, 6128, -1)
30 | (322, 6498, 6827, 5262, 6041)
31 | (323, 6872, 6879, 5249, 5443)
32 | (341, 6453, 5462, -1, -1)
33 | (364, 6695, 6624, -1, 6790)
34 | (369, 6548, 5801, 6624, 5975)
35 | (456, -1, -1, 6428, 6275)
36 | (461, 6860, 6199, 5478, 6076)
37 | (462, 5597, 6621, -1, 5462)
38 | (463, 5021, 6577, 5090, 5379)
39 | (470, 6830, 6940, 6189, 6762)
40 | (473, 5210, 6055, -1, 6747)
41 | (482, 5994, 5347, 5848, 6060)
42 | (493, 5691, 5101, -1, 6328)
43 | (540, -1, 6798, 5421, -1)
44 | (566, 6041, 5374, 5086, 5249)
45 | (609, 6506, 6916, -1, -1)
46 | (612, 6607, 6192, 6089, 6407)
47 | (615, 5179, 5274, 5739, 6069)
48 | (620, 6682, -1, 5898, 6827)
49 | (631, 6682, 6280, 6698, -1)
50 | (645, 6826, 6532, 5997, 5431)
51 | (661, 5703, 5042, 5900, 6091)
52 | (683, 6004, -1, -1, 6863)
53 | (684, -1, 6431, 6569, -1)
54 | (697, 5832, 5685, 5042, 6351)
55 | (702, 5674, 5978, 6371, 6548)
56 | (707, 6966, 6809, 5993, 5685)
57 | (717, 5347, 6350, 6863, 6714)
58 | (731, 6897, 6749, 5848, 6846)
59 | (736, 6239, 6585, 6736, 5645)
60 | (752, 6785, 6465, 6483, 5994)
61 | (754, 5679, 5146, 6846, 6714)
62 | (757, 6980, 5679, -1, -1)
63 | (758, 6189, 6214, 6350, 6483)
64 | (800, 6751, -1, -1, 5023)
65 | (810, 6771, 5814, 6817, 5674)
66 | (824, 6422, 5470, 6981, 5562)
67 | (830, 5044, 6631, 6625, 6894)
68 | (831, 5866, 6089, 6006, 5542)
69 | (850, 5188, 6629, 5687, 6798)
70 | (859, 5466, 5739, 5726, 5866)
71 | (899, 6734, 6369, 5030, 6817)
72 | (926, 6499, 6060, 6613, 5150)
73 | (933, 5768, 5873, 6407, 5726)
74 | (943, 5664, 5751, 5210, 5072)
75 | (955, 5260, 6249, 5457, 6631)
76 | (957, 5562, 5929, 6734, 5850)
77 | (1019, 6555, -1, 5235, 6629)
78 | (1023, 6551, 6367, 6830, 6239)
79 | (1028, -1, 6249, 6356, -1)
80 | (1055, 6498, 6879, 6005, 6280)
81 | (1099, 6826, 6723, 6268, 6192)
82 | (1139, -1, -1, 5266, 6432)
83 | (1182, 6128, 6648, 5836, 6917)
84 | (1186, 6134, 5645, 6577, 6644)
85 | (1190, 5993, 6183, 6648, 5900)
86 | (1225, 6008, 5431, 6959, 5751)
87 | (1240, 6884, -1, 6055, 6959)
88 | (1265, 5691, 6831, 5986, 5832)
89 | (1273, -1, 5356, 5478, 5023)
90 | (1302, 5553, 6991, -1, 6698)
91 | (1335, 6895, 6453, 5801, 6692)
92 | (1348, 6445, 6677, 5634, -1)
93 | (1350, 6376, 5630, 5850, 5814)
94 | (1352, 6462, 5188, -1, -1)
95 | (1362, 5928, 6335, 5202, 6621)
96 | (1366, 5044, 6803, 5324, 6220)
97 | (1375, 6183, 6442, 6217, 5401)
98 | (1386, -1, 5101, 6351, 6556)
99 | (1396, -1, 5179, 5374, 5511)
100 | (1407, 5997, 6662, -1, 6884)
101 | (1412, 6353, 6778, 5146, 5384)
102 | (1436, 6376, 6346, 6966, 5986)
103 | (1439, 5379, 5471, 6628, 5018)
104 | (1476, 5836, 5401, 6885, 5998)
105 | (1531, 6771, 5975, 5749, 6346)
106 | (1534, 6971, 5382, -1, -1)
107 | (1567, 6890, 6432, 6004, 6214)
108 | (1576, 5018, 6549, 5421, 6023)
109 | (1591, 5150, 6076, 5816, 5920)
110 | (1593, -1, -1, 5471, 6988)
111 | (1605, -1, 6569, 5964, 6747)
112 | (1623, 6023, 5687, 6029, 5021)
113 | (1649, -1, 6723, 6008, 5837)
114 | (1670, 6217, 6790, -1, 6200)
115 | (1679, 5062, -1, 6890, 6940)
116 | (1680, 5606, 6353, 5072, 5964)
117 | (1692, 5617, 5358, 6532, 6607)
118 | (1705, 5062, 6367, 6885, 6200)
119 | (1716, 6556, 5703, -1, -1)
120 | (1742, -1, 5483, 6981, -1)
121 | (1750, 6803, 6974, 6872, -1)
122 | (1759, -1, 5683, 5920, 6849)
123 | (1816, 5606, 6431, 6275, 6511)
124 | (1838, 5125, 6897, 6778, 6511)
125 | (1849, 6917, 5706, 6003, -1)
126 | (1856, -1, 6716, 5898, -1)
127 | (1877, -1, -1, 6555, 6462)
128 | (1890, -1, 5243, 6628, -1)
129 | (1909, -1, 5511, 5262, 6716)
130 | (1910, 5637, 6328, -1, 6675)
131 | (1921, 5483, 6356, 5876, 5929)
132 | (1943, 6613, 6749, 5011, 6860)
133 | (1945, 6268, -1, 6335, 6006)
134 | (1967, 6506, 5002, 5466, 6493)
135 | (1985, -1, 5266, 5202, -1)
--------------------------------------------------------------------------------
/CodeCraft-2019/2-map-exam-2/result.txt:
--------------------------------------------------------------------------------
1 |
2 | ====================
3 | {'MAX_COVERAGE': 0.14, 'MAX_TO_START': 200, 'K_PRIOR': 1.5, 'K_NON_PRIOR': 1.5, 'REFRESH_FREQUENCY': 3, 'M1': 10, 'M2': 10, 'MapName': '2-map-exam-2', 'TimeUsed': 521.9070224761963}
4 | {'T_Prior': 634, 'T_Total': 1682, 'T_Final': 2497, 'S_Prior': 2840975, 'S_Total': 51567742, 'S_Final': 67374518, 'Factor_A': 1.285241, 'Factor_B': 5.5638559999999995}
5 | ===== Succeeded!!! ======
6 |
7 | ====================
8 | {'MAX_COVERAGE': 0.13, 'MAX_TO_START': 200, 'K_PRIOR': 1.5, 'K_NON_PRIOR': 1.5, 'REFRESH_FREQUENCY': 5, 'M1': 10, 'M2': 10, 'MapName': '2-map-exam-2', 'TimeUsed': 29.194998502731323}
9 | {'T_Prior': 123, 'T_Total': 124, 'T_Final': 282, 'S_Prior': 59788, 'S_Total': 271302, 'S_Final': 603954, 'Factor_A': 1.285241, 'Factor_B': 5.5638559999999995}
10 | ===== FAILED !!! ======
11 |
12 | ====================
13 | {'MAX_COVERAGE': 0.12, 'MAX_TO_START': 200, 'K_PRIOR': 1.5, 'K_NON_PRIOR': 1.5, 'REFRESH_FREQUENCY': 5, 'M1': 10, 'M2': 10, 'MapName': '2-map-exam-2', 'TimeUsed': 416.59899830818176}
14 | {'T_Prior': 668, 'T_Total': 1928, 'T_Final': 2787, 'S_Prior': 3217807, 'S_Total': 59345280, 'S_Final': 77248695, 'Factor_A': 1.285241, 'Factor_B': 5.5638559999999995}
15 | ===== Succeeded!!! ======
16 |
--------------------------------------------------------------------------------
/CodeCraft-2019/2-map-exam-2/road.txt:
--------------------------------------------------------------------------------
1 | #(id,length,speed,channel,from,to,isDuplex)
2 | (5002, 36, 8, 1, 1967, 84, 1)
3 | (5011, 20, 10, 3, 1943, 52, 1)
4 | (5018, 40, 8, 2, 1576, 1439, 1)
5 | (5021, 30, 10, 1, 1623, 463, 1)
6 | (5023, 24, 10, 3, 1273, 800, 1)
7 | (5028, 40, 8, 3, 93, 41, 1)
8 | (5030, 30, 8, 2, 899, 217, 1)
9 | (5042, 36, 10, 2, 661, 697, 1)
10 | (5044, 24, 10, 3, 1366, 830, 1)
11 | (5062, 40, 15, 3, 1705, 1679, 1)
12 | (5072, 36, 8, 2, 1680, 943, 1)
13 | (5086, 36, 10, 3, 84, 566, 1)
14 | (5090, 36, 10, 1, 463, 157, 1)
15 | (5101, 24, 15, 2, 1386, 493, 1)
16 | (5125, 36, 15, 2, 52, 1838, 1)
17 | (5146, 36, 12, 3, 754, 1412, 0)
18 | (5150, 24, 12, 3, 1591, 926, 1)
19 | (5179, 36, 10, 1, 615, 1396, 1)
20 | (5188, 24, 12, 3, 1352, 850, 1)
21 | (5202, 20, 10, 1, 1985, 1362, 1)
22 | (5210, 20, 8, 3, 943, 473, 1)
23 | (5211, 30, 12, 1, 197, 84, 1)
24 | (5235, 24, 8, 1, 1019, 205, 1)
25 | (5243, 24, 15, 3, 131, 1890, 1)
26 | (5249, 20, 8, 3, 323, 566, 1)
27 | (5260, 20, 12, 2, 180, 955, 1)
28 | (5262, 20, 15, 1, 322, 1909, 1)
29 | (5266, 30, 10, 3, 1139, 1985, 1)
30 | (5274, 30, 10, 1, 615, 263, 1)
31 | (5324, 24, 15, 2, 217, 1366, 1)
32 | (5347, 40, 15, 3, 482, 717, 1)
33 | (5356, 24, 8, 3, 41, 1273, 1)
34 | (5358, 24, 12, 1, 1692, 283, 1)
35 | (5374, 20, 8, 1, 566, 1396, 1)
36 | (5379, 30, 15, 2, 1439, 463, 1)
37 | (5382, 24, 8, 2, 112, 1534, 1)
38 | (5384, 36, 8, 2, 1412, 148, 1)
39 | (5401, 40, 8, 3, 1476, 1375, 1)
40 | (5421, 20, 8, 3, 540, 1576, 1)
41 | (5431, 20, 8, 1, 1225, 645, 1)
42 | (5443, 20, 10, 3, 197, 323, 1)
43 | (5457, 20, 15, 3, 955, 5, 1)
44 | (5462, 30, 15, 3, 341, 462, 1)
45 | (5466, 40, 12, 2, 1967, 859, 0)
46 | (5470, 30, 12, 3, 153, 824, 1)
47 | (5471, 36, 10, 1, 1439, 1593, 1)
48 | (5478, 36, 10, 1, 1273, 461, 1)
49 | (5483, 30, 15, 1, 1742, 1921, 1)
50 | (5511, 36, 15, 3, 1396, 1909, 1)
51 | (5542, 20, 12, 1, 111, 831, 1)
52 | (5553, 30, 8, 3, 110, 1302, 1)
53 | (5562, 30, 10, 3, 824, 957, 1)
54 | (5597, 40, 8, 2, 462, 32, 1)
55 | (5606, 30, 8, 3, 1816, 1680, 1)
56 | (5617, 36, 10, 2, 1692, 112, 1)
57 | (5630, 36, 8, 1, 256, 1350, 1)
58 | (5634, 20, 8, 3, 1348, 108, 1)
59 | (5637, 24, 12, 2, 1910, 256, 1)
60 | (5645, 24, 10, 1, 1186, 736, 1)
61 | (5664, 20, 10, 3, 148, 943, 1)
62 | (5674, 20, 15, 3, 810, 702, 1)
63 | (5679, 36, 12, 3, 754, 757, 1)
64 | (5683, 20, 15, 2, 1759, 108, 1)
65 | (5685, 36, 12, 2, 697, 707, 1)
66 | (5687, 30, 15, 3, 850, 1623, 1)
67 | (5691, 24, 12, 3, 493, 1265, 1)
68 | (5703, 30, 15, 1, 1716, 661, 1)
69 | (5706, 24, 8, 3, 1849, 33, 1)
70 | (5726, 20, 12, 2, 859, 933, 1)
71 | (5739, 36, 12, 1, 859, 615, 1)
72 | (5749, 30, 15, 3, 62, 1531, 1)
73 | (5751, 20, 8, 3, 943, 1225, 0)
74 | (5768, 20, 15, 3, 933, 263, 1)
75 | (5801, 40, 10, 2, 369, 1335, 1)
76 | (5814, 40, 15, 1, 1350, 810, 1)
77 | (5816, 30, 15, 3, 41, 1591, 1)
78 | (5832, 20, 12, 2, 697, 1265, 1)
79 | (5836, 24, 8, 2, 1182, 1476, 1)
80 | (5837, 24, 15, 2, 148, 1649, 1)
81 | (5848, 24, 10, 1, 482, 731, 0)
82 | (5850, 24, 10, 2, 1350, 957, 1)
83 | (5866, 30, 10, 2, 831, 859, 1)
84 | (5873, 24, 12, 2, 933, 112, 1)
85 | (5876, 40, 8, 3, 1921, 180, 1)
86 | (5898, 24, 8, 2, 620, 1856, 1)
87 | (5900, 30, 8, 1, 661, 1190, 1)
88 | (5920, 36, 10, 3, 1759, 1591, 1)
89 | (5928, 36, 10, 3, 1362, 111, 1)
90 | (5929, 20, 10, 1, 957, 1921, 1)
91 | (5964, 40, 8, 1, 1680, 1605, 1)
92 | (5975, 20, 10, 2, 1531, 369, 1)
93 | (5978, 40, 10, 1, 702, 217, 1)
94 | (5986, 40, 8, 2, 1265, 1436, 0)
95 | (5993, 20, 12, 2, 1190, 707, 1)
96 | (5994, 20, 10, 3, 752, 482, 1)
97 | (5997, 40, 12, 2, 645, 1407, 1)
98 | (5998, 36, 15, 3, 33, 1476, 1)
99 | (6003, 24, 10, 1, 205, 1849, 1)
100 | (6004, 20, 10, 2, 1567, 683, 1)
101 | (6005, 30, 10, 3, 110, 1055, 1)
102 | (6006, 24, 15, 1, 1945, 831, 1)
103 | (6008, 30, 12, 1, 1649, 1225, 1)
104 | (6023, 40, 8, 3, 1576, 1623, 1)
105 | (6029, 36, 10, 1, 1623, 205, 1)
106 | (6041, 20, 8, 2, 566, 322, 0)
107 | (6055, 30, 12, 3, 473, 1240, 1)
108 | (6060, 36, 15, 1, 926, 482, 1)
109 | (6069, 36, 12, 2, 84, 615, 1)
110 | (6076, 36, 10, 2, 1591, 461, 1)
111 | (6089, 24, 12, 2, 831, 612, 0)
112 | (6091, 40, 12, 1, 317, 661, 1)
113 | (6128, 20, 15, 3, 317, 1182, 1)
114 | (6134, 20, 12, 3, 1186, 33, 0)
115 | (6183, 40, 15, 3, 1190, 1375, 1)
116 | (6189, 20, 10, 2, 470, 758, 1)
117 | (6192, 36, 8, 1, 1099, 612, 1)
118 | (6199, 24, 15, 1, 461, 174, 1)
119 | (6200, 30, 12, 1, 1705, 1670, 1)
120 | (6214, 30, 10, 3, 758, 1567, 1)
121 | (6217, 40, 12, 3, 1375, 1670, 1)
122 | (6220, 20, 10, 1, 180, 1366, 1)
123 | (6239, 40, 8, 2, 736, 1023, 1)
124 | (6249, 36, 15, 1, 1028, 955, 1)
125 | (6268, 30, 12, 2, 1945, 1099, 1)
126 | (6271, 40, 10, 1, 174, 52, 1)
127 | (6275, 36, 15, 1, 456, 1816, 1)
128 | (6280, 30, 15, 3, 1055, 631, 1)
129 | (6328, 36, 15, 2, 493, 1910, 1)
130 | (6332, 40, 10, 2, 32, 111, 1)
131 | (6335, 36, 12, 3, 1362, 1945, 1)
132 | (6346, 40, 15, 1, 1436, 1531, 1)
133 | (6350, 36, 8, 3, 758, 717, 1)
134 | (6351, 30, 10, 2, 1386, 697, 1)
135 | (6353, 40, 8, 2, 1412, 1680, 1)
136 | (6356, 20, 12, 1, 1921, 1028, 1)
137 | (6367, 30, 15, 1, 1023, 1705, 1)
138 | (6369, 40, 15, 1, 899, 180, 1)
139 | (6371, 24, 15, 3, 702, 291, 1)
140 | (6376, 36, 15, 2, 1436, 1350, 1)
141 | (6407, 24, 8, 2, 612, 933, 1)
142 | (6422, 40, 12, 1, 256, 824, 1)
143 | (6428, 40, 15, 1, 52, 456, 1)
144 | (6431, 30, 8, 2, 1816, 684, 1)
145 | (6432, 20, 10, 3, 1567, 1139, 1)
146 | (6442, 20, 8, 2, 1375, 62, 0)
147 | (6445, 30, 15, 1, 157, 1348, 1)
148 | (6453, 24, 15, 3, 341, 1335, 1)
149 | (6462, 40, 15, 3, 1352, 1877, 1)
150 | (6465, 40, 8, 1, 130, 752, 0)
151 | (6483, 40, 12, 3, 752, 758, 1)
152 | (6493, 36, 12, 1, 111, 1967, 1)
153 | (6498, 24, 12, 2, 1055, 322, 1)
154 | (6499, 36, 8, 2, 108, 926, 1)
155 | (6506, 20, 15, 1, 609, 1967, 1)
156 | (6511, 30, 12, 3, 1838, 1816, 1)
157 | (6528, 20, 15, 3, 5, 47, 1)
158 | (6532, 36, 15, 3, 645, 1692, 1)
159 | (6548, 36, 10, 2, 369, 702, 1)
160 | (6549, 30, 8, 1, 131, 1576, 1)
161 | (6551, 30, 15, 1, 33, 1023, 1)
162 | (6555, 40, 10, 2, 1877, 1019, 1)
163 | (6556, 40, 8, 1, 1716, 1386, 1)
164 | (6569, 40, 15, 3, 684, 1605, 1)
165 | (6577, 30, 8, 1, 463, 1186, 1)
166 | (6585, 30, 12, 2, 736, 130, 1)
167 | (6607, 30, 8, 3, 612, 1692, 1)
168 | (6613, 40, 12, 3, 926, 1943, 1)
169 | (6621, 24, 10, 2, 462, 1362, 1)
170 | (6624, 40, 8, 1, 364, 369, 1)
171 | (6625, 36, 15, 1, 830, 47, 1)
172 | (6628, 24, 12, 1, 1890, 1439, 1)
173 | (6629, 20, 10, 1, 850, 1019, 1)
174 | (6631, 20, 12, 3, 955, 830, 1)
175 | (6644, 30, 15, 2, 205, 1186, 1)
176 | (6648, 20, 8, 3, 1182, 1190, 1)
177 | (6662, 20, 8, 3, 1407, 283, 1)
178 | (6675, 20, 8, 1, 1910, 153, 1)
179 | (6677, 20, 12, 3, 1348, 130, 1)
180 | (6682, 40, 10, 1, 631, 620, 1)
181 | (6692, 40, 10, 1, 1335, 291, 1)
182 | (6695, 24, 15, 2, 62, 364, 1)
183 | (6698, 24, 8, 3, 1302, 631, 1)
184 | (6714, 36, 15, 1, 717, 754, 1)
185 | (6716, 36, 15, 1, 1909, 1856, 1)
186 | (6723, 40, 8, 3, 1649, 1099, 1)
187 | (6734, 40, 15, 1, 957, 899, 1)
188 | (6736, 40, 15, 3, 157, 736, 1)
189 | (6747, 20, 10, 2, 1605, 473, 1)
190 | (6749, 40, 10, 3, 1943, 731, 1)
191 | (6751, 24, 12, 2, 800, 174, 1)
192 | (6762, 40, 15, 3, 130, 470, 1)
193 | (6771, 20, 8, 1, 1531, 810, 1)
194 | (6778, 36, 8, 2, 1838, 1412, 1)
195 | (6785, 36, 10, 2, 108, 752, 1)
196 | (6790, 20, 8, 2, 1670, 364, 1)
197 | (6798, 30, 15, 3, 540, 850, 1)
198 | (6803, 40, 10, 2, 1366, 1750, 1)
199 | (6809, 24, 15, 1, 707, 62, 1)
200 | (6817, 30, 12, 1, 810, 899, 0)
201 | (6826, 36, 10, 3, 1099, 645, 1)
202 | (6827, 20, 8, 1, 322, 620, 1)
203 | (6830, 20, 8, 2, 1023, 470, 0)
204 | (6831, 20, 15, 2, 1265, 256, 1)
205 | (6846, 30, 15, 1, 731, 754, 1)
206 | (6849, 20, 8, 3, 93, 1759, 1)
207 | (6860, 40, 10, 2, 461, 1943, 0)
208 | (6863, 24, 10, 1, 717, 683, 1)
209 | (6872, 24, 15, 3, 1750, 323, 1)
210 | (6879, 24, 8, 1, 323, 1055, 1)
211 | (6884, 20, 8, 1, 1240, 1407, 1)
212 | (6885, 40, 10, 1, 1476, 1705, 1)
213 | (6890, 20, 8, 1, 1679, 1567, 1)
214 | (6894, 20, 12, 3, 830, 110, 1)
215 | (6895, 40, 15, 2, 1335, 32, 1)
216 | (6897, 20, 10, 3, 731, 1838, 1)
217 | (6916, 24, 10, 2, 32, 609, 1)
218 | (6917, 40, 12, 1, 1849, 1182, 1)
219 | (6940, 20, 12, 1, 470, 1679, 1)
220 | (6959, 40, 12, 1, 1225, 1240, 1)
221 | (6966, 24, 10, 2, 707, 1436, 1)
222 | (6971, 36, 8, 1, 283, 1534, 1)
223 | (6974, 30, 8, 1, 1750, 110, 1)
224 | (6980, 36, 15, 2, 757, 148, 1)
225 | (6981, 40, 10, 3, 824, 1742, 1)
226 | (6988, 30, 15, 3, 1593, 157, 1)
227 | (6991, 40, 12, 2, 47, 1302, 1)
--------------------------------------------------------------------------------
/CodeCraft-2019/resource/CodeCraft2019RemFlowControl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MarkShawn2020/CodeCraft2019Rem/8ecd5b93831b9343d89fb8fd0a3ae60676fb970e/CodeCraft-2019/resource/CodeCraft2019RemFlowControl.png
--------------------------------------------------------------------------------
/CodeCraft-2019/src/CodeCraft-2019.py:
--------------------------------------------------------------------------------
1 | #-*-coding:utf-8-*-
2 | __author__ = 'MarkShawn'
3 |
4 |
5 | from core import *
6 | from utils import *
7 |
8 |
9 | """
10 | ==================================================================
11 | 装饰器 log_each_step 用于打印某个调度过程中发生的一些数据改变量
12 | 装饰器 log_each_round 用于打印某个时间片结束时的一些数据标量
13 | ==================================================================
14 | """
15 |
16 |
17 | @log_each_step
18 | def schedule_step_1(time_round):
19 | """
20 | 第一步调度,标定道路上能移动或需要等待的小车
21 | 该步骤结束时,将全图发优先车
22 | """
23 | if np.mod(time_round, REFRESH_FREQUENCY) == 1 : # and Data.total_finished_ratio < 0.9
24 | c.update_roads() # 更新路权
25 |
26 | for road in c.road_dict.values():
27 | for lane_seq in range(road.car_arr.shape[0]):
28 | res = road.mark_cars_on_this_lane_in_step_1(lane_seq)
29 | if res and road not in Data.roads_to_schedule_in_step_2:
30 | Data.roads_to_schedule_in_step_2.append(road)
31 |
32 | c.load_cars(time_round=time_round, priority=True)
33 | c.depart_cars(time_round=time_round, priority=True)
34 |
35 |
36 | @dead_lock_check # 死锁检测装饰器,服务器运行时自动休眠
37 | def period_schedule_in_step_2(time_round):
38 | for road in list(Data.roads_to_schedule_in_step_2):
39 | while True:
40 | first_car = road.get_first_waiting_car()
41 |
42 | if not first_car:
43 | Data.roads_to_schedule_in_step_2.remove(road)
44 | break
45 |
46 | if c.car_is_conflicted(first_car) or not first_car.can_move_to_next_road:
47 | break
48 |
49 | lane = first_car.lane
50 | first_car.move_to_next_road()
51 | Data.to_schedule -= 1
52 | road.move_cars_on_this_lane_in_step_2(lane)
53 | c.depart_cars(time_round=time_round, priority=True, road=road)
54 |
55 |
56 | @log_each_step
57 | def schedule_step_2(time_round):
58 | """
59 | 第二步调度,循环调度以使道路上所有的车移动至结束状态
60 | 该步骤中,只要有小车通过路口,将继续对该小车原所在路做一次优先车发车
61 | 该步骤结束后,将依次先全图发优先车,再全图发非优先车
62 | """
63 |
64 | while Data.roads_to_schedule_in_step_2:
65 | try:
66 | period_schedule_in_step_2(time_round=time_round)
67 | except:
68 | raise evaluate_results(c, succeed=False)
69 |
70 | c.depart_cars(time_round=time_round, priority=True)
71 | c.load_cars(time_round=time_round, priority=False)
72 | c.depart_cars(time_round=time_round, priority=False)
73 |
74 |
75 | @log_each_round
76 | def each_round(time_round):
77 | schedule_step_1(time_round)
78 | schedule_step_2(time_round)
79 |
80 | scan_and_log_cars_each_time_round(c, logger)
81 |
82 |
83 | def main():
84 | while Data.total_finished != Data.CARS_CNT:
85 | Data.time_round += 1
86 | each_round(Data.time_round)
87 |
88 | if ENABLE_CAR_ARRIVAL_TIME_FILE_WRITE:
89 | write_arrival_times(c, 'arrival_core.txt')
90 |
91 | if ENABLE_EVALUATING_RESULTS_LOG:
92 | evaluate_results(c)
93 |
94 |
95 | if __name__ == '__main__':
96 | c = Core()
97 | c.init_data()
98 | c.pre_process_data()
99 | main()
100 | write_answer(c, ANSWER_PATH, including_preset=False)
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/CodeCraft-2019/src/CodeCraft-2019_judge.py:
--------------------------------------------------------------------------------
1 | #-*-coding:utf-8-*-
2 | __author__ = 'MarkShawn'
3 |
4 | from core_judge import *
5 | from utils import *
6 |
7 |
8 | @log_each_step
9 | def schedule_step_1(time_round):
10 |
11 | for road in c.road_dict.values():
12 | for lane_seq in range(road.car_arr.shape[0]):
13 | res = road.mark_cars_on_this_lane_in_step_1(lane_seq)
14 | if res and road not in c.roads_to_schedule_in_step_2:
15 | Data.roads_to_schedule_in_step_2.append(road)
16 |
17 | c.depart_cars(time_round=time_round, priority=True)
18 |
19 |
20 | @dead_lock_check
21 | def period_schedule_in_step_2(time_round):
22 |
23 | for road in list(Data.roads_to_schedule_in_step_2):
24 | while True:
25 | first_car = road.get_first_waiting_car()
26 |
27 | if not first_car:
28 | Data.roads_to_schedule_in_step_2.remove(road)
29 | break
30 |
31 | if c.car_is_conflicted(first_car) or not first_car.can_move_to_next_road:
32 | break
33 |
34 | lane = first_car.lane
35 | first_car.move_to_next_road()
36 | Data.to_schedule -= 1
37 | road.move_cars_on_this_lane_in_step_2(lane)
38 | c.depart_cars(time_round=time_round, priority=True, road=road)
39 |
40 |
41 | @log_each_step
42 | def schedule_step_2(time_round):
43 |
44 | while Data.roads_to_schedule_in_step_2:
45 | period_schedule_in_step_2(time_round=time_round)
46 |
47 | c.depart_cars(time_round=time_round, priority=False)
48 |
49 |
50 | @log_each_round
51 | def each_round(time_round):
52 |
53 | schedule_step_1(time_round)
54 | schedule_step_2(time_round)
55 |
56 | scan_and_log_cars_each_time_round(c, logger)
57 |
58 |
59 | def main():
60 | while Data.total_finished != Data.CARS_CNT:
61 | Data.time_round += 1
62 | each_round(Data.time_round)
63 |
64 | if ENABLE_CAR_ARRIVAL_TIME_FILE_WRITE:
65 | write_arrival_times(c, 'arrival_judge.txt')
66 |
67 | if ENABLE_EVALUATING_RESULTS_LOG:
68 | evaluate_results(c)
69 |
70 |
71 | if __name__ == '__main__':
72 | c = CoreJudge()
73 | c.init_data()
74 | c.pre_process_judging_data()
75 | main()
76 | write_answer(c, '{}/{}/my_answer.txt'.format(MAP_PATH, MAP_NAME))
77 |
78 |
--------------------------------------------------------------------------------
/CodeCraft-2019/src/VersionControl.md:
--------------------------------------------------------------------------------
1 | # Version Control
2 |
3 | ## 初赛
4 | ### V1.0 分组法原版
5 |
6 | ### V2.0 去除G版
7 |
8 | ### V3.0 精简版
9 |
10 | ### V4.0 优先对列版
11 | - V4.1 将出发对列改成了heapq方法
12 | - V4.2 将is_conflicted方法更改成了复赛版本,修改了对应Road类的cars_to_go_queue对列
13 |
14 | ### V6.0 使用了优先对列
15 | - V6.1 优化第三步发车装载的逻辑,对非预设车的发车做了delay控制,可以避免堵塞
16 | - V6.2 更改车库内最短距离问题,使用了新的列表存储,并且降低了PriorCar的权利,因为地图2很容易死
17 | - V6.3 去除了装载模块,原因是装载模块遍历时耗时很长,尤其是频率堆积的时候;修复了第一步骤的调度车道,本来放在for循环里的,浪费了时间
18 | - V6.4 优化了上路的道路尾部判断,使用一个标定锚即可;并且对后续上路的车辆进行了速度惩罚,调慢了一点点优先车辆的速度
19 | - V6.5 修复:第二调度阶段,一旦有车通过路口,即全图上车(之前是局部扫描);在第二调度阶段,因为改为全图上车后,就扫描全部道路(之前是第一调度后有车移动后的道路)
20 |
21 |
22 | ## 复赛(1)CodeCraftRem
23 | - V5.0 自5.0版本以来开始使用全局动态路径算法
24 | - V6.0 正式解决小车delay引起的实际判别器调度顺序不一致问题,与动态路径产生调度错乱问题,原则上已经完全模拟服务器的判别器
25 | - V7.0 由于V6.0的一些意外,以及服务器运行结果总是不一致,继续调节各种参数与逻辑。。。
26 |
27 | ## 复赛(2)SpiderMenCome
28 | - V1.0 **完全修复bug,开始拟合之路!**
29 | - V1.1 完善了1.0,并调试出4,0.16的较好参数
30 |
31 | # Thoughts
32 | - 不能使用道路尾部空位的位置变化作为判断是否激活车库发车的依据,例子:
33 | + A道路长度6,在车道0上有1-5五辆小车连在一起,尾部0位置空缺,因为5号小车在道路头部,因此第一步调度时它处于等待状态,这会导致后面的小车均处于等待状态,这样的话车库里一辆速度为2的小车就无法进入该道路,因为被阻挡的1号小车处于等待状态
34 | + 经过第二步调度后5号小车因为下一条道路全部占满堵死从而无法穿过路口,并标记成了结束状态,这会导致1-4号车均标记为结束状态,此时空位(0,0)并无发生改变,但车库里的车却能上路了
35 | - 每次小车越过路口后,要重新生成优先级队列,因为如果普通车辆后面是优先车辆,普通车走了后,优先级就会发生变化
36 | - 凡是加入了车库的车,都要参与车库发车的排序,而且必须是在第一阶段调度之前就要装载好优先车,第三阶段调度之前装载好普通车,其他时间不能装载小车
37 | - 对优先小车组和普通小车组使用不同的路径,按照出发时间、速度、到达时间、ID排序,不断加载固定数目的小车,让他们参与发车
38 | - 通过时间和道路检测
39 | - **动态规划路径的时候要注意更改剩余路径的问题**
40 | + 假设一辆车21499在第5时间片要从道路5911(77,41)驶往6448(41,78),因为下一段距离不够本应该行驶到路的尽头使整条路后面的车辆以及车库里的车得到调度;
41 | + 但是因为转向问题冲突从而停止调度,继被冲突的车驶过路口后它才开始调度,但是整个路面的情况已经发生了改变
42 | + 此时,你又开始进行了路径的重新规划,并给21499车重新设计了一条直行的路,并且在下一时间片6的时候通过了路口,此路径保存了下来
43 | + 官方判别器在运行时,无法侦查到此种改变,因此21499在第5时间片就直接驶过了它在未来要直行通过的路口,因此整个判别过程与程序运行时开始大相径庭
44 | + 一个较好的系统,原本可能没有的死锁,开始意外发生
--------------------------------------------------------------------------------
/CodeCraft-2019/src/__pycache__/base.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MarkShawn2020/CodeCraft2019Rem/8ecd5b93831b9343d89fb8fd0a3ae60676fb970e/CodeCraft-2019/src/__pycache__/base.cpython-37.pyc
--------------------------------------------------------------------------------
/CodeCraft-2019/src/__pycache__/car.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MarkShawn2020/CodeCraft2019Rem/8ecd5b93831b9343d89fb8fd0a3ae60676fb970e/CodeCraft-2019/src/__pycache__/car.cpython-37.pyc
--------------------------------------------------------------------------------
/CodeCraft-2019/src/__pycache__/core.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MarkShawn2020/CodeCraft2019Rem/8ecd5b93831b9343d89fb8fd0a3ae60676fb970e/CodeCraft-2019/src/__pycache__/core.cpython-37.pyc
--------------------------------------------------------------------------------
/CodeCraft-2019/src/__pycache__/core_judge.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MarkShawn2020/CodeCraft2019Rem/8ecd5b93831b9343d89fb8fd0a3ae60676fb970e/CodeCraft-2019/src/__pycache__/core_judge.cpython-37.pyc
--------------------------------------------------------------------------------
/CodeCraft-2019/src/__pycache__/cross.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MarkShawn2020/CodeCraft2019Rem/8ecd5b93831b9343d89fb8fd0a3ae60676fb970e/CodeCraft-2019/src/__pycache__/cross.cpython-37.pyc
--------------------------------------------------------------------------------
/CodeCraft-2019/src/__pycache__/data.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MarkShawn2020/CodeCraft2019Rem/8ecd5b93831b9343d89fb8fd0a3ae60676fb970e/CodeCraft-2019/src/__pycache__/data.cpython-37.pyc
--------------------------------------------------------------------------------
/CodeCraft-2019/src/__pycache__/road.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MarkShawn2020/CodeCraft2019Rem/8ecd5b93831b9343d89fb8fd0a3ae60676fb970e/CodeCraft-2019/src/__pycache__/road.cpython-37.pyc
--------------------------------------------------------------------------------
/CodeCraft-2019/src/__pycache__/settings.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MarkShawn2020/CodeCraft2019Rem/8ecd5b93831b9343d89fb8fd0a3ae60676fb970e/CodeCraft-2019/src/__pycache__/settings.cpython-37.pyc
--------------------------------------------------------------------------------
/CodeCraft-2019/src/__pycache__/utils.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MarkShawn2020/CodeCraft2019Rem/8ecd5b93831b9343d89fb8fd0a3ae60676fb970e/CodeCraft-2019/src/__pycache__/utils.cpython-37.pyc
--------------------------------------------------------------------------------
/CodeCraft-2019/src/base.py:
--------------------------------------------------------------------------------
1 | #-*-coding:utf-8-*-
2 | __author__ = 'MarkShawn'
3 |
4 | from settings import *
5 | from utils import *
6 | from data import Data
7 | from car import Car
8 | from road import Road
9 | from cross import Cross
10 |
11 | from collections import OrderedDict, defaultdict, Counter
12 | from queue import PriorityQueue
13 | import numpy as np
14 | import time
15 |
16 |
17 | class Base():
18 |
19 | def __init__(self):
20 |
21 | self.start_time = time.time()
22 |
23 | self.cross_dict = None
24 | self.road_dict = None
25 | self.car_dict = None
26 |
27 | self.roads_to_schedule_in_step_2 = [] # 第一阶段调度后仍有等待车辆的道路列表,可提高程序性能
28 | self.car_queues = defaultdict(PriorityQueue) # 四种车库,优先预置,非优先预置,非优先预置,非优先非预置
29 |
30 | self.MAX_PRESET_REAL_TIME = None
31 |
32 | @property
33 | def all_car_id_set(self):
34 | return set(self.car_dict)
35 |
36 | @property
37 | def prior_car_id_set(self):
38 | return set(i.id for i in self.car_dict.values() if i.priority == 1)
39 |
40 | @property
41 | def preset_car_id_set(self):
42 | return set(i.id for i in self.car_dict.values() if i.preset == 1)
43 |
44 | @property
45 | def CARS_CNT(self):
46 | return len(self.all_car_id_set)
47 |
48 | @property
49 | def PRIOR_CARS_CNT(self):
50 | return len(self.prior_car_id_set)
51 |
52 | @property
53 | def PRESET_CARS_CNT(self):
54 | return len(self.preset_car_id_set)
55 |
56 | @property
57 | def CROSSES_CNT(self):
58 | return len(self.cross_dict)
59 |
60 | @property
61 | def ROADS_CNT(self):
62 | return len(self.road_dict)
63 |
64 | @property
65 | def PAYLOAD_OF_MAP(self):
66 | return sum(i.payload for i in self.road_dict.values())
67 |
68 | @property
69 | def MAX_CARS_ON_MAP(self):
70 | return int(MAX_COVERAGE * self.PAYLOAD_OF_MAP)
71 |
72 | """
73 | =======================
74 | 读取并初始化路口、道路、小车的字典信息,生成数据结构
75 | =======================
76 | """
77 |
78 | def read_cross_dict(self):
79 | cross_data = read_items_from_file(CROSS_PATH)
80 | sorted_cross_data = sorted(cross_data, key=lambda x: x[0])
81 | self.cross_dict = OrderedDict((i, Cross(i, *j)) for i, j in enumerate(sorted_cross_data))
82 | self.cross_real_id_to_id_dict = dict((j.real_id, j.id) for j in self.cross_dict.values())
83 | self.cross_id_to_real_id_dict = dict((j.id, j.real_id) for j in self.cross_dict.values())
84 |
85 | Data.CROSSES_CNT = self.CROSSES_CNT
86 | Data.init_arr()
87 |
88 | logging.info('MAP: {}'.format(MAP_NAME))
89 | logging.info('TotalCrosses: {}'.format(self.CROSSES_CNT))
90 |
91 | def read_road_dict(self):
92 | """
93 | 并初始化最短路径
94 | :return:
95 | """
96 | self.road_dict = dict()
97 | self.road_id_to_vid_dict = dict()
98 | self.road_id_set = set()
99 | road_data = read_items_from_file(ROAD_PATH)
100 | for road_item in road_data:
101 | road_item[4] = self.cross_real_id_to_id_dict[road_item[4]]
102 | road_item[5] = self.cross_real_id_to_id_dict[road_item[5]]
103 | road = Road(*road_item)
104 |
105 | self.road_dict[road.vid] = road
106 | self.road_id_to_vid_dict[road_item[0]] = (road_item[4], road_item[5])
107 | self.road_id_set.add(road_item[0])
108 |
109 | Data.first_dis_arr[road.vid] = road.length / road.speed_limited
110 |
111 | if road.is_duplex: # 因为会有双向路,而roads_container是按照道路的向量表示的,因此对于双向路要重建一个road类
112 | road_item[4], road_item[5] = road_item[5], road_item[4]
113 | road = Road(*road_item)
114 |
115 | self.road_dict[road.vid] = road
116 |
117 | Data.first_dis_arr[road.vid] = road.length / road.speed_limited
118 |
119 | Data.PAYLOAD_OF_MAP = self.PAYLOAD_OF_MAP
120 | Data.MAX_CARS_ON_MAP = self.MAX_CARS_ON_MAP
121 | Data.first_dis_arr /= Data.first_dis_arr[np.isfinite(Data.first_dis_arr)].max()
122 | Data.first_path_arr = get_path_arr(Data.first_dis_arr) # 需要上一步生成的距离矩阵,并且生成路径矩阵
123 | Data.path_time_arr = self.get_path_time_arr(Data.first_path_arr)
124 |
125 | self.road_dict = OrderedDict(sorted(self.road_dict.items(), key=lambda x: (x[1].to_cross_id, x[1].id)))
126 | logging.info({'TotalRoads': self.ROADS_CNT,
127 | 'ByRoadID': len(road_data),
128 | 'PayRoadOfMap': self.PAYLOAD_OF_MAP,
129 | 'MAX_COVERAGE': MAX_COVERAGE,
130 | 'MAX_CARS_ON_MAP': self.MAX_CARS_ON_MAP
131 | })
132 |
133 | def read_car_dict(self):
134 | car_data = read_items_from_file(CAR_PATH)
135 | car_dict = dict()
136 | for car_item in car_data:
137 | car_item[1] = self.cross_real_id_to_id_dict[car_item[1]]
138 | car_item[2] = self.cross_real_id_to_id_dict[car_item[2]]
139 | car_dict[car_item[0]] = car = Car(*car_item)
140 |
141 | if car.priority:
142 | Data.MAX_HIGH_TIME = max(Data.MAX_HIGH_TIME, car.real_time)
143 |
144 | car.time_need = Data.path_time_arr[car.vid]
145 |
146 | self.car_dict = car_dict
147 |
148 |
149 | def read_preset_answer_file(self):
150 | preset_data = read_items_from_file(PRESET_ANSWER_PATH)
151 | max_preset_real_time = 0
152 | for preset_item in preset_data:
153 | car = self.car_dict[preset_item[0]]
154 | car.real_time = preset_item[1]
155 | self.add_road_id_path(car, preset_item[2:])
156 |
157 | if car.priority:
158 | Data.MAX_HIGH_TIME = max(Data.MAX_HIGH_TIME, car.real_time)
159 | logging.info('\n\n')
160 |
161 |
162 | def read_answer_file(self):
163 | answer_data = read_items_from_file(ANSWER_PATH)
164 | for answer_item in answer_data:
165 | car = self.car_dict[answer_item[0]]
166 | car.real_time = answer_item[1]
167 | self.add_road_id_path(car, answer_item[2:])
168 |
169 |
170 | """
171 | ======================
172 | 小车的方向与冲突检测
173 | ======================
174 | """
175 |
176 | def _get_car_dir(self, car):
177 | if not car.this_road or not car.next_road:
178 | return 2
179 | else:
180 | this_cross = self.cross_dict[car.this_road.to_cross_id]
181 | return this_cross.get_offset_value_between_two_roads(car.this_road.id, car.next_road.id)
182 |
183 | def _is_conflicted(self, car, data_list):
184 | cross_id = car.this_road.to_cross_id
185 | for data in data_list:
186 | offset, min_priority, dir = data
187 | road_id = self.cross_dict[cross_id].get_offset_road_id(car.this_road.id, offset)
188 | if road_id:
189 | road_vid = self.get_road_vid_from_cross_and_road_id(cross_id, road_id)
190 | if road_vid:
191 | first_car = self.road_dict[road_vid].get_first_waiting_car()
192 | if first_car and first_car.priority >= min_priority and self._get_car_dir(first_car) == dir:
193 | # 这里还是加一个waiting_car 比较好
194 | car.waiting_car = first_car
195 | return True
196 | return False
197 |
198 | def car_is_conflicted(self, car):
199 | dir = self._get_car_dir(car)
200 | if car.priority == 1:
201 | if dir == 2:
202 | return False
203 | elif dir == 1:
204 | return self._is_conflicted(car, [(3, 1, 2)]) # 左转优先车等右手位直行优先车
205 | else:
206 | return self._is_conflicted(car, [(1, 1, 2), (2, 1, 1)]) # 右转优先车等左手位直行优先车或对手位左转优先车
207 |
208 | else:
209 | if dir == 2:
210 | return self._is_conflicted(car, [(1, 1, 1), (3, 1, 3)]) # 直行劣等车等左手位左转优先车或右手位右转优先车
211 | elif dir == 1:
212 | return self._is_conflicted(car, [(3, 0, 2), (2, 1, 3)]) # 左转劣等车等右手位直行任意车或对手位右转直行车
213 | else:
214 | return self._is_conflicted(car, [(1, 0, 2), (2, 0, 1)]) # 右转劣等车等左手位任意直行车或对手位任意左转车
215 |
216 | """
217 | ==============================
218 | 以下是关于小车路径的各种转换与读写,支持三种加载小车路径的方法
219 |
220 | 法一:在程序中生成小车的vid路径,vid是指道路的向量表示形式,API为self.add_road_vid_path(road_vid_path)
221 | 调用这个API后会先生成road_vid_path,然后基于此通过道路字典生成road_cls_path与road_id_path
222 |
223 | 法二:直接从答案文件加载,比如加载预置小车路径或者加载测试答案路径时,API为self.add_road_id_path(road_id_path)
224 | 调用这个API后会内部通过self.convert_road_id_path_to_road_vid_path()转化成road_vid_path
225 | 然后生成法一中的road_cls_path和road_id_path
226 |
227 | 法三:【更新于4月13号】动态路径直接更改 car.roads_to_go即可,已经实现,API在 core.update_roads()
228 | ==============================
229 | """
230 |
231 |
232 | def get_road_cls_path_from_vid_path(self, road_vid_path):
233 | return list(self.road_dict[i] for i in road_vid_path)
234 |
235 |
236 | def convert_road_id_path_to_road_vid_path(self, car, road_id_path):
237 | cross_id_path = [car.from_cross_id]
238 | for road_id in road_id_path:
239 | for next_cross_id in self.road_id_to_vid_dict[road_id]:
240 | if next_cross_id != cross_id_path[-1]:
241 | cross_id_path.append(next_cross_id)
242 | break
243 |
244 | road_vid_path = list((i, j) for i, j in zip(cross_id_path[:-1], cross_id_path[1:]))
245 | self.add_road_vid_path(car, road_vid_path)
246 |
247 | def add_road_id_path(self, car, input_road_id_path):
248 | car.road_id_path = list(input_road_id_path)
249 | self.convert_road_id_path_to_road_vid_path(car, car.road_id_path)
250 |
251 | def add_road_vid_path(self, car, input_road_vid_path):
252 | car.road_vid_path = input_road_vid_path
253 | car.road_cls_path = self.get_road_cls_path_from_vid_path(car.road_vid_path)
254 | car.roads_to_go = car.road_cls_path.copy()
255 |
256 | if not car.road_id_path:
257 | car.road_id_path = list(i.id for i in car.road_cls_path)
258 |
259 |
260 | """
261 | ===================================
262 | 一些其他功能
263 | ===================================
264 | """
265 |
266 | def get_time_used(self, decimal=3, is_seconds=True):
267 | seconds = time.time() - self.start_time
268 | return round(seconds if is_seconds else seconds / 60, decimal)
269 |
270 | def get_road_real_vid(self, road):
271 | """
272 | 该函数用于获得道路的真实向量
273 | """
274 | return (self.cross_id_to_real_id_dict[road.from_cross_id],
275 | self.cross_id_to_real_id_dict[road.to_cross_id],)
276 |
277 | def get_road_vid_from_cross_and_road_id(self, to_cross_id, road_id):
278 | """
279 | 该函数用于路口判断,从路口ID和道路ID得到另一个路口的ID,并返回道路的向量。
280 | 如果是单向路,则返回空
281 | """
282 |
283 | def swap_tuple(input_tuple):
284 | converted_list = list(input_tuple)
285 | converted_list[0], converted_list[1] = converted_list[1], converted_list[0]
286 | return tuple(converted_list)
287 |
288 | road_vid_tuple = self.road_id_to_vid_dict[road_id]
289 | road_vid_tuple = road_vid_tuple if road_vid_tuple[1] == to_cross_id else swap_tuple(road_vid_tuple)
290 | if road_vid_tuple in self.road_dict:
291 | return road_vid_tuple
292 |
293 |
294 | def get_path_time_arr(self, input_path_arr):
295 | """
296 | 该函数用于将路径矩阵转换成时间矩阵,用于初始化小车形成的预估时间
297 | :param input_path_arr:
298 | :return:
299 | """
300 | def get_path_time(input_path):
301 | total_time = 0
302 | if input_path:
303 | for road_vid in input_path:
304 | road = self.road_dict[road_vid]
305 | total_time += int(road.length / road.speed_limited) + 1
306 | return total_time
307 |
308 | vfunc = np.vectorize(get_path_time)
309 | return vfunc(input_path_arr)
310 |
311 |
312 | def get_second_dis_path_arr(self):
313 | """
314 | 该函数用于调整最频繁道路的路权,从而生成新的路径矩阵
315 | 主要用于区分优先小车和普通小车的路径
316 | """
317 | road_list = [road_vid for ele in Data.first_path_arr.flatten() for road_vid in ele if ele]
318 | road_counter = Counter(road_list)
319 | max_freq = road_counter.most_common(1)[0][1]
320 |
321 | Data.second_dis_arr = Data.first_dis_arr.copy()
322 | for road_vid, road_freq in road_counter.items():
323 | road_freq_rate = road_freq / max_freq
324 |
325 | Data.second_dis_arr[road_vid] += road_freq_rate * MULTIPLIER_TO_FIRST_ROAD
326 |
327 |
328 | """
329 | ==================================
330 | 以下是评分函数
331 | ==================================
332 | """
333 |
334 | def get_some_property(self, is_prior, property, func):
335 | a = self.prior_car_id_set if is_prior else self.all_car_id_set
336 | b = [getattr(self.car_dict[i], property) for i in a]
337 | return func(b)
338 |
339 | def get_all_time_period(self):
340 | return Data.time_round
341 |
342 | def get_prior_time_period(self):
343 | return self.get_some_property(is_prior=True, property='finished_time', func=max) - \
344 | self.get_some_property(is_prior=True, property='plan_time', func=min)
345 |
346 | def get_all_scheduled_cnt(self):
347 | return sum(car.get_life_span() for car in self.car_dict.values())
348 |
349 | def get_prior_scheduled_cnt(self):
350 | return sum(car.get_life_span() for car in self.car_dict.values() if car.priority)
351 |
352 | def get_cars_cnt_ratio(self):
353 | return round(self.CARS_CNT / self.PRIOR_CARS_CNT, 5)
354 |
355 | def get_speed_ratio(self):
356 | numerator = round(self.get_some_property(False, 'speed', max) / self.get_some_property(False, 'speed', min), 5)
357 | denominator = round(self.get_some_property(True, 'speed', max) / self.get_some_property(True, 'speed', min), 5)
358 | return round(numerator / denominator, 5)
359 |
360 | def get_plan_time_ratio(self):
361 | numerator = round(
362 | self.get_some_property(False, 'plan_time', max) / self.get_some_property(False, 'plan_time', min), 5)
363 | denominator = round(
364 | self.get_some_property(True, 'plan_time', max) / self.get_some_property(True, 'plan_time', min), 5)
365 | return round(numerator / denominator, 5)
366 |
367 | def get_from_distributed_ratio(self):
368 | numerator = self.get_some_property(False, 'from_cross_id', lambda x: len(set(x)))
369 | denominator = self.get_some_property(True, 'from_cross_id', lambda x: len(set(x)))
370 | return round(numerator / denominator, 5)
371 |
372 | def get_to_distributed_ratio(self):
373 | numerator = self.get_some_property(False, 'to_cross_id', lambda x: len(set(x)))
374 | denominator = self.get_some_property(True, 'to_cross_id', lambda x: len(set(x)))
375 | return round(numerator / denominator, 5)
376 |
377 | def get_factor_from_weights_list(self, weights_list):
378 | return sum(i * j for i, j in zip(
379 | [self.get_cars_cnt_ratio(), self.get_speed_ratio(), self.get_plan_time_ratio(),
380 | self.get_from_distributed_ratio(), self.get_to_distributed_ratio()],
381 | weights_list
382 | ))
383 |
384 | def get_factor_a(self):
385 | return self.get_factor_from_weights_list([.05, .2375, .2375, .2375, .2375])
386 |
387 | def get_factor_b(self):
388 | return self.get_factor_from_weights_list([.8, .05, .05, .05, .05])
389 |
390 | def get_final_time_round(self):
391 | return int(round(self.get_factor_a() * self.get_prior_time_period() + self.get_all_time_period(), 0))
392 |
393 | def get_final_schedule_time(self):
394 | return int(round(self.get_factor_b() * self.get_prior_scheduled_cnt() + self.get_all_scheduled_cnt(), 0))
395 |
396 |
397 |
--------------------------------------------------------------------------------
/CodeCraft-2019/src/car.py:
--------------------------------------------------------------------------------
1 | #-*-coding:utf-8-*-
2 | __author__ = 'MarkShawn'
3 |
4 | from data import *
5 | from settings import *
6 |
7 | import logging
8 | logger = logging.getLogger('car')
9 | if ENABLE_CAR_LOG:
10 | logger.addHandler(logging.FileHandler(filename='log_car_judge.log', mode='w'))
11 | logger.setLevel(logging.DEBUG)
12 | else:
13 | logger.setLevel(logging.WARNING)
14 |
15 |
16 |
17 | class Car(object):
18 | def __init__(self, car_id, car_from, car_to, car_v, plan_time, priority, preset):
19 | self.id = car_id
20 | self.from_cross_id = car_from
21 | self.to_cross_id = car_to
22 | self.speed = car_v
23 | self.plan_time = plan_time
24 | self.priority = priority
25 | self.preset = preset
26 |
27 | self.vid = (self.from_cross_id, self.to_cross_id)
28 |
29 | self._real_time = self.plan_time
30 | self._start_time = self.plan_time
31 | self.finished_time = self.plan_time
32 |
33 | self.road_id_path = None
34 | self.road_vid_path = None
35 | self.roads_passed = []
36 | self.roads_to_go = []
37 | # self.visited_cross_id_set = {self.from_cross_id}
38 |
39 | self.pos_track = [self.id]
40 |
41 | self.row = None
42 | self.lane = None
43 |
44 | self.is_waiting = False
45 | self.has_finished = False
46 |
47 | self.waiting_car = None
48 | self.follow_car = None
49 |
50 | self.time_need = None
51 |
52 |
53 | """
54 | ====================================
55 | 小车的优先队列判定函数
56 | ====================================
57 | """
58 |
59 | def __lt__(self, other):
60 | """
61 | 由于在程序中使用了优先对列PriorityQueue,且直接对小车的类进行排序
62 | 因此定义该函数,在内部实现基于优先级、发车时间、ID的排序
63 | 这样能够保证在神奇车库内发车时,总是吻合官方方案的(前提是判别器的路面判断没有太大误差)
64 | :param other: 与该辆小车比较顺序的另外一辆小车
65 | :return: 返回True即该小车的优先级较高,否则反之
66 | """
67 |
68 | if self.priority > other.priority:
69 | return True
70 | elif self.priority < other.priority:
71 | return False
72 |
73 | elif int(self.real_time) < int(other.real_time):
74 | return True
75 | elif int(self.real_time) > int(other.real_time):
76 | return False
77 |
78 | elif self.id < other.id:
79 | return True
80 | elif self.id > other.id:
81 | return False
82 |
83 | else:
84 | logging.error('Cant compare between these two cars: {}, {}'.format(self.id, other.id))
85 |
86 |
87 | """
88 | ====================================
89 | 小车的一些时间属性
90 | ====================================
91 | """
92 | @property
93 | def real_time(self):
94 | return self._real_time
95 |
96 | @real_time.setter
97 | def real_time(self, value):
98 | """
99 | 由于官方会有对发车时间与计划时间的检测
100 | 因此我们定义了Setter的方法,检测发车时间的有效性
101 | """
102 | if value < self.plan_time:
103 | logging.error({'car_id': self.id, 'preset': self.preset, 'plan_time': self.plan_time, 'rel_time': value, })
104 | else:
105 | self._real_time = value
106 | self._start_time = self._real_time
107 |
108 | @property
109 | def start_time(self):
110 | return self._start_time
111 |
112 | @start_time.setter
113 | def start_time(self, value):
114 | self._start_time = value
115 |
116 | @property
117 | def due_finished_time(self):
118 | return self.start_time + self.time_need
119 |
120 | def get_life_span(self):
121 | return self.finished_time - self.plan_time
122 |
123 |
124 | """
125 | ====================================
126 | 小车的一些位置属性
127 | ====================================
128 | """
129 |
130 | @property
131 | def current_pos(self):
132 | return (self.lane, self.row, self.this_road.id)
133 |
134 | @property
135 | def this_road(self):
136 | if self.roads_passed:
137 | return self.roads_passed[-1]
138 |
139 | @property
140 | def next_road(self):
141 | if self.roads_to_go:
142 | return self.roads_to_go[0]
143 |
144 | @property
145 | def max_v_on_this_road(self):
146 | return min(self.speed, self.this_road.speed_limited)
147 |
148 | @property
149 | def max_v_on_next_road(self):
150 | return min(self.speed, self.next_road.speed_limited)
151 |
152 | @property
153 | def remaining_dis_on_this_road(self):
154 | return self.this_road.length - self.row - 1
155 |
156 | @property
157 | def max_dis_on_next_road(self):
158 | if not self.this_road:
159 | return self.max_v_on_next_road
160 | elif self.next_road:
161 | return max(self.max_v_on_next_road - self.remaining_dis_on_this_road, 0)
162 | else:
163 | return None
164 |
165 | @property
166 | def max_row_on_this_road(self):
167 | return min(self.row + self.max_v_on_this_road, self.this_road.length - 1)
168 |
169 | @property
170 | def will_exceed_this_road(self):
171 | return self.row + self.max_v_on_this_road >= self.this_road.length
172 |
173 |
174 | """
175 | ==========================================
176 | 以下是小车的两种位置标记函数
177 | ==========================================
178 | """
179 |
180 | def _clear_current_position(self):
181 | self.is_waiting = False
182 |
183 | self.this_road.del_car(self)
184 |
185 | def _update_new_position(self, lane, row):
186 |
187 | self.lane = lane
188 | self.row = row
189 | self.pos_track.append(self.current_pos)
190 | self.this_road.add_car(self)
191 |
192 |
193 | """
194 | ==========================================
195 | 以下判断头部小车能否过路口,以及过路口的函数
196 | 注意!这里没有考虑小车冲突的问题,冲突会在主调度中检测!
197 | ==========================================
198 | """
199 | @property
200 | def can_move_to_next_road(self):
201 | if not self.next_road:
202 | return True
203 | elif self.next_road.is_blocking:
204 | return True
205 | else:
206 | block_car_on_next_road, max_pos = self.next_road.get_block_car_at_the_entrance(self.max_dis_on_next_road)
207 | if block_car_on_next_road and block_car_on_next_road.is_waiting:
208 | # 这里要补一句这个waiting_car,以生成waiting chain
209 | self.waiting_car = block_car_on_next_road
210 | return False
211 | else:
212 | return True
213 |
214 | def move_to_next_road(self):
215 | """
216 | 专门给要通过路口的小车使用的,建立在self.can_move_to_next_road==True的基础上
217 | 该函数要配合road.move_cars_on_this_lane_in_step_2使用
218 | """
219 | self.this_road.pop_head_car(self)
220 |
221 | if not self.next_road:
222 | return self.finish()
223 |
224 | elif self.next_road.is_blocking or self.max_dis_on_next_road == 0:
225 | return self.move(row=self.max_row_on_this_road, step_seq=2, desc='Cross')
226 |
227 | else:
228 | block_car_on_next_road, max_pos = self.next_road.get_block_car_at_the_entrance(self.max_dis_on_next_road)
229 | return self.move(*max_pos, next_road=True, block_dis=self.max_row_on_this_road-max_pos[1]+1, step_seq=2, desc='Cross')
230 |
231 |
232 |
233 | """
234 | ==========================================
235 | 以下是小车的五种运动函数
236 | ==========================================
237 | """
238 |
239 | @stat_data
240 | def start(self, lane, row, block_dis=0):
241 |
242 | self.is_waiting = False
243 | self.start_time = Data.time_round
244 | self.roads_passed.append(self.roads_to_go.pop(0))
245 | self._update_new_position(lane, row)
246 | self.block_dis = block_dis
247 |
248 | return 1
249 |
250 | @stat_data
251 | def finish(self):
252 | self.finished_time = Data.time_round
253 | self.has_finished = True
254 | self._clear_current_position()
255 | return 2
256 |
257 | @stat_data
258 | def move(self, lane=None, row=None, next_road=False, block_dis=0, follow_car=None, step_seq=None, desc=None):
259 | self._clear_current_position()
260 |
261 | if lane is None:
262 | lane=self.lane
263 | if row is None:
264 | logging.error('Row is necessary!')
265 | if next_road:
266 | self.roads_passed.append(self.roads_to_go.pop(0))
267 | # self.visited_cross_id_set.add(self.this_road.to_cross_id)
268 |
269 | self._update_new_position(lane, row)
270 | self.is_waiting = False
271 | self.follow_car = follow_car
272 | self.block_dis = block_dis
273 |
274 | return 3
275 |
276 | @stat_data
277 | def wait(self, waiting_car=None):
278 | self.waiting_car = waiting_car
279 | self.is_waiting = True
280 | return 4
281 |
282 | @stat_data
283 | def delay(self, non_preset_inc_time=False, non_preset_sync_time=False):
284 | """
285 | Delay的时候非预置车可以考虑将实际出发时间+1,但往往不需要,尤其是模拟模式下根本不要
286 | """
287 | if non_preset_inc_time and self.preset==0:
288 | self.real_time += 1
289 | if non_preset_sync_time and self.preset == 0:
290 | self.real_time = Data.time_round + 1
291 |
292 | return 5
--------------------------------------------------------------------------------
/CodeCraft-2019/src/core.py:
--------------------------------------------------------------------------------
1 | #-*-coding:utf-8-*-
2 | __author__ = 'MarkShawn'
3 |
4 |
5 | from base import *
6 | import heapq
7 | from collections import Counter
8 |
9 | logger = logging.getLogger('core')
10 | if ENABLE_CORE_LOG:
11 | logger.addHandler(logging.FileHandler(filename='log_core.log', mode='w'))
12 | logger.setLevel(logging.DEBUG)
13 | else:
14 | logger.setLevel(logging.WARNING)
15 |
16 |
17 | class Core(Base):
18 |
19 | """
20 | ===========================
21 | 一次性初始化程序
22 | ===========================
23 | """
24 |
25 | def transfer_Data(self):
26 | logging.info({'TotalCars': self.CARS_CNT,
27 | 'PriorCars': self.PRIOR_CARS_CNT,
28 | 'PresetCars': self.PRESET_CARS_CNT,
29 | 'IntersectedCars': len(self.prior_car_id_set.intersection(self.preset_car_id_set))
30 | })
31 |
32 | Data.CARS_CNT = self.CARS_CNT
33 | Data.PRIOR_CARS_CNT = self.PRIOR_CARS_CNT
34 | Data.PRESET_CARS_CNT = self.PRESET_CARS_CNT
35 | Data.MAX_CARS_ON_MAP = self.MAX_CARS_ON_MAP
36 |
37 | def init_data(self):
38 | clear_file(LOG_FILE_PATH)
39 | self.read_cross_dict() # 已传输CROSSES_CNT信息给Data
40 | self.read_road_dict() # 已传输MAX_CARS_ON_MAP等信息给Data,并且已生成第一条最短路径
41 | self.read_car_dict() # 已传输CARS_CNT信息给Data
42 |
43 | def pre_process_data(self):
44 | self.read_preset_answer_file() # 自动加载预置小车信息,并配备出发时间和路径
45 |
46 | self.get_second_dis_path_arr()
47 |
48 | self.change_preset_property()
49 |
50 | self.transfer_Data()
51 |
52 | self.pure_sort_cars(self.preset_car_id_set)
53 | self.sort_prior_cars(self.prior_car_id_set-self.preset_car_id_set, log_k=ARG_K_PRIOR)
54 | self.sort_cars(self.all_car_id_set - self.preset_car_id_set - self.prior_car_id_set, log_k=ARG_K_NON_PRIOR, update_time=True)
55 |
56 |
57 |
58 | """
59 | =======================
60 | 三种排车方案
61 | =======================
62 | """
63 | def touch_top(self):
64 | cars = [self.car_dict[i] for i in self.preset_car_id_set]
65 | car_info_list = [i.real_time for i in cars]
66 | counter = Counter(car_info_list)
67 | return
68 |
69 | def change_preset_property(self):
70 | cars = [self.car_dict[i] for i in self.preset_car_id_set]
71 | sorted_cars = sorted(cars, key=lambda x: (- x.time_need, -x.priority, -x.speed))
72 | car_cnt = len(cars)
73 | max_cars_to_change = int(car_cnt/10)
74 |
75 | for seq, car in enumerate(sorted_cars):
76 | if seq < max_cars_to_change:
77 | car.preset = 0
78 | else:
79 | break
80 |
81 | def pure_sort_cars(self, car_id_set):
82 | """
83 | 静态装载小车,预置小车专用,因为它已经有出发时间和路径信息
84 | """
85 | for car_id in car_id_set:
86 | car = self.car_dict[car_id]
87 | self.car_queues[car.priority, car.preset].put(car)
88 |
89 | return
90 |
91 | def sort_cars(self, car_id_set, log_k=2, update_time=True):
92 | """
93 | log_k: 排车的log对数底,数值越大,说明排车越靠前,系数设置为2时接近下降阶梯分布
94 | Prior: 1, x
95 | Preset: x, 1
96 | """
97 | car_list = sorted([self.car_dict[i] for i in car_id_set],
98 | key=lambda x: (x.real_time, -x.speed, -x.real_time - x.time_need, x.id))
99 | car_cnt = len(car_list)
100 |
101 | ALL_MAX_TIME = self.get_some_property(is_prior=False, property='real_time', func=max)
102 |
103 | cur_sum_cnt = 0
104 | for time_round in range(1, ALL_MAX_TIME + 1):
105 | max_sum_cnt = np.log(time_round / ALL_MAX_TIME * (log_k-1)+1) / np.log(log_k) * car_cnt
106 | while car_list and car_list[0].real_time <= time_round and cur_sum_cnt time_round:
184 | self.car_queues[priority, 1].put(car)
185 | break
186 | else:
187 | self.load_car_into_garage(car)
188 |
189 | while not self.car_queues[priority, 0].empty():
190 | car = self.car_queues[priority, 0].get_nowait()
191 |
192 | if car.real_time > time_round or Data.total_to_start >= MAX_TO_START:
193 | """
194 | 对于非预置车的装车,不但有发车时间限制,还加入了车库数量的限制,这样能保证发车阶段遍历车库时有较高的性能
195 | """
196 | self.car_queues[priority, 0].put(car)
197 | break
198 |
199 | else:
200 | """
201 | 对优先车和非优先车分别使用两种道路权值,尽量使他们的路径避开
202 | """
203 | path_arr = None
204 | if car.priority:
205 | path_arr = Data.path_arr_for_prior
206 |
207 | elif Data.prior_finished_ratio >= 0.99 and car.speed > SPEED_GROUP_CUT:
208 | path_arr = Data.path_arr_for_prior
209 |
210 | else:
211 | path_arr = Data.path_arr_for_non_prior
212 |
213 | self.load_car_into_garage(car, sync_time=True, new_path_arr=path_arr)
214 |
215 | def load_car_into_garage(self, car, new_path_arr=None, sync_time=False):
216 | if sync_time is True:
217 | car.real_time = Data.time_round
218 | if new_path_arr is not None:
219 | self.add_road_vid_path(car, new_path_arr[car.vid])
220 | car.next_road.add_car_to_garage(car)
221 |
222 |
223 | """
224 | =======================
225 | 发车
226 | =======================
227 | """
228 |
229 | def depart_cars(self, time_round, priority=True, road=None):
230 | """
231 | 先上优先车,再上劣等车
232 | 其中,有预置车就必上,否则可以进行一些判断,以自定义调节一些发车
233 | """
234 | if road:
235 | self.start_cars_in_garage(road=road, time_round=time_round, priority=priority)
236 |
237 | else:
238 | for road in self.road_dict.values():
239 | self.start_cars_in_garage(road=road, time_round=time_round, priority=priority)
240 |
241 | def start_cars_in_garage(self, road, time_round, priority):
242 |
243 | def start():
244 | car.start(*max_pos, block_dis=car.max_v_on_next_road - max_pos[1])
245 |
246 | def wait():
247 | car.delay(non_preset_sync_time=True)
248 | cars_failed_to_start.append(car)
249 |
250 | garage = road.prior_garage if priority else road.normal_garage
251 | cars_failed_to_start = []
252 |
253 | while not garage.empty():
254 | car = garage.get()
255 |
256 | if int(car.real_time) > time_round: # 如果从车库内pop出来的车,出发时间大于当前时间,迭代结束
257 | cars_failed_to_start.append(car)
258 | break
259 |
260 | elif road.is_blocking: # 当前道路已经完全被堵
261 | wait()
262 |
263 | else:
264 | blocked_car, max_pos = road.get_block_car_at_the_entrance(car.max_v_on_next_road)
265 | if not max_pos: # 若有正在等待的车阻挡(可能自己速度较快),则pop下一辆可以上路的车(可能速度较慢点就可以上路了)
266 | wait()
267 |
268 | elif car.preset: # 预置车上路不受任何限制,只要有路就上
269 | start()
270 |
271 | elif max_pos[0] == road.lanes_cnt-1 and max_pos[1] < 1:
272 | wait()
273 |
274 | elif car.priority:
275 | start()
276 |
277 | elif Data.cars_on_map < Data.MAX_CARS_ON_MAP:
278 | start()
279 |
280 | else:
281 | wait()
282 |
283 | for car in cars_failed_to_start:
284 | garage.put(car)
285 |
286 |
--------------------------------------------------------------------------------
/CodeCraft-2019/src/core_judge.py:
--------------------------------------------------------------------------------
1 | #-*-coding:utf-8-*-
2 | __author__ = 'MarkShawn'
3 |
4 |
5 | from base import *
6 |
7 | logger = logging.getLogger('core_judge')
8 | if ENABLE_CORE_LOG:
9 | logger.addHandler(logging.FileHandler(filename='log_core_judge.log', mode='w'))
10 | logger.setLevel(logging.DEBUG)
11 | else:
12 | logger.setLevel(logging.WARNING)
13 |
14 |
15 |
16 | class CoreJudge(Base):
17 |
18 | """
19 | ===========================
20 | 一次性初始化程序
21 | ===========================
22 | """
23 |
24 |
25 | def init_data(self):
26 | clear_file(LOG_FILE_PATH)
27 | self.read_cross_dict() # 已传输CROSSES_CNT信息给Data
28 | self.read_road_dict() # 已传输MAX_CARS_ON_MAP等信息给Data,并且已生成第一条最短路径
29 | self.read_car_dict() # 已传输CARS_CNT信息给Data
30 |
31 | def pre_process_judging_data(self):
32 | self.read_answer_file()
33 | self.read_preset_answer_file() # 自动加载预置小车信息,并配备出发时间和路径
34 | for car in self.car_dict.values():
35 | car.next_road.add_car_to_garage(car)
36 |
37 | """
38 | =======================
39 | 模拟模式只有发车
40 | =======================
41 | """
42 |
43 | def depart_cars(self, time_round, priority=True, road=None):
44 | """
45 | 先上优先车,再上劣等车
46 | 其中,有预置车就必上,否则可以进行一些判断,以自定义调节一些发车
47 | """
48 | if road:
49 | self.start_cars_in_garage(road=road, time_round=time_round, priority=priority)
50 |
51 | else:
52 | for road in self.road_dict.values():
53 | self.start_cars_in_garage(road=road, time_round=time_round, priority=priority)
54 |
55 |
56 | def start_cars_in_garage(self, road, time_round, priority):
57 | def _start_cars_in_garage(_priority):
58 | garage = road.prior_garage if _priority else road.normal_garage
59 | visited_but_failed_cars = []
60 |
61 | while not garage.empty():
62 | car = garage.get()
63 |
64 | if int(car.real_time) > time_round:
65 | visited_but_failed_cars.append(car)
66 | break
67 |
68 | elif road.is_blocking:
69 | visited_but_failed_cars.append(car)
70 | # logger.debug(
71 | # {'TimeRound': Data.time_round,
72 | # 'Id': car.id,
73 | # 'RealTime': car.real_time,
74 | # 'Priority': car.priority,
75 | # 'Preset': car.preset,
76 | # 'Action': 'DelayedByBlocking',
77 | # })
78 |
79 | else:
80 | blocked_car, max_pos = road.get_block_car_at_the_entrance(car.max_v_on_next_road)
81 | if not max_pos:
82 | car.delay()
83 | visited_but_failed_cars.append(car)
84 | # logger.debug(
85 | # {'TimeRound': Data.time_round,
86 | # 'Id': car.id,
87 | # 'RealTime': car.real_time,
88 | # 'Priority': car.priority,
89 | # 'Preset': car.preset,
90 | # 'Action': 'DelayedByNoPos',
91 | # })
92 | else:
93 | car.start(*max_pos)
94 | # logger.debug(
95 | # {'TimeRound': Data.time_round,
96 | # 'Id': car.id,
97 | # 'RealTime': car.real_time,
98 | # 'Priority': car.priority,
99 | # 'Preset': car.preset,
100 | # 'Action': 'START',
101 | # })
102 |
103 | for car in visited_but_failed_cars:
104 | garage.put(car)
105 |
106 | _start_cars_in_garage(1)
107 | if not priority:
108 | _start_cars_in_garage(0)
109 |
110 |
111 |
--------------------------------------------------------------------------------
/CodeCraft-2019/src/cross.py:
--------------------------------------------------------------------------------
1 | #-*-coding:utf-8-*-
2 | __author__ = 'MarkShawn'
3 |
4 | import numpy as np
5 |
6 |
7 | class Cross(object):
8 |
9 | def __init__(self, fake_id, real_id, *road_id_list):
10 | self.id = fake_id
11 | self.real_id = real_id
12 | self.road_id_list = road_id_list
13 |
14 | """
15 | ==================================
16 | 以下函数用于道路ID和次序之间的转换与偏转
17 | ---基于所有的道路输入是按顺时针旋转的---
18 | ==================================
19 | """
20 |
21 | @property
22 | def road_id_to_seq_dict(self):
23 | return dict((j, i) for i, j in enumerate(self.road_id_list) if j != -1)
24 |
25 | @property
26 | def road_seq_to_id_dict(self):
27 | return dict((i, j) for i, j in enumerate(self.road_id_list) if j != -1)
28 |
29 | def get_offset_road_id(self, road_id, offset):
30 | offset_seq = np.mod(self.road_id_to_seq_dict[road_id] + offset, 4)
31 | return self.road_seq_to_id_dict.get(offset_seq)
32 |
33 | def get_offset_value_between_two_roads(self, this_road_id, next_road_id):
34 | return np.mod(self.road_id_to_seq_dict[next_road_id] - self.road_id_to_seq_dict[this_road_id], 4)
35 |
36 | """
37 | ===================================
38 | 以下该函数用于绘图
39 | ===================================
40 | """
41 |
42 | def get_rotation_matrix(self, road_m, road_n):
43 | rot = np.mod(self.road_id_to_seq_dict[road_n] - self.road_id_to_seq_dict[road_m], 4) * (- np.pi / 2)
44 | return np.matrix([[np.cos(rot), -np.sin(rot)], [np.sin(rot), np.cos(rot)]])
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/CodeCraft-2019/src/data.py:
--------------------------------------------------------------------------------
1 | #-*-coding:utf-8-*-
2 | __author__ = 'MarkShawn'
3 |
4 |
5 | import numpy as np
6 | import time
7 |
8 |
9 | class classproperty(object):
10 | """
11 | =======================
12 | 该类只是为提供直接的类属性
13 | =======================
14 | """
15 | def __init__(cls, f):
16 | cls.f = f
17 | def __get__(cls, obj, owner):
18 | return cls.f(owner)
19 |
20 |
21 | class Data():
22 |
23 | start_time = time.time()
24 |
25 | time_round = 0
26 | scheduled = 0
27 | prior_scheduled = 0
28 |
29 | to_schedule = 0
30 | update_path_arr_cnt = 0
31 | car_set_on_map = set()
32 |
33 | total_loaded = 0
34 | prior_loaded = 0
35 | preset_loaded = 0
36 |
37 | total_started = 0
38 | prior_started = 0
39 | preset_started = 0
40 | normal_started = 0
41 |
42 | total_finished = 0
43 | prior_finished = 0
44 | preset_finished = 0
45 | normal_finished = 0
46 |
47 | total_moved = 0
48 | prior_moved = 0
49 | preset_moved = 0
50 |
51 | total_waited = 0
52 | prior_waited = 0
53 | preset_waited = 0
54 |
55 | total_delayed = 0
56 | prior_delayed = 0
57 | preset_delayed = 0
58 |
59 | CARS_CNT = None
60 | CROSSES_CNT = None
61 | PRESET_CARS_CNT = None
62 | PRIOR_CARS_CNT = None
63 | MAX_CARS_ON_MAP = None
64 | PAYLOAD_OF_MAP = None
65 |
66 | MAX_HIGH_TIME = 0
67 |
68 | road_use_arr = None
69 | road_block_arr = None
70 | path_time_arr = None
71 | first_dis_arr = None
72 | first_path_arr = None
73 | second_dis_arr = None
74 | second_path_arr = None
75 | path_arr_for_prior = None
76 | path_arr_for_non_prior = None
77 |
78 | roads_to_schedule_in_step_2 = []
79 |
80 | @classmethod
81 | def init_arr(cls):
82 | cls.road_use_arr = np.zeros((cls.CROSSES_CNT, cls.CROSSES_CNT), dtype=float)
83 | cls.road_block_arr = np.zeros((cls.CROSSES_CNT, cls.CROSSES_CNT), dtype=float)
84 |
85 | cls.first_dis_arr = np.zeros((cls.CROSSES_CNT, cls.CROSSES_CNT), dtype=float)
86 | cls.first_dis_arr.fill(np.inf)
87 | cls.first_path_arr = np.empty((cls.CROSSES_CNT, cls.CROSSES_CNT), dtype=object)
88 |
89 | cls.second_dis_arr = np.zeros((cls.CROSSES_CNT, cls.CROSSES_CNT), dtype=float)
90 | cls.second_dis_arr.fill(np.inf)
91 | cls.second_path_arr = np.empty((cls.CROSSES_CNT, cls.CROSSES_CNT), dtype=object)
92 |
93 | cls.path_arr_for_prior = np.empty((cls.CROSSES_CNT, cls.CROSSES_CNT), dtype=object)
94 | cls.path_arr_for_non_prior = np.empty((cls.CROSSES_CNT, cls.CROSSES_CNT), dtype=object)
95 |
96 | @classmethod
97 | def get_run_time(self, decimal=3, is_seconds=True):
98 | seconds = time.time() - self.start_time
99 | return round(seconds if is_seconds else seconds / 60, decimal)
100 |
101 | @classproperty
102 | def cars_on_map(cls):
103 | return cls.total_started - cls.total_finished
104 |
105 | @classproperty
106 | def cars_coverage(cls):
107 | return round(cls.cars_on_map / cls.PAYLOAD_OF_MAP, 5)
108 |
109 | @classproperty
110 | def prior_cars_on_map(cls):
111 | return cls.prior_started - cls.prior_finished
112 |
113 | @classproperty
114 | def preset_cars_on_map(cls):
115 | return cls.preset_started - cls.preset_finished
116 |
117 | @classproperty
118 | def normal_cars_on_map(cls):
119 | return cls.normal_started - cls.normal_finished
120 |
121 | @classproperty
122 | def prior_finished_ratio(cls):
123 | return round(cls.prior_finished / cls.PRIOR_CARS_CNT, 5)
124 |
125 | @classproperty
126 | def preset_finished_ratio(cls):
127 | return round(cls.preset_finished / cls.PRESET_CARS_CNT, 5)
128 |
129 | @classproperty
130 | def total_finished_ratio(cls):
131 | return round(cls.total_finished / cls.CARS_CNT, 5)
132 |
133 | @classproperty
134 | def prior_to_start(cls):
135 | return cls.prior_loaded - cls.prior_started
136 |
137 | @classproperty
138 | def preset_to_start(cls):
139 | return cls.preset_loaded - cls.preset_started
140 |
141 | @classproperty
142 | def total_to_start(cls):
143 | return cls.total_loaded - cls.total_started
144 |
145 |
146 |
147 | def stat_data(func):
148 | """
149 | ==================================================================
150 | 装饰器 stat_Data 收集每辆小车的运动状态信息,用于跟踪、反馈与分析
151 | ==================================================================
152 | 1: start 小车出发上路
153 | 2: finish 小车抵达了目的地
154 | 3: move 移动,或去下一条路
155 | 4: wait 小车等待
156 | 5: delay 小车延迟一秒出发,分车满被阻挡和主动延迟两种
157 |
158 | """
159 | def wrapper(self, *args, **kwargs):
160 | a = func(self, *args, **kwargs)
161 | if a == 1:
162 | Data.total_started += 1
163 |
164 | if self.priority:
165 | Data.prior_started +=1
166 |
167 | if self.preset:
168 | Data.preset_started += 1
169 |
170 | if not self.priority and not self.preset:
171 | Data.normal_started += 1
172 |
173 | Data.car_set_on_map.add(self)
174 | # Data.road_block_arr[self.this_road.vid] += self.block_dis / self.this_road.payload
175 |
176 |
177 | elif a == 2:
178 | Data.total_finished += 1
179 |
180 | if self.priority:
181 | Data.prior_finished += 1
182 |
183 | if self.preset:
184 | Data.preset_finished += 1
185 |
186 | if not self.priority and not self.preset:
187 | Data.normal_finished += 1
188 |
189 | Data.car_set_on_map.remove(self) # 这里竟然填了add?
190 |
191 | elif a == 3:
192 | Data.total_moved += 1
193 |
194 | # Data.road_block_arr[self.this_road.vid] += self.block_dis / self.this_road.payload
195 |
196 | elif a == 4:
197 | Data.total_waited += 1
198 |
199 | elif a == 5:
200 | Data.total_delayed += 1
201 |
202 | if self.priority:
203 | Data.prior_delayed += 1
204 |
205 | if self.preset:
206 | Data.preset_delayed += 1
207 |
208 |
209 | return a
210 | return wrapper
211 |
212 |
213 |
--------------------------------------------------------------------------------
/CodeCraft-2019/src/road.py:
--------------------------------------------------------------------------------
1 | #-*-coding:utf-8-*-
2 | __author__ = 'MarkShawn'
3 |
4 | import numpy as np
5 | from queue import PriorityQueue
6 | from data import Data
7 |
8 |
9 | class Road(object):
10 |
11 | def __init__(self, id, length, speed_limited, lanes_cnt, from_cross_id, to_cross, is_duplex):
12 | self.id = id
13 | self.length = length
14 | self.speed_limited = speed_limited
15 | self.lanes_cnt = lanes_cnt
16 | self.from_cross_id = from_cross_id
17 | self.to_cross_id = to_cross
18 | self.is_duplex = is_duplex
19 |
20 | # VID元祖是指道路的指向,即数学上的向量,用于链接道路字典
21 | self.vid = (self.from_cross_id, self.to_cross_id)
22 |
23 |
24 | # 使用Numpy数组保存小车的车位信息,数组的横轴是道路的宽度,纵轴是道路的长度,即三行五列的数组表示3个车道长度为5
25 | self.car_arr = np.empty([self.lanes_cnt, self.length], dtype=object)
26 | self.pos_arr = np.empty([self.lanes_cnt, self.length], dtype=object)
27 |
28 | self.normal_garage = PriorityQueue()
29 | self.prior_garage = PriorityQueue()
30 | self.preset_cars_loaded_cnt = 0
31 |
32 | self.head_cars = set()
33 | self.cars_load_cnt = 0
34 |
35 | @property
36 | def payload(self): # 道路的最大负载量,即车位的总数,长乘以宽
37 | return self.car_arr.size
38 |
39 |
40 | def add_car(self, car):
41 | self.car_arr[car.lane, car.row] = car
42 | self.cars_load_cnt += 1
43 | Data.road_use_arr[self.vid] += 1 / self.payload
44 |
45 | def del_car(self, car):
46 | self.car_arr[car.lane, car.row] = None
47 | self.cars_load_cnt -= 1
48 | Data.road_use_arr[self.vid] -= 1 / self.payload
49 |
50 |
51 | def push_head_car(self, car):
52 | self.head_cars.add(car)
53 |
54 | def pop_head_car(self, car):
55 | self.head_cars.remove(car)
56 |
57 | def get_min_v(self, lane_seq):
58 | v_list = [i.speed for i in self.car_arr[lane_seq, :] if i]
59 | if v_list:
60 | return min(min(v_list), self.speed_limited)
61 | return self.speed_limited
62 |
63 |
64 | """
65 | ===========================
66 | 以下方法用于获取道路的头部小车与尾部进入逻辑
67 | ===========================
68 | """
69 | @property
70 | def is_blocking(self):
71 | """
72 | 尾部是否满载堵塞,即所有车道入口均被小车堵塞,且处于停止状态
73 | 此函数可用于简化判断该道路能不能进入新的小车
74 | :return:
75 | """
76 | for i in self.car_arr[:, 0]:
77 | if not i or i.is_waiting:
78 | return False
79 | return True
80 |
81 | def get_block_car_at_the_entrance(self, max_dis):
82 | """
83 | Has MaxPos: can enter
84 | Else if:
85 | BlockCar is waiting: cant enter, delay or waiting
86 | BlockCar is stopped: cant enter, road is blocking, delay or marked to stop
87 | """
88 | blocked_car = None
89 | max_pos = None
90 | for lane_seq, lane_cars in enumerate(self.car_arr[:, :max_dis]):
91 | for row_seq, car in enumerate(lane_cars):
92 | if not car:
93 | max_pos = (lane_seq, row_seq) # 没车,标记为可以进入的道路点
94 | elif car.is_waiting:
95 | return car, None # 有车,正在等待吗,则标记为无法进入
96 | else:
97 | blocked_car = car # 有车,已经停止,继续遍历其他道路点
98 | break
99 | if max_pos:
100 | return blocked_car, max_pos # 如有有可以进入的道路点,则直接进入
101 | return blocked_car, max_pos # 最终结果,如果有车且停止,但没路,说明
102 |
103 |
104 | def get_first_waiting_car(self):
105 | if self.head_cars:
106 | return sorted(self.head_cars, key=lambda x: (-x.priority, -x.row, x.lane))[0]
107 |
108 |
109 |
110 |
111 | """
112 | ========================
113 | 神奇车库的装载
114 | ========================
115 | """
116 | def add_car_to_garage(self, car):
117 | """
118 | 装载要出发的小车到道路上,并且标记待完成小车数量加一
119 | """
120 |
121 | Data.total_loaded += 1
122 | if car.priority:
123 | self.prior_garage.put(car)
124 | Data.prior_loaded += 1
125 | else:
126 | self.normal_garage.put(car)
127 |
128 | if car.preset:
129 | Data.preset_loaded += 1
130 |
131 |
132 | """
133 | ===============================
134 | 以下两个函数分别对应于调度步骤一和步骤二里车队的标记
135 | ===============================
136 | """
137 |
138 | def mark_cars_on_this_lane_in_step_1(self, lane_seq):
139 | """
140 | 所有的车此时应该都是stop的状态,不存在waiting;所以要将car标记成stop或者wait
141 | """
142 | block_car = None
143 | HAS_WAITING_CAR = False
144 | for car in self.car_arr[lane_seq, ::-1]:
145 | if car:
146 | if not block_car:
147 | if car.will_exceed_this_road:
148 | car.wait()
149 | self.push_head_car(car)
150 |
151 | Data.to_schedule += 1
152 | HAS_WAITING_CAR = True
153 | else:
154 | car.move(row=car.max_row_on_this_road, step_seq=1, desc='Mark')
155 |
156 | elif car.row + car.max_v_on_this_road >= block_car.row:
157 | if block_car.is_waiting:
158 | car.wait(block_car)
159 |
160 | Data.to_schedule += 1
161 | HAS_WAITING_CAR = True
162 | else:
163 | car.move(row=block_car.row-1, block_dis=car.max_row_on_this_road-block_car.row+1, step_seq=1, desc='Mark')
164 |
165 | else:
166 | car.move(row=car.max_row_on_this_road, step_seq=1, desc='Mark')
167 |
168 | block_car = car
169 | return HAS_WAITING_CAR
170 |
171 | def move_cars_on_this_lane_in_step_2(self, lane_seq):
172 | """
173 | 所有的车此时最前面应该都是waiting的状态,所以要将最前面的车标记成stop或者wait状态,最后一辆车就是该车道是否发生改变的标记
174 | 该函数要配合car.move_to_next_road使用
175 | """
176 | block_car = None
177 | for car in self.car_arr[lane_seq, ::-1]:
178 | if car:
179 | if not car.is_waiting:
180 | block_car = car
181 | continue
182 |
183 | elif block_car is None:
184 | if car.will_exceed_this_road:
185 | car.wait()
186 | self.push_head_car(car)
187 | else:
188 | car.move(row=car.max_row_on_this_road, step_seq=2, desc='Follow')
189 | Data.to_schedule -= 1
190 |
191 | elif car.row + car.max_v_on_this_road >= block_car.row:
192 | if block_car.is_waiting:
193 | car.wait(block_car)
194 | else:
195 | car.move(row=block_car.row-1, block_dis=car.max_row_on_this_road-block_car.row+1, step_seq=2, desc='Follow')
196 | Data.to_schedule -= 1
197 | else:
198 | car.move(row=car.max_row_on_this_road, step_seq=2, desc='Follow')
199 | Data.to_schedule -= 1
200 |
201 | block_car = car
202 |
203 |
--------------------------------------------------------------------------------
/CodeCraft-2019/src/settings.py:
--------------------------------------------------------------------------------
1 | #-*-coding:utf-8-*-
2 | __author__ = 'MarkShawn'
3 |
4 | import logging
5 | import sys
6 |
7 |
8 | MAP_PATH = '..'
9 |
10 | """
11 | 复赛测试地图
12 | 2-map-training-1
13 | 2-map-training-2
14 |
15 | 小数据测试地图
16 | 2-training-training-1-answer
17 | 2-training-training-2-answer
18 | """
19 |
20 | # MAP_NAME = '2-training-training-1-answer'
21 | # MAP_NAME = '2-map-training-1'
22 | MAP_NAME = '2-map-exam-2'
23 | #
24 |
25 | ENABLE_EVALUATING_RESULTS_LOG = True
26 | ENABLE_EACH_ROUND_LOG = True if len(sys.argv) < 2 else False
27 | ENABLE_DEAD_LOCK_CHECK = True
28 |
29 | ENABLE_CORE_LOG = False # core[_judge]
30 | ENABLE_CAR_LOG = False # car
31 | ENABLE_EACH_CAR_POS_LOG = False # utils.scan_and_log_cars_each_time_round()
32 | ENABLE_CAR_ARRIVAL_TIME_FILE_WRITE = False
33 |
34 | # MAX_STD_LOAD = 0.15
35 | # MAX_PRIOR_TO_START = 300
36 |
37 | MAX_COVERAGE = 0.14 # 地图上最大车辆覆盖率,如果使用纯动态规划可达0.20,保险0.15,半动态能到0.10,纯静态0.05
38 | REFRESH_FREQUENCY = 3 # 必须大于1,每N时间片更新一次道路权重(包含优先路径和非优先路径),越短越耗性能
39 |
40 | MULTIPLIER_TO_FIRST_ROAD = 10 # 相对于最常使用道路的罚权倍数,场景:非优先车对于优先车的躲避
41 | MULTIPLIER_TO_TRAFFIC = 10 # 相对于当前交通流量的罚权倍数,场景:每N时间片
42 |
43 | PRIOR_FINISH_CUT = 0.99 # 优先小车完成多少比例时,给速度快的小车赋更短的路程
44 | SPEED_GROUP_CUT = 8 # 定义车速的分界点
45 |
46 | MAX_TO_START = 200 # 车库中最大的车辆保有数目,每次发车都要遍历车库内所有的车,因此这个数字越小性能越高,但也意味着最优车辆越稀缺,进而导致全地图车辆数目较少
47 |
48 | ARG_K_PRIOR = 1.5 # 优先车排车的对数参数,2为平缓下降解读,数值越大,前段时间排的车越多
49 | ARG_K_NON_PRIOR = 1.5 # ??? # 非优先车排车的对数参数,由于非优先车很多,一般取2及以下,避免早期大量拥挤
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | if len(sys.argv) == 6:
72 | MAP_PATH = '.'
73 | LOG_FILE_PATH = '../logs/CodeCraft-2019.log'
74 | CAR_PATH, ROAD_PATH, CROSS_PATH, PRESET_ANSWER_PATH, ANSWER_PATH = sys.argv[1:]
75 | MAP_NAME = CAR_PATH.split('/')[0].split('\\')[0]
76 |
77 | else:
78 | LOG_FILE_PATH = '../../logs/CodeCraft-2019.log'
79 | CAR_PATH, ROAD_PATH, CROSS_PATH, PRESET_ANSWER_PATH, ANSWER_PATH = \
80 | map(lambda x: '{}/{}/{}.txt'.format(MAP_PATH, MAP_NAME, x), ('car', 'road', 'cross', 'presetAnswer', 'answer'))
81 |
82 | logging.basicConfig(level=logging.DEBUG,
83 | filename=LOG_FILE_PATH,
84 | format='[%(asctime)s] %(levelname)s [%(funcName)s: %(filename)s, %(lineno)d] %(message)s',
85 | datefmt='%Y-%m-%d %H:%M:%S',
86 | filemode='a')
87 |
88 | logging.info('MAP: {}'.format(MAP_NAME))
--------------------------------------------------------------------------------
/CodeCraft-2019/src/test.py:
--------------------------------------------------------------------------------
1 | # #-*-coding:utf-8-*-
2 | # __author__ = 'MarkShawn'
3 | #
4 | #
5 |
6 | """
7 | 绘制发车分布情况
8 | """
9 | import matplotlib.pyplot as plt
10 | import seaborn as sns
11 |
12 | queue = self.car_queues[0, 0]
13 | qlist = []
14 | while not queue.empty():
15 | qlist.append(queue.get())
16 |
17 |
18 | tlist = [i.real_time for i in qlist]
19 | sns.distplot(tlist)
20 | plt.show()
21 |
22 |
23 |
24 |
25 | """
26 | 打印车库里队列信息
27 | """
28 | while True:
29 | queue = c.car_queues[1, 0]
30 | if not queue.empty():
31 | car = queue.get_nowait()
32 | print(car.real_time, car.speed, car.id)
33 | else:
34 | break
35 |
36 |
37 | """
38 | 读取并排序答案
39 | """
40 | import re
41 | def read_items_from_file(file):
42 | with open(file, 'r') as f:
43 | return [list(map(int, re.findall(r'-?\d+', i))) for i in f.readlines() if not i.startswith('#')]
44 | data_list = read_items_from_file('answer.txt')
45 | sorted_list = sorted(data_list, key=lambda x: (x[1], x[0]))
46 |
47 | data_list_2 = read_items_from_file('my_answer.txt')
48 | sorted_list_2 = sorted(data_list_2, key=lambda x: (x[1], x[0]))
49 |
50 | print(sorted_list == sorted_list_2)
51 |
52 |
53 |
54 |
55 | """
56 | 读取两个判别器的日志并对比
57 | """
58 |
59 | with open('log_car_core.log', 'r') as f1:
60 | with open('log_car_judge.log', 'r') as f2:
61 | seq = 0
62 | while True:
63 | seq += 1
64 | s1 = f1.readline()
65 | s2 = f2.readline()
66 | if s1 != s2:
67 | print(seq, s1, s2)
68 | break
69 |
70 |
71 | """
72 | 分析答案中是否存在环
73 | """
74 |
75 | from core_judge import *
76 |
77 | def check_ring(car):
78 | visited_nodes = []
79 | nodes_list = [road.to_cross_id for road in car.roads_to_go]
80 | HAS_RING = False
81 | for i in nodes_list:
82 | if i not in visited_nodes:
83 | visited_nodes.append(i)
84 | else:
85 | HAS_RING = True
86 | return HAS_RING
87 |
88 |
89 | if __name__ == '__main__':
90 | c = CoreJudge()
91 | c.init_data()
92 | c.read_answer_file()
93 |
94 | ring_cars = list(filter(check_ring, c.car_dict.values()))
95 |
96 | print('Finished')
--------------------------------------------------------------------------------
/CodeCraft-2019/src/utils.py:
--------------------------------------------------------------------------------
1 | #-*-coding:utf-8-*-
2 | __author__ = 'MarkShawn'
3 |
4 | import settings
5 | from settings import *
6 | from data import Data
7 |
8 | from scipy.sparse.csgraph import shortest_path
9 | import numpy as np
10 | import logging
11 | import time
12 | import sys
13 | import re
14 |
15 |
16 | def clear_file(file_path):
17 | with open(file_path, 'w') as f:
18 | f.write('#\n')
19 |
20 | def read_items_from_file(file):
21 | with open(file, 'r') as f:
22 | return [list(map(int, re.findall(r'-?\d+', i))) for i in f.readlines() if not i.startswith('#')]
23 |
24 | def write_arrival_times(c, car_arrival_time_file):
25 | sorted_cars = sorted(c.car_dict.values(), key=lambda x: (x.finished_time, x.id))
26 | with open(car_arrival_time_file, 'w') as f:
27 | for car in sorted_cars:
28 | f.write('({}, {})\n'.format(car.id, car.finished_time))
29 |
30 | def get_path_arr(dis_arr):
31 | """
32 | :param dis_arr: 输入距离矩阵
33 | :return: 返回路径列表(每条道路都时向量形式)
34 | """
35 |
36 | def convert_path_arr_to_road_vid_path_arr(path_arr):
37 | path_list_arr = np.empty(path_arr.shape, dtype=object)
38 | for row_seq, row in enumerate(path_arr):
39 | for col_seq, cell in enumerate(row):
40 | path_list = [col_seq]
41 | while True:
42 | path_node = row[path_list[0]]
43 | if path_node >= 0:
44 | path_list.insert(0, path_node)
45 | else:
46 | break
47 | path_list_arr[row_seq, col_seq] = [(i, j) for i, j in zip(path_list[:-1], path_list[1:])]
48 | return path_list_arr
49 |
50 | dis_arr, path_node_arr = shortest_path(dis_arr, return_predecessors=True,)
51 | path_arr = convert_path_arr_to_road_vid_path_arr(path_node_arr)
52 |
53 |
54 | return path_arr
55 |
56 |
57 | def dead_lock_check(func):
58 | def wrapper(*args, **kwargs):
59 | """
60 | 输入调度步骤二每个周期开始时的累计小车移动数量,与结束时的累计小车移动数量作比较
61 | 如果相同,且确实还有在等待的小车,则代表这个周期内没有移动小车,即发生了死锁
62 | """
63 |
64 | def yield_next_first_waiting_car(car):
65 | waiting_car = car.waiting_car
66 | waiting_road = waiting_car.this_road
67 | next_waiting_car = waiting_road.get_first_waiting_car()
68 | yield waiting_car
69 | yield next_waiting_car
70 | # waiting car == next_waiting_car 的情况是指冲突的时候
71 | if next_waiting_car == waiting_car or next_waiting_car not in visited_cars_set:
72 | visited_cars_set.add(next_waiting_car)
73 | yield from yield_next_first_waiting_car(next_waiting_car)
74 | else:
75 | return
76 |
77 | to_schedule = Data.to_schedule
78 | visited_cars_set = set()
79 | a = func(*args, **kwargs)
80 |
81 | if ENABLE_DEAD_LOCK_CHECK:
82 | if Data.to_schedule != 0 and Data.to_schedule==to_schedule:
83 | road = next(iter(Data.roads_to_schedule_in_step_2))
84 | start_car = road.get_first_waiting_car()
85 |
86 | waiting_chain = list(map(lambda x: (x.id, x.priority, x.current_pos, x.this_road.vid)
87 | ,[start_car] + [i for i in yield_next_first_waiting_car(start_car)]))
88 |
89 | while waiting_chain[0] != waiting_chain[-1]:
90 | waiting_chain.pop(0)
91 |
92 |
93 | from pprint import pformat
94 | logging.error('\n{}'.format(pformat(waiting_chain, indent=4)))
95 | logging.error('Dead Lock!')
96 |
97 | raise Exception('Dead Lock!')
98 | return a
99 | return wrapper
100 |
101 |
102 | def log_each_step(func):
103 | def wrapper(*args, **kwargs):
104 | start_time = time.time()
105 | data_old = Data.__dict__.copy()
106 | a = func(*args, **kwargs)
107 | if ENABLE_EACH_ROUND_LOG:
108 | data_new = Data.__dict__
109 | data_changed = {'TimeUsed': round(time.time() - start_time, 3)}
110 | data_changed.update(dict((i, data_new[i]-data_old[i]) for i, j in data_old.items() if isinstance(j, (int, float)) and data_new[i] != data_old[i]))
111 | logging.info(data_changed)
112 | return a
113 | return wrapper
114 |
115 |
116 |
117 | def log_each_round(func):
118 | def wrapper(*args, **kwargs):
119 | a = func(*args, **kwargs)
120 | if ENABLE_EACH_ROUND_LOG:
121 | logging.info('\nTimeRound: {}, CarsOnMap: {}, PriorOnMap: {}, PresetOnMap: {}, NormalOnMap: {}\n'
122 | 'TotalStarted: {}, PriorToStart: {}, PresetToStart: {}, TotalToStart: {}, PriorStarted: {}, PresetStarted: {}\n'
123 | 'Coverage: {:.2f}%, PriorFinishedRatio: {:.2f}%, PresetFinishedRatio: {:.2f}%, TotalFinishedRatio: {:.2f}%\n'
124 | 'TimeRun: {:.3f}s, DueTime: {:.3f}s\n'.format(
125 | Data.time_round, Data.cars_on_map, Data.prior_cars_on_map, Data.preset_cars_on_map, Data.normal_cars_on_map,
126 | Data.total_started, Data.prior_to_start, Data.preset_to_start, Data.total_to_start, Data.prior_started, Data.preset_started,
127 | Data.cars_coverage * 100, Data.prior_finished_ratio*100, Data.preset_finished_ratio*100, Data.total_finished_ratio*100,
128 | Data.get_run_time(), Data.get_run_time()*Data.CARS_CNT / (Data.total_finished + 1) ))
129 | # logging.info({'StdEachRoad': np.std(Data.road_use_arr[np.nonzero(Data.road_use_arr)]).round(2)})
130 | return a
131 | return wrapper
132 |
133 |
134 | def write_answer(c, answer_file, including_preset=False):
135 | with open(answer_file, 'w') as f:
136 | f.write('#\n')
137 | for car in c.car_dict.values():
138 | if (including_preset and car.preset) or not including_preset:
139 | f.write('({}, {}, {})\n'.format(car.id, int(car.real_time if car.preset else car.start_time), str([i.id for i in car.roads_passed])[1:-1]))
140 |
141 |
142 |
143 | def scan_and_log_cars_each_time_round(c, logger):
144 | if ENABLE_EACH_CAR_POS_LOG:
145 | for road in c.road_dict.values():
146 | road_cars = [car.current_pos for car in road.car_arr.flatten() if car]
147 | if road_cars:
148 | logger.info({'TimeRound': Data.time_round, 'RoadId': road.id, 'RoadCars': road_cars})
149 |
150 |
151 |
152 |
153 | """
154 | ==================================
155 | 评分函数的打印
156 | ==================================
157 | """
158 |
159 | def evaluate_results(c, succeed=True):
160 | """
161 | 本函数用于生成最后的输出结果,因此程序是基于模拟的动态判别器,所以结果具有较高的准确度,但还没有完全准确(或者说其实还相差不少)
162 | :return:
163 | """
164 | logger = logging.getLogger('EVALUATE_RESULTS')
165 | fh = logging.FileHandler(filename='{}/{}/result.txt'.format(MAP_PATH, MAP_NAME), mode='a')
166 | logger.addHandler(fh)
167 |
168 | info_1 = {
169 | 'MAX_COVERAGE': settings.MAX_COVERAGE,
170 | 'MAX_TO_START': settings.MAX_TO_START,
171 | 'K_PRIOR': settings.ARG_K_PRIOR,
172 | 'K_NON_PRIOR': settings.ARG_K_NON_PRIOR,
173 | 'REFRESH_FREQUENCY': settings.REFRESH_FREQUENCY,
174 | 'M1': settings.MULTIPLIER_TO_FIRST_ROAD,
175 | 'M2': settings.MULTIPLIER_TO_TRAFFIC,
176 | 'MapName': MAP_NAME,
177 | 'TimeUsed': time.time()-c.start_time,
178 | }
179 |
180 | info_2 = {
181 | 'T_Prior': c.get_prior_time_period(),
182 | 'T_Total': c.get_all_time_period(),
183 | 'T_Final': c.get_final_time_round(),
184 | 'S_Prior': c.get_prior_scheduled_cnt(),
185 | 'S_Total': c.get_all_scheduled_cnt(),
186 | 'S_Final': c.get_final_schedule_time(),
187 | 'Factor_A': c.get_factor_a(),
188 | 'Factor_B': c.get_factor_b(),
189 | }
190 |
191 | logger.info('\n{}'.format('='* 20))
192 | logger.info(info_1)
193 | logger.info(info_2)
194 | if not succeed:
195 | logger.info('===== FAILED !!! ======')
196 | else:
197 | logger.info('===== Succeeded!!! ======')
198 |
199 |
--------------------------------------------------------------------------------
/CodeCraft_tar.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | SCRIPT=$(readlink -f "$0")
4 | BASEDIR=$(dirname "$SCRIPT")
5 | cd $BASEDIR
6 |
7 | if [ ! -d CodeCraft-2019 ]
8 | then
9 | echo "ERROR: $BASEDIR is not a valid directory of SDK_python for CodeCraft-2019."
10 | echo " Please run this script in a regular directory of SDK_python."
11 | exit -1
12 | fi
13 |
14 | rm -f CodeCraft_code.tar.gz
15 | tar -zcPf CodeCraft_code.tar.gz *
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CodeCraft2019复赛南川版智能发车系统使用说明
2 |
3 | ## 流程控制
4 | 
5 |
6 | ## 两种模式
7 | - 正常模式,即使用自定义的流程与算法生成答案,启动路径CodeCraft-2019.py
8 | - 模拟模式,即模拟官方判别器,该模式将会读取对应地图里的answer.txt文件,启动路径CodeCraft-2019_judge.py
9 |
10 | ## 目录结构
11 | - base.py 提供了两种启动模式,主要为了解决在IDE中使用命令行启动较为繁琐的问题,并针对各自的main函数适配了log日志文件的位置
12 | - core.py 定义了主类Core,它继承base.Base类,在Core中只定义一些必要的初始化和核心的算法函数,因此要修改模型只需要在Core中修改即可,其他部分的代码可以当做模块使用无需更改
13 | - core_judge.py 定义了主类CoreJudge类,它也集成base.Base类,用于运行官方判别器
14 | - car.py, road.py, cross.py 分别定义了Car, Raod, Cross 三种对象,实现小车与道路、路口、Core的联动
15 | - data.py 定义了Data类,为收集程序运行过程中每个时间片的信息而生,配合Core使用,Core类中亦有定义一个transfer函数将Core的部分数据同步给了Data
16 | - utils.py 提供了一些通用的函数,比如读取文件、格式化文件、生成最短路径、生成答案等
17 | - settings.py 配置你要使用的一些信息,比如选择地图、是否启动模拟模式,以及修改一些暴露的参数等
18 | - CodeCraft-2019.py 启动主程序文件,直接运行即可,也可使用官方的命令行启动模式,已在base.py中定义好两种接口
19 | - CodeCraft-2019_judge.py 启动模拟模式
20 |
21 |
22 | ## 一些属性
23 | ### 小车的属性
24 | - 速度
25 | - 出发地和目的地,引申至发车时间
26 |
27 | ## 道路的属性
28 | - 长度
29 | - 宽度
30 | - 限速
31 | - 出发地和目的地
32 |
33 |
34 | ## 重要的调度环节
35 | - 排车,位于core.quick_sort_cars(快排)和core.sort_cars(严排)
36 | - 装车,位于core.load_cars
37 | - 发车,位于core.depart_cars
38 |
39 | > 其中,排车、装车、发车环节在模拟模式中都已经固定好,无法调整,也请不要修改任何```if self.ENABLE_JUDGEMENT:```语句下的内容。
40 | 而在正常模式中,主要修改排车、装车、发车部分的算法。
41 |
42 | ### 排车
43 |
44 | ### 装车
45 |
46 | 装车,在本系统中,指将(系统设定或主动调节后的)实际出发时间小于或等于当前时间片车装载到车库中,
47 | 预置车和非预置车有不同的装车方案,因为预置车无法主动顺延出发时间,因此我们的系统中每一次装车是分两步的,
48 | - 第一步:将符合规定的预置车装载到车库内,这里,唯一的判定就是系统预设的实际出发时间,而且必须装。
49 | - 第二步,将符合规定的非预置车装载到车库内,这里,有很多自定义的空间。
50 | 在我们的系统中,我们暂时选择了当车库内待出发的车辆数达到一定阈值时,就不再装非预置车。
51 | 换言之,我们对排序步骤里可能已经主动延迟的小车在装车环节里进一步延迟
52 |
53 | 这里,有几点值得关注
54 | - 排车是在系统运行之初,就初始化的,也就是说只要运行一次,但装车是每个时间片都要装一次的,以保证实时、轻量
55 | - 在每个时间片里,将会有两次装车
56 | - 第一次是在标定完道路上小车之后,此时,我们只装优先车辆,因为接下来只发优先车辆,我们没有必要装普通车
57 | - 第二次是在循环调度完所有道路上的小车后(或者继调度完当前时间片最后一次发优先车后,这个更好),
58 | 此时,我们只装非优先小车,因为接下来只发非优先车
59 | - 以上的装车顺序十分重要,假设你在循环调度阶段也装了一次优先车,并在循环调度阶段使新装的小车上了路,
60 | 自己的调度器可能正常运行,但是生成的答案里面,由于在循环调度阶段和在标定阶段装的小车、发的小车是同一时间的,
61 | 因此就可能发生在官方判定器里其实是循环调度阶段装的车先上路的情况,与本地系统实时运行的结果不一致。
62 | 而非优先小车其实在发非优先小车之前的任意阶段皆可,为了保证装车时的信息是最新的,我们直接放在非优先车上路之前。
63 |
64 | ### 发车
65 |
66 | 发车,在本系统中,是指使装载好存放在车库内的小车根据官方判定器的优先对列顺序遍历判断能否上路。
67 | 因为使用了优先队列,因此这里的发车顺序基本不会错乱,换言之,对于装车环节里装的任意一辆车,发车时都不会错乱。
68 |
69 | ### 时间线
70 | 1. 标定道路上的小车(调度步骤一)
71 | 2. 装优先车
72 | 3. 发优先车
73 | 4. 循环调度道路上正在等待的小车(调度步骤二)(中途一旦有车过路口,对该路口发优先车)
74 | 5. 发优先车
75 | 6. 装非优先车
76 | 7. 发非优先车
77 |
78 |
79 | # 基于交通流量动态不确定下的智能排车、装车、发车方案全解析V2.0
80 |
81 | ## 判别器实现的要领、步骤与注意事项
82 |
83 | ## 为什么本地判别器判别结果与小地图数据不一致
84 | ### 系统设计问题
85 | ### 评分精度问题
86 |
87 | ## 为什么本地判别器与小地图数据一致,但与上传到服务器的程序模拟结果不一致
88 | ### 发车排序问题
89 | ### 答案保存问题
90 |
91 | ## 快速排车与全序排车的比较及排车方案的指标选取与优先考虑
92 |
93 | ## 静态装车与动态装车的性能与需求及动态路权调整的开销与收益权衡
94 |
95 | ## *智能算法在优化发车方案中的价值与应用
96 |
97 | ## 应对死锁的解决方案参考:*数学推导、回滚机制、数据统计及可视化
98 |
99 | ## 基于论坛单步调度器的一些可视化方案思考
100 |
101 | > 作者:南川,江山赛区SpiderMen队。
102 |
103 |
104 |
--------------------------------------------------------------------------------