Search in sources :

Example 1 with NGraph

use of org.eclipse.elk.alg.common.networksimplex.NGraph in project elk by eclipse.

the class NetworkSimplexLayerer method initialize.

/**
 * Helper method for the network simplex layerer. It instantiates all necessary attributes for
 * the execution of the network simplex layerer and initializes them with their default values.
 * All edges in the connected component given by the input argument will be determined, as well
 * as the number of incoming and outgoing edges of each node ( {@code inDegree}, respectively
 * {@code outDegree}). All sinks and source nodes in the connected component identified in this
 * step will be added to {@code sinks}, respectively {@code sources}.
 *
 * @param theNodes
 *            a {@code Collection} containing all nodes of the graph
 */
private NGraph initialize(final List<LNode> theNodes) {
    final Map<LNode, NNode> nodeMap = Maps.newHashMap();
    // transform nodes
    NGraph graph = new NGraph();
    for (LNode lNode : theNodes) {
        NNode nNode = NNode.of().origin(lNode).create(graph);
        nodeMap.put(lNode, nNode);
    }
    // transform edges
    for (LNode lNode : theNodes) {
        for (LEdge lEdge : lNode.getOutgoingEdges()) {
            // ignore self-loops
            if (lEdge.isSelfLoop()) {
                continue;
            }
            NEdge.of(lEdge).weight(1 * Math.max(1, lEdge.getProperty(LayeredOptions.PRIORITY_SHORTNESS))).delta(1).source(nodeMap.get(lEdge.getSource().getNode())).target(nodeMap.get(lEdge.getTarget().getNode())).create();
        }
    }
    return graph;
}
Also used : NNode(org.eclipse.elk.alg.common.networksimplex.NNode) LEdge(org.eclipse.elk.alg.layered.graph.LEdge) NGraph(org.eclipse.elk.alg.common.networksimplex.NGraph) LNode(org.eclipse.elk.alg.layered.graph.LNode)

Example 2 with NGraph

use of org.eclipse.elk.alg.common.networksimplex.NGraph in project elk by eclipse.

the class NetworkSimplexLayerer method process.

/**
 * The main method of the network simplex layerer. It determines an optimal layering of all
 * nodes in the graph concerning a minimal length of all edges by using the network simplex
 * algorithm described in {@literal Emden R. Gansner, Eleftherios Koutsofios, Stephen
 * C. North, Kiem-Phong Vo: "A Technique for Drawing Directed Graphs", AT&T Bell Laboratories.
 * Note that the execution time of this implemented algorithm has not been proven quadratic yet.
 *
 * @param theLayeredGraph
 *            a layered graph which initially only contains layerless nodes and is
 *            then filled with layers
 * @param monitor
 *            the progress monitor
 */
public void process(final LGraph theLayeredGraph, final IElkProgressMonitor monitor) {
    monitor.begin("Network simplex layering", 1);
    layeredGraph = theLayeredGraph;
    int thoroughness = theLayeredGraph.getProperty(LayeredOptions.THOROUGHNESS) * ITER_LIMIT_FACTOR;
    List<LNode> theNodes = layeredGraph.getLayerlessNodes();
    if (theNodes.size() < 1) {
        monitor.done();
        return;
    }
    // layer graph, each connected component separately
    List<List<LNode>> connectedComponents = connectedComponents(theNodes);
    int[] previousLayeringNodeCounts = null;
    for (List<LNode> connComp : connectedComponents) {
        // determine a limit on the number of iterations
        int iterLimit = thoroughness * (int) Math.sqrt(connComp.size());
        NGraph graph = initialize(connComp);
        // execute the network simplex algorithm on the (sub-)graph
        NetworkSimplex.forGraph(graph).withIterationLimit(iterLimit).withPreviousLayering(previousLayeringNodeCounts).withBalancing(true).execute(monitor.subTask(1));
        // the layers are store in the NNode's layer field.
        List<Layer> layers = layeredGraph.getLayers();
        for (NNode nNode : graph.nodes) {
            // add additional layers to match required number
            while (layers.size() <= nNode.layer) {
                layers.add(layers.size(), new Layer(layeredGraph));
            }
            LNode lNode = (LNode) nNode.origin;
            lNode.setLayer(layers.get(nNode.layer));
        }
        if (connectedComponents.size() > 1) {
            previousLayeringNodeCounts = new int[layeredGraph.getLayers().size()];
            int layerIdx = 0;
            for (Layer l : layeredGraph) {
                previousLayeringNodeCounts[layerIdx++] = l.getNodes().size();
            }
        }
    }
    // empty the list of unlayered nodes
    theNodes.clear();
    // release the created resources
    dispose();
    monitor.done();
}
Also used : NNode(org.eclipse.elk.alg.common.networksimplex.NNode) NGraph(org.eclipse.elk.alg.common.networksimplex.NGraph) LNode(org.eclipse.elk.alg.layered.graph.LNode) List(java.util.List) LinkedList(java.util.LinkedList) Layer(org.eclipse.elk.alg.layered.graph.Layer)

