init
parent
9a9bcfc18a
commit
02e36b1f79
|
|
@ -385,17 +385,18 @@ public class ComplianceCheckUtil {
|
|||
|
||||
|
||||
// 数据来源:industryProfessionalPersonCos(备案人员自带专业能力)+ certCapabilityList(证书专业能力)
|
||||
boolean allMet = canFullyAssign(personCapabilityMap, requiredMap);
|
||||
Map<String, Long> assignedMap = canFullyAssign(personCapabilityMap, requiredMap);
|
||||
|
||||
|
||||
IndustryEnum industryEnum = IndustryEnum.ofCode(standardsDOList.get(0).getIndustryCode());
|
||||
String industryName = industryEnum != null ? industryEnum.getValue() : standardsDOList.get(0).getIndustryCode();
|
||||
|
||||
boolean allMet = true;
|
||||
StringBuilder failureMsg = new StringBuilder();
|
||||
for (Map.Entry<String, Long> entry : requiredMap.entrySet()) {
|
||||
String capCode = entry.getKey();
|
||||
long required = entry.getValue();
|
||||
int assigned = assignedMap.getOrDefault(capCode, 0);
|
||||
long required = entry.getValue() == null ? 0L : entry.getValue();
|
||||
long assigned = assignedMap.getOrDefault(capCode, 0L);
|
||||
if (assigned < required) {
|
||||
allMet = false;
|
||||
ProfessionalCapabilityEnum capEnum = ProfessionalCapabilityEnum.ofCode(capCode);
|
||||
|
|
@ -415,13 +416,13 @@ public class ComplianceCheckUtil {
|
|||
|
||||
|
||||
/**
|
||||
* 判断是否存在一种分配方案,使所有能力都达到要求人数
|
||||
* 判断是否存在一种分配方案,使所有能力都达到要求人数,并返回每个能力的实际分配人数
|
||||
*
|
||||
* @param personCapabilityMap 人员ID → 具备的能力code集合
|
||||
* @param requiredMap 能力code → 需求人数
|
||||
* @return true 当且仅当存在满足所有需求的分配
|
||||
* @return 能力code → 实际分配人数(可用于生成失败明细)
|
||||
*/
|
||||
public static boolean canFullyAssign(
|
||||
public static Map<String, Long> canFullyAssign(
|
||||
Map<Long, Set<String>> personCapabilityMap, Map<String, Long> requiredMap) {
|
||||
// ---- 1. 构图 ----
|
||||
// 节点编号分配
|
||||
|
|
@ -452,7 +453,6 @@ public class ComplianceCheckUtil {
|
|||
capNode.put(capCodes.get(i), P + 1 + i);
|
||||
}
|
||||
|
||||
long totalRequired = 0;
|
||||
// 源点 → 人员 (容量1)
|
||||
for (int i = 0; i < P; i++) {
|
||||
dinic.addEdge(S, personNode.get(personIds.get(i)), 1);
|
||||
|
|
@ -469,18 +469,30 @@ public class ComplianceCheckUtil {
|
|||
}
|
||||
}
|
||||
|
||||
// 能力 → 汇点 (容量 = 需求人数)
|
||||
// 能力 → 汇点 (容量 = 需求人数),记录正向边引用以便后续读取实际流量
|
||||
Map<String, Dinic.Edge> capSinkEdgeMap = new HashMap<>();
|
||||
for (Map.Entry<String, Long> entry : requiredMap.entrySet()) {
|
||||
String cap = entry.getKey();
|
||||
long req = entry.getValue();
|
||||
totalRequired += req;
|
||||
long req = entry.getValue() == null ? 0L : entry.getValue();
|
||||
int v = capNode.get(cap);
|
||||
dinic.addEdge(v, T, req);
|
||||
// 正向边为 graph[v] 的最后一条
|
||||
capSinkEdgeMap.put(cap, dinic.graph[v].get(dinic.graph[v].size() - 1));
|
||||
}
|
||||
|
||||
// ---- 2. 计算最大流 ----
|
||||
long maxFlow = dinic.maxFlow(S, T);
|
||||
return maxFlow == totalRequired;
|
||||
dinic.maxFlow(S, T);
|
||||
|
||||
// ---- 3. 提取每个能力的实际分配人数 ----
|
||||
// 实际流量 = 原始容量 - 剩余容量
|
||||
Map<String, Long> assignedMap = new LinkedHashMap<>();
|
||||
for (String capCode : capCodes) {
|
||||
long req = requiredMap.get(capCode) == null ? 0L : requiredMap.get(capCode);
|
||||
Dinic.Edge edge = capSinkEdgeMap.get(capCode);
|
||||
long assigned = edge == null ? 0L : req - edge.cap;
|
||||
assignedMap.put(capCode, assigned);
|
||||
}
|
||||
return assignedMap;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -493,14 +505,22 @@ public class ComplianceCheckUtil {
|
|||
personMap.put(4L, new HashSet<>(Arrays.asList("B")));
|
||||
personMap.put(5L, new HashSet<>(Arrays.asList("A")));
|
||||
|
||||
Map<String, Long> required = new HashMap<>();
|
||||
required.put("A", 2L);
|
||||
required.put("B", 2L);
|
||||
// 场景1: A需2人, B需2人 → 可满足 (5人中A能力4人, B能力3人, 一人一岗后可分2+2=4)
|
||||
Map<String, Long> required1 = new HashMap<>();
|
||||
required1.put("A", 2L);
|
||||
required1.put("B", 2L);
|
||||
Map<String, Long> assigned1 = canFullyAssign(personMap, required1);
|
||||
System.out.println("场景1 分配结果: " + assigned1);
|
||||
System.out.println("场景1 是否满足: " + required1.entrySet().stream()
|
||||
.allMatch(e -> assigned1.getOrDefault(e.getKey(), 0L) >= e.getValue()));
|
||||
|
||||
System.out.println(canFullyAssign(personMap, required)); // true
|
||||
|
||||
// 让需求不可满足:A需要3人,B需要2人
|
||||
required.put("A", 3L);
|
||||
System.out.println(canFullyAssign(personMap, required)); // false
|
||||
// 场景2: A需3人, B需2人 → 不可满足 (一人一岗最多用5人, 但A只有4人能干, 且B占走部分人后A不够)
|
||||
Map<String, Long> required2 = new HashMap<>();
|
||||
required2.put("A", 3L);
|
||||
required2.put("B", 2L);
|
||||
Map<String, Long> assigned2 = canFullyAssign(personMap, required2);
|
||||
System.out.println("场景2 分配结果: " + assigned2);
|
||||
System.out.println("场景2 是否满足: " + required2.entrySet().stream()
|
||||
.allMatch(e -> assigned2.getOrDefault(e.getKey(), 0L) >= e.getValue()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue