瀏覽代碼

ENH: DependencyGraph: Added tests for cycle detection and subgraph ordering on disconnected (directed) graphs

Sascha Zelzer 14 年之前
父節點
當前提交
ddaf383f5c
共有 2 個文件被更改,包括 328 次插入0 次删除
  1. 2 0
      Libs/Core/Testing/Cpp/CMakeLists.txt
  2. 326 0
      Libs/Core/Testing/Cpp/ctkDependencyGraphTest2.cpp

+ 2 - 0
Libs/Core/Testing/Cpp/CMakeLists.txt

@@ -10,6 +10,7 @@ CREATE_TEST_SOURCELIST(Tests ${KIT}CppTests.cpp
   ctkModelTesterTest1.cpp
   ctkUtilsTest1.cpp
   ctkDependencyGraphTest1.cpp
+  ctkDependencyGraphTest2.cpp
   ctkPimplTest1.cpp
   ctkSingletonTest1.cpp
   #EXTRA_INCLUDE TestingMacros.h
@@ -39,6 +40,7 @@ ENDMACRO( SIMPLE_TEST  )
 
 SIMPLE_TEST( ctkCommandLineParserTest1 )
 SIMPLE_TEST( ctkDependencyGraphTest1 )
+SIMPLE_TEST( ctkDependencyGraphTest2 )
 SIMPLE_TEST( ctkModelTesterTest1 )
 SIMPLE_TEST( ctkPimplTest1 )
 SIMPLE_TEST( ctkSingletonTest1 )

+ 326 - 0
Libs/Core/Testing/Cpp/ctkDependencyGraphTest2.cpp

@@ -0,0 +1,326 @@
+/*=========================================================================
+
+  Library:   CTK
+ 
+  Copyright (c) 2010 German Cancer Research Center,
+    Division of Medical and Biological Informatics
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.commontk.org/LICENSE
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ 
+=========================================================================*/
+
+// CTK includes
+#include "ctkDependencyGraph.h"
+
+// STL includes
+#include <cstdlib>
+#include <iostream>
+
+// Qt includes
+#include <QDebug>
+
+
+int ctkDependencyGraphTest2(int argc, char * argv [] )
+{
+  Q_UNUSED(argc);
+  Q_UNUSED(argv);  
+
+  // check that cycle detection works
+  {
+  const int numberOfVertices = 2;
+
+  ctkDependencyGraph graph(numberOfVertices);
+
+  //
+  //  1  ->  2
+  //   \    /
+  //     <-
+  //
+  graph.insertEdge(1,2);
+  graph.insertEdge(2,1);
+
+  int expectedNumberOfEdge = 2;
+  
+  int nov = graph.numberOfVertices();
+
+  if( nov != numberOfVertices )
+    {
+    qCritical() << "Number of vertices does not match (expected" << numberOfVertices << "got" << nov << ")";
+    return EXIT_FAILURE;
+    }
+
+  int noe = graph.numberOfEdges();
+  if( noe != expectedNumberOfEdge )
+    {
+    qCritical() << "Number of edges does not match (expected" << expectedNumberOfEdge << "got" << noe << ")";
+    return EXIT_FAILURE;
+    }
+
+  bool cfc = graph.checkForCycle();
+  
+  if( cfc == false )
+    {
+    qCritical() << "Cycle detection failed";
+    return EXIT_FAILURE;
+    }
+
+  bool cdtd = graph.cycleDetected();
+
+  if( cdtd == false )
+    {
+    qCritical() << "Cycle detected flag wrong";
+    return EXIT_FAILURE;
+    }
+
+  int co = graph.cycleOrigin();
+  int ce = graph.cycleEnd();
+
+  if (co != 2)
+    {
+    qCritical() << "Wrong cycle origin (expected" << 2 << "got" << co << ")";
+    return EXIT_FAILURE;
+    }
+
+  if (ce != 1)
+    {
+    qCritical() << "Wrong cycle end (expected" << 1 << "got" << ce << ")";
+    return EXIT_FAILURE;
+    }
+
+  }
+
+  {
+  const int numberOfVertices = 4;
+
+  ctkDependencyGraph graph(numberOfVertices);
+
+  //         ->  3
+  //       /
+  // 1 -> 2  ->  4
+  //       \    /
+  //         <-
+  //
+  graph.insertEdge(1,2);
+  graph.insertEdge(2,3);
+  graph.insertEdge(2,4);
+  graph.insertEdge(4,2);
+
+  int expectedNumberOfEdge = 4;
+
+  int nov = graph.numberOfVertices();
+
+  if( nov != numberOfVertices )
+    {
+    qCritical() << "Number of vertices does not match (expected" << numberOfVertices << "got" << nov << ")";
+    return EXIT_FAILURE;
+    }
+
+  int noe = graph.numberOfEdges();
+  if( noe != expectedNumberOfEdge )
+    {
+    qCritical() << "Number of edges does not match (expected" << expectedNumberOfEdge << "got" << noe << ")";
+    return EXIT_FAILURE;
+    }
+
+  bool cfc = graph.checkForCycle();
+
+  if( cfc == false )
+    {
+    qCritical() << "Cycle detection failed";
+    return EXIT_FAILURE;
+    }
+
+  bool cdtd = graph.cycleDetected();
+
+  if( cdtd == false )
+    {
+    qCritical() << "Cycle detected flag wrong";
+    return EXIT_FAILURE;
+    }
+
+  int co = graph.cycleOrigin();
+  int ce = graph.cycleEnd();
+
+  if (co != 2)
+    {
+    qCritical() << "Wrong cycle origin (expected" << 2 << "got" << co << ")";
+    return EXIT_FAILURE;
+    }
+
+  if (ce != 4)
+    {
+    qCritical() << "Wrong cycle end (expected" << 4 << "got" << ce << ")";
+    return EXIT_FAILURE;
+    }
+
+  }
+
+  // check that cycle detection works on disconnected graphs
+  {
+  const int numberOfVertices = 8;
+
+  ctkDependencyGraph graph(numberOfVertices);
+
+  /* 1 -> 2  -> 3
+   *       \
+   *         -> 4
+   *
+   *         ->  7
+   *       /
+   * 5 -> 6  ->  8
+   *  \         /
+   *    ---<---
+   */
+  graph.insertEdge(1,2);
+  graph.insertEdge(2,3);
+  graph.insertEdge(2,4);
+  graph.insertEdge(5,6);
+  graph.insertEdge(6,7);
+  graph.insertEdge(6,8);
+  graph.insertEdge(8,5);
+
+  int expectedNumberOfEdge = 7;
+
+  int nov = graph.numberOfVertices();
+
+  if( nov != numberOfVertices )
+    {
+    qCritical() << "Number of vertices does not match (expected" << numberOfVertices << "got" << nov << ")";
+    return EXIT_FAILURE;
+    }
+
+  int noe = graph.numberOfEdges();
+  if( noe != expectedNumberOfEdge )
+    {
+    qCritical() << "Number of edges does not match (expected" << expectedNumberOfEdge << "got" << noe << ")";
+    return EXIT_FAILURE;
+    }
+
+  bool cfc = graph.checkForCycle();
+
+  if( cfc == false )
+    {
+    qCritical() << "Cycle detection failed";
+    return EXIT_FAILURE;
+    }
+
+  bool cdtd = graph.cycleDetected();
+
+  if( cdtd == false )
+    {
+    qCritical() << "Cycle detected flag wrong";
+    return EXIT_FAILURE;
+    }
+
+  }
+
+  // check that topological ordering and paths
+  // work on disconnected graphs
+  {
+  const int numberOfVertices = 11;
+
+  ctkDependencyGraph graph(numberOfVertices);
+
+  /* 1 -> 2  -> 3
+   *       \
+   *         -> 4
+   *
+   *         ->  7 ->
+   *       /          \
+   * 5 -> 6  ->  8 ->  9
+   *             ^
+   *             |
+   *            10 -> 11
+   */
+  graph.insertEdge(1,2);
+  graph.insertEdge(2,3);
+  graph.insertEdge(2,4);
+  graph.insertEdge(5,6);
+  graph.insertEdge(6,7);
+  graph.insertEdge(6,8);
+  graph.insertEdge(7,9);
+  graph.insertEdge(8,9);
+  graph.insertEdge(10,8);
+  graph.insertEdge(10,11);
+
+  int expectedNumberOfEdge = 10;
+
+  int nov = graph.numberOfVertices();
+
+  if( nov != numberOfVertices )
+    {
+    qCritical() << "Number of vertices does not match (expected" << numberOfVertices << "got" << nov << ")";
+    return EXIT_FAILURE;
+    }
+
+  int noe = graph.numberOfEdges();
+  if( noe != expectedNumberOfEdge )
+    {
+    qCritical() << "Number of edges does not match (expected" << expectedNumberOfEdge << "got" << noe << ")";
+    return EXIT_FAILURE;
+    }
+
+  bool cfc = graph.checkForCycle();
+
+  if( cfc == true )
+    {
+    qCritical() << "Cycle detection failed";
+    return EXIT_FAILURE;
+    }
+
+  bool cdtd = graph.cycleDetected();
+
+  if( cdtd == true )
+    {
+    qCritical() << "Cycle detected flag wrong";
+    return EXIT_FAILURE;
+    }
+
+  QList<int> sources;
+  graph.sourceVertices(sources);
+
+  QList<int> expectedSources;
+  expectedSources << 1 << 5 << 10;
+
+  if (sources != expectedSources)
+    {
+    qCritical() << "Source vertices do not match (expected" << expectedSources << "got" << sources << ")";
+    return EXIT_FAILURE;
+    }
+
+  QList<int> globalSort;
+  graph.topologicalSort(globalSort);
+
+  QList<int> expectedGlobalSort;
+  expectedGlobalSort << 1 << 5 << 10 << 2 << 6 << 11 << 3 << 4 << 7 << 8 << 9;
+  if (globalSort != expectedGlobalSort)
+  {
+    qCritical() << "Topological sort error (expected" << expectedGlobalSort << "got" << globalSort << ")";
+    return EXIT_FAILURE;
+  }
+
+  QList<int> subSort10;
+  graph.topologicalSort(subSort10, 10);
+
+  QList<int> expectedSubSort10;
+  expectedSubSort10 << 10 << 8 << 11 << 9;
+  if (subSort10 != expectedSubSort10)
+  {
+    qCritical() << "Topological subgraph sort error (expected" << expectedSubSort10 << "got" << subSort10 << ")";
+    return EXIT_FAILURE;
+  }
+
+  }
+
+  return EXIT_SUCCESS;
+}