Skip to content

Commit

Permalink
Unstable. The graph does not properly load from string. GraphTest::lo…
Browse files Browse the repository at this point in the history
…adFromString() never returns.

Added test code for BFS.

Signed-off-by: unknown <saq10002@iteb-219.ad.engr.uconn.edu>
  • Loading branch information
unknown committed Sep 30, 2014
1 parent 1107de7 commit d8c7085
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 26 deletions.
192 changes: 169 additions & 23 deletions YASI_12/alg.graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@ namespace yasi{
namespace alg{

namespace graph{
using namespace ds;


/////////////////////////////////////
// BFS algorithm
// Child classes must override default (empty) visit functions
////////////////////////////////////
template<class G> // graph
class BFS{
////////////// enable testing //////////////
friend class BSFTest;
public:
typedef typename G::VertexType VertexType;
typedef typename G::EdgeType EdgeType;
Expand All @@ -25,39 +31,42 @@ namespace graph{
VERTEX_VISITING,
VERTEX_VISITED
};
const G& g;
// the BFS ordering of vertices
int* pBfsParent;
void clear(){

}
public:
BFS(const G& g):g(g){
pBfsParent = new int[g.numVertices()];
}
virtual ~BFS(){
DELETE_ARR_SAFE(pBfsParent);
}
///////////////////////////////////////////////////
// override thesse function in child classes
// for your own BSF visit action
virtual void visitVertexBeforeSniffingNeighbors(VertexType* v){
virtual void visitVertexBeforeSchedulingNeighbors(VertexType* v){
// do nothing
}
virtual void visitVertexAfterSniffingNeighbors(VertexType* v){
virtual void visitVertexAfterSchedulingNeighbors(VertexType* v){
// do nothing
}
virtual void visitEdge(EdgeType* e){
// do nothing
}
//////////////////////////////////////////////////
void clear(){
DELETE_ARR_SAFE(pBfsParent);
}
public:
BFS(){
}
virtual ~BFS(){
clear();
}

// perform bfs
// the BFS tree is saved in BFS::pVertexSequence
// the vertex id's must be in the range [0..n-1]
void search(const G& g, const VertexType* src) const{
// init
void search(const G& g, VertexType* src) {
// global init
clear();
int n = g.numVertices();
pBfsParent = new int[n]; // record BFS tree

// init
const int srcId = src->id;
DoublyLinkedList<VertexType*> q;

Expand All @@ -76,41 +85,178 @@ namespace graph{

// the traversal
while (!q.empty()){
VertexType* currentVertex = q.popFront();
// pop next candidate vertex from queue
VertexType* currentVertex = q.front();
q.popFront();
int currentId = currentVertex->id;

// visit currentVertex
vertexStatus[currentId] = VERTEX_VISITING;
visitVertexBeforeSniffingNeighbors(currentVertex);
//////////////////////////////////////////////////////////
visitVertexBeforeSchedulingNeighbors(currentVertex);
//////////////////////////////////////////////////////////

for (EdgeIterator i = v->pOutEdges->begin(); i != v->pOutEdges->end(); i++){
for (EdgeIterator i = currentVertex->pOutEdges->begin(); i != currentVertex->pOutEdges->end(); i++){
EdgeType* e = *i;
// process this edge
//////////////////////////////////////////////////////////
visitEdge(e);

//////////////////////////////////////////////////////////

VertexType* neighborVertex = e->end;
int neighborId = neighborVertex->id;
if (vertexStatus[neighborId] == VERTEX_UNDISCOVERED){
// schedule a visit to the neighbor
vertexStatus[neighborid] == VERTEX_DISCOVERED;
pBfsParent[neighborVertex] = currentVertex;
vertexStatus[neighborId] == VERTEX_DISCOVERED;
pBfsParent[neighborId] = currentId;
q.pushBack(neighborVertex);
}

}

// done visiting current vertex
visitVertexAfterSniffingNeighbors(currentVertex);
//////////////////////////////////////////////////////////
visitVertexAfterSchedulingNeighbors(currentVertex);
//////////////////////////////////////////////////////////
vertexStatus[currentId] = VERTEX_VISITED;

}

// cleanup
DELETE_SAFE_ARR(vertexVisited);
DELETE_ARR_SAFE(vertexStatus);
}

};



class BFSTest : public Test {
typedef Graph<int,char> G;
typedef G::VertexType VertexType;

template<class G>
class MyBFS : public BFS < G > {
protected:
typedef BFS<G> parent;
typedef typename parent::VertexType VertexType;
typedef typename parent::EdgeType EdgeType;

stringstream visitSequence;
public:
MyBFS() : parent(){
}
virtual ~MyBFS(){

}
/////////// override specific visit functions //////
virtual void visitVertexBeforeScheudlingNeighbors(VertexType* pVertex){
visitSequence << pVertex->label << " ";
}
string getVisitSequence() const{
return visitSequence.str();
}
};


public:
void simpleGraphs(){

{
SCOPED_TRACE("path");
string strPath =
"1 2 0.5\n"
"2 3 0.5\n"
"3 4 0.5\n"
"4 5 0.5\n"
;
G g;
g.loadFromString(strPath);
string expectedVisitSequence = "1 2 3 4 5 ";

MyBFS<G> bfs;
VertexType* src = *(g.getVertexList()->begin());
bfs.search(g, src);
string actualVisitSequence = bfs.getVisitSequence();
ASSERT_EQ(expectedVisitSequence, actualVisitSequence);
}
{
SCOPED_TRACE("binary tree");
string strBalancedBinaryTree =
"1 2 0.5\n"
"1 3 0.5\n"
"2 4 0.5\n"
"2 5 0.5\n"
"3 6 0.5\n"
"3 7 0.5\n"
;
G g;
g.loadFromString(strBalancedBinaryTree);
string expectedVisitSequence = "1 2 3 4 5 6 7 ";

MyBFS<G> bfs;
VertexType* src = *(g.getVertexList()->begin());
bfs.search(g, src);
string actualVisitSequence = bfs.getVisitSequence();
ASSERT_EQ(expectedVisitSequence, actualVisitSequence);
}

{
SCOPED_TRACE("cycle");
string strCycle =
"1 2 0.5\n"
"2 3 0.5\n"
"3 4 0.5\n"
"4 1 0.5\n"
;
G g;
g.loadFromString(strCycle);
string expectedVisitSequence = "1 2 3 4 ";

MyBFS<G> bfs;
VertexType* src = *(g.getVertexList()->begin());
bfs.search(g, src);
string actualVisitSequence = bfs.getVisitSequence();
ASSERT_EQ(expectedVisitSequence, actualVisitSequence);
}
{
SCOPED_TRACE("complete graph K5");
string strK5 =
"1 5 0.5\n"
"1 2 0.5\n"
"1 4 0.5\n"
"1 3 0.5\n"
"2 1 0.5\n"
"2 3 0.5\n"
"2 4 0.5\n"
"2 5 0.5\n"
"3 2 0.5\n"
"3 1 0.5\n"
"3 4 0.5\n"
"3 5 0.5\n"
"4 2 0.5\n"
"4 3 0.5\n"
"4 1 0.5\n"
"4 5 0.5\n"
"5 2 0.5\n"
"5 3 0.5\n"
"5 4 0.5\n"
"5 1 0.5\n"
;
G g;
g.loadFromString(strK5);
string expectedVisitSequence = "1 5 2 4 3 ";

MyBFS<G> bfs;
VertexType* src = *(g.getVertexList()->begin());
bfs.search(g, src);
string actualVisitSequence = bfs.getVisitSequence();
ASSERT_EQ(expectedVisitSequence, actualVisitSequence);
}
}
};

ADD_TEST_F(BFSTest, simpleGraphs);

} // namespace graph
}
}
10 changes: 8 additions & 2 deletions YASI_12/ds.graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ class Graph : public IGraph{
edgeList.clear();
}
public:
Graph(bool weighted = true) :_weighted(weighted), _vertexId(0){
// by default, unweighted directed graph
Graph(bool weighted = false) :_weighted(weighted), _vertexId(0){
}
virtual ~Graph(){
clear();
Expand Down Expand Up @@ -116,7 +117,12 @@ class Graph : public IGraph{
VertexList* neighbors(const VertexType* v) const{
return
}

VertexList* getVertexList(){
return &vertexList;
}
EdgeList* getEdgeList(){
return &edgeList;
}
// strEdgeList contains non-empty lines
// one line for each edge
// line format: vid1 vid2 weight
Expand Down
2 changes: 1 addition & 1 deletion gtest-1.7.0/msvc/gtest/gtest.tlog/gtest.lastbuildstate
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
#TargetFrameworkVersion=v4.0:PlatformToolSet=v120:EnableManagedIncrementalBuild=false:VCToolArchitecture=Native32Bit
Debug|Win32|C:\Saad\Dropbox\Projects\C++\SimilarKinases\|
Debug|Win32|C:\Saad\Dropbox\Projects\C++\YASI\|

0 comments on commit d8c7085

Please sign in to comment.