Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
yangxiujun
/
paidan_demo
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit e9575d03
authored
Jul 03, 2023
by
chamberone
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 提交过程打印逻辑,优化实体类,添加时间控制参数
1 parent
5022be8c
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
160 additions
and
43 deletions
project-dispatch/src/main/java/com/dituhui/pea/dispatch/constraint/DispatchConstraintProvider.java
project-dispatch/src/main/java/com/dituhui/pea/dispatch/controller/DispatchController.java
project-dispatch/src/main/java/com/dituhui/pea/dispatch/pojo/Customer.java
project-dispatch/src/main/java/com/dituhui/pea/dispatch/pojo/Location.java
project-dispatch/src/main/java/com/dituhui/pea/dispatch/pojo/Technician.java
project-dispatch/src/main/java/com/dituhui/pea/dispatch/service/DispatchService.java
project-dispatch/src/main/java/com/dituhui/pea/dispatch/service/impl/DispatchServiceImpl.java
project-dispatch/src/main/java/com/dituhui/pea/dispatch/constraint/DispatchConstraintProvider.java
View file @
e9575d0
...
...
@@ -13,11 +13,8 @@ public class DispatchConstraintProvider 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
),
customerTimeWindowsMatch2
(
factory
),
skillMatch
(
factory
),
technicianBalance
(
factory
),
technicianBalance2
(
factory
),
technicianBalanceSoft
(
factory
),
totalDistance
(
factory
),
preferredTotalDistance
(
factory
)
};
}
...
...
@@ -30,7 +27,7 @@ public class DispatchConstraintProvider implements ConstraintProvider {
// 4,技术员技能跟订单相匹配skillMatch
// 5,订单均分technicianBalance
p
rotected
Constraint
greaterThanZero
(
ConstraintFactory
factory
)
{
p
ublic
Constraint
greaterThanZero
(
ConstraintFactory
factory
)
{
return
factory
.
forEach
(
Technician
.
class
).
filter
(
technician
->
technician
.
getCustomerList
().
size
()
==
0
)
.
penalizeLong
(
HardSoftLongScore
.
ONE_HARD
,
technician
->
1
).
asConstraint
(
"每个技术员至少分配一个单子"
);
}
...
...
@@ -42,6 +39,7 @@ public class DispatchConstraintProvider implements ConstraintProvider {
}
protected
Constraint
customerTimeWindowsMatch2
(
ConstraintFactory
factory
)
{
// 迟到2小时惩罚
return
factory
.
forEach
(
Customer
.
class
).
filter
(
customer
->
customer
.
getTechnician
()
!=
null
&&
customer
.
getArrivalTime
()
>
customer
.
getEndTime
()
+
120
)
.
penalizeLong
(
HardSoftLongScore
.
ONE_HARD
,
customer
->
1
).
asConstraint
(
"技术员到达时间跟时间窗吻合2"
);
...
...
@@ -51,7 +49,12 @@ public class DispatchConstraintProvider implements ConstraintProvider {
return
factory
.
forEach
(
Customer
.
class
)
.
filter
(
customer
->
customer
.
getTechnician
()
!=
null
&&
!
customer
.
getTechnician
().
getSkills
().
contains
(
customer
.
getRequiredSkill
()))
.
penalizeLong
(
HardSoftLongScore
.
ONE_HARD
,
customer
->
1
).
asConstraint
(
"技术员技能跟订单相匹配skillMatch"
);
.
penalizeLong
(
HardSoftLongScore
.
ONE_HARD
,
// 技能匹配跟时间窗匹配存在很明显的跷跷板效应,权重小于3就会存在技能匹配问题
// 3-技能匹配问题1个,时间窗问题8个
// 4-技能匹配问题0个,时间窗问题14个
customer
->
4
)
.
asConstraint
(
"技术员技能跟订单相匹配skillMatch"
);
}
protected
Constraint
technicianBalance
(
ConstraintFactory
factory
)
{
...
...
@@ -65,9 +68,7 @@ public class DispatchConstraintProvider implements ConstraintProvider {
protected
Constraint
technicianBalance2
(
ConstraintFactory
factory
)
{
// 单量不能过少 FIXME
return
factory
.
forEach
(
Technician
.
class
).
filter
(
technician
->
technician
.
getOffWorkTime
()
<=
960
)
.
penalizeLong
(
HardSoftLongScore
.
ONE_HARD
,
technician
->
1
)
.
asConstraint
(
"订单均分2"
);
.
penalizeLong
(
HardSoftLongScore
.
ONE_HARD
,
technician
->
1
).
asConstraint
(
"订单均分2"
);
}
// protected Constraint technicianBalance(ConstraintFactory factory) {
...
...
@@ -92,6 +93,7 @@ public class DispatchConstraintProvider implements ConstraintProvider {
// ************************************************************************
// 1, 总路程最小 totalDistance
// 2, 技术员中心点偏好 preferredTotalDistance
// 3, 订单数量均衡 technicianBalanceSoft
protected
Constraint
totalDistance
(
ConstraintFactory
factory
)
{
return
factory
.
forEach
(
Technician
.
class
)
...
...
@@ -104,4 +106,10 @@ public class DispatchConstraintProvider implements ConstraintProvider {
.
asConstraint
(
"技术员中心点偏好"
);
}
protected
Constraint
technicianBalanceSoft
(
ConstraintFactory
factory
)
{
return
factory
.
forEachUniquePair
(
Technician
.
class
).
penalizeLong
(
HardSoftLongScore
.
ONE_SOFT
,
// 权重需要调节,差距一个相当于多一公里 FIXME 这里应该是时长均衡,不是订单量均衡
(
a
,
b
)
->
Math
.
abs
(
a
.
getCustomerSize
()
-
b
.
getCustomerSize
())
*
1000
).
asConstraint
(
"订单均分soft"
);
}
}
project-dispatch/src/main/java/com/dituhui/pea/dispatch/controller/DispatchController.java
View file @
e9575d0
...
...
@@ -19,6 +19,7 @@ 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.RequestParam
;
import
org.springframework.web.bind.annotation.RestController
;
import
com.dituhui.pea.common.Result
;
...
...
@@ -35,9 +36,11 @@ public class DispatchController {
private
DispatchService
dispatchService
;
@GetMapping
(
"/manual"
)
public
Result
<?>
manualDispatch
()
{
public
Result
<?>
manualDispatch
(
@RequestParam
(
value
=
"unimprovedSecondsSpentLimit"
,
required
=
false
)
long
unimprovedSecondsSpentLimit
,
@RequestParam
(
value
=
"secondsSpentLimit"
,
required
=
false
)
long
secondsSpentLimit
)
{
try
{
return
dispatchService
.
manualDispatch
();
return
dispatchService
.
manualDispatch
(
unimprovedSecondsSpentLimit
,
secondsSpentLimit
);
}
catch
(
Exception
e
)
{
return
Result
.
failed
(
e
.
getMessage
());
}
...
...
project-dispatch/src/main/java/com/dituhui/pea/dispatch/pojo/Customer.java
View file @
e9575d0
package
com
.
dituhui
.
pea
.
dispatch
.
pojo
;
import
org.optaplanner.core.api.domain.entity.PlanningEntity
;
import
org.optaplanner.core.api.domain.variable.InverseRelationShadowVariable
;
import
org.optaplanner.core.api.domain.variable.ShadowVariable
;
import
com.fasterxml.jackson.annotation.JsonIgnore
;
import
lombok.
Data
;
import
org.optaplanner.core.api.domain.variable.InverseRelationShadowVariable
;
import
lombok.
Getter
;
import
lombok.Setter
;
/**
* 订单
...
...
@@ -14,7 +15,8 @@ import org.optaplanner.core.api.domain.variable.InverseRelationShadowVariable;
* @author gpzhang
*
*/
@Data
@Setter
@Getter
@PlanningEntity
public
class
Customer
{
...
...
@@ -44,7 +46,8 @@ public class Customer {
public
Customer
()
{
}
public
Customer
(
long
id
,
String
code
,
Location
location
,
int
startTime
,
int
endTime
,
String
requiredSkill
,
int
serviceDuration
)
{
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
;
...
...
@@ -145,4 +148,25 @@ public class Customer {
return
previousCustomer
.
getLocation
().
getPathTimeTo
(
location
);
}
@Override
public
int
hashCode
()
{
return
Long
.
valueOf
(
this
.
id
).
hashCode
();
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
obj
==
null
)
return
false
;
if
(!(
obj
instanceof
Customer
))
return
false
;
if
(
obj
==
this
)
return
true
;
return
this
.
id
==
((
Customer
)
obj
).
getId
();
}
@Override
public
String
toString
()
{
return
"Customer{"
+
"id="
+
id
+
'}'
;
}
}
project-dispatch/src/main/java/com/dituhui/pea/dispatch/pojo/Location.java
View file @
e9575d0
...
...
@@ -55,6 +55,21 @@ public class Location {
// Complex methods
// ************************************************************************
@Override
public
int
hashCode
()
{
return
Long
.
valueOf
(
this
.
id
).
hashCode
();
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
obj
==
null
)
return
false
;
if
(!(
obj
instanceof
Location
))
return
false
;
if
(
obj
==
this
)
return
true
;
return
this
.
id
==
((
Location
)
obj
).
getId
();
}
@Override
public
String
toString
()
{
...
...
project-dispatch/src/main/java/com/dituhui/pea/dispatch/pojo/Technician.java
View file @
e9575d0
...
...
@@ -13,9 +13,11 @@ import org.optaplanner.core.api.domain.variable.PlanningListVariable;
import
com.fasterxml.jackson.annotation.JsonIgnore
;
import
lombok.Data
;
import
lombok.Getter
;
import
lombok.Setter
;
@Data
@Setter
@Getter
@PlanningEntity
public
class
Technician
{
...
...
@@ -150,4 +152,27 @@ public class Technician {
}
}
@Override
public
int
hashCode
()
{
return
Long
.
valueOf
(
this
.
id
).
hashCode
();
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
obj
==
null
)
return
false
;
if
(!(
obj
instanceof
Technician
))
return
false
;
if
(
obj
==
this
)
return
true
;
return
this
.
id
==
((
Technician
)
obj
).
getId
();
}
@Override
public
String
toString
()
{
return
"Technician{"
+
"id="
+
id
+
'}'
;
}
}
project-dispatch/src/main/java/com/dituhui/pea/dispatch/service/DispatchService.java
View file @
e9575d0
...
...
@@ -26,6 +26,7 @@ import com.dituhui.pea.common.Result;
*/
public
interface
DispatchService
{
Result
<?>
manualDispatch
()
throws
UncheckedIOException
,
IOException
;
Result
<?>
manualDispatch
(
long
unimprovedSecondsSpentLimit
,
long
secondsSpentLimit
)
throws
UncheckedIOException
,
IOException
;
}
project-dispatch/src/main/java/com/dituhui/pea/dispatch/service/impl/DispatchServiceImpl.java
View file @
e9575d0
...
...
@@ -16,10 +16,10 @@
package
com
.
dituhui
.
pea
.
dispatch
.
service
.
impl
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileNotFoundException
;
import
java.io.UncheckedIOException
;
import
java.time.Duration
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.HashMap
;
...
...
@@ -33,21 +33,28 @@ import java.util.stream.Collectors;
import
org.apache.commons.io.IOUtils
;
import
org.apache.commons.lang3.RegExUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.optaplanner.core.api.score.ScoreExplanation
;
import
org.optaplanner.core.api.score.buildin.hardsoftlong.HardSoftLongScore
;
import
org.optaplanner.core.api.solver.SolutionManager
;
import
org.optaplanner.core.api.solver.Solver
;
import
org.optaplanner.core.api.solver.SolverFactory
;
import
org.optaplanner.core.api.solver.event.BestSolutionChangedEvent
;
import
org.optaplanner.core.api.solver.event.SolverEventListener
;
import
org.optaplanner.core.config.solver.SolverConfig
;
import
org.optaplanner.core.config.solver.termination.TerminationConfig
;
import
org.optaplanner.persistence.jackson.impl.domain.solution.JacksonSolutionFileIO
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.stereotype.Service
;
import
com.dituhui.pea.dispatch.constraint.DispatchConstraintProvider
;
import
com.dituhui.pea.dispatch.pojo.DispatchSolution
;
import
com.dituhui.pea.common.Result
;
import
com.dituhui.pea.dispatch.
service.DispatchService
;
import
com.dituhui.pea.dispatch.
constraint.DispatchConstraintProvider
;
import
com.dituhui.pea.dispatch.pojo.Customer
;
import
com.dituhui.pea.dispatch.pojo.Depot
;
import
com.dituhui.pea.dispatch.pojo.DispatchSolution
;
import
com.dituhui.pea.dispatch.pojo.Location
;
import
com.dituhui.pea.dispatch.pojo.Technician
;
import
com.dituhui.pea.dispatch.service.DispatchService
;
/**
* @author gpzhang
...
...
@@ -58,7 +65,7 @@ public class DispatchServiceImpl implements DispatchService {
private
Logger
logger
=
LoggerFactory
.
getLogger
(
getClass
());
@Override
public
Result
<?>
manualDispatch
()
throws
UncheckedIOException
,
FileNotFoundException
{
public
Result
<?>
manualDispatch
(
long
unimprovedSecondsSpentLimit
,
long
secondsSpentLimit
)
throws
UncheckedIOException
,
FileNotFoundException
{
logger
.
info
(
"{}"
,
"invoke manualDispatch"
);
// 创建解决方案对象
...
...
@@ -66,17 +73,25 @@ public class DispatchServiceImpl implements DispatchService {
Map
<
Integer
,
String
>
technicianIndexMap
=
loadTechnicianIndex
();
Map
<
String
,
Set
<
String
>>
technicianCodeSkillsMap
=
loadTechnicianCodeSkillsMap
();
Map
<
String
,
String
>
customerCodeSkillMap
=
loadCustomerCodeSkillMap
();
Map
<
String
,
Map
<
String
,
Long
>>
preferredlocationDistanceMap
=
loadPreferredlocationDistanceMap
();
Map
<
String
,
Map
<
String
,
Long
>>
preferredlocationDistanceMap
=
loadPreferredlocationDistanceMap
();
Map
<
String
,
Integer
>
customerCodeServiceTimeMap
=
loadCustomerCodeServiceTimeMap
();
DispatchSolution
problem
=
createVehicleRoutingSolution
(
customerIndexMap
,
technicianIndexMap
,
technicianCodeSkillsMap
,
customerCodeSkillMap
,
preferredlocationDistanceMap
,
customerCodeServiceTimeMap
);
technicianCodeSkillsMap
,
customerCodeSkillMap
,
preferredlocationDistanceMap
,
customerCodeServiceTimeMap
);
// 创建求解器配置
// 创建 SolverConfig 对象,并设置求解器配置
SolverConfig
solverConfig
=
new
SolverConfig
();
solverConfig
.
setSolutionClass
(
DispatchSolution
.
class
);
solverConfig
.
withEntityClassList
(
Arrays
.
asList
(
Technician
.
class
,
Customer
.
class
));
// 这里不能漏掉,否则约束不生效
solverConfig
.
withTerminationSpentLimit
(
Duration
.
ofSeconds
(
60
));
TerminationConfig
terminationConfig
=
new
TerminationConfig
();
// 运行时长提升效果
// 5s/60s: 技能权重4-技能匹配问题0个,时间窗问题14个
// 10s/300s: 技能权重4-技能匹配问题0个,时间窗问题9个
terminationConfig
.
setUnimprovedSecondsSpentLimit
(
unimprovedSecondsSpentLimit
==
0
?
5
:
unimprovedSecondsSpentLimit
);
// XX秒没有找到更好方案
terminationConfig
.
setSecondsSpentLimit
(
secondsSpentLimit
==
0
?
60
:
secondsSpentLimit
);
// 总时间不能超过XXs
solverConfig
.
withTerminationConfig
(
terminationConfig
);
// 约束条件
solverConfig
.
withConstraintProviderClass
(
DispatchConstraintProvider
.
class
);
...
...
@@ -84,21 +99,44 @@ public class DispatchServiceImpl implements DispatchService {
// 创建求解器
SolverFactory
<
DispatchSolution
>
solverFactory
=
SolverFactory
.
create
(
solverConfig
);
Solver
<
DispatchSolution
>
solver
=
solverFactory
.
buildSolver
();
DispatchSolution
solution
=
solver
.
solve
(
problem
);
SolutionManager
<
DispatchSolution
,
HardSoftLongScore
>
scoreManager
=
SolutionManager
.
create
(
solverFactory
);
solver
.
addEventListener
(
new
SolverEventListener
<
DispatchSolution
>()
{
public
void
bestSolutionChanged
(
BestSolutionChangedEvent
<
DispatchSolution
>
event
)
{
// System.out.printf("found better score:%s at time:%ss %n", event.getNewBestScore().toShortString(),
// event.getTimeMillisSpent() / 1000);
System
.
out
.
printf
(
"%s,%s%n"
,
event
.
getNewBestScore
().
toLevelDoubles
()[
0
],
event
.
getTimeMillisSpent
()
/
1000
F
);
}
});
DispatchSolution
solution
=
solver
.
solve
(
problem
);
printSolution
(
solution
,
customerIndexMap
,
technicianIndexMap
);
System
.
out
.
println
(
"hardScore: "
+
solution
.
getScore
().
hardScore
());
System
.
out
.
println
(
"softScore: "
+
solution
.
getScore
().
softScore
());
System
.
out
.
println
(
"final Score: "
+
solution
.
getScore
().
toShortString
());
// Create a JacksonSolutionFileIO instance.
JacksonSolutionFileIO
<
DispatchSolution
>
exporter
=
new
JacksonSolutionFileIO
<
DispatchSolution
>(
DispatchSolution
.
class
);
// Set the output file.
exporter
.
write
(
solution
,
new
File
(
"dispatchSolution.json"
));
// Obtain a ScoreExplanation object for the best solution
// Using score calculation outside the Solver
// https://www.optaplanner.org/docs/optaplanner/latest/score-calculation/score-calculation.html
ScoreExplanation
<
DispatchSolution
,
HardSoftLongScore
>
scoreExplanation
=
scoreManager
.
explain
(
solution
);
System
.
out
.
println
(
scoreExplanation
.
getSummary
());
// Map<String, ConstraintMatchTotal<HardSoftLongScore>> constraintMatchTotalMap = scoreExplanation
// .getConstraintMatchTotalMap();
// constraintMatchTotalMap.forEach((key, value) -> {
// System.out.println(key + ":" + value.getConstraintName() + ":" + value.getScore().toShortString());
// });
return
Result
.
success
(
solution
.
getTechnicianList
());
}
private
static
Map
<
String
,
Integer
>
loadCustomerCodeServiceTimeMap
()
throws
UncheckedIOException
,
FileNotFoundException
{
List
<
String
>
customerServiceTime
=
IOUtils
.
readLines
(
new
FileInputStream
(
"data/customerServiceTime.csv"
),
"utf-8"
);
List
<
String
>
customerServiceTime
=
IOUtils
.
readLines
(
new
FileInputStream
(
"data/customerServiceTime.csv"
),
"utf-8"
);
Map
<
String
,
Integer
>
customerCodeServiceTimeMap
=
new
HashMap
<
String
,
Integer
>();
// code-time
for
(
int
i
=
0
;
i
<
customerServiceTime
.
size
();
i
++)
{
String
line
=
customerServiceTime
.
get
(
i
);
...
...
@@ -110,8 +148,8 @@ public class DispatchServiceImpl implements DispatchService {
private
static
Map
<
String
,
Map
<
String
,
Long
>>
loadPreferredlocationDistanceMap
()
throws
UncheckedIOException
,
FileNotFoundException
{
List
<
String
>
technicianCodeLocation
=
IOUtils
.
readLines
(
new
FileInputStream
(
"data/technicianLocation.csv"
),
"utf-8"
);
List
<
String
>
technicianCodeLocation
=
IOUtils
.
readLines
(
new
FileInputStream
(
"data/technicianLocation.csv"
),
"utf-8"
);
Map
<
String
,
String
>
technicianCodeLocationMap
=
new
HashMap
<
String
,
String
>();
// 序号-code
for
(
int
i
=
0
;
i
<
technicianCodeLocation
.
size
();
i
++)
{
String
line
=
technicianCodeLocation
.
get
(
i
);
...
...
@@ -119,8 +157,8 @@ public class DispatchServiceImpl implements DispatchService {
technicianCodeLocationMap
.
put
(
temps
[
0
],
temps
[
1
]
+
","
+
temps
[
2
]);
}
List
<
String
>
customerCodeLocation
=
IOUtils
.
readLines
(
new
FileInputStream
(
"data/customerLocation.csv"
),
"utf-8"
);
List
<
String
>
customerCodeLocation
=
IOUtils
.
readLines
(
new
FileInputStream
(
"data/customerLocation.csv"
),
"utf-8"
);
Map
<
String
,
String
>
customerCodeLocationMap
=
new
HashMap
<
String
,
String
>();
// 序号-code
for
(
int
i
=
0
;
i
<
customerCodeLocation
.
size
();
i
++)
{
String
line
=
customerCodeLocation
.
get
(
i
);
...
...
@@ -137,7 +175,7 @@ public class DispatchServiceImpl implements DispatchService {
long
distance
=
(
long
)
getDistance
(
Double
.
parseDouble
(
temps
[
1
]),
Double
.
parseDouble
(
temps
[
0
]),
Double
.
parseDouble
(
temps2
[
1
]),
Double
.
parseDouble
(
temps2
[
0
]));
Map
<
String
,
Long
>
customerMaps
=
customerTecnicianDistanceMap
.
get
(
technicianCode
);
if
(
null
==
customerMaps
)
{
if
(
null
==
customerMaps
)
{
customerMaps
=
new
HashMap
<
String
,
Long
>();
customerTecnicianDistanceMap
.
put
(
technicianCode
,
customerMaps
);
}
...
...
@@ -218,7 +256,8 @@ public class DispatchServiceImpl implements DispatchService {
private
static
DispatchSolution
createVehicleRoutingSolution
(
Map
<
Integer
,
String
>
customerIndexMap
,
Map
<
Integer
,
String
>
technicianIndexMap
,
Map
<
String
,
Set
<
String
>>
technicianCodeSkillsMap
,
Map
<
String
,
String
>
customerCodeSkillMap
,
Map
<
String
,
Map
<
String
,
Long
>>
preferredlocationDistanceMap
,
Map
<
String
,
Integer
>
customerCodeServiceTimeMap
)
throws
UncheckedIOException
,
FileNotFoundException
{
Map
<
String
,
String
>
customerCodeSkillMap
,
Map
<
String
,
Map
<
String
,
Long
>>
preferredlocationDistanceMap
,
Map
<
String
,
Integer
>
customerCodeServiceTimeMap
)
throws
UncheckedIOException
,
FileNotFoundException
{
DispatchSolution
vehicleRoutingSolution
=
new
DispatchSolution
();
// 翻转map
...
...
@@ -351,14 +390,16 @@ public class DispatchServiceImpl implements DispatchService {
totalNum
.
addAndGet
(
technician
.
getCustomerList
().
size
());
for
(
Customer
customer
:
technician
.
getCustomerList
())
{
Customer
previousCustomer
=
customer
.
getPreviousCustomer
();
int
startPath
,
endPath
;
//路上时间
int
startPath
,
endPath
;
//
路上时间
if
(
null
==
previousCustomer
)
{
startPath
=
technician
.
getDepot
().
getStartTime
();
// endPath = startPath + customer.getLocation().getPathTimeTo(technician.getDepot().getLocation());
// endPath = startPath +
// customer.getLocation().getPathTimeTo(technician.getDepot().getLocation());
endPath
=
startPath
+
technician
.
getDepot
().
getLocation
().
getPathTimeTo
(
customer
.
getLocation
());
}
else
{
startPath
=
previousCustomer
.
getDepartureTime
();
// endPath = startPath + customer.getLocation().getPathTimeTo(previousCustomer.getLocation());
// endPath = startPath +
// customer.getLocation().getPathTimeTo(previousCustomer.getLocation());
endPath
=
startPath
+
previousCustomer
.
getLocation
().
getPathTimeTo
(
customer
.
getLocation
());
}
...
...
Write
Preview
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment