Loading isis/src/control/objs/ControlNet/ControlNet.cpp +0 −161 Original line number Diff line number Diff line Loading @@ -860,167 +860,6 @@ namespace Isis { } /** * This method uses Kruskal's Algorithm to construct a minimum spanning tree * of the given island, with control measures acting as the edges between * graph nodes. Because measures do not directly connect graph nodes, but * rather connect graph nodes to control points, points are considered * "intermediate vertices". When building the tree, we treat points like * normal graph node vertices, but after the tree is built, we prune away any * measures that, in conjunction with a point, form an "incomplete edge". * Such an edge goes from a graph node to a point, but does not have another * edge going from that point to another node. Since the primary purpose of * this tree is to evaluate image connectivity, such edges are unnecessary. * A "complete edge" consists of two measures and a point, and connects two * graph nodes, or images. * * The cost of each edge is determined by the provided less-than comparison * function. If a Control Measure is less-than another, it is said to have a * lower cost, and is thus more likely to appear in the minimum spanning tree. * * Minimum spanning trees are constructed on islands, not networks, so it is * important that the caller first retrieve the list of islands in the network * from the GetNodeConnections() method before invoking this method. Creating * a minimum spanning tree for an entire network with multiple islands would * be impractical, as this method does not account for the possibility that * some nodes are disconnected in the input. * * A common usage of the minimum spanning tree is to measure the importance of * a given measure or point to the overall connectivity of a network. If a * measurement is not in the MST, we do not need to worry about creating * additional islands by removing it. * * It is important that the user choose their less-than function carefully. * If a poor less-than function is used, then "bad" measures could end up in * the MST while "good" measures are excluded, thus giving the user the false * impression that a good measure can be safely deleted, while a bad measure * must be preserved. The application "cnetwinnow", for example, tries to * remove as many measures with high residuals as possible without increasing * the island count of the network, so its less-than function compares the * residual magnitude of the two input measures. * * @param island The list of graph nodes forming the island to be minimized * @param lessThan A comparison function telling us if one measure is better * than another * * @return The set of all measures (edges) in the minimum spanning tree */ QSet< ControlMeasure * > ControlNet::MinimumSpanningTree( QList< ControlCubeGraphNode *> &island, bool lessThan(const ControlMeasure *, const ControlMeasure *)) const { // Kruskal's Algorithm QSet< ControlMeasure * > minimumTree; // We start with a map containing all the unconnected vertices (nodes and // points), each its own single-element tree. Our goal is join them all // together into one tree connecting every vertex. We map into the forest // with point ID and serial number so the two types of vertices can share a // common, nearly constant-time lookup interface. QMap< QString, ControlVertex * > forest; // Get a list of all the candidate edges on the island, and a set of their // associated Control Points (to avoid duplication, as measures share common // points). Keep a count of how many measures in the MST are connected to // each point, as we'll want to prune off points with only one such // conenction. QList< ControlMeasure * > edges; QMap< ControlPoint *, int > uniquePoints; for (int i = 0; i < island.size(); i++) { // Add each graph node as a tree in the forest ControlCubeGraphNode *node = island[i]; forest.insert(node->getSerialNumber(), new ControlVertex(node)); // Every graph node has a list of measures: these are our edges QList< ControlMeasure * > measures = node->getMeasures(); for (int j = 0; j < measures.size(); j++) { edges.append(measures[j]); // Every measure has a point: these act as intermediate vertices. We // keep a count of how many edges in the MST come off this point. // Points with less than 2 edges are considered incomplete, as they do // not form a connection from one graph node to another, or a "complete // edge" uniquePoints.insert(measures[j]->Parent(), 0); } } // Sort the edges in increasing cost with the provided less-than function qSort(edges.begin(), edges.end(), lessThan); // Add every unique point on the island as a tree in the forest QList< ControlPoint * > pointList = uniquePoints.keys(); for (int i = 0; i < pointList.size(); i++) { ControlPoint *point = pointList[i]; forest.insert(point->GetId(), new ControlVertex(point)); } // Every time we join two trees together, we reduce the total number of // trees by one, but our forest data structure is unchanged, so keep a // record of the actual forest size to decrement manually as we go along int trees = forest.size(); // Keep trying to join trees until there is only one tree remaining or we're // out of edges to try while (trees > 1 && edges.size() > 0) { // Try to add our lowest-cost edge to the minimum spanning tree ControlMeasure *leastEdge = edges.takeFirst(); // Each edge connects two vertices: a point and a graph node. So grab the // trees for each node and check that they're disjoint, and thus able to // be joined. QString pointId = leastEdge->Parent()->GetId(); ControlVertex *pointVertex = forest[pointId]; QString serialNum = leastEdge->ControlSN()->getSerialNumber(); ControlVertex *nodeVertex = forest[serialNum]; // When the edge joins two different trees (i.e., they have different // roots), then add the edge to the minimum spanning tree and join the // trees into one. Otherwise, we have formed a cycle and should thus // discard the edge. if (pointVertex->getRoot() != nodeVertex->getRoot()) { ControlVertex::join(pointVertex, nodeVertex); trees--; minimumTree.insert(leastEdge); uniquePoints[pointVertex->getPoint()]++; } } // Prune edges that go from a graph node to a point, but not from that // point to another graph node. We care about image (graph node) // connectivity, not point connectivity. A complete edge consists of two // measures and a point, so remove any incomplete edges. QList< ControlMeasure * > unprunedEdges = minimumTree.values(); for (int i = 0; i < unprunedEdges.size(); i++) { if (uniquePoints[unprunedEdges[i]->Parent()] < 2) // The point this edge is connected to does not go on to another node, // so prune it minimumTree.remove(unprunedEdges[i]); } // Clean up our vertices. This will not delete any of the points, measures, // or graph nodes. All of that is owned by the network. QList< ControlVertex * > vertexList = forest.values(); for (int i = 0; i < vertexList.size(); i++) delete vertexList[i]; // Sanity check: an island with n > 1 nodes must, by definition, have an MST // of e edges such that n <= e <= 2n int n = island.size(); int e = minimumTree.size(); if (n > 1) { if (e < n || e > 2 * n) { IString msg = "An island of n = [" + IString(n) + "] > 1 nodes must have a minimum spanning tree of e edges such that " " n <= e <= 2n, but e = [" + IString(e) + "]"; throw IException(IException::Programmer, msg, _FILEINFO_); } } return minimumTree; } /** * @returns The total number of edges in the bi-directional graph for images */ Loading isis/src/control/objs/ControlNet/ControlNet.h +4 −71 Original line number Diff line number Diff line Loading @@ -213,6 +213,9 @@ namespace Isis { * image. Previously, this had to be done throug the graph. * @history 2018-01-26 Kristin Berry - Added pointAdded() function to eliminate redundant measure * adds to the control network. * @history 2018-01-26 Kristin Berry - Removed unused methods and associated code: * MinimumSpanningTree, * */ class ControlNet : public QObject { Q_OBJECT Loading Loading @@ -243,9 +246,6 @@ namespace Isis { QList< ControlCubeGraphNode * > GetCubeGraphNodes(); QList< QList< QString > > GetSerialConnections() const; QList< QList< ControlCubeGraphNode * > > GetNodeConnections() const; QSet< ControlMeasure * > MinimumSpanningTree( QList< ControlCubeGraphNode *> &island, bool lessThan(const ControlMeasure *, const ControlMeasure *)) const; int getEdgeCount() const; QString CubeGraphToString() const; QList< ControlMeasure * > GetMeasuresInCube(QString serialNumber); Loading Loading @@ -362,73 +362,6 @@ namespace Isis { double(ControlMeasure::*m_accessor)() const; }; /** * Encapsulation of a vertex in a minimum spanning tree. Can be either a * Control Point or a Graph Node. Each vertex is connected to another by * a measure. A vertex without a parent vertex is considered a root node, * or the base of its own tree. * * @author ????-??-?? Unknown * * @internal */ class ControlVertex { public: //! Construct a vertex from a Graph Node ControlVertex(ControlCubeGraphNode *node) { m_node = node; m_point = NULL; m_parent = NULL; } //! Construct a vertex from a Control Point ControlVertex(ControlPoint *point) { m_point = point; m_node = NULL; m_parent = NULL; } //! Does not own any of its private data ~ControlVertex() {} //! Set the parent vertex, removing the root node status. void setParent(ControlVertex *v) { m_parent = v; } //! Get the root node, or greatest ancestor ControlVertex * getRoot() { ControlVertex *current = this; while (current->getParent() != NULL) current = current->getParent(); return current; } //! Get the parent node. A root node has no parent. ControlVertex * getParent() { return m_parent; } //! Get the node representation of this vertex ControlCubeGraphNode * getNode() { return m_node; } //! Get the point representation of this vertex ControlPoint * getPoint() { return m_point; } //! Join two nodes by setting one root to be the other's parent static void join(ControlVertex *v1, ControlVertex *v2) { v1->getRoot()->setParent(v2->getRoot()); } private: //! The possibly non-existant graph node ControlCubeGraphNode *m_node; //! The possibly non-existant control point ControlPoint *m_point; //! The possibly non-existant parent vertex ControlVertex *m_parent; }; private: // data //! hash ControlPoints by ControlPoint Id QHash< QString, ControlPoint * > * points; Loading isis/src/control/objs/ControlNet/unitTest.cpp +66 −61 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ using namespace Isis; * @author ????-??-?? Unknown * @internal * @history 2016-05-11 Jeannie Backer - Added tests for setTarget methods. * @history 2018-05-29 Kristin Berry - Commented out (to probably be removed) code related to * unused, removed methods. */ bool lessThan(const ControlMeasure *m1, const ControlMeasure *m2) { return m1->GetResidualMagnitude() < m2->GetResidualMagnitude(); Loading Loading @@ -148,67 +150,70 @@ void testConnectivity() { if (islands[0].contains(m9->ControlSN())) islands.swap(0, 1); cout << " " << "Island Count = " << islands.size() << endl; cout << "\nTesting MinimumSpanningTree()\n"; QList< QSet< ControlMeasure * > > spanningTrees; int nodeCount = 0; for (int i = 0; i < islands.size(); i++) { spanningTrees.append(net.MinimumSpanningTree(islands[i], lessThan)); nodeCount += islands[i].size(); } cout << " " << "Tree Count = " << spanningTrees.size() << endl; cout << " " << "Graph Node Count = " << nodeCount << endl; QList< QMap< QString, ControlMeasure * > > includedMaps; QList< QMap< QString, ControlMeasure * > > excludedMaps; for (int i = 0; i < spanningTrees.size(); i++) { includedMaps.append(QMap< QString, ControlMeasure * >()); excludedMaps.append(QMap< QString, ControlMeasure * >()); } int measureCount = 0; for (int p = 0; p < net.GetNumPoints(); p++) { ControlPoint *point = net.GetPoint(p); for (int m = 0; m < point->GetNumMeasures(); m++) { ControlMeasure *measure = point->GetMeasure(m); measureCount++; for (int i = 0; i < spanningTrees.size(); i++) { if (islands[i].contains(measure->ControlSN())) { if (spanningTrees[i].contains(measure)) includedMaps[i].insert(measureNames[measure], measure); else excludedMaps[i].insert(measureNames[measure], measure); } } } } cout << " " << "Measure Count = " << measureCount << endl; int includedMeasures = 0; for (int i = 0; i < spanningTrees.size(); i++) { QSet< ControlMeasure * > measures = spanningTrees[i]; includedMeasures += measures.size(); } if (islands.size() != spanningTrees.size()) { cout << " " << "Island Count == " << islands.size() << " != " << spanningTrees.size() << " == MST Count" << endl; } else { cout << " " << "Island Count == " << islands.size() << " == MST Count" << endl; for (int i = 0; i < spanningTrees.size(); i++) { cout << "\n " << "Minimum Spanning Tree " << i << endl; cout << " " << "Nodes = " << islands[i].size() << endl; cout << " " << "Included Measures = " << includedMaps[i].size() << endl; printMeasures(includedMaps[i].values(), measureNames); cout << " " << "Excluded Measures = " << excludedMaps[i].size() << endl; printMeasures(excludedMaps[i].values(), measureNames); } } // This region all has to do with testing the (unused) removed MinimumSpanningTree // method. It's left in here commented-out for now in case we would like to test // island functionality here, using similar output, after updating ControlNet to use boost. //cout << "\nTesting MinimumSpanningTree()\n"; //QList< QSet< ControlMeasure * > > spanningTrees; //int nodeCount = 0; //for (int i = 0; i < islands.size(); i++) { // spanningTrees.append(net.MinimumSpanningTree(islands[i], lessThan)); // nodeCount += islands[i].size(); //} // //cout << " " << "Tree Count = " << spanningTrees.size() << endl; //cout << " " << "Graph Node Count = " << nodeCount << endl; // //QList< QMap< QString, ControlMeasure * > > includedMaps; //QList< QMap< QString, ControlMeasure * > > excludedMaps; //for (int i = 0; i < spanningTrees.size(); i++) { // includedMaps.append(QMap< QString, ControlMeasure * >()); // excludedMaps.append(QMap< QString, ControlMeasure * >()); //} // //int measureCount = 0; //for (int p = 0; p < net.GetNumPoints(); p++) { // ControlPoint *point = net.GetPoint(p); // for (int m = 0; m < point->GetNumMeasures(); m++) { // ControlMeasure *measure = point->GetMeasure(m); // measureCount++; // for (int i = 0; i < spanningTrees.size(); i++) { // if (islands[i].contains(measure->ControlSN())) { // if (spanningTrees[i].contains(measure)) // includedMaps[i].insert(measureNames[measure], measure); // else // excludedMaps[i].insert(measureNames[measure], measure); // } // } // } //} //cout << " " << "Measure Count = " << measureCount << endl; // //int includedMeasures = 0; //for (int i = 0; i < spanningTrees.size(); i++) { // QSet< ControlMeasure * > measures = spanningTrees[i]; // includedMeasures += measures.size(); //} // //if (islands.size() != spanningTrees.size()) { // cout << " " << "Island Count == " << islands.size() << " != " << // spanningTrees.size() << " == MST Count" << endl; //} //else { // cout << " " << "Island Count == " << islands.size() << // " == MST Count" << endl; // // for (int i = 0; i < spanningTrees.size(); i++) { // cout << "\n " << "Minimum Spanning Tree " << i << endl; // // cout << " " << "Nodes = " << islands[i].size() << endl; // cout << " " << "Included Measures = " << includedMaps[i].size() << endl; // printMeasures(includedMaps[i].values(), measureNames); // // cout << " " << "Excluded Measures = " << excludedMaps[i].size() << endl; // printMeasures(excludedMaps[i].values(), measureNames); // } //} } Loading Loading
isis/src/control/objs/ControlNet/ControlNet.cpp +0 −161 Original line number Diff line number Diff line Loading @@ -860,167 +860,6 @@ namespace Isis { } /** * This method uses Kruskal's Algorithm to construct a minimum spanning tree * of the given island, with control measures acting as the edges between * graph nodes. Because measures do not directly connect graph nodes, but * rather connect graph nodes to control points, points are considered * "intermediate vertices". When building the tree, we treat points like * normal graph node vertices, but after the tree is built, we prune away any * measures that, in conjunction with a point, form an "incomplete edge". * Such an edge goes from a graph node to a point, but does not have another * edge going from that point to another node. Since the primary purpose of * this tree is to evaluate image connectivity, such edges are unnecessary. * A "complete edge" consists of two measures and a point, and connects two * graph nodes, or images. * * The cost of each edge is determined by the provided less-than comparison * function. If a Control Measure is less-than another, it is said to have a * lower cost, and is thus more likely to appear in the minimum spanning tree. * * Minimum spanning trees are constructed on islands, not networks, so it is * important that the caller first retrieve the list of islands in the network * from the GetNodeConnections() method before invoking this method. Creating * a minimum spanning tree for an entire network with multiple islands would * be impractical, as this method does not account for the possibility that * some nodes are disconnected in the input. * * A common usage of the minimum spanning tree is to measure the importance of * a given measure or point to the overall connectivity of a network. If a * measurement is not in the MST, we do not need to worry about creating * additional islands by removing it. * * It is important that the user choose their less-than function carefully. * If a poor less-than function is used, then "bad" measures could end up in * the MST while "good" measures are excluded, thus giving the user the false * impression that a good measure can be safely deleted, while a bad measure * must be preserved. The application "cnetwinnow", for example, tries to * remove as many measures with high residuals as possible without increasing * the island count of the network, so its less-than function compares the * residual magnitude of the two input measures. * * @param island The list of graph nodes forming the island to be minimized * @param lessThan A comparison function telling us if one measure is better * than another * * @return The set of all measures (edges) in the minimum spanning tree */ QSet< ControlMeasure * > ControlNet::MinimumSpanningTree( QList< ControlCubeGraphNode *> &island, bool lessThan(const ControlMeasure *, const ControlMeasure *)) const { // Kruskal's Algorithm QSet< ControlMeasure * > minimumTree; // We start with a map containing all the unconnected vertices (nodes and // points), each its own single-element tree. Our goal is join them all // together into one tree connecting every vertex. We map into the forest // with point ID and serial number so the two types of vertices can share a // common, nearly constant-time lookup interface. QMap< QString, ControlVertex * > forest; // Get a list of all the candidate edges on the island, and a set of their // associated Control Points (to avoid duplication, as measures share common // points). Keep a count of how many measures in the MST are connected to // each point, as we'll want to prune off points with only one such // conenction. QList< ControlMeasure * > edges; QMap< ControlPoint *, int > uniquePoints; for (int i = 0; i < island.size(); i++) { // Add each graph node as a tree in the forest ControlCubeGraphNode *node = island[i]; forest.insert(node->getSerialNumber(), new ControlVertex(node)); // Every graph node has a list of measures: these are our edges QList< ControlMeasure * > measures = node->getMeasures(); for (int j = 0; j < measures.size(); j++) { edges.append(measures[j]); // Every measure has a point: these act as intermediate vertices. We // keep a count of how many edges in the MST come off this point. // Points with less than 2 edges are considered incomplete, as they do // not form a connection from one graph node to another, or a "complete // edge" uniquePoints.insert(measures[j]->Parent(), 0); } } // Sort the edges in increasing cost with the provided less-than function qSort(edges.begin(), edges.end(), lessThan); // Add every unique point on the island as a tree in the forest QList< ControlPoint * > pointList = uniquePoints.keys(); for (int i = 0; i < pointList.size(); i++) { ControlPoint *point = pointList[i]; forest.insert(point->GetId(), new ControlVertex(point)); } // Every time we join two trees together, we reduce the total number of // trees by one, but our forest data structure is unchanged, so keep a // record of the actual forest size to decrement manually as we go along int trees = forest.size(); // Keep trying to join trees until there is only one tree remaining or we're // out of edges to try while (trees > 1 && edges.size() > 0) { // Try to add our lowest-cost edge to the minimum spanning tree ControlMeasure *leastEdge = edges.takeFirst(); // Each edge connects two vertices: a point and a graph node. So grab the // trees for each node and check that they're disjoint, and thus able to // be joined. QString pointId = leastEdge->Parent()->GetId(); ControlVertex *pointVertex = forest[pointId]; QString serialNum = leastEdge->ControlSN()->getSerialNumber(); ControlVertex *nodeVertex = forest[serialNum]; // When the edge joins two different trees (i.e., they have different // roots), then add the edge to the minimum spanning tree and join the // trees into one. Otherwise, we have formed a cycle and should thus // discard the edge. if (pointVertex->getRoot() != nodeVertex->getRoot()) { ControlVertex::join(pointVertex, nodeVertex); trees--; minimumTree.insert(leastEdge); uniquePoints[pointVertex->getPoint()]++; } } // Prune edges that go from a graph node to a point, but not from that // point to another graph node. We care about image (graph node) // connectivity, not point connectivity. A complete edge consists of two // measures and a point, so remove any incomplete edges. QList< ControlMeasure * > unprunedEdges = minimumTree.values(); for (int i = 0; i < unprunedEdges.size(); i++) { if (uniquePoints[unprunedEdges[i]->Parent()] < 2) // The point this edge is connected to does not go on to another node, // so prune it minimumTree.remove(unprunedEdges[i]); } // Clean up our vertices. This will not delete any of the points, measures, // or graph nodes. All of that is owned by the network. QList< ControlVertex * > vertexList = forest.values(); for (int i = 0; i < vertexList.size(); i++) delete vertexList[i]; // Sanity check: an island with n > 1 nodes must, by definition, have an MST // of e edges such that n <= e <= 2n int n = island.size(); int e = minimumTree.size(); if (n > 1) { if (e < n || e > 2 * n) { IString msg = "An island of n = [" + IString(n) + "] > 1 nodes must have a minimum spanning tree of e edges such that " " n <= e <= 2n, but e = [" + IString(e) + "]"; throw IException(IException::Programmer, msg, _FILEINFO_); } } return minimumTree; } /** * @returns The total number of edges in the bi-directional graph for images */ Loading
isis/src/control/objs/ControlNet/ControlNet.h +4 −71 Original line number Diff line number Diff line Loading @@ -213,6 +213,9 @@ namespace Isis { * image. Previously, this had to be done throug the graph. * @history 2018-01-26 Kristin Berry - Added pointAdded() function to eliminate redundant measure * adds to the control network. * @history 2018-01-26 Kristin Berry - Removed unused methods and associated code: * MinimumSpanningTree, * */ class ControlNet : public QObject { Q_OBJECT Loading Loading @@ -243,9 +246,6 @@ namespace Isis { QList< ControlCubeGraphNode * > GetCubeGraphNodes(); QList< QList< QString > > GetSerialConnections() const; QList< QList< ControlCubeGraphNode * > > GetNodeConnections() const; QSet< ControlMeasure * > MinimumSpanningTree( QList< ControlCubeGraphNode *> &island, bool lessThan(const ControlMeasure *, const ControlMeasure *)) const; int getEdgeCount() const; QString CubeGraphToString() const; QList< ControlMeasure * > GetMeasuresInCube(QString serialNumber); Loading Loading @@ -362,73 +362,6 @@ namespace Isis { double(ControlMeasure::*m_accessor)() const; }; /** * Encapsulation of a vertex in a minimum spanning tree. Can be either a * Control Point or a Graph Node. Each vertex is connected to another by * a measure. A vertex without a parent vertex is considered a root node, * or the base of its own tree. * * @author ????-??-?? Unknown * * @internal */ class ControlVertex { public: //! Construct a vertex from a Graph Node ControlVertex(ControlCubeGraphNode *node) { m_node = node; m_point = NULL; m_parent = NULL; } //! Construct a vertex from a Control Point ControlVertex(ControlPoint *point) { m_point = point; m_node = NULL; m_parent = NULL; } //! Does not own any of its private data ~ControlVertex() {} //! Set the parent vertex, removing the root node status. void setParent(ControlVertex *v) { m_parent = v; } //! Get the root node, or greatest ancestor ControlVertex * getRoot() { ControlVertex *current = this; while (current->getParent() != NULL) current = current->getParent(); return current; } //! Get the parent node. A root node has no parent. ControlVertex * getParent() { return m_parent; } //! Get the node representation of this vertex ControlCubeGraphNode * getNode() { return m_node; } //! Get the point representation of this vertex ControlPoint * getPoint() { return m_point; } //! Join two nodes by setting one root to be the other's parent static void join(ControlVertex *v1, ControlVertex *v2) { v1->getRoot()->setParent(v2->getRoot()); } private: //! The possibly non-existant graph node ControlCubeGraphNode *m_node; //! The possibly non-existant control point ControlPoint *m_point; //! The possibly non-existant parent vertex ControlVertex *m_parent; }; private: // data //! hash ControlPoints by ControlPoint Id QHash< QString, ControlPoint * > * points; Loading
isis/src/control/objs/ControlNet/unitTest.cpp +66 −61 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ using namespace Isis; * @author ????-??-?? Unknown * @internal * @history 2016-05-11 Jeannie Backer - Added tests for setTarget methods. * @history 2018-05-29 Kristin Berry - Commented out (to probably be removed) code related to * unused, removed methods. */ bool lessThan(const ControlMeasure *m1, const ControlMeasure *m2) { return m1->GetResidualMagnitude() < m2->GetResidualMagnitude(); Loading Loading @@ -148,67 +150,70 @@ void testConnectivity() { if (islands[0].contains(m9->ControlSN())) islands.swap(0, 1); cout << " " << "Island Count = " << islands.size() << endl; cout << "\nTesting MinimumSpanningTree()\n"; QList< QSet< ControlMeasure * > > spanningTrees; int nodeCount = 0; for (int i = 0; i < islands.size(); i++) { spanningTrees.append(net.MinimumSpanningTree(islands[i], lessThan)); nodeCount += islands[i].size(); } cout << " " << "Tree Count = " << spanningTrees.size() << endl; cout << " " << "Graph Node Count = " << nodeCount << endl; QList< QMap< QString, ControlMeasure * > > includedMaps; QList< QMap< QString, ControlMeasure * > > excludedMaps; for (int i = 0; i < spanningTrees.size(); i++) { includedMaps.append(QMap< QString, ControlMeasure * >()); excludedMaps.append(QMap< QString, ControlMeasure * >()); } int measureCount = 0; for (int p = 0; p < net.GetNumPoints(); p++) { ControlPoint *point = net.GetPoint(p); for (int m = 0; m < point->GetNumMeasures(); m++) { ControlMeasure *measure = point->GetMeasure(m); measureCount++; for (int i = 0; i < spanningTrees.size(); i++) { if (islands[i].contains(measure->ControlSN())) { if (spanningTrees[i].contains(measure)) includedMaps[i].insert(measureNames[measure], measure); else excludedMaps[i].insert(measureNames[measure], measure); } } } } cout << " " << "Measure Count = " << measureCount << endl; int includedMeasures = 0; for (int i = 0; i < spanningTrees.size(); i++) { QSet< ControlMeasure * > measures = spanningTrees[i]; includedMeasures += measures.size(); } if (islands.size() != spanningTrees.size()) { cout << " " << "Island Count == " << islands.size() << " != " << spanningTrees.size() << " == MST Count" << endl; } else { cout << " " << "Island Count == " << islands.size() << " == MST Count" << endl; for (int i = 0; i < spanningTrees.size(); i++) { cout << "\n " << "Minimum Spanning Tree " << i << endl; cout << " " << "Nodes = " << islands[i].size() << endl; cout << " " << "Included Measures = " << includedMaps[i].size() << endl; printMeasures(includedMaps[i].values(), measureNames); cout << " " << "Excluded Measures = " << excludedMaps[i].size() << endl; printMeasures(excludedMaps[i].values(), measureNames); } } // This region all has to do with testing the (unused) removed MinimumSpanningTree // method. It's left in here commented-out for now in case we would like to test // island functionality here, using similar output, after updating ControlNet to use boost. //cout << "\nTesting MinimumSpanningTree()\n"; //QList< QSet< ControlMeasure * > > spanningTrees; //int nodeCount = 0; //for (int i = 0; i < islands.size(); i++) { // spanningTrees.append(net.MinimumSpanningTree(islands[i], lessThan)); // nodeCount += islands[i].size(); //} // //cout << " " << "Tree Count = " << spanningTrees.size() << endl; //cout << " " << "Graph Node Count = " << nodeCount << endl; // //QList< QMap< QString, ControlMeasure * > > includedMaps; //QList< QMap< QString, ControlMeasure * > > excludedMaps; //for (int i = 0; i < spanningTrees.size(); i++) { // includedMaps.append(QMap< QString, ControlMeasure * >()); // excludedMaps.append(QMap< QString, ControlMeasure * >()); //} // //int measureCount = 0; //for (int p = 0; p < net.GetNumPoints(); p++) { // ControlPoint *point = net.GetPoint(p); // for (int m = 0; m < point->GetNumMeasures(); m++) { // ControlMeasure *measure = point->GetMeasure(m); // measureCount++; // for (int i = 0; i < spanningTrees.size(); i++) { // if (islands[i].contains(measure->ControlSN())) { // if (spanningTrees[i].contains(measure)) // includedMaps[i].insert(measureNames[measure], measure); // else // excludedMaps[i].insert(measureNames[measure], measure); // } // } // } //} //cout << " " << "Measure Count = " << measureCount << endl; // //int includedMeasures = 0; //for (int i = 0; i < spanningTrees.size(); i++) { // QSet< ControlMeasure * > measures = spanningTrees[i]; // includedMeasures += measures.size(); //} // //if (islands.size() != spanningTrees.size()) { // cout << " " << "Island Count == " << islands.size() << " != " << // spanningTrees.size() << " == MST Count" << endl; //} //else { // cout << " " << "Island Count == " << islands.size() << // " == MST Count" << endl; // // for (int i = 0; i < spanningTrees.size(); i++) { // cout << "\n " << "Minimum Spanning Tree " << i << endl; // // cout << " " << "Nodes = " << islands[i].size() << endl; // cout << " " << "Included Measures = " << includedMaps[i].size() << endl; // printMeasures(includedMaps[i].values(), measureNames); // // cout << " " << "Excluded Measures = " << excludedMaps[i].size() << endl; // printMeasures(excludedMaps[i].values(), measureNames); // } //} } Loading