35namespace energybased {
69 template<
typename ForceFunc,
bool UseForcePrime>
73 template<
typename ForceFunc,
bool UseForcePrime>
77 template<
typename ForceFunc,
bool UseForcePrime>
81 template<
typename AttrForceFunc,
bool UseForcePrime>
95 template<
typename RepForceFunc>
102 template<
typename RepForceFunc>
106 template<
typename RepForceFunc>
111 template<
typename RepForceFunc,
typename AttrForceFunc,
bool UseForcePrime>
115 template<
typename RepForceFunc,
typename AttrForceFunc>
119 template<
typename RepForceFunc,
typename AttrForceFunc>
124 template<
typename RepForceFunc>
192template<
typename ForceFunc,
bool UseForcePrime>
197 for (
node s = m_graph.firstNode(); s; s = s->succ()) {
200 m_nodeInfo[
t].position, delta);
205 force = force /
dist * mass(s) * mass(
t);
208 for (
int d = 0;
d <
Dim;
d++) {
209 m_nodeInfo[s].force[
d] += force * delta[
d];
210 m_nodeInfo[
t].force[
d] -= force * delta[
d];
214 force_prime = force_prime * mass(s) * mass(
t);
215 m_nodeInfo[s].force_prime += force_prime;
216 m_nodeInfo[
t].force_prime += force_prime;
224template<
typename ForceFunc>
229 for (
node s = m_graph.firstNode(); s; s = s->succ()) {
236 force = force /
dist * mass(s) * mass(
t);
239 for (
int d = 0;
d <
Dim;
d++) {
240 m_nodeInfo[s].force[
d] += force * delta[
d];
241 m_nodeInfo[s].force[
d] += force * delta[
d];
249template<
typename ForceFunc,
bool UseForcePrime>
253 for (
node v = m_graph.firstNode(); v; v = v->succ()) {
255 for (
int d = 0;
d <
Dim;
d++) {
256 m_pTreeForce->setPosition(
currIndex,
d, m_nodeInfo[v].position[
d]);
260 m_pTreeForce->setMass(
currIndex, m_nodeInfo[v].mass);
271 for (
node v = m_graph.firstNode(); v; v = v->succ()) {
273 for (
int d = 0;
d <
Dim;
d++) {
274 m_nodeInfo[v].force[
d] += m_pTreeForce->force(
currIndex,
d);
278 m_nodeInfo[v].force_prime += m_pTreeForce->force_prime(
currIndex);
287template<
typename ForceFunc>
292 for (
node v = m_graph.firstNode(); v; v = v->succ()) {
294 for (
int d = 0;
d <
Dim;
d++) {
299 m_pTreeForce->setMass(
currIndex, m_nodeInfo[v].mass);
310 for (
node v = m_graph.firstNode(); v; v = v->succ()) {
312 for (
int d = 0;
d <
Dim;
d++) {
313 m_nodeInfo[v].force[
d] += m_pTreeForce->force(
currIndex,
d);
322template<
typename ForceFunc,
bool UseForcePrime>
324 if (m_graph.numberOfNodes() <= m_maxNumNodesExactRepForces) {
333template<
typename ForceFunc>
336 if (m_graph.numberOfNodes() <= m_maxNumNodesExactRepForces) {
345template<
typename AttrForceFunc,
bool UseForcePrime>
348 for (
edge e = m_graph.firstEdge(); e; e = e->succ()) {
349 node s = e->source();
350 node t = e->target();
364 for (
int d = 0;
d <
Dim;
d++) {
365 delta[
d] = m_nodeInfo[
t].position[
d] - m_nodeInfo[s].position[
d];
383 m_nodeInfo[s].force_prime +=
f_prime;
384 m_nodeInfo[
t].force_prime +=
f_prime;
389 f *= m_edgeWeight[e];
392 for (
int d = 0;
d <
Dim;
d++) {
393 m_nodeInfo[s].force[
d] +=
f * delta[
d] /
dist;
394 m_nodeInfo[
t].force[
d] -=
f * delta[
d] /
dist;
401template<
typename AttrForceFunc>
405 for (
edge e = m_graph.firstEdge(); e; e = e->succ()) {
406 node s = e->source();
407 node t = e->target();
421 for (
int d = 0;
d <
Dim;
d++) {
422 delta[
d] = m_nodeInfo[
t].position[
d] - m_nodeInfo[s].position[
d];
431 double f = (
dist) * (
dist) * m_edgeWeight[e];
439 m_nodeInfo[s].force_prime +=
f_prime;
440 m_nodeInfo[
t].force_prime +=
f_prime;
443 for (
int d = 0;
d <
Dim;
d++) {
444 m_nodeInfo[s].force[
d] +=
f * delta[
d] /
dist;
445 m_nodeInfo[
t].force[
d] -=
f * delta[
d] /
dist;
451void DTreeEmbedder<Dim>::computeEdgeForcesSq()
453 for (
node s = m_graph.firstNode(); s; s = s->
succ()) {
459 for (
int d = 0;
d <
Dim;
d++) {
465 node t = adj->twinNode();
478 for (
int d = 0;
d <
Dim;
d++) {
479 delta[
d] = m_nodeInfo[
t].position[
d] - m_nodeInfo[s].position[
d];
488 for (
int d = 0;
d <
Dim;
d++) {
494 for (
int d = 0;
d <
Dim;
d++) {
507 for (
node v = m_graph.firstNode(); v; v = v->succ()) {
510 for (
int d = 0;
d <
Dim;
d++) {
511 double displ = m_nodeInfo[v].force[
d] / m_nodeInfo[v].force_prime;
512 m_nodeInfo[v].position[
d] +=
displ;
531 for (
node v = m_graph.firstNode(); v; v = v->succ()) {
534 for (
int d = 0;
d <
Dim;
d++) {
535 double displ = m_nodeInfo[v].force[
d] * timeStep;
536 m_nodeInfo[v].position[
d] +=
displ;
553 for (
node v = m_graph.firstNode(); v; v = v->succ()) {
555 for (
int d = 0;
d <
Dim;
d++) {
556 m_nodeInfo[v].force[
d] = 0.0;
558 m_nodeInfo[v].force_prime = 0.0;
564template<
typename RepForceFunc,
bool>
577 return moveNodes(m_defaultTimeStep);
581template<
typename RepForceFunc>
585 double maxDisplacement = epsilon;
595template<
typename RepForceFunc>
602 double timeStep = m_defaultTimeStep;
609 double maxDisplacement = 100000000.0;
626 maxDisplacement = moveNodes(timeStep);
634 timeStep = timeStep *
t;
655template<
typename RepForceFunc,
typename AttrForceFunc,
bool UseForcePrime>
658 if (m_graph.numberOfNodes() < 2) {
664 <<
"doIterationsNewton: V = " << m_graph.numberOfNodes()
665 <<
" E = " << m_graph.numberOfEdges() <<
" Iterations " <<
numIterations << std::endl;
668 double maxDisplacement = 10000.0;
684 maxDisplacement = moveNodesByForcePrime();
686 maxDisplacement = moveNodes(0.1);
694template<
typename RepForceFunc,
typename AttrForceFunc>
702template<
typename RepForceFunc,
typename AttrForceFunc>
715 for (
int d = 0;
d <
Dim;
d++) {
720 for (
node v = m_graph.firstNode(); v; v = v->succ()) {
721 for (
int d = 0;
d <
Dim;
d++) {
728 for (
int d = 0;
d <
Dim;
d++) {
732 for (
node v = m_graph.firstNode(); v; v = v->
succ()) {
733 for (
int d = 0;
d <
Dim;
d++) {
734 setPosition(v,
d, delta[
d]);
741 for (
node v = m_graph.firstNode(); v; v = v->succ()) {
742 for (
int d = 0;
d <
Dim;
d++) {
743 setPosition(v,
d, position(v,
d) * scaleFactor);
750 return m_nodeInfo[v].position[
d];
755 m_nodeInfo[v].position[
d] = coord;
760 return m_nodeInfo[v].mass;
765 m_nodeInfo[v].mass = mass;
775 m_edgeWeight[e] = weight;
780 return m_edgeWeight[e];
adjEntry succ() const
Returns the successor in the adjacency list.
Dynamic arrays indexed with edges.
void init()
Reinitializes the array. Associates the array with no graph.
Class for the representation of edges.
Data type for general directed graphs (adjacency list representation).
int numberOfNodes() const
Returns the number of nodes in the graph.
node firstNode() const
Returns the first node in the list of all nodes.
static std::ostream & slout(Level level=Level::Default)
stream for logging-output (global)
Dynamic arrays indexed with nodes.
Class for the representation of nodes.
int degree() const
Returns the degree of the node (indegree + outdegree).
node succ() const
Returns the successor in the list of all nodes.
adjEntry firstAdj() const
Returns the first entry in the adjaceny list.
void centerNodesAt(double centerBBox[Dim])
computes the bounding box and all nodes are translated such that bbox center is at centerBBox
const Graph & m_graph
the graph
NodeArray< NodeInfo > m_nodeInfo
node states of all nodes
void doIterationsNewton(int numIterations, double epsilon, RepForceFunc repForceFunc, AttrForceFunc attrForceFunc)
void setMass(node v, double mass)
sets the mass of a node v
virtual ~DTreeEmbedder()
destructor
DTreeEmbedder(const Graph &graph)
constructor with a given graph, allocates memory and does initialization
void computeEdgeForces(AttrForceFunc attrForceFunc)
computes the edge forces for one iteration
void computeRepForces(ForceFunc forceFunc)
computes the repulsive forces
void setPosition(node v, int d, double coord)
sets the d-th coordinate of node v to coord
double moveNodesByForcePrime()
void doIterationsTempl(int numIterations, double epsilon, RepForceFunc repForceFunc, AttrForceFunc attrForceFunc)
does multiple iterations using the given repulsive force function
void resetForces()
sets the forces of all nodes to 0
void doIterationsStandard(int numIterations, double epsilon, RepForceFunc repForceFunc, AttrForceFunc attrForceFunc)
double position(node v, int d) const
returns the d-th coordinate of node v
const Graph & graph() const
returns the graph
double moveNodes(double timeStep)
moves the nodes by the computed force vector
DTreeForce< Dim > * m_pTreeForce
the tree force approx
void computeRepForcesExact(ForceFunc forceFunc)
computes the repulsive forces for one iteration in O(n^2)
EdgeArray< double > m_edgeWeight
the weight of the edges
void computeRepForcesApprox(ForceFunc forceFunc)
uses the tree code to approximate the repulsive forces in O(nlogn) for one iteration
double mass(node v) const
returns the mass of node v
double edgeWeight(edge e) const
returns the edge weight
int m_maxNumNodesExactRepForces
void setEdgeWeight(edge e, double weight)
sets the weight of an edge
void scaleNodes(double scaleFactor)
changes the position of nodes according to a given scale factor
AdjElement * adjEntry
The type of adjacency entries.
NodeElement * node
The type of nodes.
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
The namespace for all OGDF objects.
double mass
the mass of this node
double force[Dim]
the forces on a node
double position[Dim]
position of a node
double force_prime
sum of the derivs