|
@@ -1,5 +1,7 @@
|
|
|
package com.rongwei.rwapsserver.aps.score;
|
|
|
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
+import cn.hutool.core.date.DateUnit;
|
|
|
import cn.hutool.core.date.DateUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
import com.rongwei.rwapsserver.aps.domain.Equipment;
|
|
@@ -718,14 +720,25 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
productionProcesses.getEndTime().atZone(zoneId).toInstant().toEpochMilli()>deliveryMinDate.getTime();
|
|
|
return bol;
|
|
|
})
|
|
|
- .penalize(HardSoftScore.ONE_SOFT,
|
|
|
- (productionProcesses) ->
|
|
|
- 100
|
|
|
-// ((int)(DateUtil.between(deliveryMinDate, Date.from(productionProcesses.getEndTime().atZone(zoneId).toInstant()), DateUnit.MINUTE)+1)*10)
|
|
|
- )
|
|
|
+ .penalize(HardSoftScore.ONE_SOFT,(productionProcesses) ->{
|
|
|
+ Date deliveryMinDate = null;
|
|
|
+ for (ProduceOrder produceOrder : productionProcesses.getProduceOrder()) {
|
|
|
+ if(deliveryMinDate == null){
|
|
|
+ deliveryMinDate = produceOrder.getDeliveryDate();
|
|
|
+ }else{
|
|
|
+ if(deliveryMinDate.compareTo(produceOrder.getDeliveryDate())>0){
|
|
|
+ deliveryMinDate = produceOrder.getDeliveryDate();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ int i = (int) (DateUtil.between(deliveryMinDate, Date.from(productionProcesses.getEndTime().atZone(zoneId).toInstant()), DateUnit.MINUTE) + 1) * 10;
|
|
|
+ return i;
|
|
|
+ })
|
|
|
.asConstraint("deliveryDate");
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
/**
|
|
|
* 均衡排产的软约束,任务尽量分配到不同设备上
|
|
|
* @param constraintFactory
|
|
@@ -736,13 +749,75 @@ public class ApsConstraintProvider implements ConstraintProvider {
|
|
|
.filter((tc) -> {
|
|
|
return true;
|
|
|
})
|
|
|
- .groupBy(ProductionProcesses::getEquipmentId,count())
|
|
|
- .filter((productionProcesses, num) -> num > 1)
|
|
|
- .penalize(HardSoftScore.ONE_SOFT,
|
|
|
- (productionProcesses, num) -> 1)
|
|
|
+ .groupBy(ProductionProcesses::getTaskType,ConstraintCollectors.toList())
|
|
|
+ .filter((taskType, processess) ->{
|
|
|
+ boolean isbalance = false;
|
|
|
+ Integer balanceNum = balanceCount(processess);
|
|
|
+ if(balanceNum>0){
|
|
|
+ isbalance = true;
|
|
|
+ }
|
|
|
+ return isbalance;
|
|
|
+ })
|
|
|
+ .penalize(HardSoftScore.ONE_SOFT,(taskType, processess) -> {
|
|
|
+ Integer balanceNum = balanceCount(processess);
|
|
|
+ return balanceNum;
|
|
|
+ })
|
|
|
.asConstraint("balancedEqUse");
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 均衡排产分数计算
|
|
|
+ * @param processess
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private Integer balanceCount(List<ProductionProcesses> processess){
|
|
|
+ Integer balanceNum = 0;
|
|
|
+ if(processess != null && processess.size()>0){
|
|
|
+ /**
|
|
|
+ * 缓存所有设备计划均衡排产时间和实际排产时间
|
|
|
+ * map的value是List<Integer>类型长度为2,第一个为计划均衡排产时间,第二个为实际排产时间
|
|
|
+ */
|
|
|
+ Map<String,List<Integer>> equipmentPlanActualTime = new HashMap<>();
|
|
|
+ for (ProductionProcesses productionProcesses : processess) {
|
|
|
+ if(productionProcesses.getEquipmentId() == null){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // 排产作业的加工时间除以可选设备个数即为均衡排产时间
|
|
|
+ int balanceTime = (productionProcesses.getProduceTime() / productionProcesses.getOptionalEquipments().size())+1;
|
|
|
+ for (String optionalEquipment : productionProcesses.getOptionalEquipments()) {
|
|
|
+ // 缓存里有当前设备时,累计计划和实际时间
|
|
|
+ if(equipmentPlanActualTime.containsKey(optionalEquipment)){
|
|
|
+ List<Integer> planActualTimeList = equipmentPlanActualTime.get(optionalEquipment);
|
|
|
+ Integer planTime = planActualTimeList.get(0)+balanceTime;
|
|
|
+ Integer actualTime = planActualTimeList.get(1);
|
|
|
+ if(productionProcesses.getEquipmentId().equals(optionalEquipment)){
|
|
|
+ actualTime = actualTime + productionProcesses.getProduceTime();
|
|
|
+ }
|
|
|
+ planActualTimeList.set(0,planTime);
|
|
|
+ planActualTimeList.set(1,actualTime);
|
|
|
+ }
|
|
|
+ // 缓存里没有当前设备时初始化并赋值
|
|
|
+ else{
|
|
|
+ List<Integer> planActualTimeList = new ArrayList<>();
|
|
|
+ planActualTimeList.add(balanceTime);
|
|
|
+ if(productionProcesses.getEquipmentId().equals(optionalEquipment)){
|
|
|
+ planActualTimeList.add(productionProcesses.getProduceTime());
|
|
|
+ }else {
|
|
|
+ planActualTimeList.add(0);
|
|
|
+ }
|
|
|
+ equipmentPlanActualTime.put(optionalEquipment,planActualTimeList);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 计算所有设备的计划时间和实际时间之差的绝对值之和
|
|
|
+ for(String eqid : equipmentPlanActualTime.keySet()){
|
|
|
+ List<Integer> integers = equipmentPlanActualTime.get(eqid);
|
|
|
+ balanceNum = balanceNum + (Math.abs(integers.get(1)-integers.get(0)));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return balanceNum;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 合并生产工序,订单合并、尽量保证单次生产设备最大量
|
|
|
* @param constraintFactory
|