use of org.gradoop.flink.model.impl.operators.layouting.util.Centroid in project gradoop by dbs-leipzig.
the class CentroidRepulsionForceMapper method map.
@Override
public Force map(LVertex vertex) {
forceSumVect.reset();
for (Centroid c : centroids) {
centroidVertex.setId(c.getId());
centroidVertex.setPosition(c.getPosition().copy());
forceSumVect.mAdd(rf.join(vertex, centroidVertex).getValue());
}
centroidVertex.setPosition(center.get(0));
forceSumVect.mAdd(rf.join(vertex, centroidVertex).getValue());
sumForce.set(vertex.getId(), forceSumVect);
return sumForce;
}
use of org.gradoop.flink.model.impl.operators.layouting.util.Centroid in project gradoop by dbs-leipzig.
the class CentroidUpdater method calculateNewCentroidPosition.
/**
* Expects the group of vertex-positions for a centroid. Calculates the new position of the
* centroid as average of the vertex-positions.
* <p>
* forceObjects does not really contain "forces", but it has the fields needed herre (id and
* vector). The id of the force object represents the id of the centroid of which the new
* position is calculated and the
* force-vector is the position of a vertex belonging to the centroid.
*
* @param forceObjects List of vertex positions, wrapped in Force-objects.
* @param collector The newly created centoid
*/
protected void calculateNewCentroidPosition(Iterable<Force> forceObjects, Collector<Centroid> collector) {
int count = 0;
Vector posSum = new Vector();
for (Force f : forceObjects) {
count++;
posSum.mAdd(f.getValue());
}
collector.collect(new Centroid(posSum.mDiv(count), count));
}
use of org.gradoop.flink.model.impl.operators.layouting.util.Centroid in project gradoop by dbs-leipzig.
the class CentroidFRLayouter method execute.
@Override
public LogicalGraph execute(LogicalGraph g) {
g = createInitialLayout(g);
DataSet<EPGMVertex> gradoopVertices = g.getVertices();
DataSet<EPGMEdge> gradoopEdges = g.getEdges();
DataSet<LVertex> vertices = gradoopVertices.map(LVertex::new);
DataSet<LEdge> edges = gradoopEdges.map(LEdge::new);
centroids = chooseInitialCentroids(vertices);
// flink can only iterate over one dataset at once. Create a dataset containing both
// centroids and vertices. Split them again at the begin of every iteration
DataSet<SimpleGraphElement> graphElements = vertices.map(x -> x);
graphElements = graphElements.union(centroids.map(x -> x));
IterativeDataSet<SimpleGraphElement> loop = graphElements.iterate(iterations);
vertices = loop.filter(x -> x instanceof LVertex).map(x -> (LVertex) x);
centroids = loop.filter(x -> x instanceof Centroid).map(x -> (Centroid) x);
centroids = calculateNewCentroids(centroids, vertices);
center = calculateLayoutCenter(vertices);
LGraph graph = new LGraph(vertices, edges);
// we have overridden repulsionForces() so layout() will use or new centroid-based solution
layout(graph);
graphElements = graph.getVertices().map(x -> x);
graphElements = graphElements.union(centroids.map(x -> x));
graphElements = loop.closeWith(graphElements);
vertices = graphElements.filter(x -> x instanceof LVertex).map(x -> (LVertex) x);
gradoopVertices = vertices.join(gradoopVertices).where(LVertex.ID_POSITION).equalTo(new Id<>()).with(new LVertexEPGMVertexJoinFunction());
return g.getFactory().fromDataSets(gradoopVertices, gradoopEdges);
}
use of org.gradoop.flink.model.impl.operators.layouting.util.Centroid in project gradoop by dbs-leipzig.
the class CentroidUpdater method removeOrSplitCentroids.
/**
* Remove centroids that are to specific and split split centroids that are to general
*
* @param c Current centroids
* @param collector Collector for new centroids
*/
protected void removeOrSplitCentroids(Centroid c, Collector<Centroid> collector) {
if (c.getCount() == 0) {
collector.collect(c);
} else if (c.getCount() < minMassFactor * vertexCount) {
// do nothing
} else if (c.getCount() > maxMassFactor * vertexCount) {
Centroid splitted = new Centroid(c.getPosition().add(new Vector(Math.random() * 2 - 1, Math.random() * 2 - 1)), c.getCount() / 2);
c.setCount(c.getCount() / 2);
collector.collect(c);
collector.collect(splitted);
} else {
collector.collect(c);
}
}
use of org.gradoop.flink.model.impl.operators.layouting.util.Centroid in project gradoop by dbs-leipzig.
the class CentroidUpdater method map.
/**
* For every vertex chooses the closest centroid.
* The Force-class is abused here, because it bundles a GradoopId and a Vector (what is
* exactly what we need here)
* We can not give it a proper name and use method-references as then it would no be
* * recognised as RichMapFunction.
*
* @param vertex The current vertices
* @return A Force object with the id of the centroid and the position of the vertex.
* @throws IllegalStateException If there are no centroids. (Therefore can not choose a closest
* centroid.
*/
public Force map(LVertex vertex) {
if (centroids == null) {
throw new IllegalStateException("DataSet of centroids MUST be broadcasted to this class");
}
if (centroids.size() == 0) {
throw new IllegalStateException("There are no centroids (left). This should NEVER happen. Layouting failed...");
}
Force best = new Force();
double bestDist = Double.MAX_VALUE;
for (Centroid c : centroids) {
double dist = c.getPosition().distance(vertex.getPosition());
if (dist < bestDist) {
best.set(c.getId(), vertex.getPosition());
bestDist = dist;
}
}
if (best.getId() == null) {
throw new IllegalStateException("There is no closest centroid. This means there " + "is a bug in this implementation, probably a NaN occured " + "during distance calculation.");
}
return best;
}
Aggregations