mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-13 16:54:22 +00:00
Fix Mod Sorting reporting incorrect cycles when sorting fails. Closes #10942
Co-authored-by: ZZZank <[email protected]>
This commit is contained in:
1 file changed
+26
-28
+26
-28
@@ -22,15 +22,18 @@ import java.util.Set;
|
|||||||
*
|
*
|
||||||
* <p>This detector evaluates the graph lazily and won't reflect the modifications in the
|
* <p>This detector evaluates the graph lazily and won't reflect the modifications in the
|
||||||
* graph after initial evaluation.
|
* graph after initial evaluation.
|
||||||
|
*
|
||||||
|
* <p> Implementation based on <a href="https://en.wikipedia.org/w/index.php?title=Tarjan%27s_strongly_connected_components_algorithm&oldid=1384955226">Wikipedia Psudocode</a>
|
||||||
*/
|
*/
|
||||||
public class StronglyConnectedComponentDetector<T> {
|
public class StronglyConnectedComponentDetector<T> {
|
||||||
private final Graph<T> graph;
|
private final Graph<T> graph;
|
||||||
private final Map<T, Integer> ids = new HashMap<>();
|
private final Map<T, Integer> ids = new HashMap<>();
|
||||||
private T[] elements;
|
private T[] elements;
|
||||||
private int[] dfn;
|
private int[] indexes;
|
||||||
private int[] low;
|
private int[] lowlinks;
|
||||||
private int[] stack;
|
private int[] stack;
|
||||||
private int top;
|
private int top;
|
||||||
|
private int index;
|
||||||
private BitSet onStack;
|
private BitSet onStack;
|
||||||
private Set<Set<T>> components;
|
private Set<Set<T>> components;
|
||||||
|
|
||||||
@@ -58,48 +61,43 @@ public class StronglyConnectedComponentDetector<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final int n = nodes.size();
|
final int n = nodes.size();
|
||||||
dfn = new int[n];
|
indexes = new int[n];
|
||||||
low = new int[n];
|
lowlinks = new int[n];
|
||||||
stack = new int[n];
|
stack = new int[n];
|
||||||
onStack = new BitSet(n);
|
onStack = new BitSet(n);
|
||||||
top = -1;
|
top = -1;
|
||||||
|
index = 1;
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
if (dfn[i] == 0) {
|
if (indexes[i] == 0)
|
||||||
dfs(i, 1);
|
dfs(i);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dfs(int now, int depth) {
|
private void dfs(int now) {
|
||||||
dfn[now] = depth;
|
indexes[now] = lowlinks[now] = index++;
|
||||||
low[now] = depth;
|
stack[++top] = now;
|
||||||
top++;
|
|
||||||
stack[top] = now;
|
|
||||||
onStack.set(now);
|
onStack.set(now);
|
||||||
|
|
||||||
for (T each : graph.successors(elements[now])) {
|
for (T each : graph.successors(elements[now])) {
|
||||||
int to = ids.get(each);
|
int to = ids.get(each);
|
||||||
if (dfn[to] != 0) {
|
if (indexes[to] == 0) { // 0 is unvisited
|
||||||
if (low[now] > dfn[to]) {
|
dfs(to);
|
||||||
low[now] = dfn[to];
|
if (lowlinks[now] > lowlinks[to])
|
||||||
}
|
lowlinks[now] = lowlinks[to];
|
||||||
} else {
|
} else if (onStack.get(to)) {
|
||||||
dfs(to, depth + 1);
|
if (lowlinks[now] > indexes[to])
|
||||||
if (low[now] > low[to]) {
|
lowlinks[now] = indexes[to];
|
||||||
low[now] = low[to];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dfn[now] == low[now]) {
|
if (indexes[now] == lowlinks[now]) {
|
||||||
Set<T> component = new HashSet<>();
|
Set<T> component = new HashSet<>();
|
||||||
while (top >= 0) {
|
while (top >= 0) {
|
||||||
final int t = stack[top];
|
final int w = stack[top--];
|
||||||
component.add(elements[t]);
|
onStack.clear(w);
|
||||||
onStack.clear(t);
|
component.add(elements[w]);
|
||||||
top--;
|
if (w == now)
|
||||||
if (t == now) {
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
components.add(component);
|
components.add(component);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user