├── .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 | 15 | 16 | 19 | -------------------------------------------------------------------------------- /.idea/libraries/R_User_Library.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/other.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 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 | 70 | 71 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 377 | 378 | 379 | 380 | 381 | 398 | 399 | 400 | 417 | 418 | 419 | 436 | 437 | 438 | 455 | 456 | 457 | 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 | 502 | 503 | 1555241344677 504 | 509 | 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 | 557 | 558 | 560 | 561 | 562 | 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 | 576 | 577 | file://$PROJECT_DIR$/CodeCraft-2019/src/JudgeMent.py 578 | 95 579 | 581 | 582 | 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 | ![](CodeCraft-2019/resource/CodeCraft2019RemFlowControl.png) 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 | --------------------------------------------------------------------------------