6 * $Date: 2012-07-07 17:14:54 +0200 (Sa, 07. Jul 2012) $
7 ***************************************************************/
10 * \brief Implementation of class NodePairEnergy
12 * \author Rene Weiskircher
15 * This file is part of the Open Graph Drawing Framework (OGDF).
19 * See README.txt in the root directory of the OGDF installation for details.
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * Version 2 or 3 as published by the Free Software Foundation;
25 * see the file LICENSE.txt included in the packaging of this file
29 * This program is distributed in the hope that it will be useful,
30 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 * GNU General Public License for more details.
35 * You should have received a copy of the GNU General Public
36 * License along with this program; if not, write to the Free
37 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
38 * Boston, MA 02110-1301, USA.
40 * \see http://www.gnu.org/copyleft/gpl.html
41 ***************************************************************/
44 #include <ogdf/internal/energybased/NodePairEnergy.h>
47 #ifdef OGDF_SYSTEM_UNIX
51 #ifdef OGDF_SYSTEM_WINDOWS
60 NodePairEnergy::NodePairEnergy(const String energyname
, GraphAttributes
&AG
) :
61 EnergyFunction(energyname
,AG
),
62 m_candPairEnergy(m_G
),
68 forall_nodes(v
,m_G
) { //saving the shapes of the nodes in m_shape
69 DPoint
center(AG
.x(v
),AG
.y(v
));
70 lengthSum
+= AG
.width(v
);
71 lengthSum
+= AG
.height(v
);
72 m_shape
[v
] = IntersectionRectangle(center
,AG
.width(v
),AG
.height(v
));
74 m_G
.allNodes(m_nonIsolated
);
75 ListIterator
<node
> it
, itSucc
;
76 for(it
= m_nonIsolated
.begin(); it
.valid(); it
= itSucc
) {
78 if((*it
)->degree() == 0) m_nonIsolated
.del(it
);
80 m_nodeNums
= OGDF_NEW NodeArray
<int>(m_G
,0);
82 for(it
= m_nonIsolated
.begin(); it
.valid(); ++it
) {
83 (*m_nodeNums
)[*it
] = n_num
;
87 m_pairEnergy
= new Array2D
<double> (1,n_num
,1,n_num
);
91 void NodePairEnergy::computeEnergy()
93 int n_num
= m_nonIsolated
.size();
94 double energySum
= 0.0;
95 Array
<node
> numNodes(1,n_num
);
97 ListIterator
<node
> it
;
98 for(it
= m_nonIsolated
.begin(); it
.valid(); ++it
) {
99 numNodes
[(*m_nodeNums
)[*it
]] = *it
;
101 for(int i
= 1; i
<= n_num
-1 ; i
++) {
102 for(int j
= i
+1; j
<= n_num
; j
++) {
103 double E
= computePairEnergy(numNodes
[i
],numNodes
[j
]);
104 (*m_pairEnergy
)(i
,j
) = E
;
108 m_energy
= energySum
;
112 double NodePairEnergy::computePairEnergy(const node v
, const node w
) const {
113 return computeCoordEnergy(v
,w
,currentPos(v
),currentPos(w
));
117 void NodePairEnergy::internalCandidateTaken() {
119 int candNum
= (*m_nodeNums
)[v
];
120 ListIterator
<node
> it
;
121 for(it
= m_nonIsolated
.begin(); it
.valid(); ++ it
) {
123 int numit
= (*m_nodeNums
)[*it
];
124 (*m_pairEnergy
)(min(numit
,candNum
),max(numit
,candNum
)) = m_candPairEnergy
[*it
];
125 m_candPairEnergy
[*it
] = 0.0;
131 void NodePairEnergy::compCandEnergy()
134 int numv
= (*m_nodeNums
)[v
];
135 m_candidateEnergy
= energy();
136 ListIterator
<node
> it
;
137 for(it
= m_nonIsolated
.begin(); it
.valid(); ++ it
) {
139 int j
= (*m_nodeNums
)[*it
];
140 m_candidateEnergy
-= (*m_pairEnergy
)(min(j
,numv
),max(j
,numv
));
141 m_candPairEnergy
[*it
] = computeCoordEnergy(v
,*it
,testPos(),currentPos(*it
));
142 m_candidateEnergy
+= m_candPairEnergy
[*it
];
143 if(m_candidateEnergy
< 0.0) {
144 OGDF_ASSERT(m_candidateEnergy
> -0.00001);
145 m_candidateEnergy
= 0.0;
148 else m_candPairEnergy
[*it
] = 0.0;
150 OGDF_ASSERT(m_candidateEnergy
>= -0.0001);
155 void NodePairEnergy::printInternalData() const {
156 ListConstIterator
<node
> it
;
157 for(it
= m_nonIsolated
.begin(); it
.valid(); ++it
) {
158 cout
<< "\nNode: " << (*m_nodeNums
)[*it
];
159 cout
<< " CandidatePairEnergy: " << m_candPairEnergy
[*it
];
161 cout
<< "\nPair energies:";
162 for(int i
=1; i
< m_nonIsolated
.size(); i
++)
163 for(int j
=i
+1; j
<= m_nonIsolated
.size(); j
++)
164 if((*m_pairEnergy
)(i
,j
) != 0.0)
165 cout
<< "\nEnergy(" << i
<< ',' << j
<< ") = " << (*m_pairEnergy
)(i
,j
);