Commit 3f193d09 by chamberone

feat: 提交派工算法模块

1 parent 545f443f
Showing with 2024 additions and 11 deletions
......@@ -44,15 +44,6 @@
</properties>
<modules>
<!--
<module>project-storage</module>
<module>project-account</module>
<module>project-praise-provider</module>
<module>project-praise-consumer</module>
<module>project-common</module>
<module>project-frontend</module> -->
<module>project-order</module>
<module>project-gateway</module>
<module>project-interface</module>
......@@ -60,6 +51,7 @@
<module>project-gis</module>
<module>project-geometry</module>
<module>project-district</module>
<module>project-dispatch</module>
</modules>
<!-- 用来统一管理jar包依赖的版本,但是不会引入依赖,只有当在某个模块中显示引入某个依赖的时候才会真正的引入jar包 -->
......
106330400
106632743
106632993
106704506
106729637
106732179
106737923
106758769
106765790
106790276
106798348
106845767
106848936
106854117
106855369
106865528
106867266
106879505
106882180
106893582
106228451
106660472
106684680
106703025
106762173
106802404
106820041
106820735
106824266
106828070
106833813
106835282
106853363
106856986
106861402
106863823
106870737
106870765
106871040
106872591
106872658
106875426
106890613
106893208
106279591
106704564
106729640
106732181
106738036
106758988
106765761
106818668
106823211
106824512
106836405
106841840
106851428
106852112
106853178
106854359
106855674
106856390
106859149
106859862
106860870
106862449
106865892
106866730
106868422
106870053
106873767
106873992
106876557
106876682
106881724
106883231
106883391
106888947
106889389
106893581
106776742
106820178
106826035
106835053
106839639
106840295
106848186
106869743
106871570
106871918
106872059
106874727
106879292
106881156
106884799
106886425
106890832
106576847
106704602
106729639
106732180
106738035
106853161
106855710
106856389
106859148
106860869
106862447
106866729
106868053
106888946
106854169
106870713
106891293
106549827
106765447
106781641
106793056
106803268
106818600
106822716
106829323
106840366
106847687
106866881
106870492
106871200
106872822
106878500
106880124
106880969
106892125
106763043
106801344
106806874
106824742
106858813
106870383
106632622
106744960
106809648
106862554
106649991
106753590
106845946
106859379
106632543
106632849
106665842
106730931
106744959
106809662
106813589
106862553
106871868
106879520
106694001
106828628
106834398
106886055
106665727
106665740
106704534
106809681
106862552
106884214
106884485
106885700
106887147
106754377
106775190
106849556
106867319
106888973
106889146
106228451,"120.721813,31.303003"
106279591,"120.982906,31.440902"
106330400,"120.982906,31.440902"
106549827,"121.144142,31.422735"
106576847,"121.106111,31.480717"
106632543,"120.726916,31.592422"
106632622,"120.726916,31.592422"
106632743,"120.726916,31.592422"
106632849,"120.726916,31.592422"
106632993,"120.868246,31.041383"
106649991,"120.632112,31.286827"
106660472,"120.611127,31.250817"
106665727,"120.64402,31.77468"
106665740,"120.64402,31.77468"
106665842,"120.64402,31.77468"
106684680,"120.626474,31.224566"
106694001,"120.632112,31.286827"
106703025,"120.530752,31.281024"
106704506,"120.625144,31.257837"
106704534,"120.625144,31.257837"
106704564,"120.625144,31.257837"
106704602,"120.625144,31.257837"
106729637,"120.959821,31.402083"
106729639,"120.959821,31.402083"
106729640,"120.959821,31.402083"
106730931,"120.639926,31.306425"
106732179,"121.077572,31.563578"
106732180,"121.077572,31.563578"
106732181,"121.077572,31.563578"
106737923,"120.622214,31.333417"
106738035,"120.622214,31.333417"
106738036,"120.622214,31.333417"
106744959,"121.077777,31.560303"
106744960,"121.077777,31.560303"
106753590,"120.597212,31.294007"
106754377,"120.639734,31.32923"
106758769,"120.731802,31.300809"
106758988,"120.731802,31.300809"
106762173,"120.606634,31.292016"
106763043,"120.687676,31.443469"
106765447,"120.616316,31.402105"
106765761,"120.847507,31.42479"
106765790,"120.847507,31.42479"
106775190,"120.612111,31.189908"
106776742,"120.70851,31.248646"
106781641,"120.606019,31.398212"
106790276,"120.606255,31.268432"
106793056,"120.747643,31.310646"
106798348,"120.959821,31.402083"
106801344,"120.69381,31.304455"
106802404,"120.654614,31.098804"
106803268,"120.607062,31.398126"
106806874,"120.650618,31.176803"
106809648,"120.956653,31.459789"
106809662,"120.956653,31.459789"
106809681,"120.956653,31.459789"
106813589,"120.844551,31.013903"
106818600,"121.144926,31.461553"
106818668,"120.493618,31.24607"
106820041,"120.719909,31.382979"
106820178,"120.678376,31.149701"
106820735,"120.58446,31.322863"
106822716,"120.705113,31.257879"
106823211,"120.651719,31.278747"
106824266,"120.697424,31.344814"
106824512,"120.754292,31.337413"
106824742,"120.77035,31.312694"
106826035,"120.49468,31.996066"
106828070,"120.596177,31.283586"
106828628,"120.77099,31.682885"
106829323,"120.673489,31.297058"
106833813,"120.523634,31.858481"
106834398,"120.761397,31.311754"
106835053,"120.600039,31.295101"
106835282,"121.039728,31.400563"
106836405,"120.665415,31.32013"
106839639,"120.883187,31.287842"
106840295,"120.526884,31.373801"
106840366,"120.649177,31.303238"
106841840,"120.615365,31.186788"
106845767,"120.687214,31.253326"
106845946,"120.747488,31.340815"
106847687,"120.530373,31.853617"
106848186,"121.135103,31.441649"
106848936,"120.679366,31.287809"
106849556,"120.605103,31.296943"
106851428,"120.98225,31.417492"
106852112,"120.654228,31.337012"
106853161,"120.632811,31.173964"
106853178,"120.632811,31.173964"
106853363,"121.104428,31.453363"
106854117,"120.664649,31.316367"
106854169,"120.634382,31.374593"
106854359,"120.84248,31.284855"
106855369,"120.616312,31.385716"
106855674,"120.743073,31.677162"
106855710,"120.743073,31.677162"
106856389,"120.655769,31.393115"
106856390,"120.655769,31.393115"
106856986,"120.745434,31.304664"
106858813,"120.769821,31.342065"
106859148,"120.724624,31.487646"
106859149,"120.724624,31.487646"
106859379,"120.756575,31.336275"
106859862,"120.549426,31.376686"
106860869,"120.748602,31.317585"
106860870,"120.748602,31.317585"
106861402,"120.785598,31.097726"
106862447,"120.777722,31.636159"
106862449,"120.777722,31.636159"
106862552,"120.685176,31.471252"
106862553,"120.685176,31.471252"
106862554,"120.685176,31.471252"
106863823,"120.966152,31.389332"
106865528,"120.623197,31.470323"
106865892,"120.664487,31.282887"
106866729,"120.606376,31.391923"
106866730,"120.606376,31.391923"
106866881,"120.629969,31.270552"
106867266,"120.597917,31.348755"
106867319,"120.696831,31.275636"
106868053,"120.606634,31.292016"
106868422,"120.702768,31.333509"
106869743,"120.938132,31.396139"
106870053,"120.732045,31.30597"
106870383,"120.624333,31.361689"
106870492,"120.650458,31.225728"
106870713,"120.633518,31.153463"
106870737,"120.612394,31.194301"
106870765,"120.451477,31.938889"
106871040,"120.686309,31.327041"
106871200,"120.59747,31.285217"
106871570,"120.634245,31.188141"
106871868,"120.686193,31.327165"
106871918,"120.64205,31.296388"
106872059,"120.589301,31.3104"
106872591,"120.591992,31.292224"
106872658,"120.768159,31.337805"
106872822,"120.616482,31.402948"
106873767,"120.964531,31.349257"
106873992,"120.574297,31.321478"
106874727,"120.748439,31.684466"
106875426,"120.64272,31.277918"
106876557,"120.721418,31.487407"
106876682,"121.088316,31.5656"
106878500,"120.606019,31.398212"
106879292,"120.715751,31.29945"
106879505,"120.765083,31.697774"
106879520,"120.614752,31.309742"
106880124,"120.615837,31.316617"
106880969,"120.677186,31.149534"
106881156,"120.566187,31.855965"
106881724,"120.601868,31.148427"
106882180,"120.664487,31.282887"
106883231,"121.120276,31.465135"
106883391,"120.861145,31.080919"
106884214,"120.620985,31.129614"
106884485,"120.485939,31.334295"
106884799,"120.605229,31.394392"
106885700,"120.727943,31.254621"
106886055,"120.598933,31.297181"
106886425,"120.548647,31.842596"
106887147,"120.790707,31.683097"
106888946,"120.628533,31.368943"
106888947,"120.628533,31.368943"
106888973,"120.898629,31.749332"
106889146,"120.60652,31.404533"
106889389,"120.680358,31.325299"
106890613,"120.526677,31.863775"
106890832,"120.604399,31.349966"
106891293,"120.636053,31.289328"
106892125,"120.587065,31.283529"
106893208,"120.748525,31.324368"
106893581,"121.107535,31.479541"
106893582,"121.107535,31.479541"
106228451,40
106279591,30
106330400,30
106549827,40
106576847,30
106632543,40
106632622,60
106632743,30
106632849,40
106632993,30
106649991,60
106660472,40
106665727,40
106665740,40
106665842,40
106684680,40
106694001,40
106703025,40
106704506,30
106704534,40
106704564,30
106704602,30
106729637,30
106729639,30
106729640,30
106730931,40
106732179,30
106732180,30
106732181,30
106737923,30
106738035,30
106738036,30
106744959,40
106744960,60
106753590,60
106754377,40
106758769,30
106758988,30
106762173,40
106763043,40
106765447,40
106765761,30
106765790,30
106775190,40
106776742,40
106781641,40
106790276,30
106793056,40
106798348,30
106801344,40
106802404,40
106803268,40
106806874,40
106809648,60
106809662,40
106809681,40
106813589,40
106818600,40
106818668,30
106820041,40
106820178,40
106820735,40
106822716,40
106823211,30
106824266,40
106824512,30
106824742,40
106826035,40
106828070,40
106828628,40
106829323,40
106833813,40
106834398,40
106835053,40
106835282,40
106836405,30
106839639,40
106840295,40
106840366,40
106841840,30
106845767,30
106845946,60
106847687,40
106848186,40
106848936,30
106849556,40
106851428,30
106852112,30
106853161,30
106853178,30
106853363,40
106854117,30
106854169,40
106854359,30
106855369,30
106855674,30
106855710,30
106856389,30
106856390,30
106856986,40
106858813,40
106859148,30
106859149,30
106859379,60
106859862,30
106860869,30
106860870,30
106861402,40
106862447,30
106862449,30
106862552,40
106862553,40
106862554,60
106863823,40
106865528,30
106865892,30
106866729,30
106866730,30
106866881,40
106867266,30
106867319,40
106868053,30
106868422,30
106869743,40
106870053,30
106870383,40
106870492,40
106870713,40
106870737,40
106870765,40
106871040,40
106871200,40
106871570,40
106871868,40
106871918,40
106872059,40
106872591,40
106872658,40
106872822,40
106873767,30
106873992,30
106874727,40
106875426,40
106876557,30
106876682,30
106878500,40
106879292,40
106879505,30
106879520,40
106880124,40
106880969,40
106881156,40
106881724,30
106882180,30
106883231,30
106883391,30
106884214,40
106884485,40
106884799,40
106885700,40
106886055,40
106886425,40
106887147,40
106888946,30
106888947,30
106888973,40
106889146,40
106889389,30
106890613,40
106890832,40
106891293,40
106892125,40
106893208,40
106893581,30
106893582,30
106228451,博世/西门子冰箱修理
106279591,博世/西门子洗衣机安装
106330400,博世/西门子冰箱安装
106549827,博世/西门子洗碗机安装
106576847,博世/西门子烘干机安装
106632543,博世/西门子灶具安装
106632622,博世/西门子烟机安装
106632743,博世/西门子冰箱安装
106632849,博世/西门子灶具安装
106632993,博世/西门子冰箱安装
106649991,博世/西门子烟机修理
106660472,博世/西门子冰箱修理
106665727,博世/西门子蒸烤箱微波炉安装
106665740,博世/西门子蒸烤箱微波炉安装
106665842,博世/西门子灶具安装
106684680,博世/西门子冰箱修理
106694001,博世/西门子灶具修理
106703025,博世/西门子冰箱修理
106704506,博世/西门子冰箱安装
106704534,博世/西门子蒸烤箱微波炉安装
106704564,博世/西门子洗衣机安装
106704602,博世/西门子烘干机安装
106729637,博世/西门子冰箱安装
106729639,博世/西门子烘干机安装
106729640,博世/西门子洗衣机安装
106730931,博世/西门子灶具安装
106732179,博世/西门子冰箱安装
106732180,博世/西门子烘干机安装
106732181,博世/西门子洗衣机安装
106737923,博世/西门子冰箱安装
106738035,博世/西门子烘干机安装
106738036,博世/西门子洗衣机安装
106744959,博世/西门子灶具安装
106744960,博世/西门子烟机安装
106753590,博世/西门子烟机修理
106754377,博世/西门子蒸烤箱微波炉修理
106758769,博世/西门子冰箱安装
106758988,博世/西门子洗衣机安装
106762173,博世/西门子冰箱修理
106763043,博世/西门子洗碗机修理
106765447,博世/西门子洗碗机安装
106765761,博世/西门子洗衣机安装
106765790,博世/西门子冰箱安装
106775190,博世/西门子蒸烤箱微波炉修理
106776742,博世/西门子洗衣机修理
106781641,博世/西门子洗碗机安装
106790276,博世/西门子冰箱安装
106793056,博世/西门子洗碗机安装
106798348,博世/西门子冰箱安装
106801344,博世/西门子洗碗机修理
106802404,博世/西门子冰箱修理
106803268,博世/西门子洗碗机安装
106806874,博世/西门子洗碗机修理
106809648,博世/西门子烟机安装
106809662,博世/西门子灶具安装
106809681,博世/西门子蒸烤箱微波炉安装
106813589,博世/西门子灶具安装
106818600,博世/西门子洗碗机安装
106818668,博世/西门子洗衣机安装
106820041,博世/西门子冰箱修理
106820178,博世/西门子洗衣机修理
106820735,博世/西门子冰箱修理
106822716,博世/西门子洗碗机安装
106823211,博世/西门子洗衣机安装
106824266,博世/西门子冰箱修理
106824512,博世/西门子洗衣机安装
106824742,博世/西门子洗碗机修理
106826035,博世/西门子洗衣机修理
106828070,博世/西门子冰箱修理
106828628,博世/西门子灶具修理
106829323,博世/西门子洗碗机安装
106833813,博世/西门子冰箱修理
106834398,博世/西门子灶具修理
106835053,博世/西门子洗衣机修理
106835282,博世/西门子冰箱修理
106836405,博世/西门子洗衣机安装
106839639,博世/西门子洗衣机修理
106840295,博世/西门子洗衣机修理
106840366,博世/西门子洗碗机安装
106841840,博世/西门子洗衣机安装
106845767,博世/西门子冰箱安装
106845946,博世/西门子烟机修理
106847687,博世/西门子洗碗机安装
106848186,博世/西门子洗衣机修理
106848936,博世/西门子冰箱安装
106849556,博世/西门子蒸烤箱微波炉修理
106851428,博世/西门子洗衣机安装
106852112,博世/西门子洗衣机安装
106853161,博世/西门子烘干机安装
106853178,博世/西门子洗衣机安装
106853363,博世/西门子冰箱修理
106854117,博世/西门子冰箱安装
106854169,博世/西门子烘干机修理
106854359,博世/西门子洗衣机安装
106855369,博世/西门子冰箱安装
106855674,博世/西门子洗衣机安装
106855710,博世/西门子烘干机安装
106856389,博世/西门子烘干机安装
106856390,博世/西门子洗衣机安装
106856986,博世/西门子冰箱修理
106858813,博世/西门子洗碗机修理
106859148,博世/西门子烘干机安装
106859149,博世/西门子洗衣机安装
106859379,博世/西门子烟机修理
106859862,博世/西门子洗衣机安装
106860869,博世/西门子烘干机安装
106860870,博世/西门子洗衣机安装
106861402,博世/西门子冰箱修理
106862447,博世/西门子烘干机安装
106862449,博世/西门子洗衣机安装
106862552,博世/西门子蒸烤箱微波炉安装
106862553,博世/西门子灶具安装
106862554,博世/西门子烟机安装
106863823,博世/西门子冰箱修理
106865528,博世/西门子冰箱安装
106865892,博世/西门子洗衣机安装
106866729,博世/西门子烘干机安装
106866730,博世/西门子洗衣机安装
106866881,博世/西门子洗碗机安装
106867266,博世/西门子冰箱安装
106867319,博世/西门子蒸烤箱微波炉修理
106868053,博世/西门子烘干机安装
106868422,博世/西门子洗衣机安装
106869743,博世/西门子洗衣机修理
106870053,博世/西门子洗衣机安装
106870383,博世/西门子洗碗机修理
106870492,博世/西门子洗碗机安装
106870713,博世/西门子烘干机修理
106870737,博世/西门子冰箱修理
106870765,博世/西门子冰箱修理
106871040,博世/西门子冰箱修理
106871200,博世/西门子洗碗机安装
106871570,博世/西门子洗衣机修理
106871868,博世/西门子灶具安装
106871918,博世/西门子洗衣机修理
106872059,博世/西门子洗衣机修理
106872591,博世/西门子冰箱修理
106872658,博世/西门子冰箱修理
106872822,博世/西门子洗碗机安装
106873767,博世/西门子洗衣机安装
106873992,博世/西门子洗衣机安装
106874727,博世/西门子洗衣机修理
106875426,博世/西门子冰箱修理
106876557,博世/西门子洗衣机安装
106876682,博世/西门子洗衣机安装
106878500,博世/西门子洗碗机安装
106879292,博世/西门子洗衣机修理
106879505,博世/西门子冰箱安装
106879520,博世/西门子灶具安装
106880124,博世/西门子洗碗机安装
106880969,博世/西门子洗碗机安装
106881156,博世/西门子洗衣机修理
106881724,博世/西门子洗衣机安装
106882180,博世/西门子冰箱安装
106883231,博世/西门子洗衣机安装
106883391,博世/西门子洗衣机安装
106884214,博世/西门子蒸烤箱微波炉安装
106884485,博世/西门子蒸烤箱微波炉安装
106884799,博世/西门子洗衣机修理
106885700,博世/西门子蒸烤箱微波炉安装
106886055,博世/西门子灶具修理
106886425,博世/西门子洗衣机修理
106887147,博世/西门子蒸烤箱微波炉安装
106888946,博世/西门子烘干机安装
106888947,博世/西门子洗衣机安装
106888973,博世/西门子蒸烤箱微波炉修理
106889146,博世/西门子蒸烤箱微波炉修理
106889389,博世/西门子洗衣机安装
106890613,博世/西门子冰箱修理
106890832,博世/西门子洗衣机修理
106891293,博世/西门子烘干机修理
106892125,博世/西门子洗碗机安装
106893208,博世/西门子冰箱修理
106893581,博世/西门子洗衣机安装
106893582,博世/西门子冰箱安装
106228451,0,600
106279591,0,600
106330400,0,600
106549827,0,240
106576847,0,600
106632543,0,120
106632622,0,600
106632743,240,600
106632849,0,600
106632993,0,600
106649991,0,120
106660472,0,240
106665727,0,600
106665740,0,600
106665842,0,600
106684680,0,240
106694001,120,240
106703025,0,240
106704506,0,240
106704534,0,600
106704564,0,600
106704602,0,240
106729637,120,240
106729639,0,600
106729640,0,600
106730931,0,600
106732179,0,600
106732180,0,600
106732181,0,600
106737923,360,480
106738035,0,600
106738036,0,240
106744959,0,600
106744960,0,600
106753590,360,480
106754377,0,600
106758769,0,240
106758988,0,600
106762173,0,600
106763043,0,240
106765447,0,600
106765761,0,600
106765790,0,600
106775190,300,420
106776742,0,240
106781641,0,600
106790276,0,600
106793056,0,600
106798348,0,600
106801344,0,240
106802404,0,240
106803268,0,600
106806874,0,600
106809648,0,240
106809662,0,600
106809681,0,600
106813589,0,240
106818600,0,600
106818668,60,180
106820041,0,600
106820178,0,240
106820735,0,600
106822716,0,600
106823211,0,600
106824266,0,240
106824512,0,240
106824742,0,600
106826035,0,600
106828070,0,240
106828628,0,600
106829323,0,600
106833813,0,240
106834398,0,600
106835053,0,600
106835282,0,600
106836405,0,600
106839639,0,600
106840295,0,600
106840366,0,600
106841840,0,600
106845767,0,600
106845946,0,240
106847687,0,600
106848186,0,240
106848936,0,240
106849556,0,600
106851428,0,600
106852112,0,240
106853161,0,600
106853178,0,600
106853363,0,600
106854117,0,600
106854169,0,600
106854359,0,600
106855369,0,600
106855674,0,600
106855710,0,240
106856389,0,600
106856390,0,600
106856986,0,240
106858813,0,600
106859148,0,600
106859149,0,600
106859379,0,600
106859862,0,600
106860869,0,240
106860870,0,600
106861402,0,240
106862447,0,600
106862449,0,240
106862552,0,600
106862553,0,600
106862554,240,600
106863823,0,240
106865528,240,600
106865892,240,600
106866729,0,600
106866730,240,600
106866881,0,600
106867266,0,600
106867319,0,600
106868053,240,600
106868422,0,600
106869743,0,600
106870053,240,600
106870383,0,600
106870492,0,600
106870713,240,600
106870737,0,240
106870765,0,240
106871040,0,240
106871200,0,600
106871570,240,600
106871868,0,600
106871918,0,600
106872059,0,240
106872591,0,240
106872658,0,240
106872822,240,600
106873767,0,600
106873992,240,600
106874727,0,240
106875426,0,240
106876557,0,600
106876682,240,600
106878500,0,600
106879292,240,600
106879505,0,600
106879520,0,600
106880124,0,600
106880969,240,600
106881156,0,240
106881724,240,600
106882180,0,600
106883231,180,300
106883391,0,600
106884214,0,600
106884485,0,600
106884799,240,600
106885700,0,600
106886055,0,600
106886425,240,600
106887147,0,600
106888946,0,600
106888947,240,600
106888973,0,600
106889146,0,600
106889389,240,600
106890613,0,600
106890832,0,240
106891293,240,600
106892125,0,600
106893208,0,600
106893581,240,600
106893582,0,600
This diff could not be displayed because it is too large.
6200040351
6200040858
6200040863
6200040869
6200040872
6200041018
6200041211
6200041212
6200041442
6200043168
6200043174
6200043592
6200044031
6200044125
6200044147
6200044398
6200044459
6200044665
6200044816
6200045418
\ No newline at end of file
6200040351,"120.753872,31.312792"
6200040858,"120.609365,31.37701"
6200040863,"120.593355,31.314191"
6200040869,"120.678101,31.312457"
6200040872,"120.694276,31.230944"
6200041018,"120.687856,31.631952"
6200041211,"120.62794,31.25647"
6200041212,"120.630037,31.153815"
6200041442,"120.537372,31.36919"
6200043168,"120.597624,31.18977"
6200043174,"120.627131,31.29919"
6200043592,"120.69743,31.234127"
6200044031,"120.634638,31.298191"
6200044125,"120.723353,31.296595"
6200044147,"120.399134,31.233416"
6200044398,"120.726766,31.304399"
6200044459,"120.66996,31.272656"
6200044665,"120.6085,31.126906"
6200044816,"120.385022,31.351074"
6200045418,"120.736174,31.337832"
\ No newline at end of file
6200040351,博世/西门子冰箱安装
6200040351,博世/西门子冰箱修理
6200040351,博世/西门子洗衣机安装
6200040351,博世/西门子洗衣机修理
6200040351,博世/西门子洗衣机清洗
6200040351,博世/西门子烘干机安装
6200040351,博世/西门子烘干机修理
6200040351,博世/西门子洗碗机安装
6200040351,博世/西门子洗碗机修理
6200040351,博世/西门子咖啡机安装
6200040351,博世/西门子咖啡机修理
6200040351,博世/西门子烟机安装
6200040351,博世/西门子烟机修理
6200040351,博世/西门子灶具修理
6200040351,博世/西门子蒸烤箱微波炉安装
6200040351,博世/西门子蒸烤箱微波炉修理
6200040858,博世/西门子冰箱安装
6200040858,博世/西门子冰箱修理
6200040858,博世/西门子洗衣机安装
6200040858,博世/西门子洗衣机修理
6200040858,博世/西门子洗衣机清洗
6200040858,博世/西门子烘干机安装
6200040858,博世/西门子烘干机修理
6200040858,博世/西门子洗碗机安装
6200040858,博世/西门子洗碗机修理
6200040858,博世/西门子咖啡机安装
6200040858,博世/西门子咖啡机修理
6200040858,博世/西门子烟机安装
6200040858,博世/西门子烟机修理
6200040858,博世/西门子灶具修理
6200040858,博世/西门子蒸烤箱微波炉安装
6200040858,博世/西门子蒸烤箱微波炉修理
6200040863,博世/西门子冰箱安装
6200040863,博世/西门子洗衣机安装
6200040863,博世/西门子洗衣机清洗
6200040863,博世/西门子烘干机安装
6200040863,博世/西门子洗碗机安装
6200040863,博世/西门子咖啡机安装
6200040863,博世/西门子烟机安装
6200040863,博世/西门子蒸烤箱微波炉安装
6200040869,博世/西门子冰箱安装
6200040869,博世/西门子嵌入式冰箱安装
6200040869,博世/西门子洗衣机安装
6200040869,博世/西门子洗衣机清洗
6200040869,博世/西门子烘干机安装
6200040869,博世/西门子洗碗机安装
6200040869,博世/西门子咖啡机安装
6200040869,博世/西门子烟机安装
6200040869,博世/西门子蒸烤箱微波炉安装
6200040872,博世/西门子冰箱安装
6200040872,博世/西门子嵌入式冰箱安装
6200040872,博世/西门子洗衣机安装
6200040872,博世/西门子烘干机安装
6200040872,博世/西门子洗碗机安装
6200040872,博世/西门子咖啡机安装
6200040872,博世/西门子烟机安装
6200040872,博世/西门子蒸烤箱微波炉安装
6200041018,博世/西门子冰箱安装
6200041018,博世/西门子冰箱修理
6200041018,博世/西门子洗衣机安装
6200041018,博世/西门子洗衣机修理
6200041018,博世/西门子洗衣机清洗
6200041018,博世/西门子烘干机安装
6200041018,博世/西门子烘干机修理
6200041018,博世/西门子洗碗机安装
6200041018,博世/西门子洗碗机修理
6200041018,博世/西门子咖啡机安装
6200041018,博世/西门子咖啡机修理
6200041018,博世/西门子烟机安装
6200041018,博世/西门子烟机修理
6200041018,博世/西门子灶具修理
6200041018,博世/西门子蒸烤箱微波炉安装
6200041018,博世/西门子蒸烤箱微波炉修理
6200041211,博世/西门子冰箱安装
6200041211,博世/西门子嵌入式冰箱安装
6200041211,博世/西门子洗衣机安装
6200041211,博世/西门子洗衣机清洗
6200041211,博世/西门子烘干机安装
6200041211,博世/西门子洗碗机安装
6200041211,博世/西门子咖啡机安装
6200041211,博世/西门子烟机安装
6200041211,博世/西门子蒸烤箱微波炉安装
6200041212,博世/西门子冰箱安装
6200041212,博世/西门子嵌入式冰箱安装
6200041212,博世/西门子洗衣机安装
6200041212,博世/西门子烘干机安装
6200041212,博世/西门子洗碗机安装
6200041212,博世/西门子咖啡机安装
6200041212,博世/西门子烟机安装
6200041212,博世/西门子蒸烤箱微波炉安装
6200041442,博世/西门子冰箱安装
6200041442,博世/西门子冰箱修理
6200041442,博世/西门子嵌入式冰箱安装
6200041442,博世/西门子洗衣机安装
6200041442,博世/西门子洗衣机修理
6200041442,博世/西门子洗衣机清洗
6200041442,博世/西门子烘干机安装
6200041442,博世/西门子烘干机修理
6200041442,博世/西门子洗碗机安装
6200041442,博世/西门子洗碗机修理
6200041442,博世/西门子咖啡机安装
6200041442,博世/西门子咖啡机修理
6200041442,博世/西门子烟机安装
6200041442,博世/西门子烟机修理
6200041442,博世/西门子灶具修理
6200041442,博世/西门子蒸烤箱微波炉安装
6200041442,博世/西门子蒸烤箱微波炉修理
6200043168,博世/西门子冰箱安装
6200043168,博世/西门子洗衣机安装
6200043168,博世/西门子洗衣机清洗
6200043168,博世/西门子烘干机安装
6200043168,博世/西门子洗碗机安装
6200043168,博世/西门子咖啡机安装
6200043168,博世/西门子蒸烤箱微波炉安装
6200043174,博世/西门子冰箱安装
6200043174,博世/西门子洗衣机安装
6200043174,博世/西门子洗衣机清洗
6200043174,博世/西门子烘干机安装
6200043174,博世/西门子洗碗机安装
6200043174,博世/西门子咖啡机安装
6200043174,博世/西门子烟机安装
6200043174,博世/西门子蒸烤箱微波炉安装
6200043592,博世/西门子冰箱安装
6200043592,博世/西门子嵌入式冰箱安装
6200043592,博世/西门子洗衣机安装
6200043592,博世/西门子洗衣机清洗
6200043592,博世/西门子烘干机安装
6200043592,博世/西门子洗碗机安装
6200043592,博世/西门子咖啡机安装
6200043592,博世/西门子烟机安装
6200043592,博世/西门子蒸烤箱微波炉安装
6200044031,博世/西门子冰箱安装
6200044031,博世/西门子洗衣机安装
6200044031,博世/西门子洗衣机清洗
6200044031,博世/西门子烘干机安装
6200044031,博世/西门子洗碗机安装
6200044031,博世/西门子咖啡机安装
6200044031,博世/西门子烟机安装
6200044031,博世/西门子蒸烤箱微波炉安装
6200044125,博世/西门子冰箱安装
6200044125,博世/西门子嵌入式冰箱安装
6200044125,博世/西门子洗衣机安装
6200044125,博世/西门子洗衣机清洗
6200044125,博世/西门子烘干机安装
6200044125,博世/西门子洗碗机安装
6200044125,博世/西门子咖啡机安装
6200044125,博世/西门子嵌饮机安装
6200044125,博世/西门子烟机安装
6200044125,博世/西门子蒸烤箱微波炉安装
6200044147,博世/西门子冰箱安装
6200044147,博世/西门子冰箱修理
6200044147,博世/西门子嵌入式冰箱安装
6200044147,博世/西门子洗衣机安装
6200044147,博世/西门子洗衣机修理
6200044147,博世/西门子洗衣机清洗
6200044147,博世/西门子烘干机安装
6200044147,博世/西门子烘干机修理
6200044147,博世/西门子洗碗机安装
6200044147,博世/西门子洗碗机修理
6200044147,博世/西门子咖啡机安装
6200044147,博世/西门子咖啡机修理
6200044147,博世/西门子嵌饮机安装
6200044147,博世/西门子烟机安装
6200044147,博世/西门子烟机修理
6200044147,博世/西门子灶具修理
6200044147,博世/西门子蒸烤箱微波炉安装
6200044147,博世/西门子蒸烤箱微波炉修理
6200044398,博世/西门子冰箱安装
6200044398,博世/西门子冰箱修理
6200044398,博世/西门子洗衣机安装
6200044398,博世/西门子洗衣机修理
6200044398,博世/西门子洗衣机清洗
6200044398,博世/西门子烘干机安装
6200044398,博世/西门子烘干机修理
6200044398,博世/西门子洗碗机安装
6200044398,博世/西门子洗碗机修理
6200044398,博世/西门子咖啡机安装
6200044398,博世/西门子咖啡机修理
6200044398,博世/西门子烟机安装
6200044398,博世/西门子烟机修理
6200044398,博世/西门子灶具修理
6200044398,博世/西门子蒸烤箱微波炉安装
6200044398,博世/西门子蒸烤箱微波炉修理
6200044459,博世/西门子冰箱安装
6200044459,博世/西门子洗衣机安装
6200044459,博世/西门子洗衣机清洗
6200044459,博世/西门子烘干机安装
6200044459,博世/西门子洗碗机安装
6200044459,博世/西门子咖啡机安装
6200044459,博世/西门子烟机安装
6200044459,博世/西门子蒸烤箱微波炉安装
6200044665,博世/西门子冰箱安装
6200044665,博世/西门子洗衣机安装
6200044665,博世/西门子洗衣机清洗
6200044665,博世/西门子烘干机安装
6200044665,博世/西门子洗碗机安装
6200044665,博世/西门子咖啡机安装
6200044665,博世/西门子烟机安装
6200044665,博世/西门子蒸烤箱微波炉安装
6200044816,博世/西门子冰箱安装
6200044816,博世/西门子洗衣机安装
6200044816,博世/西门子洗衣机清洗
6200044816,博世/西门子烘干机安装
6200044816,博世/西门子洗碗机安装
6200044816,博世/西门子咖啡机安装
6200044816,博世/西门子烟机安装
6200044816,博世/西门子蒸烤箱微波炉安装
6200045418,博世/西门子冰箱安装
6200045418,博世/西门子洗衣机安装
6200045418,博世/西门子烘干机安装
6200045418,博世/西门子洗碗机安装
6200045418,博世/西门子咖啡机安装
6200045418,博世/西门子灶具安装
6200045418,博世/西门子蒸烤箱微波炉安装
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud-alibaba-parent</artifactId>
<groupId>com.alibaba.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>project-dispatch</artifactId>
<name>Spring Cloud Alibaba Dispatch</name>
<properties>
<druid.version>1.1.10</druid.version>
<version.org.optaplanner>9.38.0.Final</version.org.optaplanner>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>project-interface</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.optaplanner</groupId>
<artifactId>optaplanner-core</artifactId>
<version>${version.org.optaplanner}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.13.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
/*
* Copyright 2013-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.dituhui.pea.dispatch;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author gpzhang
*/
@SpringBootApplication
public class DispatchServiceApplication {
public static void main(String[] args) {
SpringApplication.run(DispatchServiceApplication.class, args);
}
}
package com.dituhui.pea.dispatch.constraint;
import org.optaplanner.core.api.score.buildin.hardsoftlong.HardSoftLongScore;
import org.optaplanner.core.api.score.stream.Constraint;
import org.optaplanner.core.api.score.stream.ConstraintFactory;
import org.optaplanner.core.api.score.stream.ConstraintProvider;
import com.dituhui.pea.dispatch.pojo.Customer;
import com.dituhui.pea.dispatch.pojo.Technician;
public class VehicleRoutingConstraintProvider implements ConstraintProvider {
@Override
public Constraint[] defineConstraints(ConstraintFactory factory) {
return new Constraint[] { greaterThanZero(factory), customerTimeWindowsMatch1(factory),
customerTimeWindowsMatch2(factory),
skillMatch(factory),
technicianBalance(factory),
technicianBalance2(factory),
totalDistance(factory),
preferredTotalDistance(factory) };
}
// ************************************************************************
// Hard constraints
// ************************************************************************
// 1,每个技术员至少分配一个greaterThanZero
// 2,技术员到达时间跟时间窗吻合customerTimeWindowsMatch
// 3,技术员时间窗吻合technicianTimeWindowsMatch
// 4,技术员技能跟订单相匹配skillMatch
// 5,订单均分technicianBalance
protected Constraint greaterThanZero(ConstraintFactory factory) {
return factory.forEach(Technician.class).filter(technician -> technician.getCustomerList().size() == 0)
.penalizeLong(HardSoftLongScore.ONE_HARD, technician -> 1).asConstraint("每个技术员至少分配一个单子");
}
protected Constraint customerTimeWindowsMatch1(ConstraintFactory factory) {
return factory.forEach(Customer.class).filter(
customer -> customer.getTechnician() != null && customer.getArrivalTime() > customer.getEndTime())
.penalizeLong(HardSoftLongScore.ONE_HARD, customer -> 1).asConstraint("技术员到达时间跟时间窗吻合1");
}
protected Constraint customerTimeWindowsMatch2(ConstraintFactory factory) {
return factory.forEach(Customer.class).filter(
customer -> customer.getTechnician() != null && customer.getArrivalTime() > customer.getEndTime() + 120)
.penalizeLong(HardSoftLongScore.ONE_HARD, customer -> 1).asConstraint("技术员到达时间跟时间窗吻合2");
}
protected Constraint skillMatch(ConstraintFactory factory) {
return factory.forEach(Customer.class)
.filter(customer -> customer.getTechnician() != null
&& !customer.getTechnician().getSkills().contains(customer.getRequiredSkill()))
.penalizeLong(HardSoftLongScore.ONE_HARD, customer -> 1).asConstraint("技术员技能跟订单相匹配skillMatch");
}
protected Constraint technicianBalance(ConstraintFactory factory) {
// 会导致剩余单子集中?
return factory.forEach(Technician.class).filter(technician -> technician.getOffWorkTime() > 1440)
.penalizeLong(HardSoftLongScore.ONE_HARD,
technician -> (long) Math.ceil(technician.getOffWorkTime() / 1440f))
.asConstraint("订单均分");
}
protected Constraint technicianBalance2(ConstraintFactory factory) {
// 单量不能过少 FIXME
return factory.forEach(Technician.class).filter(technician -> technician.getOffWorkTime() <= 1140)
.penalizeLong(HardSoftLongScore.ONE_HARD,
technician -> 1)
.asConstraint("订单均分2");
}
// protected Constraint technicianBalance(ConstraintFactory factory) {
// return factory.forEachUniquePair(Technician.class, Joiners.filtering(
// // 一个人的工作时长超过另外一个人的2倍 FIXME 无效
// (t1, t2) -> (t1.getWorkTime() > t2.getWorkTime() * 2) || (t2.getWorkTime() > t1.getWorkTime() * 2)))
// .penalizeLong(HardSoftLongScore.ONE_HARD, (c1, c2) -> 1).asConstraint("订单均分");
// }
// protected Constraint technicianBalance(ConstraintFactory factory) {
// return factory.forEachUniquePair(Technician.class, Joiners.filtering(
// // 一个人的数量是另外一个人的3倍 FIXME 无效
// (t1, t2) -> {
// int size1 = t1.getCustomerSize();
// int size2 = t2.getCustomerSize();
// return (size1 > size2 * 3) || (size2 > size1 * 3);
// })).penalizeLong(HardSoftLongScore.ONE_HARD, (c1, c2) -> 1).asConstraint("订单均分");
// }
// ************************************************************************
// Soft constraints
// ************************************************************************
// 1, 总路程最小 totalDistance
// 2, 技术员中心点偏好 preferredTotalDistance
protected Constraint totalDistance(ConstraintFactory factory) {
return factory.forEach(Technician.class)
.penalizeLong(HardSoftLongScore.ONE_SOFT, Technician::getTotalDistanceMeters).asConstraint("总路程最小");
}
protected Constraint preferredTotalDistance(ConstraintFactory factory) {
return factory.forEach(Technician.class)
.penalizeLong(HardSoftLongScore.ONE_SOFT, Technician::getPreferredTotalDistanceMeters)
.asConstraint("技术员中心点偏好");
}
}
/*
* Copyright 2013-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.dituhui.pea.dispatch.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.dituhui.pea.common.Result;
import com.dituhui.pea.dispatch.service.DispatchService;
/**
* @author gpzhang
*/
@RestController
@RequestMapping("/dispatch")
public class DispatchController {
@Autowired
private DispatchService dispatchService;
@GetMapping("/manual")
public Result<?> manualDispatch() {
try {
return dispatchService.manualDispatch();
} catch (Exception e) {
return Result.failed(e.getMessage());
}
}
}
package com.dituhui.pea.dispatch.pojo;
import org.optaplanner.core.api.domain.entity.PlanningEntity;
import org.optaplanner.core.api.domain.variable.ShadowVariable;
import lombok.Data;
import org.optaplanner.core.api.domain.variable.InverseRelationShadowVariable;
/**
* 订单
*
* @author gpzhang
*
*/
@Data
@PlanningEntity
public class Customer {
private long id;
private String code;
private Location location;
// 时间窗 分钟
private int startTime;
private int endTime;
private int serviceDuration;
// 需要技能
private String requiredSkill;
// Shadow variables
private Technician technician;
private Customer previousCustomer;
private Customer nextCustomer;
// 到达时间
private Integer arrivalTime;
// 离开时间
// private Integer departureTime;
public Customer() {
}
public Customer(long id, String code, Location location, int startTime, int endTime, String requiredSkill, int serviceDuration) {
this.id = id;
this.code = code;
this.location = location;
this.startTime = startTime;
this.endTime = endTime;
this.requiredSkill = requiredSkill;
this.serviceDuration = serviceDuration;
}
@InverseRelationShadowVariable(sourceVariableName = "customerList")
public Technician getTechnician() {
return technician;
}
@org.optaplanner.core.api.domain.variable.PreviousElementShadowVariable(sourceVariableName = "customerList")
public Customer getPreviousCustomer() {
return previousCustomer;
}
@org.optaplanner.core.api.domain.variable.NextElementShadowVariable(sourceVariableName = "customerList")
public Customer getNextCustomer() {
return nextCustomer;
}
@ShadowVariable(variableListenerClass = com.dituhui.pea.dispatch.shadowVariable.ArrivalTimeUpdatingVariableListener.class, sourceVariableName = "technician")
@ShadowVariable(variableListenerClass = com.dituhui.pea.dispatch.shadowVariable.ArrivalTimeUpdatingVariableListener.class, sourceVariableName = "previousCustomer")
public Integer getArrivalTime() {
return arrivalTime;
}
// ************************************************************************
// Complex methods
// ************************************************************************
public Integer getDepartureTime() {
if (arrivalTime == null) {
return null;
}
return Math.max(arrivalTime, startTime) + serviceDuration;
}
public boolean isArrivalBeforeStartTime() {
return arrivalTime != null && arrivalTime < startTime;
}
public boolean isArrivalAfterEndTime() {
return arrivalTime != null && endTime < arrivalTime;
}
/**
* 计算2个订单之间时间窗gap 注意:有交集返回0,其他返回相离时间
*
* @param other
* @return
*/
public Integer getTimeWindowGapTo(Customer other) {
// dueTime doesn't account for serviceDuration
int latestDepartureTime = endTime + serviceDuration;
int otherLatestDepartureTime = other.getEndTime() + other.getServiceDuration();
if (latestDepartureTime < other.getStartTime()) {
return other.getStartTime() - latestDepartureTime;
}
if (otherLatestDepartureTime < startTime) {
return startTime - otherLatestDepartureTime;
}
return 0;
}
/**
* 与前一个订单或者出发地depot的距离
*
* @return
*/
public long getDistanceFromPreviousStandstill() {
if (technician == null) {
throw new IllegalStateException(
"This method must not be called when the shadow variables are not initialized yet.");
}
if (previousCustomer == null) {
return technician.getDepot().getLocation().getDistanceTo(location);
}
return previousCustomer.getLocation().getDistanceTo(location);
}
/**
* 与前一个订单或者出发地depot的路程时间
*
* @return
*/
public int getPathTimeFromPreviousStandstill() {
if (technician == null) {
throw new IllegalStateException(
"This method must not be called when the shadow variables are not initialized yet.");
}
if (previousCustomer == null) {
return technician.getDepot().getLocation().getPathTimeTo(location);
}
return previousCustomer.getLocation().getPathTimeTo(location);
}
// @Override
// public String toString() {
// return "Customer{" + "id=" + id + '}';
// }
}
package com.dituhui.pea.dispatch.pojo;
import lombok.Data;
/**
* 出发地
*
* @author gpzhang
*
*/
@Data
public class Depot {
private final long id;
private final Location location;
// 时间窗 分钟
private int startTime;
private int endTime;
public Depot(long id, Location location, int startTime, int endTime) {
this.id = id;
this.location = location;
this.startTime = startTime;
this.endTime = endTime;
}
}
package com.dituhui.pea.dispatch.pojo;
import java.util.HashMap;
import java.util.Map;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Location {
private final long id;
private Map<Location, Long> distanceMap= new HashMap<Location, Long>();;// 路网距离矩阵
private Map<Location, Long> distanceTimeMap= new HashMap<Location, Long>();;// 路网时间矩阵
public Location(long id) {
this.id = id;
}
/**
* Set the distance map. Distances are in meters.
*
* @param distanceMap a map containing distances from here to other locations
*/
public void setDistanceMap(Map<Location, Long> distanceMap) {
this.distanceMap = distanceMap;
}
/**
* Distance to the given location in meters.
*
* @param location other location
* @return distance in meters
*/
public long getDistanceTo(Location location) {
return distanceMap.get(location);
}
/**
* time to the given location in minutes.
* FIXME 这里简化处理没有用时间矩阵 时间=距离/100
*
* @param location other location
* @return time in minutes
*/
public int getPathTimeTo(Location location) {
return (int)(distanceMap.get(location)/100);
}
// ************************************************************************
// Complex methods
// ************************************************************************
@Override
public String toString() {
return "Location{" + "id=" + id + '}';
}
}
package com.dituhui.pea.dispatch.pojo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.optaplanner.core.api.domain.entity.PlanningEntity;
import org.optaplanner.core.api.domain.lookup.PlanningId;
import org.optaplanner.core.api.domain.variable.PlanningListVariable;
import lombok.Data;
@Data
@PlanningEntity
public class Technician {
@PlanningId
private long id;
private String code;
private Depot depot;
// 上班时间窗 分钟480-1080 8-18点
private int startTime;
private int endTime;
// 技能
private Set<String> skills;
// 偏好坐标
// private Location preferredlocation;
// teck code : customer code , distance
private Map<String, Long> preferredlocationDistanceMap = new HashMap<String, Long>();
@PlanningListVariable
private List<Customer> customerList = new ArrayList<>();
public Technician() {
}
public Technician(long id, String code, Depot depot, int startTime, int endTime, Set<String> skills,
Map<String, Long> preferredlocationDistanceMap) {
this.id = id;
this.code = code;
this.depot = depot;
this.startTime = startTime;
this.endTime = endTime;
this.skills = skills;
this.preferredlocationDistanceMap = preferredlocationDistanceMap;
}
// ************************************************************************
// Complex methods
// ************************************************************************
/**
* @return route of the vehicle
*/
public List<Location> getRoute() {
if (customerList.isEmpty()) {
return Collections.emptyList();
}
List<Location> route = new ArrayList<Location>();
route.add(depot.getLocation());
for (Customer customer : customerList) {
route.add(customer.getLocation());
}
// route.add(depot.getLocation());
return route;
}
/**
* 总路线距离
*
* @return
*/
public long getTotalDistanceMeters() {
if (customerList.isEmpty()) {
return 0;
}
long totalDistance = 0;
Location previousLocation = depot.getLocation();
for (Customer customer : customerList) {
totalDistance += previousLocation.getDistanceTo(customer.getLocation());
previousLocation = customer.getLocation();
}
totalDistance += previousLocation.getDistanceTo(depot.getLocation());
return totalDistance;
}
/**
* 获取偏好总距离 所有customer与该技术员的PreferredLocation距离之和
*
* @return
*/
public long getPreferredTotalDistanceMeters() {
if (customerList.isEmpty()) {
return 0;
}
long totalDistance = 0;
for (Customer customer : customerList) {
totalDistance += preferredlocationDistanceMap.get(customer.getCode());
}
return totalDistance;
}
public int getCustomerSize() {
return customerList.size();
}
/**
* 获取总上班时间,第一个订单到最后一个订单时间跨度
*
* @return
*/
public int getWorkTime() {
int size = customerList.size();
if (0 == size) {
return 0;
} else {
return customerList.get(size - 1).getArrivalTime() + customerList.get(size - 1).getServiceDuration()
- customerList.get(0).getArrivalTime();
}
}
/**
* 获取下班时间,最后一个订单完成时间
*
* @return
*/
public int getOffWorkTime() {
int size = customerList.size();
if (0 == size) {
return 0;
} else {
Customer lastCustomer = customerList.get(size - 1);
return lastCustomer.getDepartureTime();
}
}
}
package com.dituhui.pea.dispatch.pojo;
import java.util.List;
import org.optaplanner.core.api.domain.solution.PlanningEntityCollectionProperty;
import org.optaplanner.core.api.domain.solution.PlanningScore;
import org.optaplanner.core.api.domain.solution.PlanningSolution;
import org.optaplanner.core.api.domain.solution.ProblemFactCollectionProperty;
import org.optaplanner.core.api.domain.solution.ProblemFactProperty;
import org.optaplanner.core.api.domain.valuerange.ValueRangeProvider;
import org.optaplanner.core.api.score.buildin.hardsoftlong.HardSoftLongScore;
import lombok.Data;
@Data
@PlanningSolution
public class VehicleRoutingSolution {
private String name;
@ProblemFactCollectionProperty
private List<Location> locationList;
// 单起点,多技术员
@ProblemFactProperty
private Depot depot;
@PlanningEntityCollectionProperty
private List<Technician> technicianList;
@ProblemFactCollectionProperty
@ValueRangeProvider
private List<Customer> customerList;
@PlanningScore
private HardSoftLongScore score;
public VehicleRoutingSolution() {
}
public VehicleRoutingSolution(String name, List<Location> locationList, Depot depot,
List<Technician> technicianList, List<Customer> customerList) {
this.name = name;
this.locationList = locationList;
this.depot = depot;
this.technicianList = technicianList;
this.customerList = customerList;
}
// ************************************************************************
// Complex methods
// ************************************************************************
public long getDistanceMeters() {
return score == null ? 0 : -score.softScore();
}
}
/*
* Copyright 2013-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.dituhui.pea.dispatch.service;
import java.io.FileNotFoundException;
import java.io.UncheckedIOException;
import com.dituhui.pea.common.Result;
/**
* @author gpzhang
*/
public interface DispatchService {
Result<?> manualDispatch() throws UncheckedIOException, FileNotFoundException;
}
package com.dituhui.pea.dispatch.shadowVariable;
import java.util.Objects;
import org.optaplanner.core.api.domain.variable.VariableListener;
import org.optaplanner.core.api.score.director.ScoreDirector;
import com.dituhui.pea.dispatch.pojo.Customer;
import com.dituhui.pea.dispatch.pojo.VehicleRoutingSolution;
public class ArrivalTimeUpdatingVariableListener implements VariableListener<VehicleRoutingSolution, Customer> {
@Override
public void beforeEntityAdded(ScoreDirector<VehicleRoutingSolution> scoreDirector, Customer customer) {
// Do nothing
}
@Override
public void afterEntityAdded(ScoreDirector<VehicleRoutingSolution> scoreDirector, Customer customer) {
updateArrivalTime(scoreDirector, customer);
}
@Override
public void beforeVariableChanged(ScoreDirector<VehicleRoutingSolution> scoreDirector, Customer customer) {
// Do nothing
}
@Override
public void afterVariableChanged(ScoreDirector<VehicleRoutingSolution> scoreDirector, Customer customer) {
updateArrivalTime(scoreDirector, customer);
}
@Override
public void beforeEntityRemoved(ScoreDirector<VehicleRoutingSolution> scoreDirector, Customer customer) {
// Do nothing
}
@Override
public void afterEntityRemoved(ScoreDirector<VehicleRoutingSolution> scoreDirector, Customer customer) {
updateArrivalTime(scoreDirector, customer);
}
protected void updateArrivalTime(ScoreDirector<VehicleRoutingSolution> scoreDirector, Customer sourceCustomer) {
if (sourceCustomer.getTechnician() == null) {
if (sourceCustomer.getArrivalTime() != null) {
scoreDirector.beforeVariableChanged(sourceCustomer, "arrivalTime");
sourceCustomer.setArrivalTime(null);
scoreDirector.afterVariableChanged(sourceCustomer, "arrivalTime");
}
return;
}
Customer previousCustomer = sourceCustomer.getPreviousCustomer();
Integer departureTime;
if (previousCustomer == null) {
departureTime = (sourceCustomer.getTechnician().getDepot()).getStartTime();
} else {
departureTime = previousCustomer.getDepartureTime();
}
Customer shadowCustomer = sourceCustomer;
Integer arrivalTime = calculateArrivalTime(shadowCustomer, departureTime);
while (shadowCustomer != null && !Objects.equals(shadowCustomer.getArrivalTime(), arrivalTime)) {
scoreDirector.beforeVariableChanged(shadowCustomer, "arrivalTime");
shadowCustomer.setArrivalTime(arrivalTime);
scoreDirector.afterVariableChanged(shadowCustomer, "arrivalTime");
departureTime = shadowCustomer.getDepartureTime();
shadowCustomer = shadowCustomer.getNextCustomer();
arrivalTime = calculateArrivalTime(shadowCustomer, departureTime);
}
}
private Integer calculateArrivalTime(Customer customer, Integer previousDepartureTime) {
if (customer == null || previousDepartureTime == null) {
return null;
}
return previousDepartureTime + customer.getPathTimeFromPreviousStandstill();
}
}
server:
port: 8011
spring:
application:
name: project-dispatch
cloud:
nacos:
discovery:
server-addr: nacos-server:8848
group: project
config:
server-addr: nacos-server:8848
group: project
file-extension: yaml
import-check:
# no config file
enabled: false
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://10.10.0.116:3306/saas_aftersale_test?serverTimezone=UTC
username: root
password: 123456
type: com.alibaba.druid.pool.DruidDataSource
seata:
application-id: ${spring.application.name}
tx-service-group: ${spring.application.name}-group
service:
vgroup-mapping:
project-dispatch-group: default
grouplist:
default: seata-server:8091
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] [%-20.20c] %-5p %m%n</pattern>
</encoder>
</appender>
<logger name="org.optaplanner" level="info"/>
<root level="info">
<appender-ref ref="consoleAppender" />
</root>
</configuration>
......@@ -48,4 +48,6 @@ project-gis 地图数据模块
project-geometry GIS底层依赖模块
project-district 行政区模块
\ No newline at end of file
project-district 行政区模块
project-dispatch 派工算法模块
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!