Commit 5bf96c89 by chamberone

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

1 parent 0e585ff2
......@@ -17,6 +17,10 @@ public enum ConstraintNameEnum {
* 技术员到达时间跟时间窗吻合
*/
customerTimeWindowsMatch,
/**
* 已分配匹配
*/
dispatchedMatch,
// 软约束
/**
......
......@@ -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.ConstraintProvider;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.dituhui.pea.dispatch.pojo.Customer;
import com.dituhui.pea.dispatch.pojo.Technician;
......@@ -19,6 +20,8 @@ public class DispatchConstraintProvider implements ConstraintProvider {
// 10s/300s: 技能权重4-技能匹配问题0个,时间窗问题9个
customerTimeWindowsMatch(factory),
skillMatch(factory),
dispatchedMatch(factory),
// 软约束
technicianBalanceSoft(factory),
totalDistance(factory),
......@@ -47,6 +50,15 @@ public class DispatchConstraintProvider implements ConstraintProvider {
.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) {
// return factory.forEach(Customer.class).filter(
// customer -> customer.getTechnician() != null && customer.getArrivalTime() > customer.getEndTime())
......
......@@ -21,6 +21,8 @@ public class Customer {
private long id;
private String code;
// 已分配
private String dispatchedTechnicianCode;
// orderid(code)+dt 确定唯一一条工单
private String dt;
@JsonIgnore
......
......@@ -19,6 +19,8 @@ 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.google.common.collect.Lists;
import com.google.common.collect.Maps;
public class DataUtils {
......@@ -292,6 +294,18 @@ public class DataUtils {
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.setDepot(depot);
vehicleRoutingSolution.setLocationList(new ArrayList<>(locationIndex.values()));
......
......@@ -208,7 +208,8 @@ public class DispatchSolutionUtils {
}
/**
* 移动某个技术员的订单,返回新方案
* 移动某个技术员的订单,返回新方案<br>
* FIXME 没有成功
*
* @param solution
* @param source 技术员
......@@ -297,6 +298,7 @@ public class DispatchSolutionUtils {
switch (ConstraintNameEnum.valueOf(value.getConstraintName())) {
case skillMatch:
case customerTimeWindowsMatch:
case dispatchedMatch:
for (Object indictedObject : constraintMatch.getIndictedObjectList()) {
// 违反硬约束对象,根据具体约束返回不同类型对象
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!