Merge pull request #415 from mosinnik/#414
fix #414 Extremely slow calculateRankCrossing in java implementationdevelopment
commit
6c4e80c90f
|
@ -11,13 +11,7 @@
|
||||||
|
|
||||||
package com.mxgraph.layout.hierarchical.stage;
|
package com.mxgraph.layout.hierarchical.stage;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import com.mxgraph.layout.hierarchical.mxHierarchicalLayout;
|
import com.mxgraph.layout.hierarchical.mxHierarchicalLayout;
|
||||||
import com.mxgraph.layout.hierarchical.model.mxGraphAbstractHierarchyCell;
|
import com.mxgraph.layout.hierarchical.model.mxGraphAbstractHierarchyCell;
|
||||||
|
@ -199,73 +193,75 @@ public class mxMedianHybridCrossingReduction implements
|
||||||
protected int calculateRankCrossing(int i, mxGraphHierarchyModel model)
|
protected int calculateRankCrossing(int i, mxGraphHierarchyModel model)
|
||||||
{
|
{
|
||||||
int totalCrossings = 0;
|
int totalCrossings = 0;
|
||||||
mxGraphHierarchyRank rank = model.ranks.get(new Integer(i));
|
mxGraphHierarchyRank rank = model.ranks.get(i);
|
||||||
mxGraphHierarchyRank previousRank = model.ranks.get(new Integer(i - 1));
|
mxGraphHierarchyRank previousRank = model.ranks.get(i - 1);
|
||||||
|
|
||||||
// Create an array of connections between these two levels
|
Map<Integer, List<Integer>> tmpIndices = new TreeMap<>();
|
||||||
int currentRankSize = rank.size();
|
|
||||||
int previousRankSize = previousRank.size();
|
|
||||||
int[][] connections = new int[currentRankSize][previousRankSize];
|
|
||||||
|
|
||||||
// Iterate over the top rank and fill in the connection information
|
for (mxGraphAbstractHierarchyCell node : rank)
|
||||||
Iterator<mxGraphAbstractHierarchyCell> iter = rank.iterator();
|
|
||||||
|
|
||||||
while (iter.hasNext())
|
|
||||||
{
|
{
|
||||||
mxGraphAbstractHierarchyCell cell = iter.next();
|
int rankPosition = node.getGeneralPurposeVariable(i);
|
||||||
int rankPosition = cell.getGeneralPurposeVariable(i);
|
List<mxGraphAbstractHierarchyCell> connectedCells = node.getPreviousLayerConnectedCells(i);
|
||||||
Collection<mxGraphAbstractHierarchyCell> connectedCells = cell
|
List<Integer> nodeIndices = new ArrayList<>();
|
||||||
.getPreviousLayerConnectedCells(i);
|
|
||||||
Iterator<mxGraphAbstractHierarchyCell> iter2 = connectedCells
|
|
||||||
.iterator();
|
|
||||||
|
|
||||||
while (iter2.hasNext())
|
for (mxGraphAbstractHierarchyCell connectedCell : connectedCells)
|
||||||
{
|
{
|
||||||
mxGraphAbstractHierarchyCell connectedCell = iter2.next();
|
int otherCellRankPosition = connectedCell.getGeneralPurposeVariable(i - 1);
|
||||||
int otherCellRankPosition = connectedCell
|
nodeIndices.add(otherCellRankPosition);
|
||||||
.getGeneralPurposeVariable(i - 1);
|
|
||||||
connections[rankPosition][otherCellRankPosition] = 201207;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Iterate through the connection matrix, crossing edges are
|
Collections.sort(nodeIndices, new Comparator<Integer>()
|
||||||
// indicated by other connected edges with a greater rank position
|
|
||||||
// on one rank and lower position on the other
|
|
||||||
for (int j = 0; j < currentRankSize; j++)
|
|
||||||
{
|
|
||||||
for (int k = 0; k < previousRankSize; k++)
|
|
||||||
{
|
{
|
||||||
if (connections[j][k] == 201207)
|
@Override
|
||||||
|
public int compare(Integer o1, Integer o2)
|
||||||
{
|
{
|
||||||
// Draw a grid of connections, crossings are top right
|
return o1 - o2;
|
||||||
// and lower left from this crossing pair
|
|
||||||
for (int j2 = j + 1; j2 < currentRankSize; j2++)
|
|
||||||
{
|
|
||||||
for (int k2 = 0; k2 < k; k2++)
|
|
||||||
{
|
|
||||||
if (connections[j2][k2] == 201207)
|
|
||||||
{
|
|
||||||
totalCrossings++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int j2 = 0; j2 < j; j2++)
|
|
||||||
{
|
|
||||||
for (int k2 = k + 1; k2 < previousRankSize; k2++)
|
|
||||||
{
|
|
||||||
if (connections[j2][k2] == 201207)
|
|
||||||
{
|
|
||||||
totalCrossings++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
tmpIndices.put(rankPosition, nodeIndices);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Integer> indices = new ArrayList<>();
|
||||||
|
|
||||||
|
for (List<Integer> tmpIndex : tmpIndices.values())
|
||||||
|
{
|
||||||
|
indices.addAll(tmpIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long firstIndex = 1;
|
||||||
|
while (firstIndex < previousRank.size())
|
||||||
|
{
|
||||||
|
firstIndex <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
long treeSize = 2 * firstIndex - 1;
|
||||||
|
firstIndex -= 1;
|
||||||
|
|
||||||
|
Map<Long, Integer> tree = new HashMap<>();
|
||||||
|
for (long j = 0; j < treeSize; j++)
|
||||||
|
{
|
||||||
|
tree.put(j, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Integer index : indices)
|
||||||
|
{
|
||||||
|
long treeIndex = index + firstIndex;
|
||||||
|
tree.put(treeIndex, tree.get(treeIndex) + 1);
|
||||||
|
|
||||||
|
while (treeIndex > 0)
|
||||||
|
{
|
||||||
|
if (treeIndex % 2 != 0)
|
||||||
|
{
|
||||||
|
totalCrossings += tree.get(treeIndex + 1);
|
||||||
|
}
|
||||||
|
treeIndex = (treeIndex - 1) >> 1;
|
||||||
|
tree.put(treeIndex, tree.get(treeIndex) + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return totalCrossings / 2;
|
return totalCrossings;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue