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 1b927755
authored
Jul 05, 2023
by
张晓
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
算法读取批次部分合并
1 parent
998c16f9
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
118 additions
and
47 deletions
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/impl/DispatchServiceImpl.java
project-dispatch/src/main/java/com/dituhui/pea/dispatch/pojo/Location.java
View file @
1b92775
...
@@ -67,15 +67,15 @@ public class Location {
...
@@ -67,15 +67,15 @@ public class Location {
}
}
/**
/**
* time to the given location in minutes.
* time to the given location in minutes.
* FIXME 这里简化处理没有用时间矩阵 时间=距离/100
*
* @param location other location
* @param location other location
* @return time in minutes
* @return time in minutes
*/
*/
public
int
getPathTimeTo
(
Location
location
)
{
public
int
getPathTimeTo
(
Location
location
)
{
return
(
int
)(
distanceMap
.
get
(
location
)/
100
);
return
distanceTimeMap
.
get
(
location
).
intValue
(
);
}
}
// ************************************************************************
// ************************************************************************
// Complex methods
// Complex methods
...
@@ -97,4 +97,5 @@ public class Location {
...
@@ -97,4 +97,5 @@ public class Location {
return
this
.
id
==
((
Location
)
obj
).
getId
();
return
this
.
id
==
((
Location
)
obj
).
getId
();
}
}
}
}
project-dispatch/src/main/java/com/dituhui/pea/dispatch/pojo/Technician.java
View file @
1b92775
...
@@ -195,5 +195,18 @@ public class Technician {
...
@@ -195,5 +195,18 @@ public class Technician {
return
this
.
id
==
((
Technician
)
obj
).
getId
();
return
this
.
id
==
((
Technician
)
obj
).
getId
();
}
}
@Override
public
String
toString
()
{
return
"Technician{"
+
"id="
+
id
+
", code='"
+
code
+
'\''
+
", depot="
+
depot
+
", startTime="
+
startTime
+
", endTime="
+
endTime
+
", skills="
+
skills
+
", maxCount="
+
maxCount
+
", maxMinute="
+
maxMinute
+
", maxDistanceMeter="
+
maxDistanceMeter
+
'}'
;
}
}
}
project-dispatch/src/main/java/com/dituhui/pea/dispatch/service/impl/DispatchServiceImpl.java
View file @
1b92775
...
@@ -16,10 +16,10 @@
...
@@ -16,10 +16,10 @@
package
com
.
dituhui
.
pea
.
dispatch
.
service
.
impl
;
package
com
.
dituhui
.
pea
.
dispatch
.
service
.
impl
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileInputStream
;
import
java.io.FileNotFoundException
;
import
java.io.FileNotFoundException
;
import
java.io.UncheckedIOException
;
import
java.io.UncheckedIOException
;
import
java.time.Duration
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.HashMap
;
import
java.util.HashMap
;
...
@@ -33,22 +33,28 @@ import java.util.stream.Collectors;
...
@@ -33,22 +33,28 @@ import java.util.stream.Collectors;
import
org.apache.commons.io.IOUtils
;
import
org.apache.commons.io.IOUtils
;
import
org.apache.commons.lang3.RegExUtils
;
import
org.apache.commons.lang3.RegExUtils
;
import
org.apache.commons.lang3.StringUtils
;
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.Solver
;
import
org.optaplanner.core.api.solver.SolverFactory
;
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.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.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.stereotype.Service
;
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.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.Customer
;
import
com.dituhui.pea.dispatch.pojo.Depot
;
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.Location
;
import
com.dituhui.pea.dispatch.pojo.Technician
;
import
com.dituhui.pea.dispatch.pojo.Technician
;
import
org.springframework.util.ResourceUtils
;
import
com.dituhui.pea.dispatch.service.DispatchService
;
/**
/**
* @author gpzhang
* @author gpzhang
...
@@ -59,25 +65,33 @@ public class DispatchServiceImpl implements DispatchService {
...
@@ -59,25 +65,33 @@ public class DispatchServiceImpl implements DispatchService {
private
Logger
logger
=
LoggerFactory
.
getLogger
(
getClass
());
private
Logger
logger
=
LoggerFactory
.
getLogger
(
getClass
());
@Override
@Override
public
Result
<?>
manualDispatch
()
throws
UncheckedIOException
,
FileNotFoundException
{
public
Result
<?>
manualDispatch
(
long
unimprovedSecondsSpentLimit
,
long
secondsSpentLimit
)
throws
UncheckedIOException
,
FileNotFoundException
{
logger
.
info
(
"
%s
"
,
"invoke manualDispatch"
);
logger
.
info
(
"
{}
"
,
"invoke manualDispatch"
);
// 创建解决方案对象
// 创建解决方案对象
Map
<
Integer
,
String
>
customerIndexMap
=
loadCustomerIndex
();
Map
<
Integer
,
String
>
customerIndexMap
=
loadCustomerIndex
();
Map
<
Integer
,
String
>
technicianIndexMap
=
loadTechnicianIndex
();
Map
<
Integer
,
String
>
technicianIndexMap
=
loadTechnicianIndex
();
Map
<
String
,
Set
<
String
>>
technicianCodeSkillsMap
=
loadTechnicianCodeSkillsMap
();
Map
<
String
,
Set
<
String
>>
technicianCodeSkillsMap
=
loadTechnicianCodeSkillsMap
();
Map
<
String
,
String
>
customerCodeSkillMap
=
loadCustomerCodeSkillMap
();
Map
<
String
,
String
>
customerCodeSkillMap
=
loadCustomerCodeSkillMap
();
Map
<
String
,
Map
<
String
,
Long
>>
preferredlocationDistanceMap
=
loadPreferredlocationDistanceMap
();
Map
<
String
,
Map
<
String
,
Long
>>
preferredlocationDistanceMap
=
loadPreferredlocationDistanceMap
();
Map
<
String
,
Integer
>
customerCodeServiceTimeMap
=
loadCustomerCodeServiceTimeMap
();
Map
<
String
,
Integer
>
customerCodeServiceTimeMap
=
loadCustomerCodeServiceTimeMap
();
DispatchSolution
problem
=
createVehicleRoutingSolution
(
customerIndexMap
,
technicianIndexMap
,
DispatchSolution
problem
=
createVehicleRoutingSolution
(
customerIndexMap
,
technicianIndexMap
,
technicianCodeSkillsMap
,
customerCodeSkillMap
,
preferredlocationDistanceMap
,
customerCodeServiceTimeMap
);
technicianCodeSkillsMap
,
customerCodeSkillMap
,
preferredlocationDistanceMap
,
customerCodeServiceTimeMap
);
// 创建求解器配置
// 创建求解器配置
// 创建 SolverConfig 对象,并设置求解器配置
// 创建 SolverConfig 对象,并设置求解器配置
SolverConfig
solverConfig
=
new
SolverConfig
();
SolverConfig
solverConfig
=
new
SolverConfig
();
solverConfig
.
setSolutionClass
(
DispatchSolution
.
class
);
solverConfig
.
setSolutionClass
(
DispatchSolution
.
class
);
solverConfig
.
withEntityClassList
(
Arrays
.
asList
(
Technician
.
class
,
Customer
.
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
);
solverConfig
.
withConstraintProviderClass
(
DispatchConstraintProvider
.
class
);
...
@@ -85,21 +99,44 @@ public class DispatchServiceImpl implements DispatchService {
...
@@ -85,21 +99,44 @@ public class DispatchServiceImpl implements DispatchService {
// 创建求解器
// 创建求解器
SolverFactory
<
DispatchSolution
>
solverFactory
=
SolverFactory
.
create
(
solverConfig
);
SolverFactory
<
DispatchSolution
>
solverFactory
=
SolverFactory
.
create
(
solverConfig
);
Solver
<
DispatchSolution
>
solver
=
solverFactory
.
buildSolver
();
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
);
printSolution
(
solution
,
customerIndexMap
,
technicianIndexMap
);
System
.
out
.
println
(
"final Score: "
+
solution
.
getScore
().
toShortString
());
System
.
out
.
println
(
"hardScore: "
+
solution
.
getScore
().
hardScore
());
System
.
out
.
println
(
"softScore: "
+
solution
.
getScore
().
softScore
());
// 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
());
return
Result
.
success
(
solution
.
getTechnicianList
());
}
}
private
static
Map
<
String
,
Integer
>
loadCustomerCodeServiceTimeMap
()
private
static
Map
<
String
,
Integer
>
loadCustomerCodeServiceTimeMap
()
throws
UncheckedIOException
,
FileNotFoundException
{
throws
UncheckedIOException
,
FileNotFoundException
{
List
<
String
>
customerServiceTime
=
IOUtils
.
readLines
(
new
FileInputStream
(
ResourceUtils
.
getFile
(
"classpath: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
Map
<
String
,
Integer
>
customerCodeServiceTimeMap
=
new
HashMap
<
String
,
Integer
>();
// code-time
for
(
int
i
=
0
;
i
<
customerServiceTime
.
size
();
i
++)
{
for
(
int
i
=
0
;
i
<
customerServiceTime
.
size
();
i
++)
{
String
line
=
customerServiceTime
.
get
(
i
);
String
line
=
customerServiceTime
.
get
(
i
);
...
@@ -111,8 +148,8 @@ public class DispatchServiceImpl implements DispatchService {
...
@@ -111,8 +148,8 @@ public class DispatchServiceImpl implements DispatchService {
private
static
Map
<
String
,
Map
<
String
,
Long
>>
loadPreferredlocationDistanceMap
()
private
static
Map
<
String
,
Map
<
String
,
Long
>>
loadPreferredlocationDistanceMap
()
throws
UncheckedIOException
,
FileNotFoundException
{
throws
UncheckedIOException
,
FileNotFoundException
{
List
<
String
>
technicianCodeLocation
=
IOUtils
List
<
String
>
technicianCodeLocation
=
IOUtils
.
readLines
(
new
FileInputStream
(
"data/technicianLocation.csv"
),
.
readLines
(
new
FileInputStream
(
ResourceUtils
.
getFile
(
"classpath:data/technicianLocation.csv"
)),
"utf-8"
);
"utf-8"
);
Map
<
String
,
String
>
technicianCodeLocationMap
=
new
HashMap
<
String
,
String
>();
// 序号-code
Map
<
String
,
String
>
technicianCodeLocationMap
=
new
HashMap
<
String
,
String
>();
// 序号-code
for
(
int
i
=
0
;
i
<
technicianCodeLocation
.
size
();
i
++)
{
for
(
int
i
=
0
;
i
<
technicianCodeLocation
.
size
();
i
++)
{
String
line
=
technicianCodeLocation
.
get
(
i
);
String
line
=
technicianCodeLocation
.
get
(
i
);
...
@@ -120,8 +157,8 @@ public class DispatchServiceImpl implements DispatchService {
...
@@ -120,8 +157,8 @@ public class DispatchServiceImpl implements DispatchService {
technicianCodeLocationMap
.
put
(
temps
[
0
],
temps
[
1
]
+
","
+
temps
[
2
]);
technicianCodeLocationMap
.
put
(
temps
[
0
],
temps
[
1
]
+
","
+
temps
[
2
]);
}
}
List
<
String
>
customerCodeLocation
=
IOUtils
List
<
String
>
customerCodeLocation
=
IOUtils
.
readLines
(
new
FileInputStream
(
"data/customerLocation.csv"
),
.
readLines
(
new
FileInputStream
(
ResourceUtils
.
getFile
(
"classpath:data/customerLocation.csv"
)),
"utf-8"
);
"utf-8"
);
Map
<
String
,
String
>
customerCodeLocationMap
=
new
HashMap
<
String
,
String
>();
// 序号-code
Map
<
String
,
String
>
customerCodeLocationMap
=
new
HashMap
<
String
,
String
>();
// 序号-code
for
(
int
i
=
0
;
i
<
customerCodeLocation
.
size
();
i
++)
{
for
(
int
i
=
0
;
i
<
customerCodeLocation
.
size
();
i
++)
{
String
line
=
customerCodeLocation
.
get
(
i
);
String
line
=
customerCodeLocation
.
get
(
i
);
...
@@ -130,22 +167,22 @@ public class DispatchServiceImpl implements DispatchService {
...
@@ -130,22 +167,22 @@ public class DispatchServiceImpl implements DispatchService {
}
}
// 生成订单和技术员的偏好距离Map 技术员-订单-距离
// 生成订单和技术员的偏好距离Map 技术员-订单-距离
Map
<
String
,
Map
<
String
,
Long
>>
tecnicianCustomer
DistanceMap
=
new
HashMap
<
String
,
Map
<
String
,
Long
>>();
Map
<
String
,
Map
<
String
,
Long
>>
customerTecnician
DistanceMap
=
new
HashMap
<
String
,
Map
<
String
,
Long
>>();
customerCodeLocationMap
.
forEach
((
customerCode
,
value
)
->
{
customerCodeLocationMap
.
forEach
((
customerCode
,
value
)
->
{
technicianCodeLocationMap
.
forEach
((
technicianCode
,
value2
)
->
{
technicianCodeLocationMap
.
forEach
((
technicianCode
,
value2
)
->
{
String
[]
temps
=
RegExUtils
.
removeAll
(
value
,
"\""
).
split
(
","
);
String
[]
temps
=
RegExUtils
.
removeAll
(
value
,
"\""
).
split
(
","
);
String
[]
temps2
=
RegExUtils
.
removeAll
(
value2
,
"\""
).
split
(
","
);
String
[]
temps2
=
RegExUtils
.
removeAll
(
value2
,
"\""
).
split
(
","
);
long
distance
=
(
long
)
getDistance
(
Double
.
parseDouble
(
temps
[
1
]),
Double
.
parseDouble
(
temps
[
0
]),
long
distance
=
(
long
)
getDistance
(
Double
.
parseDouble
(
temps
[
1
]),
Double
.
parseDouble
(
temps
[
0
]),
Double
.
parseDouble
(
temps2
[
1
]),
Double
.
parseDouble
(
temps2
[
0
]));
Double
.
parseDouble
(
temps2
[
1
]),
Double
.
parseDouble
(
temps2
[
0
]));
Map
<
String
,
Long
>
customerMaps
=
tecnicianCustomer
DistanceMap
.
get
(
technicianCode
);
Map
<
String
,
Long
>
customerMaps
=
customerTecnician
DistanceMap
.
get
(
technicianCode
);
if
(
null
==
customerMaps
)
{
if
(
null
==
customerMaps
)
{
customerMaps
=
new
HashMap
<
String
,
Long
>();
customerMaps
=
new
HashMap
<
String
,
Long
>();
tecnicianCustomer
DistanceMap
.
put
(
technicianCode
,
customerMaps
);
customerTecnician
DistanceMap
.
put
(
technicianCode
,
customerMaps
);
}
}
customerMaps
.
put
(
customerCode
,
distance
);
customerMaps
.
put
(
customerCode
,
distance
);
});
});
});
});
return
tecnicianCustomer
DistanceMap
;
return
customerTecnician
DistanceMap
;
}
}
/**
/**
...
@@ -170,7 +207,7 @@ public class DispatchServiceImpl implements DispatchService {
...
@@ -170,7 +207,7 @@ public class DispatchServiceImpl implements DispatchService {
}
}
private
static
Map
<
String
,
String
>
loadCustomerCodeSkillMap
()
throws
UncheckedIOException
,
FileNotFoundException
{
private
static
Map
<
String
,
String
>
loadCustomerCodeSkillMap
()
throws
UncheckedIOException
,
FileNotFoundException
{
List
<
String
>
customerSkill
=
IOUtils
.
readLines
(
new
FileInputStream
(
ResourceUtils
.
getFile
(
"classpath:data/customerSkill.csv"
)
),
"utf-8"
);
List
<
String
>
customerSkill
=
IOUtils
.
readLines
(
new
FileInputStream
(
"data/customerSkill.csv"
),
"utf-8"
);
Map
<
String
,
String
>
customerCodeSkillMap
=
new
HashMap
<
String
,
String
>();
// code-技能
Map
<
String
,
String
>
customerCodeSkillMap
=
new
HashMap
<
String
,
String
>();
// code-技能
for
(
int
i
=
0
;
i
<
customerSkill
.
size
();
i
++)
{
for
(
int
i
=
0
;
i
<
customerSkill
.
size
();
i
++)
{
String
line
=
customerSkill
.
get
(
i
);
String
line
=
customerSkill
.
get
(
i
);
...
@@ -182,7 +219,7 @@ public class DispatchServiceImpl implements DispatchService {
...
@@ -182,7 +219,7 @@ public class DispatchServiceImpl implements DispatchService {
private
static
Map
<
String
,
Set
<
String
>>
loadTechnicianCodeSkillsMap
()
private
static
Map
<
String
,
Set
<
String
>>
loadTechnicianCodeSkillsMap
()
throws
UncheckedIOException
,
FileNotFoundException
{
throws
UncheckedIOException
,
FileNotFoundException
{
List
<
String
>
technicianSkills
=
IOUtils
.
readLines
(
new
FileInputStream
(
ResourceUtils
.
getFile
(
"classpath:data/technicianSkills.csv"
)
),
"utf-8"
);
List
<
String
>
technicianSkills
=
IOUtils
.
readLines
(
new
FileInputStream
(
"data/technicianSkills.csv"
),
"utf-8"
);
Map
<
String
,
Set
<
String
>>
technicianCodeSkillsMap
=
new
HashMap
<
String
,
Set
<
String
>>();
// code-技能
Map
<
String
,
Set
<
String
>>
technicianCodeSkillsMap
=
new
HashMap
<
String
,
Set
<
String
>>();
// code-技能
for
(
int
i
=
0
;
i
<
technicianSkills
.
size
();
i
++)
{
for
(
int
i
=
0
;
i
<
technicianSkills
.
size
();
i
++)
{
String
line
=
technicianSkills
.
get
(
i
);
String
line
=
technicianSkills
.
get
(
i
);
...
@@ -200,7 +237,7 @@ public class DispatchServiceImpl implements DispatchService {
...
@@ -200,7 +237,7 @@ public class DispatchServiceImpl implements DispatchService {
}
}
private
static
Map
<
Integer
,
String
>
loadTechnicianIndex
()
throws
UncheckedIOException
,
FileNotFoundException
{
private
static
Map
<
Integer
,
String
>
loadTechnicianIndex
()
throws
UncheckedIOException
,
FileNotFoundException
{
List
<
String
>
technicianIndexlines
=
IOUtils
.
readLines
(
new
FileInputStream
(
ResourceUtils
.
getFile
(
"classpath:data/technicianIndex.csv"
)
),
"utf-8"
);
List
<
String
>
technicianIndexlines
=
IOUtils
.
readLines
(
new
FileInputStream
(
"data/technicianIndex.csv"
),
"utf-8"
);
Map
<
Integer
,
String
>
technicianIndexMap
=
new
HashMap
<
Integer
,
String
>();
// 序号-code
Map
<
Integer
,
String
>
technicianIndexMap
=
new
HashMap
<
Integer
,
String
>();
// 序号-code
for
(
int
i
=
0
;
i
<
technicianIndexlines
.
size
();
i
++)
{
for
(
int
i
=
0
;
i
<
technicianIndexlines
.
size
();
i
++)
{
technicianIndexMap
.
put
(
i
+
1
,
technicianIndexlines
.
get
(
i
));
technicianIndexMap
.
put
(
i
+
1
,
technicianIndexlines
.
get
(
i
));
...
@@ -209,7 +246,7 @@ public class DispatchServiceImpl implements DispatchService {
...
@@ -209,7 +246,7 @@ public class DispatchServiceImpl implements DispatchService {
}
}
private
static
Map
<
Integer
,
String
>
loadCustomerIndex
()
throws
UncheckedIOException
,
FileNotFoundException
{
private
static
Map
<
Integer
,
String
>
loadCustomerIndex
()
throws
UncheckedIOException
,
FileNotFoundException
{
List
<
String
>
customerIndexlines
=
IOUtils
.
readLines
(
new
FileInputStream
(
ResourceUtils
.
getFile
(
"classpath:data/customerIndex.csv"
)
),
"utf-8"
);
List
<
String
>
customerIndexlines
=
IOUtils
.
readLines
(
new
FileInputStream
(
"data/customerIndex.csv"
),
"utf-8"
);
Map
<
Integer
,
String
>
customerIndexMap
=
new
HashMap
<
Integer
,
String
>();
// 序号-code
Map
<
Integer
,
String
>
customerIndexMap
=
new
HashMap
<
Integer
,
String
>();
// 序号-code
for
(
int
i
=
0
;
i
<
customerIndexlines
.
size
();
i
++)
{
for
(
int
i
=
0
;
i
<
customerIndexlines
.
size
();
i
++)
{
customerIndexMap
.
put
(
i
+
1
,
customerIndexlines
.
get
(
i
));
customerIndexMap
.
put
(
i
+
1
,
customerIndexlines
.
get
(
i
));
...
@@ -219,14 +256,15 @@ public class DispatchServiceImpl implements DispatchService {
...
@@ -219,14 +256,15 @@ public class DispatchServiceImpl implements DispatchService {
private
static
DispatchSolution
createVehicleRoutingSolution
(
Map
<
Integer
,
String
>
customerIndexMap
,
private
static
DispatchSolution
createVehicleRoutingSolution
(
Map
<
Integer
,
String
>
customerIndexMap
,
Map
<
Integer
,
String
>
technicianIndexMap
,
Map
<
String
,
Set
<
String
>>
technicianCodeSkillsMap
,
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
();
DispatchSolution
vehicleRoutingSolution
=
new
DispatchSolution
();
// 翻转map
// 翻转map
Map
<
String
,
Integer
>
customerIndexMap2
=
customerIndexMap
.
entrySet
().
stream
()
Map
<
String
,
Integer
>
customerIndexMap2
=
customerIndexMap
.
entrySet
().
stream
()
.
collect
(
Collectors
.
toMap
(
Map
.
Entry
::
getValue
,
Map
.
Entry
::
getKey
));
.
collect
(
Collectors
.
toMap
(
Map
.
Entry
::
getValue
,
Map
.
Entry
::
getKey
));
// 初始化距离矩阵
// 初始化距离矩阵
List
<
String
>
pathMatrixlines
=
IOUtils
.
readLines
(
new
FileInputStream
(
ResourceUtils
.
getFile
(
"classpath:data/pathMatrix.csv"
)
),
"utf-8"
);
List
<
String
>
pathMatrixlines
=
IOUtils
.
readLines
(
new
FileInputStream
(
"data/pathMatrix.csv"
),
"utf-8"
);
long
[][]
pathMatrix
=
new
long
[
customerIndexMap
.
keySet
().
size
()
+
1
][
customerIndexMap
.
keySet
().
size
()
+
1
];
long
[][]
pathMatrix
=
new
long
[
customerIndexMap
.
keySet
().
size
()
+
1
][
customerIndexMap
.
keySet
().
size
()
+
1
];
for
(
int
i
=
0
;
i
<
pathMatrixlines
.
size
();
i
++)
{
for
(
int
i
=
0
;
i
<
pathMatrixlines
.
size
();
i
++)
{
String
line
=
pathMatrixlines
.
get
(
i
);
String
line
=
pathMatrixlines
.
get
(
i
);
...
@@ -249,9 +287,26 @@ public class DispatchServiceImpl implements DispatchService {
...
@@ -249,9 +287,26 @@ public class DispatchServiceImpl implements DispatchService {
}
}
// 初始化时间矩阵
// 初始化时间矩阵
List
<
String
>
pathTimeMatrixlines
=
IOUtils
.
readLines
(
new
FileInputStream
(
"data/pathTimeMatrix.csv"
),
"utf-8"
);
long
[][]
pathTimeMatrix
=
new
long
[
customerIndexMap
.
keySet
().
size
()
+
1
][
customerIndexMap
.
keySet
().
size
()
+
1
];
for
(
int
i
=
0
;
i
<
pathTimeMatrixlines
.
size
();
i
++)
{
String
line
=
pathTimeMatrixlines
.
get
(
i
);
String
[]
temps
=
line
.
split
(
","
);
for
(
int
j
=
0
;
j
<
temps
.
length
;
j
++)
{
// 秒转分钟
pathTimeMatrix
[
i
][
j
]
=
(
long
)
(
Math
.
round
(
Float
.
parseFloat
(
temps
[
j
])
/
60
));
}
}
for
(
int
i
=
0
;
i
<
pathTimeMatrix
.
length
;
i
++)
{
Location
locationi
=
locationIndex
.
get
(
i
+
1
);
for
(
int
j
=
0
;
j
<
pathTimeMatrix
[
i
].
length
;
j
++)
{
Location
locationj
=
locationIndex
.
get
(
j
+
1
);
locationi
.
getDistanceTimeMap
().
put
(
locationj
,
pathTimeMatrix
[
i
][
j
]);
}
}
// 初始化订单服务窗
// 初始化订单服务窗
List
<
String
>
customerWindowslines
=
IOUtils
.
readLines
(
new
FileInputStream
(
ResourceUtils
.
getFile
(
"classpath:data/customerWindows.csv"
)
),
"utf-8"
);
List
<
String
>
customerWindowslines
=
IOUtils
.
readLines
(
new
FileInputStream
(
"data/customerWindows.csv"
),
"utf-8"
);
Map
<
Integer
,
Integer
>
customerStartMap
=
new
HashMap
<
Integer
,
Integer
>();
Map
<
Integer
,
Integer
>
customerStartMap
=
new
HashMap
<
Integer
,
Integer
>();
Map
<
Integer
,
Integer
>
customerEndMap
=
new
HashMap
<
Integer
,
Integer
>();
Map
<
Integer
,
Integer
>
customerEndMap
=
new
HashMap
<
Integer
,
Integer
>();
for
(
int
i
=
0
;
i
<
customerWindowslines
.
size
();
i
++)
{
for
(
int
i
=
0
;
i
<
customerWindowslines
.
size
();
i
++)
{
...
@@ -335,14 +390,16 @@ public class DispatchServiceImpl implements DispatchService {
...
@@ -335,14 +390,16 @@ public class DispatchServiceImpl implements DispatchService {
totalNum
.
addAndGet
(
technician
.
getCustomerList
().
size
());
totalNum
.
addAndGet
(
technician
.
getCustomerList
().
size
());
for
(
Customer
customer
:
technician
.
getCustomerList
())
{
for
(
Customer
customer
:
technician
.
getCustomerList
())
{
Customer
previousCustomer
=
customer
.
getPreviousCustomer
();
Customer
previousCustomer
=
customer
.
getPreviousCustomer
();
int
startPath
,
endPath
;
//路上时间
int
startPath
,
endPath
;
//
路上时间
if
(
null
==
previousCustomer
)
{
if
(
null
==
previousCustomer
)
{
startPath
=
technician
.
getDepot
().
getStartTime
();
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
());
endPath
=
startPath
+
technician
.
getDepot
().
getLocation
().
getPathTimeTo
(
customer
.
getLocation
());
}
else
{
}
else
{
startPath
=
previousCustomer
.
getDepartureTime
();
startPath
=
previousCustomer
.
getDepartureTime
();
// endPath = startPath + customer.getLocation().getPathTimeTo(previousCustomer.getLocation());
// endPath = startPath +
// customer.getLocation().getPathTimeTo(previousCustomer.getLocation());
endPath
=
startPath
+
previousCustomer
.
getLocation
().
getPathTimeTo
(
customer
.
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