From 02e36b1f7905322dc6ffb08bc85ad2eca4a276a5 Mon Sep 17 00:00:00 2001 From: luotaiqian <1147642922@qq.com> Date: Thu, 16 Jul 2026 15:41:09 +0800 Subject: [PATCH] init --- .../utils/ComplianceCheckUtil.java | 60 ++++++++++++------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/utils/ComplianceCheckUtil.java b/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/utils/ComplianceCheckUtil.java index e0496c7..9e7d0c0 100644 --- a/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/utils/ComplianceCheckUtil.java +++ b/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/utils/ComplianceCheckUtil.java @@ -385,17 +385,18 @@ public class ComplianceCheckUtil { // 数据来源:industryProfessionalPersonCos(备案人员自带专业能力)+ certCapabilityList(证书专业能力) - boolean allMet = canFullyAssign(personCapabilityMap, requiredMap); + Map 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 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 canFullyAssign( Map> personCapabilityMap, Map 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 capSinkEdgeMap = new HashMap<>(); for (Map.Entry 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 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 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 required1 = new HashMap<>(); + required1.put("A", 2L); + required1.put("B", 2L); + Map 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 required2 = new HashMap<>(); + required2.put("A", 3L); + required2.put("B", 2L); + Map 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())); } }