Commit 585c802b authored by Jeff Baumes's avatar Jeff Baumes
Browse files

ENH: Created vtkDirectedAcyclicGraph, which resides between vtkDirectedGraph and vtkTree.

parent f4355e04
......@@ -82,6 +82,7 @@
#define VTK_DIRECTED_GRAPH 23
#define VTK_UNDIRECTED_GRAPH 24
#define VTK_MULTIPIECE_DATA_SET 25
#define VTK_DIRECTED_ACYCLIC_GRAPH 26
/*--------------------------------------------------------------------------*/
/* Define a casting macro for use by the constants below. */
......
......@@ -52,6 +52,7 @@ vtkDataSetToStructuredGridFilter.cxx
vtkDataSetToStructuredPointsFilter.cxx
vtkDataSetToUnstructuredGridFilter.cxx
vtkDemandDrivenPipeline.cxx
vtkDirectedAcyclicGraph.cxx
vtkDirectedGraphAlgorithm.cxx
vtkDirectedGraph.cxx
vtkEdgeListIterator.cxx
......
/*=========================================================================
Program: Visualization Toolkit
Module: vtkDirectedAcyclicGraph.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/*----------------------------------------------------------------------------
Copyright (c) Sandia Corporation
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/
#include "vtkDirectedAcyclicGraph.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkOutEdgeIterator.h"
#include "vtkSmartPointer.h"
#include <vtksys/stl/vector>
using vtksys_stl::vector;
vtkCxxRevisionMacro(vtkDirectedAcyclicGraph, "1.1");
vtkStandardNewMacro(vtkDirectedAcyclicGraph);
//----------------------------------------------------------------------------
vtkDirectedAcyclicGraph::vtkDirectedAcyclicGraph()
{
}
//----------------------------------------------------------------------------
vtkDirectedAcyclicGraph::~vtkDirectedAcyclicGraph()
{
}
//----------------------------------------------------------------------------
vtkDirectedAcyclicGraph *vtkDirectedAcyclicGraph::GetData(vtkInformation *info)
{
return info? vtkDirectedAcyclicGraph::SafeDownCast(info->Get(DATA_OBJECT())) : 0;
}
//----------------------------------------------------------------------------
vtkDirectedAcyclicGraph *vtkDirectedAcyclicGraph::GetData(vtkInformationVector *v, int i)
{
return vtkDirectedAcyclicGraph::GetData(v->GetInformationObject(i));
}
enum { DFS_WHITE, DFS_GRAY, DFS_BLACK };
//----------------------------------------------------------------------------
bool vtkDirectedAcyclicGraphDFSVisit(
vtkGraph *g,
vtkIdType u,
vtksys_stl::vector<vtkIdType> color,
vtkOutEdgeIterator *adj)
{
color[u] = DFS_GRAY;
g->GetOutEdges(u, adj);
while (adj->HasNext())
{
vtkOutEdgeType e = adj->Next();
vtkIdType v = e.Target;
if (color[v] == DFS_WHITE)
{
if (!vtkDirectedAcyclicGraphDFSVisit(g, v, color, adj))
{
return false;
}
}
else if (color[v] == DFS_GRAY)
{
return false;
}
}
return true;
}
//----------------------------------------------------------------------------
bool vtkDirectedAcyclicGraph::IsStructureValid(vtkGraph *g)
{
if (vtkDirectedAcyclicGraph::SafeDownCast(g))
{
return true;
}
// Empty graph is a valid DAG.
if (g->GetNumberOfVertices() == 0)
{
return true;
}
// A directed graph is acyclic iff a depth-first search of
// the graph yields no back edges.
// (from Introduction to Algorithms.
// Cormen, Leiserson, Rivest, p. 486).
vtkIdType numVerts = g->GetNumberOfVertices();
vector<int> color(numVerts, DFS_BLACK);
vtkIdType s, u, v;
bool cycle = false;
vtkSmartPointer<vtkOutEdgeIterator> adj =
vtkSmartPointer<vtkOutEdgeIterator>::New();
for (u = 0; u < numVerts; ++u)
{
color[u] = DFS_WHITE;
}
for (s = 0; s < numVerts; ++s)
{
if (color[s] == DFS_WHITE)
{
if (!vtkDirectedAcyclicGraphDFSVisit(g, s, color, adj))
{
return false;
}
}
}
return true;
}
//----------------------------------------------------------------------------
void vtkDirectedAcyclicGraph::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkDirectedAcyclicGraph.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/*----------------------------------------------------------------------------
Copyright (c) Sandia Corporation
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/
// .NAME vtkDirectedAcyclicGraph - A rooted tree data structure.
//
// .SECTION Description
// vtkDirectedAcyclicGraph is a connected directed graph with no cycles. A tree is a type of
// directed graph, so works with all graph algorithms.
//
// vtkDirectedAcyclicGraph is a read-only data structure.
// To construct a tree, create an instance of vtkMutableDirectedGraph.
// Add vertices and edges with AddVertex() and AddEdge(). You may alternately
// start by adding a single vertex as the root then call graph->AddChild(parent)
// which adds a new vertex and connects the parent to the child.
// The tree MUST have all edges in the proper direction, from parent to child.
// After building the tree, call tree->CheckedShallowCopy(graph) to copy the
// structure into a vtkDirectedAcyclicGraph. This method will return false if the graph is
// an invalid tree.
//
// vtkDirectedAcyclicGraph provides some convenience methods for obtaining the parent and
// children of a vertex, for finding the root, and determining if a vertex
// is a leaf (a vertex with no children).
//
// .SECTION See Also
// vtkDirectedGraph vtkMutableDirectedGraph vtkGraph
#ifndef __vtkDirectedAcyclicGraph_h
#define __vtkDirectedAcyclicGraph_h
#include "vtkDirectedGraph.h"
class vtkIdTypeArray;
class VTK_FILTERING_EXPORT vtkDirectedAcyclicGraph : public vtkDirectedGraph
{
public:
static vtkDirectedAcyclicGraph *New();
vtkTypeRevisionMacro(vtkDirectedAcyclicGraph, vtkDirectedGraph);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Return what type of dataset this is.
virtual int GetDataObjectType() {return VTK_DIRECTED_ACYCLIC_GRAPH;}
//BTX
// Description:
// Retrieve a graph from an information vector.
static vtkDirectedAcyclicGraph *GetData(vtkInformation *info);
static vtkDirectedAcyclicGraph *GetData(vtkInformationVector *v, int i=0);
//ETX
protected:
vtkDirectedAcyclicGraph();
~vtkDirectedAcyclicGraph();
// Description:
// Check the storage, and accept it if it is a valid
// tree.
virtual bool IsStructureValid(vtkGraph *g);
private:
vtkDirectedAcyclicGraph(const vtkDirectedAcyclicGraph&); // Not implemented.
void operator=(const vtkDirectedAcyclicGraph&); // Not implemented.
};
#endif
......@@ -18,6 +18,7 @@
----------------------------------------------------------------------------*/
#include "vtkAdjacentVertexIterator.h"
#include "vtkDirectedAcyclicGraph.h"
#include "vtkEdgeListIterator.h"
#include "vtkInEdgeIterator.h"
#include "vtkMutableDirectedGraph.h"
......@@ -164,6 +165,7 @@ int TestGraph(int vtkNotUsed(argc), char* vtkNotUsed(argv)[])
VTK_CREATE(vtkDirectedGraph, dg);
VTK_CREATE(vtkUndirectedGraph, ug);
VTK_CREATE(vtkTree, t);
VTK_CREATE(vtkDirectedAcyclicGraph, dag);
for (vtkIdType i = 0; i < 10; ++i)
{
......@@ -183,7 +185,7 @@ int TestGraph(int vtkNotUsed(argc), char* vtkNotUsed(argv)[])
mdgTree->AddEdge(3, 8);
mdgTree->AddEdge(3, 9);
// Not a tree since 8 and 9 form a disjoint cycle.
// Not a tree or DAG since 8 and 9 form a disjoint cycle.
mdgNotTree->AddEdge(0, 1);
mdgNotTree->AddEdge(0, 2);
mdgNotTree->AddEdge(0, 3);
......@@ -252,6 +254,21 @@ int TestGraph(int vtkNotUsed(argc), char* vtkNotUsed(argv)[])
cerr << "ERROR: Can set directed graph to undirected graph." << endl;
++errors;
}
if (!dag->CheckedShallowCopy(mdgTree))
{
cerr << "ERROR: Cannot set valid DAG." << endl;
++errors;
}
if (dag->CheckedShallowCopy(mdgNotTree))
{
cerr << "ERROR: Can set invalid DAG." << endl;
++errors;
}
if (dag->CheckedShallowCopy(mug))
{
cerr << "ERROR: Can set undirected graph to DAG." << endl;
++errors;
}
cerr << "... done." << endl;
cerr << "Testing basic graph structure ..." << endl;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment