use of org.knime.workbench.ui.layout.Graph.Node in project knime-core by knime.
the class Layerer method assignLayers.
/**
* Perform a topological sort to assign layers to nodes. If there are fixed
* nodes they will be placed on the first or last layer, depending on
* whether they are sources or sinks.
*
* @param g the graph to be layered
* @param nodeLayer a map storing the layer of each node
* @param fixedSources a list of sources to fix on the first layer, or null
* if none exist
* @param fixedSinks a list of sinks to fix on the last layer, or null if
* none exist
* @return the list of layers, each layer containing an array list of nodes
*/
static ArrayList<ArrayList<Node>> assignLayers(final Graph g, final Map<Node, Integer> nodeLayer, final ArrayList<Node> fixedSources, final ArrayList<Node> fixedSinks) {
// initialize residual degrees, and find first sources
ArrayList<ArrayList<Node>> layers = new ArrayList<ArrayList<Node>>();
Map<Node, Integer> residualDegree = g.createIntNodeMap();
ArrayList<Node> sources = new ArrayList<Node>();
for (Node n : g.nodes()) {
residualDegree.put(n, n.inDegree());
if (n.inDegree() == 0) {
sources.add(n);
}
}
// process each layer:
int layer = 0;
// handle fixed sources, if any
if (fixedSources != null) {
layers.add(fixedSources);
for (Node n : fixedSources) {
sources.remove(n);
nodeLayer.put(n, layer);
// check if any of the outgoing neighbors becomes a source
updateSources(g, n, sources, residualDegree);
}
layer++;
}
// handle regular nodes
while (!sources.isEmpty()) {
ArrayList<Node> nextSources = new ArrayList<Node>();
// put all of the current sources on the current layer
layers.add(sources);
for (Node n : sources) {
nodeLayer.put(n, layer);
updateSources(g, n, nextSources, residualDegree);
}
// advance to the next layer
sources = nextSources;
layer++;
}
// handle fixed sinks by putting them on the last layer
if (fixedSinks != null) {
// check if there are non-fixed sinks on the current last layer
boolean lastLayerValid = true;
int lastlayer = layers.size() - 1;
for (Node n : layers.get(lastlayer)) {
if (!fixedSinks.contains(n)) {
lastLayerValid = false;
}
}
// sinks to this layer, otherwise introduce new last layer
if (!lastLayerValid) {
lastlayer++;
layers.add(new ArrayList<Graph.Node>());
}
for (Node n : fixedSinks) {
layers.get(nodeLayer.get(n)).remove(n);
nodeLayer.put(n, lastlayer);
layers.get(lastlayer).add(n);
}
}
return layers;
}
Aggregations