use of org.eclipse.elk.alg.force.graph.FEdge in project elk by eclipse.
the class StressMajorization method dijkstra.
/**
* Performs Dijkstra's all pairs shortest path algorithm.
*/
private void dijkstra(final FNode source, final double[] dist) {
Queue<FNode> nodes = new PriorityQueue<FNode>((n1, n2) -> Double.compare(dist[n1.id], dist[n2.id]));
boolean[] mark = new boolean[graph.getNodes().size()];
// init
Arrays.fill(mark, false);
dist[source.id] = 0;
for (FNode n : graph.getNodes()) {
if (n.id != source.id) {
dist[n.id] = Integer.MAX_VALUE;
}
nodes.add(n);
}
// find shortest paths
while (!nodes.isEmpty()) {
FNode u = nodes.poll();
mark[u.id] = true;
for (FEdge e : connectedEdges.get(u)) {
FNode v = getOther(e, u);
if (mark[v.id]) {
continue;
}
// get e's desired length
double el;
if (e.hasProperty(StressOptions.DESIRED_EDGE_LENGTH)) {
el = e.getProperty(StressOptions.DESIRED_EDGE_LENGTH);
} else {
el = desiredEdgeLength;
}
double d = dist[u.id] + el;
if (d < dist[v.id]) {
dist[v.id] = d;
nodes.remove(v);
nodes.add(v);
}
}
}
}
use of org.eclipse.elk.alg.force.graph.FEdge in project elk by eclipse.
the class StressMajorization method initialize.
/**
* Initialize all internal structures that are required for the subsequent iterative procedure..
*
* @param fgraph the graph to be laid out.
*/
public void initialize(final FGraph fgraph) {
if (fgraph.getNodes().size() <= 1) {
return;
}
this.graph = fgraph;
this.dim = graph.getProperty(StressOptions.DIMENSION);
this.iterationLimit = graph.getProperty(StressOptions.ITERATION_LIMIT);
this.epsilon = graph.getProperty(StressOptions.EPSILON);
this.desiredEdgeLength = graph.getProperty(StressOptions.DESIRED_EDGE_LENGTH);
connectedEdges.clear();
for (FEdge edge : graph.getEdges()) {
connectedEdges.put(edge.getSource(), edge);
connectedEdges.put(edge.getTarget(), edge);
}
// all pairs shortest path
int n = graph.getNodes().size();
apsp = new double[n][n];
for (FNode source : graph.getNodes()) {
dijkstra(source, apsp[source.id]);
}
// init weight matrix
w = new double[n][n];
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
double dij = apsp[i][j];
double wij = 1.0 / (dij * dij);
w[i][j] = wij;
}
}
}
use of org.eclipse.elk.alg.force.graph.FEdge in project elk by eclipse.
the class AbstractForceModel method initialize.
/**
* Initialize the force model with the given graph. Subclasses that override this
* must call the superclass method first.
*
* @param fgraph a force graph
*/
protected void initialize(final FGraph fgraph) {
this.graph = fgraph;
this.random = fgraph.getProperty(InternalProperties.RANDOM);
// calculate the adjacency matrix for the graph
fgraph.calcAdjacency();
// calculate an upper bound for particle displacement
dispBound = Math.max(fgraph.getNodes().size() * DISP_BOUND_FACTOR + fgraph.getEdges().size(), DISP_BOUND_FACTOR * DISP_BOUND_FACTOR);
// if interactive mode is off, randomize the layout
if (!fgraph.getProperty(ForceOptions.INTERACTIVE)) {
double posScale = graph.getNodes().size();
for (FNode node : fgraph.getNodes()) {
KVector pos = node.getPosition();
pos.x = random.nextDouble() * posScale;
pos.y = random.nextDouble() * posScale;
}
}
// create bend points for node repulsion
List<FBendpoint> bends = fgraph.getBendpoints();
for (FEdge edge : fgraph.getEdges()) {
int count = edge.getProperty(ForceOptions.REPULSIVE_POWER);
if (count > 0) {
for (int i = 0; i < count; i++) {
bends.add(new FBendpoint(edge));
}
edge.distributeBendpoints();
}
}
}
use of org.eclipse.elk.alg.force.graph.FEdge in project elk by eclipse.
the class ComponentsProcessor method dfs.
/**
* Perform a DFS starting on the given node and collect all nodes that are found in the
* corresponding connected component.
*
* @param node a node.
* @param last the last node, i.e. the node from which the dfs arrived at {@value node}, or {@code null}
* if the dfs just started.
* @param graph a graph representing a connected component, or {@code null}.
* @param visited boolean indicating for each node whether it was already visited ({@code true})
* or not.
* @param incidence list of incident edges for each node.
* @return the connected component, or {@code null} if the node was already visited.
*/
private FGraph dfs(final FNode node, final FNode last, final FGraph graph, final boolean[] visited, final List<FEdge>[] incidence) {
if (!visited[node.id]) {
visited[node.id] = true;
FGraph component = graph;
if (component == null) {
component = new FGraph();
}
component.getNodes().add(node);
for (FEdge edge : incidence[node.id]) {
if (edge.getTarget() == last || edge.getSource() == last) {
// Do not handle again the edge we just arrived from
continue;
}
if (edge.getSource() != node) {
dfs(edge.getSource(), node, component, visited, incidence);
}
if (edge.getTarget() != node) {
dfs(edge.getTarget(), node, component, visited, incidence);
}
component.getEdges().add(edge);
component.getLabels().addAll(edge.getLabels());
}
return component;
}
return null;
}
use of org.eclipse.elk.alg.force.graph.FEdge in project elk by eclipse.
the class ComponentsProcessor method buildIncidenceLists.
/**
* Creates and returns the incidence list that for each node lists the incident edges.
*
* @param graph a force graph.
*/
@SuppressWarnings("unchecked")
private List<FEdge>[] buildIncidenceLists(final FGraph graph) {
int n = graph.getNodes().size();
List<FEdge>[] incidence = new List[n];
// create incidence lists
for (FNode node : graph.getNodes()) {
incidence[node.id] = new LinkedList<FEdge>();
}
// add edges to incidence lists
for (FEdge edge : graph.getEdges()) {
incidence[edge.getSource().id].add(edge);
incidence[edge.getTarget().id].add(edge);
}
return incidence;
}
Aggregations