mirror of
https://github.com/paboyle/Grid.git
synced 2024-11-10 07:55:35 +00:00
First graph class implementation and test
This commit is contained in:
parent
538b16610b
commit
c4e2202550
@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include <Hadrons/Application.hpp>
|
||||
#include <Hadrons/Graph.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
@ -53,6 +54,36 @@ Application::~Application(void)
|
||||
|
||||
// execute /////////////////////////////////////////////////////////////////////
|
||||
void Application::run(void)
|
||||
{
|
||||
Graph<string> g;
|
||||
|
||||
cout << g << endl;
|
||||
g.addEdge("A", "B");
|
||||
g.addEdge("B", "D");
|
||||
g.addEdge("D", "E");
|
||||
g.addEdge("E", "C");
|
||||
g.addEdge("C", "A");
|
||||
g.addEdge("Z", "Y");
|
||||
g.addEdge("Z", "W");
|
||||
g.addEdge("Z", "R");
|
||||
g.addEdge("W", "R");
|
||||
auto v = g.getAdjacentVertices("B");
|
||||
for (auto &s: v)
|
||||
{
|
||||
cout << s << " ";
|
||||
}
|
||||
cout << endl;
|
||||
cout << g << endl;
|
||||
g.depthFirstSearch();
|
||||
g.removedMarked();
|
||||
cout << g << endl;
|
||||
g.depthFirstSearch();
|
||||
g.removedMarked();
|
||||
cout << g << endl;
|
||||
}
|
||||
|
||||
// parse parameter file ////////////////////////////////////////////////////////
|
||||
void Application::parseParameterFile(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -37,7 +37,8 @@ public:
|
||||
// execute
|
||||
void run(void);
|
||||
private:
|
||||
void parseParameters(void);
|
||||
// parse parameter file
|
||||
void parseParameterFile(void);
|
||||
private:
|
||||
std::string parameterFileName_;
|
||||
};
|
||||
|
31
programs/Hadrons/Environment.cc
Normal file
31
programs/Hadrons/Environment.cc
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Environment.cc, part of Grid
|
||||
*
|
||||
* Copyright (C) 2015 Antonin Portelli
|
||||
*
|
||||
* Grid is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Grid is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Grid. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <Hadrons/Environment.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
using namespace Hadrons;
|
||||
|
||||
/******************************************************************************
|
||||
* Environment implementation *
|
||||
******************************************************************************/
|
||||
// constructor /////////////////////////////////////////////////////////////////
|
||||
Environment::Environment(void)
|
||||
{}
|
43
programs/Hadrons/Environment.hpp
Normal file
43
programs/Hadrons/Environment.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Environment.hpp, part of Grid
|
||||
*
|
||||
* Copyright (C) 2015 Antonin Portelli
|
||||
*
|
||||
* Grid is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Grid is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Grid. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef Hadrons_Environment_hpp_
|
||||
#define Hadrons_Environment_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
#include <Hadrons/Graph.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* Global environment *
|
||||
******************************************************************************/
|
||||
// TODO: make it a singleton
|
||||
class Environment
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
Environment(void);
|
||||
// destructor
|
||||
virtual ~Environment(void) = default;
|
||||
};
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_Environment_hpp_
|
@ -21,6 +21,7 @@
|
||||
#define Hadrons_Global_hpp_
|
||||
|
||||
#include <Grid.h>
|
||||
#include <set>
|
||||
|
||||
#define BEGIN_HADRONS_NAMESPACE \
|
||||
namespace Hadrons {\
|
||||
@ -36,6 +37,11 @@ public:
|
||||
};
|
||||
|
||||
#define LOG(channel) std::cout << HadronsLog##channel
|
||||
#define HADRON_ERROR(msg)\
|
||||
LOG(Error) << msg << std::endl;\
|
||||
abort();
|
||||
|
||||
#define DEBUG_VAR(var) LOG(Debug) << #var << "= " << (var) << std::endl;
|
||||
|
||||
extern HadronsLogger HadronsLogError;
|
||||
extern HadronsLogger HadronsLogWarning;
|
||||
|
299
programs/Hadrons/Graph.hpp
Normal file
299
programs/Hadrons/Graph.hpp
Normal file
@ -0,0 +1,299 @@
|
||||
/*
|
||||
* Graph.hpp, part of Grid
|
||||
*
|
||||
* Copyright (C) 2015 Antonin Portelli
|
||||
*
|
||||
* Grid is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Grid is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Grid. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef Hadrons_Graph_hpp_
|
||||
#define Hadrons_Graph_hpp_
|
||||
|
||||
#include <Hadrons/Global.hpp>
|
||||
|
||||
BEGIN_HADRONS_NAMESPACE
|
||||
|
||||
/******************************************************************************
|
||||
* Oriented graph class *
|
||||
******************************************************************************/
|
||||
// I/O for edges
|
||||
template <typename T>
|
||||
std::ostream & operator<<(std::ostream &out, const std::pair<T, T> &e)
|
||||
{
|
||||
out << "\"" << e.first << "\" -> \"" << e.second << "\"";
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// main class
|
||||
template <typename T>
|
||||
class Graph
|
||||
{
|
||||
public:
|
||||
typedef std::pair<T, T> Edge;
|
||||
public:
|
||||
// constructor
|
||||
Graph(void) = default;
|
||||
// destructor
|
||||
virtual ~Graph(void) = default;
|
||||
// access
|
||||
void addVertex(const T &value);
|
||||
void addEdge(const Edge &e);
|
||||
void addEdge(const T &start, const T &end);
|
||||
void removeVertex(const T &value);
|
||||
void removeEdge(const Edge &e);
|
||||
void removeEdge(const T &start, const T &end);
|
||||
// tests
|
||||
bool gotValue(const T &value) const;
|
||||
// graph topological manipulations
|
||||
std::vector<T> getAdjacentVertices(const T &value) const;
|
||||
std::vector<Graph<T>> getConnectedComponents(void) const;
|
||||
// I/O
|
||||
friend std::ostream & operator<<(std::ostream &out, const Graph<T> &g)
|
||||
{
|
||||
out << "{";
|
||||
for (auto &e: g.edgeSet_)
|
||||
{
|
||||
out << e << ", ";
|
||||
}
|
||||
if (g.edgeSet_.size() != 0)
|
||||
{
|
||||
out << "\b\b";
|
||||
}
|
||||
out << "}";
|
||||
|
||||
return out;
|
||||
}
|
||||
public:
|
||||
// vertex marking
|
||||
void mark(const T &value, const bool doMark = true);
|
||||
void unmark(const T &value);
|
||||
bool isMarked(const T &value) const;
|
||||
// prune marked/unmarked vertices
|
||||
void removedMarked(const bool isMarked = true);
|
||||
void removedUnmarked(void);
|
||||
// depth-first search marking
|
||||
void depthFirstSearch(void);
|
||||
void depthFirstSearch(const T &root);
|
||||
private:
|
||||
std::map<T, bool> isMarked_;
|
||||
std::set<Edge> edgeSet_;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* template implementation *
|
||||
******************************************************************************/
|
||||
// access //////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
void Graph<T>::addVertex(const T &value)
|
||||
{
|
||||
isMarked_[value] = false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Graph<T>::addEdge(const Edge &e)
|
||||
{
|
||||
addVertex(e.first);
|
||||
addVertex(e.second);
|
||||
edgeSet_.insert(e);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Graph<T>::addEdge(const T &start, const T &end)
|
||||
{
|
||||
addEdge(Edge(start, end));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Graph<T>::removeVertex(const T &value)
|
||||
{
|
||||
// remove vertex from the mark table
|
||||
auto vIt = isMarked_.find(value);
|
||||
|
||||
if (vIt != isMarked_.end())
|
||||
{
|
||||
isMarked_.erase(vIt);
|
||||
}
|
||||
else
|
||||
{
|
||||
HADRON_ERROR("vertex " << value << " does not exists");
|
||||
}
|
||||
|
||||
// remove all edges containing the vertex
|
||||
auto pred = [&value](const Edge &e)
|
||||
{
|
||||
return ((e.first == value) or (e.second == value));
|
||||
};
|
||||
auto eIt = find_if(edgeSet_.begin(), edgeSet_.end(), pred);
|
||||
|
||||
while (eIt != edgeSet_.end())
|
||||
{
|
||||
edgeSet_.erase(eIt);
|
||||
eIt = find_if(edgeSet_.begin(), edgeSet_.end(), pred);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Graph<T>::removeEdge(const Edge &e)
|
||||
{
|
||||
auto eIt = edgeSet_.find(e);
|
||||
|
||||
if (eIt != edgeSet_.end())
|
||||
{
|
||||
edgeSet_.erase(eIt);
|
||||
}
|
||||
else
|
||||
{
|
||||
HADRON_ERROR("edge " << e << " does not exists");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Graph<T>::removeEdge(const T &start, const T &end)
|
||||
{
|
||||
removeEdge(Edge(start, end));
|
||||
}
|
||||
|
||||
// tests ///////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
bool Graph<T>::gotValue(const T &value) const
|
||||
{
|
||||
try
|
||||
{
|
||||
isMarked_.at(value);
|
||||
}
|
||||
catch (std::out_of_range &)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// vertex marking //////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
void Graph<T>::mark(const T &value, const bool doMark)
|
||||
{
|
||||
try
|
||||
{
|
||||
isMarked_.at(value) = doMark;
|
||||
}
|
||||
catch (std::out_of_range &)
|
||||
{
|
||||
HADRON_ERROR("vertex " << value << " does not exists");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Graph<T>::unmark(const T &value)
|
||||
{
|
||||
mark(value, false);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Graph<T>::isMarked(const T &value) const
|
||||
{
|
||||
try
|
||||
{
|
||||
return isMarked_.at(value);
|
||||
}
|
||||
catch (std::out_of_range &)
|
||||
{
|
||||
HADRON_ERROR("vertex " << value << " does not exists");
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// prune marked/unmarked vertices //////////////////////////////////////////////
|
||||
template <typename T>
|
||||
void Graph<T>::removedMarked(const bool isMarked)
|
||||
{
|
||||
auto isMarkedCopy = isMarked_;
|
||||
|
||||
for (auto &v: isMarkedCopy)
|
||||
{
|
||||
if (v.second == isMarked)
|
||||
{
|
||||
removeVertex(v.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Graph<T>::removedUnmarked(void)
|
||||
{
|
||||
removedMarked(false);
|
||||
}
|
||||
|
||||
// depth-first search marking //////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
void Graph<T>::depthFirstSearch(void)
|
||||
{
|
||||
depthFirstSearch(isMarked_.begin()->first);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Graph<T>::depthFirstSearch(const T &root)
|
||||
{
|
||||
std::vector<T> adjacentVertex;
|
||||
|
||||
mark(root);
|
||||
adjacentVertex = getAdjacentVertices(root);
|
||||
for (auto &v: adjacentVertex)
|
||||
{
|
||||
if (!isMarked(v))
|
||||
{
|
||||
depthFirstSearch(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// graph topological manipulations /////////////////////////////////////////////
|
||||
template <typename T>
|
||||
std::vector<T> Graph<T>::getAdjacentVertices(const T &value) const
|
||||
{
|
||||
std::vector<T> adjacentVertex;
|
||||
|
||||
auto pred = [&value](const Edge &e)
|
||||
{
|
||||
return ((e.first == value) or (e.second == value));
|
||||
};
|
||||
auto eIt = find_if(edgeSet_.begin(), edgeSet_.end(), pred);
|
||||
|
||||
while (eIt != edgeSet_.end())
|
||||
{
|
||||
if (eIt->first == value)
|
||||
{
|
||||
adjacentVertex.push_back((*eIt).second);
|
||||
}
|
||||
else if (eIt->second == value)
|
||||
{
|
||||
adjacentVertex.push_back((*eIt).first);
|
||||
}
|
||||
eIt = find_if(++eIt, edgeSet_.end(), pred);
|
||||
}
|
||||
|
||||
return adjacentVertex;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::vector<Graph<T>> Graph<T>::getConnectedComponents(void) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
END_HADRONS_NAMESPACE
|
||||
|
||||
#endif // Hadrons_Graph_hpp_
|
4
programs/Hadrons/Make.inc
Normal file
4
programs/Hadrons/Make.inc
Normal file
@ -0,0 +1,4 @@
|
||||
bin_PROGRAMS = Hadrons
|
||||
|
||||
Hadrons_SOURCES = Hadrons.cc
|
||||
Hadrons_LDADD = -lGrid
|
Loading…
Reference in New Issue
Block a user