物料需求有向图环检测

This commit is contained in:
yinjinlu-pc\尹金路 2025-01-15 09:48:34 +08:00
parent 3d6f519a55
commit 12e74e3520

View File

@ -0,0 +1,72 @@
package com.ktg.common.utils;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* @author yinjinlu
* @description 物料BOM环形依赖关系有向图检测
* @date 2024/12/18
*/
@Service
public class MapCircleUtils {
private Map<Integer,List<Integer>> adj; // 邻接表
private MapCircleUtils() {
this.adj = new HashMap<>();
}
public void clear() {
adj.clear();
}
public void addEdge(int v, int w) {
adj.computeIfAbsent(v, k -> new ArrayList<>()).add(w);
adj.computeIfAbsent(w, k -> new ArrayList<>());
}
public int getVertices() {
return adj.size();
}
private boolean isCircleUtil(Integer v, boolean[] visited, boolean[] onStack) {
if (visited[v]) {
return true; // 已经访问过说明有环
}
if (onStack[v]) {
return false; // 已访问过且不在递归栈中
}
visited[v] = true;
onStack[v] = true;
for (Integer w : adj.getOrDefault(v, Collections.emptyList())) {
if (isCircleUtil(w, visited, onStack)) {
return true;
}
}
onStack[v] = false;
return false;
}
private int getMaxVertextIndex(){
return adj.isEmpty() ? -1 : Collections.max(adj.keySet());
}
public boolean hasCircle() {
boolean[] visited = new boolean[getMaxVertextIndex() + 1];
boolean[] onStack = new boolean[getMaxVertextIndex() + 1];
for ( int vertext: adj.keySet()) {
if (!visited[vertext] && isCircleUtil(vertext, visited, onStack)) {
return true;
}
}
return false;
}
}