Skip to content

Commit

Permalink
Fixed bugs. Now BFS can search in a graph :)
Browse files Browse the repository at this point in the history
Signed-off-by: unknown <saq10002@iteb-219.ad.engr.uconn.edu>
  • Loading branch information
unknown committed Sep 30, 2014
1 parent d8c7085 commit dc7bd3a
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 41 deletions.
60 changes: 38 additions & 22 deletions YASI_12/alg.graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace graph{
template<class G> // graph
class BFS{
////////////// enable testing //////////////
friend class BSFTest;
friend class BFSTest;
public:
typedef typename G::VertexType VertexType;
typedef typename G::EdgeType EdgeType;
Expand All @@ -32,20 +32,15 @@ namespace graph{
VERTEX_VISITED
};
// the BFS ordering of vertices
// indexed by vertex id
int* pBfsParent;

///////////////////////////////////////////////////
// override thesse function in child classes
// for your own BSF visit action
virtual void visitVertexBeforeSchedulingNeighbors(VertexType* v){
// do nothing
}
virtual void visitVertexAfterSchedulingNeighbors(VertexType* v){
// do nothing
}
virtual void visitEdge(EdgeType* e){
// do nothing
}
virtual void visitVertexBeforeSchedulingNeighbors(VertexType* v) = 0;
virtual void visitVertexAfterSchedulingNeighbors(VertexType* v) = 0;
virtual void visitEdge(EdgeType* e) = 0;
//////////////////////////////////////////////////
void clear(){
DELETE_ARR_SAFE(pBfsParent);
Expand All @@ -67,21 +62,21 @@ namespace graph{
pBfsParent = new int[n]; // record BFS tree

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

int* vertexStatus = new int[n];
// the source vertex
const int srcId = src->id;
vertexStatus[srcId] = VERTEX_DISCOVERED;
pBfsParent[srcId] = -1;
q.pushBack(src);
// other vertices
for (int i = 0; i < n; i++){
if (i == srcId) continue;
vertexStatus[i] = VERTEX_UNDISCOVERED;
// parent of each vertex in BFS tree is initially NULL
pBfsParent[i] = -1;
}

// the source vertex
vertexStatus[srcId] = VERTEX_DISCOVERED;
pBfsParent[srcId] = -1;
q.pushBack(src);

// the traversal
while (!q.empty()){
Expand All @@ -107,7 +102,7 @@ namespace graph{
int neighborId = neighborVertex->id;
if (vertexStatus[neighborId] == VERTEX_UNDISCOVERED){
// schedule a visit to the neighbor
vertexStatus[neighborId] == VERTEX_DISCOVERED;
vertexStatus[neighborId] = VERTEX_DISCOVERED;
pBfsParent[neighborId] = currentId;
q.pushBack(neighborVertex);
}
Expand Down Expand Up @@ -136,21 +131,25 @@ namespace graph{

template<class G>
class MyBFS : public BFS < G > {
////////// enable testing /////////
friend class BSFTest;
protected:
typedef BFS<G> parent;
typedef typename parent::VertexType VertexType;
typedef typename parent::EdgeType EdgeType;

stringstream visitSequence;
///////////// override visit methods /////////////
virtual void visitVertexBeforeSchedulingNeighbors(VertexType* v) override {
visitSequence << v->label << " ";
}
virtual void visitVertexAfterSchedulingNeighbors(VertexType* v) override {};
virtual void visitEdge(EdgeType* e) override {};
public:
MyBFS() : parent(){
}
virtual ~MyBFS(){

}
/////////// override specific visit functions //////
virtual void visitVertexBeforeScheudlingNeighbors(VertexType* pVertex){
visitSequence << pVertex->label << " ";
}
string getVisitSequence() const{
return visitSequence.str();
Expand All @@ -172,12 +171,17 @@ namespace graph{
G g;
g.loadFromString(strPath);
string expectedVisitSequence = "1 2 3 4 5 ";
int bfsParent[] = {-1, 1, 2, 3, 4};

MyBFS<G> bfs;
VertexType* src = *(g.getVertexList()->begin());
bfs.search(g, src);
string actualVisitSequence = bfs.getVisitSequence();
ASSERT_EQ(expectedVisitSequence, actualVisitSequence);
// bfs tree
for (int i = 1; i < g.numVertices(); i++){
ASSERT_EQ(i - 1, bfs.pBfsParent[i]);
}
}
{
SCOPED_TRACE("binary tree");
Expand All @@ -198,6 +202,11 @@ namespace graph{
bfs.search(g, src);
string actualVisitSequence = bfs.getVisitSequence();
ASSERT_EQ(expectedVisitSequence, actualVisitSequence);
// bfs tree
for (int i = 1; i < g.numVertices(); i++){
int parentId = (i%2) ? i/2 : i/2 - 1;
ASSERT_EQ(parentId, bfs.pBfsParent[i]);
}
}

{
Expand All @@ -217,7 +226,11 @@ namespace graph{
bfs.search(g, src);
string actualVisitSequence = bfs.getVisitSequence();
ASSERT_EQ(expectedVisitSequence, actualVisitSequence);
}
// bfs tree
for (int i = 1; i < g.numVertices(); i++){
ASSERT_EQ(i - 1, bfs.pBfsParent[i]);
}
}
{
SCOPED_TRACE("complete graph K5");
string strK5 =
Expand Down Expand Up @@ -251,6 +264,9 @@ namespace graph{
bfs.search(g, src);
string actualVisitSequence = bfs.getVisitSequence();
ASSERT_EQ(expectedVisitSequence, actualVisitSequence);
// bfs tree
const int expectedBfsParent[] = {-1, 0, 0, 0, 0}; // first vertex is parent of all others
ASSERT_EQ(true, arrcmp<int>(expectedBfsParent, bfs.pBfsParent, g.numVertices()));
}
}
};
Expand Down
43 changes: 24 additions & 19 deletions YASI_12/ds.graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,17 @@ struct Edge{
};


template<class Element, class EdgeElement>
template<class Element, class EdgeElement, class LabelType = int>
struct Vertex{
protected:
typedef Vertex<Element, EdgeElement> self;
typedef Edge<self, EdgeElement> edge;
public:
typedef DoublyLinkedList< edge* > EdgeList;
typedef LabelType LabelType;

int id; // id assigned by the graph data structure
int label; // label assigned with input description
LabelType label; // label assigned with input description
Element element; // possibly composite information stored at this vertex

EdgeList* pInEdges;
Expand Down Expand Up @@ -59,6 +60,7 @@ class Graph : public IGraph{
friend class GraphTest;
public:
typedef Vertex<VertexElement, EdgeElement> VertexType;
typedef typename VertexType::LabelType VertexLabelType;
typedef Edge<VertexType, EdgeElement> EdgeType;
typedef DoublyLinkedList<VertexType*> VertexList;
typedef DoublyLinkedList<EdgeType*> EdgeList;
Expand All @@ -84,8 +86,8 @@ class Graph : public IGraph{
edgeList.clear();
}
public:
// by default, unweighted directed graph
Graph(bool weighted = false) :_weighted(weighted), _vertexId(0){
// by default, weighted directed graph
Graph(bool weighted = true) :_weighted(weighted), _vertexId(0){
}
virtual ~Graph(){
clear();
Expand All @@ -103,14 +105,16 @@ class Graph : public IGraph{
v2->pInEdges->pushBack(edge);
return edge;
}
VertexType* addVertex(int label){
VertexType* addVertex(VertexLabelType label){
// VertexLabelType is just int
VertexType* pVertex = new VertexType(_vertexId++);
pVertex->label = label;
vertexList.pushBack(pVertex);
return pVertex;
}
VertexType* addVertex(int label, VertexElement e){
VertexType* pVertex = addVertex(id);
VertexType* addVertex(VertexLabelType label, VertexElement e){
// VertexLabelType is just int
VertexType* pVertex = addVertex(label);
pVertex->element = e;
return pVertex;
}
Expand All @@ -134,24 +138,25 @@ class Graph : public IGraph{
// comments char
string commentChars = ";#";

// use a temporary hashtable
// use a temporary hashtable for id-ing the vertices
IntLinearProbingHashTable< VertexType* > ht;

while (! inp.eof()){
// comment line
char leadingChar = inp.peek();
if (commentChars.find(leadingChar) != string::npos ||// comment
leadingChar == '\n'){ // empty line
// skip this comment line
bool isComment = commentChars.find(leadingChar) != string::npos;
bool isBlankLine = leadingChar == '\n';
if (isComment || isBlankLine ){
// skip this line
inp.ignore(INT_MAX, '\n');
continue;
}


int vid1, vid2;
VertexLabelType vLabel1, vLabel2;
float w;
// vertices
inp >> vid1 >> vid2;
inp >> vLabel1 >> vLabel2;
// edge weight
if (_weighted){
inp >> w;
Expand All @@ -166,19 +171,19 @@ class Graph : public IGraph{
VertexType *pv1, *pv2;

// first vertex
ppv1 = ht.get(vid1);
ppv1 = ht.get(vLabel1);
if (!ppv1){
pv1 = addVertex(vid1);
ht.put(vid1, pv1);
pv1 = addVertex(vLabel1);
ht.put(vLabel1, pv1);
}
else{
pv1 = *ppv1;
}
// second vertex
ppv2 = ht.get(vid2);
ppv2 = ht.get(vLabel2);
if (!ppv2){
pv2 = addVertex(vid2);
ht.put(vid2, pv2);
pv2 = addVertex(vLabel2);
ht.put(vLabel2, pv2);
}
else{
pv2 = *ppv2;
Expand Down

0 comments on commit dc7bd3a

Please sign in to comment.