Example 3 with NGraph

use of org.eclipse.elk.alg.common.networksimplex.NGraph in project elk by eclipse.

the class NetworkSimplexPlacer method prepare.

// ------------------------------------------------------------------------------------------------
// Preparation
// ------------------------------------------------------------------------------------------------
private void prepare() {
    this.nGraph = new NGraph();
    // "integerify" port anchor and port positions
    // note that margin.top and margin.bottom are not required to be integral
    // since they do not influence the offset calculation for the edges
    // ... while we're at it, we assign ids to the nodes and edges
    int nodeIdx = 0;
    int edgeIdx = 0;
    for (Layer l : lGraph) {
        for (LNode lNode : l) {
            lNode.id = nodeIdx++;
            for (LEdge e : lNode.getOutgoingEdges()) {
                e.id = edgeIdx++;
            }
            // if a node is flexible, an edge attaches to the port itself within
            // the auxiliary graph, thus the anchor must be integer
            // otherwise the port position can be altered such that it accounts for the anchor's position as well
            boolean anchorMustBeInteger = isFlexibleNode(lNode);
            for (LPort p : lNode.getPorts()) {
                if (anchorMustBeInteger) {
                    // anchor
                    double y = p.getAnchor().y;
                    if (y != Math.floor(y)) {
                        double offset = y - Math.round(y);
                        p.getAnchor().y -= offset;
                    }
                }
                // port + anchor
                double y = p.getPosition().y + p.getAnchor().y;
                if (y != Math.floor(y)) {
                    double offset = y - Math.round(y);
                    p.getPosition().y -= offset;
                }
            }
        }
    }
    this.nodeCount = nodeIdx;
    this.edgeCount = edgeIdx;
    this.nodeReps = new NodeRep[nodeIdx];
    this.edgeReps = new EdgeRep[edgeIdx];
    this.flexibleWhereSpacePermitsEdges.clear();
}
Also used : LEdge(org.eclipse.elk.alg.layered.graph.LEdge) NGraph(org.eclipse.elk.alg.common.networksimplex.NGraph) LPort(org.eclipse.elk.alg.layered.graph.LPort) LNode(org.eclipse.elk.alg.layered.graph.LNode) Layer(org.eclipse.elk.alg.layered.graph.Layer)

Example 4 with NGraph

use of org.eclipse.elk.alg.common.networksimplex.NGraph in project elk by eclipse.

the class NetworkSimplexPlacer method insertFlexibleWhereSpaceAuxiliaryEdges.

/**
 * Inserts auxiliary edges for the case that {@link NodeFlexibility#NODE_SIZE_WHERE_SPACE_PERMITS} node exist.
 */
