dev_1.0.1
luotaiqian 2026-07-16 15:41:09 +08:00
parent 9a9bcfc18a
commit 02e36b1f79
1 changed files with 40 additions and 20 deletions

View File

@ -385,17 +385,18 @@ public class ComplianceCheckUtil {
// 数据来源industryProfessionalPersonCos备案人员自带专业能力+ certCapabilityList证书专业能力 // 数据来源industryProfessionalPersonCos备案人员自带专业能力+ certCapabilityList证书专业能力
boolean allMet = canFullyAssign(personCapabilityMap, requiredMap); Map<String, Long> assignedMap = canFullyAssign(personCapabilityMap, requiredMap);
IndustryEnum industryEnum = IndustryEnum.ofCode(standardsDOList.get(0).getIndustryCode()); IndustryEnum industryEnum = IndustryEnum.ofCode(standardsDOList.get(0).getIndustryCode());
String industryName = industryEnum != null ? industryEnum.getValue() : standardsDOList.get(0).getIndustryCode(); String industryName = industryEnum != null ? industryEnum.getValue() : standardsDOList.get(0).getIndustryCode();
boolean allMet = true;
StringBuilder failureMsg = new StringBuilder(); StringBuilder failureMsg = new StringBuilder();
for (Map.Entry<String, Long> entry : requiredMap.entrySet()) { for (Map.Entry<String, Long> entry : requiredMap.entrySet()) {
String capCode = entry.getKey(); String capCode = entry.getKey();
long required = entry.getValue(); long required = entry.getValue() == null ? 0L : entry.getValue();
int assigned = assignedMap.getOrDefault(capCode, 0); long assigned = assignedMap.getOrDefault(capCode, 0L);
if (assigned < required) { if (assigned < required) {
allMet = false; allMet = false;
ProfessionalCapabilityEnum capEnum = ProfessionalCapabilityEnum.ofCode(capCode); ProfessionalCapabilityEnum capEnum = ProfessionalCapabilityEnum.ofCode(capCode);
@ -415,13 +416,13 @@ public class ComplianceCheckUtil {
/** /**
* 使 * 使
* *
* @param personCapabilityMap ID code * @param personCapabilityMap ID code
* @param requiredMap 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) { Map<Long, Set<String>> personCapabilityMap, Map<String, Long> requiredMap) {
// ---- 1. 构图 ---- // ---- 1. 构图 ----
// 节点编号分配 // 节点编号分配
@ -452,7 +453,6 @@ public class ComplianceCheckUtil {
capNode.put(capCodes.get(i), P + 1 + i); capNode.put(capCodes.get(i), P + 1 + i);
} }
long totalRequired = 0;
// 源点 → 人员 (容量1) // 源点 → 人员 (容量1)
for (int i = 0; i < P; i++) { for (int i = 0; i < P; i++) {
dinic.addEdge(S, personNode.get(personIds.get(i)), 1); 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()) { for (Map.Entry<String, Long> entry : requiredMap.entrySet()) {
String cap = entry.getKey(); String cap = entry.getKey();
long req = entry.getValue(); long req = entry.getValue() == null ? 0L : entry.getValue();
totalRequired += req;
int v = capNode.get(cap); int v = capNode.get(cap);
dinic.addEdge(v, T, req); dinic.addEdge(v, T, req);
// 正向边为 graph[v] 的最后一条
capSinkEdgeMap.put(cap, dinic.graph[v].get(dinic.graph[v].size() - 1));
} }
// ---- 2. 计算最大流 ---- // ---- 2. 计算最大流 ----
long maxFlow = dinic.maxFlow(S, T); dinic.maxFlow(S, T);
return maxFlow == totalRequired;
// ---- 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(4L, new HashSet<>(Arrays.asList("B")));
personMap.put(5L, new HashSet<>(Arrays.asList("A"))); personMap.put(5L, new HashSet<>(Arrays.asList("A")));
Map<String, Long> required = new HashMap<>(); // 场景1: A需2人, B需2人 → 可满足 (5人中A能力4人, B能力3人, 一人一岗后可分2+2=4)
required.put("A", 2L); Map<String, Long> required1 = new HashMap<>();
required.put("B", 2L); 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 // 场景2: A需3人, B需2人 → 不可满足 (一人一岗最多用5人, 但A只有4人能干, 且B占走部分人后A不够)
Map<String, Long> required2 = new HashMap<>();
// 让需求不可满足A需要3人B需要2人 required2.put("A", 3L);
required.put("A", 3L); required2.put("B", 2L);
System.out.println(canFullyAssign(personMap, required)); // false 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()));
} }
} }