00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00024
00025 #ifndef QVDIRECTEDGRAPH_H
00026 #define QVDIRECTEDGRAPH_H
00027
00028 #include <QPoint>
00029 #include <QHash>
00030 #include <QMap>
00031 #include <QVVector>
00032
00033 #include <qvmath.h>
00034
00038 typedef QPoint QVGraphLink;
00039
00040 bool operator<(const QVGraphLink &link1, const QVGraphLink &link2);
00041
00049 template <typename Element> class QVDirectedGraph: public QMap<QVGraphLink, Element>
00050 {
00051 private:
00052 int maxNodeIndex;
00053
00054 public:
00055
00057 QVVector getNodesConnectivity() const
00058 {
00059 QVVector result(maxNodesIndex()+1, 0.0);
00060 foreach(QVGraphLink link, this->keys())
00061 {
00062 result[link.x()]++;
00063 result[link.y()]++;
00064 }
00065
00066 return result;
00067 }
00068
00070 int getMinConnectivity() const { return int(getNodesConnectivity().min()); }
00071
00073 int getMaxConnectivity() const { return int(getNodesConnectivity().max()); }
00074
00076 double getMeanConnectivity() const { return getNodesConnectivity().mean(); }
00077
00078
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00104
00105
00106
00108 QVDirectedGraph():QMap<QVGraphLink, Element>(), maxNodeIndex(0)
00109 {
00110 }
00111
00113 void insert(const int source, const int destination, const Element element)
00114 {
00115 Q_ASSERT(source >= 0);
00116 Q_ASSERT(destination >= 0);
00117
00118 maxNodeIndex = MAX(maxNodeIndex, MAX(source, destination));
00119 QMap<QVGraphLink, Element>::insert(QVGraphLink(source, destination), element);
00120 }
00121
00123 void insert(const QVGraphLink &link, const Element element)
00124 {
00125 Q_ASSERT(link.x() >= 0);
00126 Q_ASSERT(link.y() >= 0);
00127
00128 maxNodeIndex = MAX(maxNodeIndex, MAX(link.x(), link.y()));
00129 QMap<QVGraphLink, Element>::insert(link, element);
00130 }
00131
00133 Element operator [](const QVGraphLink &link) const
00134 {
00135 Q_ASSERT(link.x() >= 0);
00136 Q_ASSERT(link.y() >= 0);
00137
00138 Q_ASSERT(link.x() <= maxNodeIndex);
00139 Q_ASSERT(link.y() <= maxNodeIndex);
00140
00141 return QMap<QVGraphLink, Element>::operator[](link);
00142 }
00143
00145 Element & operator [](const QVGraphLink &link)
00146 {
00147 Q_ASSERT(link.x() >= 0);
00148 Q_ASSERT(link.y() >= 0);
00149
00150 maxNodeIndex = MAX(maxNodeIndex, MAX(link.x(), link.y()));
00151 return QMap<QVGraphLink, Element>::operator[](link);
00152 }
00153
00155 inline const Element value(const int source, const int destination) const
00156 {
00157 Q_ASSERT(source >= 0);
00158 Q_ASSERT(destination >= 0);
00159
00160 Q_ASSERT(source <= maxNodeIndex);
00161 Q_ASSERT(destination <= maxNodeIndex);
00162
00163 return QMap<QVGraphLink, Element>::value(QVGraphLink(source, destination));
00164 }
00165
00167 inline bool contains(const int source, const int destination) const
00168 {
00169 return QMap<QVGraphLink, Element>::contains(QVGraphLink(source, destination));
00170 }
00171
00173 inline bool contains(const QVGraphLink &link) const
00174 {
00175 return QMap<QVGraphLink, Element>::contains(link);
00176 }
00177
00179 QList<QVGraphLink> getLinks() const
00180 {
00181 return this->keys();
00182 }
00183
00187 void deleteInsufficientlyConnectedNodes(const int minConnections)
00188 {
00189 QMap<int, int> counts = numLinksPerNode();
00190 while(true)
00191 {
00192 foreach( QVGraphLink p, this->keys() )
00193 if ( (counts[p.x()] < minConnections) or (counts[p.y()] < minConnections) )
00194 this->remove(p);
00195
00196 QMap<int, int> newCounts = numLinksPerNode();
00197
00198 if (counts == newCounts)
00199 break;
00200
00201 counts = newCounts;
00202 }
00203 }
00204
00206 int numNodes() const
00207 {
00208 return numLinksPerNode().count();
00209 }
00210
00213 int maxNodesIndex() const
00214 {
00215 std::cout << "WARNING: 'QVDirectedGraph::maxNodesIndex' deprecated. Use 'QVDirectedGraph::getMaxNodeIndex' instead." << std::endl;
00216 int result = 0;
00217 foreach(QVGraphLink link, this->keys())
00218 result = MAX(result, MAX(link.x(), link.y()));
00219
00220 return result;
00221 }
00222
00224 int getMaxNodeIndex() const
00225 {
00226 #ifdef DEBUG
00227 int temp = 0;
00228 foreach(QVGraphLink key, this->keys())
00229 temp = MAX(temp, MAX(key.x(), key.y()));
00230
00231 Q_ASSERT(maxNodeIndex == temp);
00232 Q_ASSERT(maxNodeIndex == maxNodesIndex());
00233 #endif // DEBUG
00234
00235 return maxNodeIndex;
00236 }
00237
00239 QMap<int, int> numLinksForNode() const
00240 {
00241 std::cout << "WARNING: 'QVDirectedGraph::numLinksForNode' deprecated. Use 'QVDirectedGraph::numLinksPerNode' instead." << std::endl;
00242 return numLinksPerNode();
00243 }
00244
00247 QMap<int, int> numLinksPerNode() const
00248 {
00249 QMap<int, int> result;
00250
00251 foreach(QVGraphLink link, this->keys())
00252 {
00253 result[link.x()] ++;
00254 result[link.y()] ++;
00255 }
00256 return result;
00257 }
00258
00259 };
00260
00261 #include <QStringList>
00262
00270 bool writeGraphToDotFile(const QString &fileName, const QVDirectedGraph<QString> &graph, const QStringList &nodeLabels = QStringList());
00271
00272 #endif
00273