private void insertFlexibleWhereSpaceAuxiliaryEdges() {
    int minLayer = nGraph.nodes.stream().map(n -> n.layer).min(Integer::compare).get();
    int maxLayer = nGraph.nodes.stream().map(n -> n.layer).max(Integer::compare).get();
    int usedLayers = maxLayer - minLayer;
    NNode globalSource = NNode.of().create(nGraph);
    NNode globalSink = NNode.of().create(nGraph);
    // make sure the distance between source and sink is preserved
    NEdge.of().weight(NODE_SIZE_WEIGHT_STATIC * 2).delta(usedLayers).source(globalSource).target(globalSink).create();
    // fix the position of most non-flexible nodes and make sure the flexible nodes
    // can only increase in size
    Arrays.stream(nodeReps).filter(nr -> nr.origin.getType() == NodeType.NORMAL).filter(// allow leaves to move
    nr -> nr.origin.getPorts().size() > 1).forEach(nr -> {
        NEdge.of().weight(0).delta(nr.tail.layer - minLayer).source(globalSource).target(nr.tail).create();
        NEdge.of().weight(0).delta(usedLayers - nr.head.layer).source(nr.head).target(globalSink).create();
    });
}
Also used : NNode(org.eclipse.elk.alg.common.networksimplex.NNode) Arrays(java.util.Arrays) ElkMargin(org.eclipse.elk.core.math.ElkMargin) Iterables(com.google.common.collect.Iterables) GraphProperties(org.eclipse.elk.alg.layered.options.GraphProperties) Layer(org.eclipse.elk.alg.layered.graph.Layer) ListIterator(java.util.ListIterator) LLabel(org.eclipse.elk.alg.layered.graph.LLabel) NorthSouthPortPreprocessor(org.eclipse.elk.alg.layered.intermediate.NorthSouthPortPreprocessor) PortSide(org.eclipse.elk.core.options.PortSide) IElkProgressMonitor(org.eclipse.elk.core.util.IElkProgressMonitor) LEdge(org.eclipse.elk.alg.layered.graph.LEdge) NGraph(org.eclipse.elk.alg.common.networksimplex.NGraph) Stack(java.util.Stack) LayeredOptions(org.eclipse.elk.alg.layered.options.LayeredOptions) ArrayList(java.util.ArrayList) Spacings(org.eclipse.elk.alg.layered.options.Spacings) IntermediateProcessorStrategy(org.eclipse.elk.alg.layered.intermediate.IntermediateProcessorStrategy) Lists(com.google.common.collect.Lists) InternalProperties(org.eclipse.elk.alg.layered.options.InternalProperties) Map(java.util.Map) NodeFlexibility.getNodeFlexibility(org.eclipse.elk.alg.layered.options.NodeFlexibility.getNodeFlexibility) StreamSupport(java.util.stream.StreamSupport) NetworkSimplex(org.eclipse.elk.alg.common.networksimplex.NetworkSimplex) NodeType(org.eclipse.elk.alg.layered.graph.LNode.NodeType) LayoutProcessorConfiguration(org.eclipse.elk.core.alg.LayoutProcessorConfiguration) NNode(org.eclipse.elk.alg.common.networksimplex.NNode) DoubleMath(com.google.common.math.DoubleMath) NodeFlexibility(org.eclipse.elk.alg.layered.options.NodeFlexibility) Iterator(java.util.Iterator) PortConstraints(org.eclipse.elk.core.options.PortConstraints) Predicate(java.util.function.Predicate) NEdge(org.eclipse.elk.alg.common.networksimplex.NEdge) Set(java.util.Set) ILayoutPhase(org.eclipse.elk.core.alg.ILayoutPhase) Maps(com.google.common.collect.Maps) Sets(com.google.common.collect.Sets) LGraphElement(org.eclipse.elk.alg.layered.graph.LGraphElement) List(java.util.List) LGraph(org.eclipse.elk.alg.layered.graph.LGraph) NodeLabelPlacement(org.eclipse.elk.core.options.NodeLabelPlacement) LayeredPhases(org.eclipse.elk.alg.layered.LayeredPhases) LabelAndNodeSizeProcessor(org.eclipse.elk.alg.layered.intermediate.LabelAndNodeSizeProcessor) LPort(org.eclipse.elk.alg.layered.graph.LPort) LNode(org.eclipse.elk.alg.layered.graph.LNode) Queue(java.util.Queue)

Example 5 with NGraph

use of org.eclipse.elk.alg.common.networksimplex.NGraph in project elk by eclipse.

the class NetworkSimplexPlacer method transformFixedPosNode.

/**
 * @return a {@link NodeRep} instance that basically contains two references to {@link LNode}.
 */
