Commit 5bf96c89 by chamberone

feat: 算法支持已分配订单要素

1 parent 0e585ff2
...@@ -17,6 +17,10 @@ public enum ConstraintNameEnum { ...@@ -17,6 +17,10 @@ public enum ConstraintNameEnum {
* 技术员到达时间跟时间窗吻合 * 技术员到达时间跟时间窗吻合
*/ */
customerTimeWindowsMatch, customerTimeWindowsMatch,
/**
* 已分配匹配
*/
dispatchedMatch,
// 软约束 // 软约束
/** /**
......
...@@ -5,6 +5,7 @@ import org.optaplanner.core.api.score.stream.Constraint; ...@@ -5,6 +5,7 @@ import org.optaplanner.core.api.score.stream.Constraint;
import org.optaplanner.core.api.score.stream.ConstraintFactory; import org.optaplanner.core.api.score.stream.ConstraintFactory;
import org.optaplanner.core.api.score.stream.ConstraintProvider; import org.optaplanner.core.api.score.stream.ConstraintProvider;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.dituhui.pea.dispatch.pojo.Customer; import com.dituhui.pea.dispatch.pojo.Customer;
import com.dituhui.pea.dispatch.pojo.Technician; import com.dituhui.pea.dispatch.pojo.Technician;
...@@ -19,6 +20,8 @@ public class DispatchConstraintProvider implements ConstraintProvider { ...@@ -19,6 +20,8 @@ public class DispatchConstraintProvider implements ConstraintProvider {
// 10s/300s: 技能权重4-技能匹配问题0个,时间窗问题9个 // 10s/300s: 技能权重4-技能匹配问题0个,时间窗问题9个
customerTimeWindowsMatch(factory), customerTimeWindowsMatch(factory),
skillMatch(factory), skillMatch(factory),
dispatchedMatch(factory),
// 软约束 // 软约束
technicianBalanceSoft(factory), technicianBalanceSoft(factory),
totalDistance(factory), totalDistance(factory),
...@@ -47,6 +50,15 @@ public class DispatchConstraintProvider implements ConstraintProvider { ...@@ -47,6 +50,15 @@ public class DispatchConstraintProvider implements ConstraintProvider {
.asConstraint(ConstraintNameEnum.customerTimeWindowsMatch.name()); .asConstraint(ConstraintNameEnum.customerTimeWindowsMatch.name());
} }
protected Constraint dispatchedMatch(ConstraintFactory factory) {
return factory.forEach(Customer.class)
.filter(customer -> customer.getDispatchedTechnicianCode() != null
&& ((customer.getTechnician() == null) || (!StringUtils
.equals(customer.getDispatchedTechnicianCode(), customer.getTechnician().getCode()))))
.penalizeLong(HardSoftLongScore.ONE_HARD, customer -> 50)
.asConstraint(ConstraintNameEnum.dispatchedMatch.name());
}
// protected Constraint customerTimeWindowsMatch1(ConstraintFactory factory) { // protected Constraint customerTimeWindowsMatch1(ConstraintFactory factory) {
// return factory.forEach(Customer.class).filter( // return factory.forEach(Customer.class).filter(
// customer -> customer.getTechnician() != null && customer.getArrivalTime() > customer.getEndTime()) // customer -> customer.getTechnician() != null && customer.getArrivalTime() > customer.getEndTime())
......
...@@ -21,6 +21,8 @@ public class Customer { ...@@ -21,6 +21,8 @@ public class Customer {
private long id; private long id;
private String code; private String code;
// 已分配
private String dispatchedTechnicianCode;
// orderid(code)+dt 确定唯一一条工单 // orderid(code)+dt 确定唯一一条工单
private String dt; private String dt;
@JsonIgnore @JsonIgnore
......
...@@ -19,6 +19,8 @@ import com.dituhui.pea.dispatch.pojo.Depot; ...@@ -19,6 +19,8 @@ import com.dituhui.pea.dispatch.pojo.Depot;
import com.dituhui.pea.dispatch.pojo.DispatchSolution; 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 com.google.common.collect.Lists;
import com.google.common.collect.Maps;
public class DataUtils { public class DataUtils {
...@@ -292,6 +294,18 @@ public class DataUtils { ...@@ -292,6 +294,18 @@ public class DataUtils {
preferredlocationDistanceMap.get(technicianIndexMap.get(i + 1)), preferredlocation)); preferredlocationDistanceMap.get(technicianIndexMap.get(i + 1)), preferredlocation));
} }
// 已分配订单 测试数据,"订单code-技术员code"
Map<String, String> orderCodeTechnichanCodesMap = Maps.newHashMap();
orderCodeTechnichanCodesMap.put("106854117", "6200041211");
orderCodeTechnichanCodesMap.put("106854169", "6200040858");
orderCodeTechnichanCodesMap.put("106863823", "6200040858");
for (Customer customer : customerList) {
if (null != orderCodeTechnichanCodesMap.get(customer.getCode())) {
System.out.println("set code"+customer.getCode()+" : "+orderCodeTechnichanCodesMap.get(customer.getCode()));
customer.setDispatchedTechnicianCode(orderCodeTechnichanCodesMap.get(customer.getCode()));
}
}
vehicleRoutingSolution.setCustomerList(customerList); vehicleRoutingSolution.setCustomerList(customerList);
vehicleRoutingSolution.setDepot(depot); vehicleRoutingSolution.setDepot(depot);
vehicleRoutingSolution.setLocationList(new ArrayList<>(locationIndex.values())); vehicleRoutingSolution.setLocationList(new ArrayList<>(locationIndex.values()));
......
...@@ -208,7 +208,8 @@ public class DispatchSolutionUtils { ...@@ -208,7 +208,8 @@ public class DispatchSolutionUtils {
} }
/** /**
* 移动某个技术员的订单,返回新方案 * 移动某个技术员的订单,返回新方案<br>
* FIXME 没有成功
* *
* @param solution * @param solution
* @param source 技术员 * @param source 技术员
...@@ -297,6 +298,7 @@ public class DispatchSolutionUtils { ...@@ -297,6 +298,7 @@ public class DispatchSolutionUtils {
switch (ConstraintNameEnum.valueOf(value.getConstraintName())) { switch (ConstraintNameEnum.valueOf(value.getConstraintName())) {
case skillMatch: case skillMatch:
case customerTimeWindowsMatch: case customerTimeWindowsMatch:
case dispatchedMatch:
for (Object indictedObject : constraintMatch.getIndictedObjectList()) { for (Object indictedObject : constraintMatch.getIndictedObjectList()) {
// 违反硬约束对象,根据具体约束返回不同类型对象 // 违反硬约束对象,根据具体约束返回不同类型对象
if (indictedObject instanceof Customer) { if (indictedObject instanceof Customer) {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!