mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Add more complicated irreducible graph test
This commit is contained in:
parent
33b319ce16
commit
0fe826ade8
|
@ -69,9 +69,11 @@ public class DJGraph {
|
|||
}
|
||||
|
||||
// Add dom edges
|
||||
for (int i = 1; i < graph.size(); ++i) {
|
||||
for (int i = 0; i < graph.size(); ++i) {
|
||||
int j = domTree.immediateDominatorOf(i);
|
||||
graph.addEdge(j, i);
|
||||
if (j >= 0) {
|
||||
graph.addEdge(j, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -91,14 +91,13 @@ public final class GraphUtils {
|
|||
|
||||
for (int startNode : start) {
|
||||
stack.push(startNode);
|
||||
IntegerArray currentComponent = new IntegerArray(1);
|
||||
IntegerStack currentComponent = new IntegerStack(1);
|
||||
while (!stack.isEmpty()) {
|
||||
int node = stack.pop();
|
||||
if (visitIndex[node] > 0) {
|
||||
if (headerIndex[node] > 0) {
|
||||
continue;
|
||||
}
|
||||
currentComponent.add(node);
|
||||
int hdr = visitIndex[node];
|
||||
for (int successor : graph.outgoingEdges(node)) {
|
||||
if (!filter.match(successor)) {
|
||||
|
@ -111,15 +110,21 @@ public final class GraphUtils {
|
|||
}
|
||||
}
|
||||
if (hdr == visitIndex[node]) {
|
||||
components.add(currentComponent.getAll());
|
||||
for (int componentMember : currentComponent.getAll()) {
|
||||
IntegerArray componentMembers = new IntegerArray(graph.size());
|
||||
while (true) {
|
||||
int componentMember = currentComponent.pop();
|
||||
componentMembers.add(componentMember);
|
||||
headerIndex[componentMember] = graph.size() + 1;
|
||||
if (visitIndex[componentMember] == hdr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
currentComponent.clear();
|
||||
components.add(componentMembers.getAll());
|
||||
}
|
||||
headerIndex[node] = hdr;
|
||||
} else {
|
||||
visitIndex[node] = ++lastIndex;
|
||||
currentComponent.push(node);
|
||||
stack.push(node);
|
||||
for (int successor : graph.outgoingEdges(node)) {
|
||||
if (!filter.match(successor) || visitIndex[successor] > 0) {
|
||||
|
|
|
@ -63,17 +63,6 @@ class IrreducibleGraphConverter {
|
|||
for (int[] scc : sccs) {
|
||||
if (scc.length > 1) {
|
||||
handleStronglyConnectedComponent(djGraph, scc, nodeMap);
|
||||
int cls = djGraph.collapse(scc);
|
||||
IntegerArray nodes = new IntegerArray(djGraph.getGraph().size());
|
||||
for (int representative : djGraph.classRepresentatives(cls)) {
|
||||
for (int node : nodeMap[representative]) {
|
||||
nodes.add(node);
|
||||
}
|
||||
}
|
||||
for (int representative : djGraph.classRepresentatives(cls)) {
|
||||
nodeMap[representative] = new int[0];
|
||||
}
|
||||
nodeMap[cls] = nodes.getAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +78,7 @@ class IrreducibleGraphConverter {
|
|||
|
||||
for (int i = 0; i < scc.length; ++i) {
|
||||
if (scc[i] == sharedDom) {
|
||||
djGraph.collapse(scc);
|
||||
collapse(djGraph, scc, nodeMap);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -146,7 +135,7 @@ class IrreducibleGraphConverter {
|
|||
// Collapse
|
||||
int[] sccAndTop = Arrays.copyOf(scc, scc.length + 1);
|
||||
sccAndTop[scc.length] = sharedDom;
|
||||
djGraph.collapse(sccAndTop);
|
||||
collapse(djGraph, sccAndTop, nodeMap);
|
||||
}
|
||||
|
||||
private void splitStronglyConnectedComponent(DJGraph djGraph, IntSet domain, int sharedDom,
|
||||
|
@ -241,6 +230,20 @@ class IrreducibleGraphConverter {
|
|||
handleLoops(new DJGraph(builder.build(), mappedWeight), newNodeMap);
|
||||
}
|
||||
|
||||
private void collapse(DJGraph djGraph, int[] scc, int[][] nodeMap) {
|
||||
int cls = djGraph.collapse(scc);
|
||||
IntegerArray nodes = new IntegerArray(djGraph.getGraph().size());
|
||||
for (int representative : djGraph.classRepresentatives(cls)) {
|
||||
for (int node : nodeMap[representative]) {
|
||||
nodes.add(node);
|
||||
}
|
||||
}
|
||||
for (int representative : djGraph.classRepresentatives(cls)) {
|
||||
nodeMap[representative] = new int[0];
|
||||
}
|
||||
nodeMap[cls] = nodes.getAll();
|
||||
}
|
||||
|
||||
private static int[] flatten(int[][] array) {
|
||||
int count = 0;
|
||||
for (int i = 0; i < array.length; ++i) {
|
||||
|
|
|
@ -107,6 +107,41 @@ public class GraphTest {
|
|||
assertThat(sccs[2], is(new int[] { 2 }));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stronglyConnectedComponentCalculated4() {
|
||||
GraphBuilder builder = new GraphBuilder();
|
||||
builder.addEdge(0, 1);
|
||||
builder.addEdge(0, 2);
|
||||
builder.addEdge(1, 2);
|
||||
builder.addEdge(1, 3);
|
||||
builder.addEdge(1, 4);
|
||||
builder.addEdge(2, 1);
|
||||
builder.addEdge(2, 3);
|
||||
builder.addEdge(3, 4);
|
||||
builder.addEdge(4, 5);
|
||||
builder.addEdge(4, 6);
|
||||
builder.addEdge(5, 6);
|
||||
builder.addEdge(6, 5);
|
||||
builder.addEdge(6, 7);
|
||||
builder.addEdge(7, 4);
|
||||
builder.addEdge(7, 3);
|
||||
builder.addEdge(7, 8);
|
||||
builder.addEdge(8, 7);
|
||||
Graph graph = builder.build();
|
||||
|
||||
int[][] sccs = GraphUtils.findStronglyConnectedComponents(graph, new int[] { 1, 2, 3, 4 },
|
||||
new GraphNodeFilter() {
|
||||
@Override public boolean match(int node) {
|
||||
return node != 0;
|
||||
}
|
||||
});
|
||||
sortSccs(sccs);
|
||||
|
||||
assertThat(sccs.length, is(2));
|
||||
assertThat(sccs[0], is(new int[] { 1, 2 }));
|
||||
assertThat(sccs[1], is(new int[] { 3, 4, 5, 6, 7, 8 }));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void irreducibleGraphSplit() {
|
||||
GraphBuilder builder = new GraphBuilder();
|
||||
|
@ -152,6 +187,39 @@ public class GraphTest {
|
|||
assertTrue("Should be equialent", isEquialent(backend, graph));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void irreducibleGraphSplit3() {
|
||||
GraphBuilder builder = new GraphBuilder();
|
||||
builder.addEdge(0, 1);
|
||||
builder.addEdge(0, 2);
|
||||
builder.addEdge(1, 2);
|
||||
builder.addEdge(1, 3);
|
||||
builder.addEdge(1, 4);
|
||||
builder.addEdge(2, 1);
|
||||
builder.addEdge(2, 3);
|
||||
builder.addEdge(3, 4);
|
||||
builder.addEdge(4, 5);
|
||||
builder.addEdge(4, 6);
|
||||
builder.addEdge(5, 6);
|
||||
builder.addEdge(6, 5);
|
||||
builder.addEdge(6, 7);
|
||||
builder.addEdge(7, 4);
|
||||
builder.addEdge(7, 3);
|
||||
builder.addEdge(7, 8);
|
||||
builder.addEdge(8, 7);
|
||||
Graph graph = builder.build();
|
||||
|
||||
DefaultGraphSplittingBackend backend = new DefaultGraphSplittingBackend(graph);
|
||||
int[] weights = new int[graph.size()];
|
||||
Arrays.fill(weights, 1);
|
||||
GraphUtils.splitIrreducibleGraph(graph, weights, backend);
|
||||
Graph result = backend.getGraph();
|
||||
|
||||
assertTrue("Should be irreducible", GraphUtils.isIrreducible(graph));
|
||||
assertFalse("Should be reducible", GraphUtils.isIrreducible(result));
|
||||
assertTrue("Should be equialent", isEquialent(backend, graph));
|
||||
}
|
||||
|
||||
private boolean isEquialent(DefaultGraphSplittingBackend backend, Graph proto) {
|
||||
Graph graph = backend.getGraph();
|
||||
for (int node = 0; node < graph.size(); ++node) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user