private NodeRep transformFixedPosNode(final LNode lNode) {
    NNode singleNode = NNode.of().origin(lNode).type("non-flexible").create(nGraph);
    // register the ports with the node
    lNode.getPorts().stream().filter(p -> PortSide.SIDES_EAST_WEST.contains(p.getSide())).forEach(p -> portMap.put(p, singleNode));
    return new NodeRep(lNode, false, singleNode, singleNode);
}
Also used : NNode(org.eclipse.elk.alg.common.networksimplex.NNode) Arrays(java.util.Arrays) ElkMargin(org.eclipse.elk.core.math.ElkMargin) Iterables(com.google.common.collect.Iterables) GraphProperties(org.eclipse.elk.alg.layered.options.GraphProperties) Layer(org.eclipse.elk.alg.layered.graph.Layer) ListIterator(java.util.ListIterator) LLabel(org.eclipse.elk.alg.layered.graph.LLabel) NorthSouthPortPreprocessor(org.eclipse.elk.alg.layered.intermediate.NorthSouthPortPreprocessor) PortSide(org.eclipse.elk.core.options.PortSide) IElkProgressMonitor(org.eclipse.elk.core.util.IElkProgressMonitor) LEdge(org.eclipse.elk.alg.layered.graph.LEdge) NGraph(org.eclipse.elk.alg.common.networksimplex.NGraph) Stack(java.util.Stack) LayeredOptions(org.eclipse.elk.alg.layered.options.LayeredOptions) ArrayList(java.util.ArrayList) Spacings(org.eclipse.elk.alg.layered.options.Spacings) IntermediateProcessorStrategy(org.eclipse.elk.alg.layered.intermediate.IntermediateProcessorStrategy) Lists(com.google.common.collect.Lists) InternalProperties(org.eclipse.elk.alg.layered.options.InternalProperties) Map(java.util.Map) NodeFlexibility.getNodeFlexibility(org.eclipse.elk.alg.layered.options.NodeFlexibility.getNodeFlexibility) StreamSupport(java.util.stream.StreamSupport) NetworkSimplex(org.eclipse.elk.alg.common.networksimplex.NetworkSimplex) NodeType(org.eclipse.elk.alg.layered.graph.LNode.NodeType) LayoutProcessorConfiguration(org.eclipse.elk.core.alg.LayoutProcessorConfiguration) NNode(org.eclipse.elk.alg.common.networksimplex.NNode) DoubleMath(com.google.common.math.DoubleMath) NodeFlexibility(org.eclipse.elk.alg.layered.options.NodeFlexibility) Iterator(java.util.Iterator) PortConstraints(org.eclipse.elk.core.options.PortConstraints) Predicate(java.util.function.Predicate) NEdge(org.eclipse.elk.alg.common.networksimplex.NEdge) Set(java.util.Set) ILayoutPhase(org.eclipse.elk.core.alg.ILayoutPhase) Maps(com.google.common.collect.Maps) Sets(com.google.common.collect.Sets) LGraphElement(org.eclipse.elk.alg.layered.graph.LGraphElement) List(java.util.List) LGraph(org.eclipse.elk.alg.layered.graph.LGraph) NodeLabelPlacement(org.eclipse.elk.core.options.NodeLabelPlacement) LayeredPhases(org.eclipse.elk.alg.layered.LayeredPhases) LabelAndNodeSizeProcessor(org.eclipse.elk.alg.layered.intermediate.LabelAndNodeSizeProcessor) LPort(org.eclipse.elk.alg.layered.graph.LPort) LNode(org.eclipse.elk.alg.layered.graph.LNode) Queue(java.util.Queue)

Aggregations

NGraph (org.eclipse.elk.alg.common.networksimplex.NGraph)6 NNode (org.eclipse.elk.alg.common.networksimplex.NNode)5 LNode (org.eclipse.elk.alg.layered.graph.LNode)5 LEdge (org.eclipse.elk.alg.layered.graph.LEdge)4 Layer (org.eclipse.elk.alg.layered.graph.Layer)4 List (java.util.List)3 LPort (org.eclipse.elk.alg.layered.graph.LPort)3 Iterables (com.google.common.collect.Iterables)2 Lists (com.google.common.collect.Lists)2 Maps (com.google.common.collect.Maps)2 Sets (com.google.common.collect.Sets)2 DoubleMath (com.google.common.math.DoubleMath)2 ArrayList (java.util.ArrayList)2 Arrays (java.util.Arrays)2 Iterator (java.util.Iterator)2 ListIterator (java.util.ListIterator)2 Map (java.util.Map)2 Queue (java.util.Queue)2 Set (java.util.Set)2 Stack (java.util.Stack)2