Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 11be5c6

Browse files
authored
adding few more algorithms
,
1 parent c321ffd commit 11be5c6

File tree

8 files changed

+600
-80
lines changed

8 files changed

+600
-80
lines changed

‎src/bgaMain.cpp

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
// modify it under the terms as GNU General Public License.
55
///////////////////////////////////////////////////////////////////
66
//
7-
// basic Graph Algorithms.cpp : This file contains the 'main' function. Program execution begins and ends there.
7+
// basic Graph Algorithms
8+
// This file contains the 'main' function to start the execution
9+
// with a basic text user interface for all algorithms.
810
//
911

10-
#include "graph.h"
12+
#include "scc.h"
1113
#include "dfs.h"
1214
#include "mst.h"
1315
#include "shortestPath.h"
@@ -51,17 +53,32 @@ int main(int argc, char** argv)
5153
{
5254
cout << " help\n";
5355
cout << " print\n";
56+
cout << " transpose\n";
57+
cout << " scc [<node>]\n";
5458
cout << " search <root_node>\n"; // dfs search tree
5559
cout << " sort \n"; // levelize or topological sort
5660
cout << " mst [prim|kruskal]\n"; // minimal spanning tree
57-
cout << " path <root_node>\n"; // Shortest Path from single source to all vertices
61+
cout << " path <start_node> [<end_node>]\n"; // Path from source to one or all vertices
5862
cout << " quit\n";
5963
}
6064
else if (choice == "print")
6165
{
6266
graph->print();
6367
cout << "\n";
6468
}
69+
else if (choice == "transpose")
70+
{
71+
transpose reverse(false);
72+
const basicGraph::bGraph* new_graph = reverse.build(graph);
73+
new_graph->print();
74+
delete new_graph;
75+
}
76+
else if (choice == "scc")
77+
{
78+
SCC::kosaraju sccBuilder(graph);
79+
sccBuilder.build();
80+
sccBuilder.print();
81+
}
6582
else if (choice == "search")
6683
{
6784
if (tokens.size() < 2) {
@@ -110,15 +127,34 @@ int main(int argc, char** argv)
110127
cerr << "Error: supply search node and try again.\n";
111128
continue;
112129
}
113-
string node = tokens[1];
114-
const basicGraph::bNode* src = graph->findNode(node);
115-
if (!src) {
116-
cerr << "Error: node " << node << "not found in the graph.\n";
130+
string node1 = tokens[1];
131+
string node2 = tokens.size() > 2 ? tokens[2] : "" ;
132+
const basicGraph::bNode* src = graph->findNode(node1);
133+
if (!src)
134+
{
135+
cerr << "Error: node " << node1 << "not found in the graph.\n";
136+
continue;
117137
}
118-
else {
138+
const basicGraph::bNode* dst = node2.length() ? graph->findNode(node2) : nullptr;
139+
if (node2.size() && !dst)
140+
{
141+
cerr << "Error: node " << node2 << "not found in the graph.\n";
142+
cerr << " will use single source path algorithm.\n";
143+
}
144+
145+
if ( dst == nullptr )
146+
{
147+
// path to all nodes from source
119148
short_paths::dijkstra single_source_path(src, graph);
120149
single_source_path.build();
121150
single_source_path.print();
151+
}
152+
else
153+
{
154+
// a_star search for source and destination.
155+
short_paths::aStar src_dst_path(src, graph);
156+
src_dst_path.build(dst);
157+
src_dst_path.print(dst);
122158
}
123159
}
124160
else if (choice == "quit" || choice == "exit")
@@ -132,5 +168,6 @@ int main(int argc, char** argv)
132168
}
133169
}
134170

171+
delete graph;
135172
return 0;
136173
}

‎src/dfs.h

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616

1717
class DFS {
1818
private:
19-
typedef enum { NOT_VISITED = 1, VISITING = 2, VISITED = 3 } NODE_MARKS;
20-
map<const basicGraph::bNode*, NODE_MARKS> nodeMarks_;
19+
map<const basicGraph::bNode*, basicGraph::NODE_MARKS> nodeMarks_;
2120
basicGraph::bGraph* graph_;
2221

2322
string tabs(unsigned int level) {
@@ -30,47 +29,47 @@ class DFS {
3029
set<const basicGraph::bNode*, basicGraph::nodeCompare>::iterator niter = graph_->nodeBegin();
3130
for (; niter != graph_->nodeEnd(); niter++) {
3231
const basicGraph::bNode* node = *niter;
33-
DFS::nodeMarks_[node] = NOT_VISITED;
32+
DFS::nodeMarks_[node] = basicGraph::NOT_VISITED;
3433
}
3534
return;
3635
}
3736

3837
void search_int(const basicGraph::bNode* src, unsigned int level = 0)
3938
{
4039
cout << tabs(level++) << src->name() << " visiting" << endl;
41-
DFS::nodeMarks_[src] = VISITING;
40+
DFS::nodeMarks_[src] = basicGraph::VISITING;
4241

4342
set<const basicGraph::bEdge*, basicGraph::edgeCompare>::iterator niter = src->edgeBegin();
4443
for (; niter != src->edgeEnd(); niter++) {
4544
const basicGraph::bNode* nextNode = (*niter)->otherNode(src);
46-
if (DFS::nodeMarks_[nextNode] == DFS::NOT_VISITED)
45+
if (DFS::nodeMarks_[nextNode] == basicGraph::NOT_VISITED)
4746
search_int(nextNode);
4847
}
4948

50-
DFS::nodeMarks_[src] = VISITED;
49+
DFS::nodeMarks_[src] = basicGraph::VISITED;
5150
cout << tabs(level--) << src->name() << " visited." << endl;
5251
}
5352

5453
void ts_visit(const basicGraph::bNode* src, vector<vector<const basicGraph::bNode*>>& container, unsigned int level=0)
5554
{
56-
if (DFS::nodeMarks_[src] == DFS::VISITED)
55+
if (DFS::nodeMarks_[src] == basicGraph::VISITED)
5756
return;
5857

59-
if (DFS::nodeMarks_[src] == DFS::VISITING)
58+
if (DFS::nodeMarks_[src] == basicGraph::VISITING)
6059
{
6160
cerr << "Error: cycle deteceted at node " << src->name() << ". Topological sorting abandoned.\n";
6261
return;
6362
}
6463

65-
DFS::nodeMarks_[src] = DFS::VISITING;
64+
DFS::nodeMarks_[src] = basicGraph::VISITING;
6665

6766
set<const basicGraph::bEdge*, basicGraph::edgeCompare>::iterator niter = src->edgeBegin();
6867
for (; niter != src->edgeEnd(); niter++) {
6968
const basicGraph::bNode* nextNode = (*niter)->otherNode(src);
7069
ts_visit(nextNode, container, level+1);
7170
}
7271

73-
DFS::nodeMarks_[src] = DFS::VISITED;
72+
DFS::nodeMarks_[src] = basicGraph::VISITED;
7473
container[level].push_back(src);
7574

7675
return;
@@ -115,7 +114,7 @@ class DFS {
115114
for (; niter != graph_->nodeEnd(); niter++)
116115
{
117116
const basicGraph::bNode* src = *niter;
118-
if (DFS::nodeMarks_[src] != VISITED)
117+
if (DFS::nodeMarks_[src] != basicGraph::VISITED)
119118
ts_visit(src, levelized_container);
120119
}
121120

‎src/graph.cpp

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,33 @@ void basicGraph::tokenizeLine(char* line, std::vector<std::string> &tokens)
4242
}
4343
}
4444

45+
basicGraph::bGraph::bGraph(const basicGraph::bGraph& other_graph)
46+
{
47+
isDirected_ = other_graph.directed();
48+
set<const basicGraph::bEdge*, basicGraph::edgeCompare>::iterator eiter;
49+
for (eiter = other_graph.edgeBegin(); eiter != other_graph.edgeEnd(); eiter++)
50+
{
51+
size_t wt = (*eiter)->hasWeight() ?
52+
dynamic_cast<const bWeightedEdge*>(*eiter)->weight() :
53+
basicGraph::bEdge::INVALID_WEIGHT;
54+
addNodesAndEdge((*eiter)->n1()->name(), (*eiter)->n2()->name(), wt);
55+
}
56+
return;
57+
}
58+
59+
void basicGraph::bGraph::addNodesAndEdge(string n1, string n2, size_t weight)
60+
{
61+
basicGraph::bNode* node1 = addNode(n1);
62+
basicGraph::bNode* node2 = addNode(n2);
63+
64+
const basicGraph::bEdge* edge = addEdge(node1, node2, weight);
65+
node1->addEdge(edge);
66+
if (!directed())
67+
node2->addEdge(edge);
68+
69+
return;
70+
}
71+
4572
void
4673
basicGraph::bGraph::print() const
4774
{
@@ -71,7 +98,7 @@ basicGraph::bGraph *basicGraph::bGraph::readBasicGraph(string filename)
7198
vector<string> tokens;
7299
tokenizeLine(line, tokens);
73100

74-
if (tokens.size() == 0 || tokens[0] == "#") {
101+
if (tokens.size() == 0 || tokens[0][0] == '#') {
75102
continue;
76103
}
77104
if (tokens.size() < 2)
@@ -87,18 +114,18 @@ basicGraph::bGraph *basicGraph::bGraph::readBasicGraph(string filename)
87114
else if (tokens[1] == "directed")
88115
new_graph->setDirected(true);
89116
else
90-
cerr << "invalid keyword after \'graph\' : " << tokens[1];
117+
cerr << "Error: invalid keyword after \'graph\' : " << tokens[1];
91118
}
92119
else {
93-
basicGraph::bNode* node1 = new_graph->addNode(tokens[0]);
94-
basicGraph::bNode* node2 = new_graph->addNode(tokens[1]);
95-
size_t weight = tokens.size() > 2 ?
96-
stol(tokens[2]) : basicGraph::bEdge::INVALID_WEIGHT;
97-
98-
const basicGraph::bEdge* edge = new_graph->addEdge(node1, node2, weight);
99-
node1->addEdge(edge);
100-
if (!new_graph->directed())
101-
node2->addEdge(edge);
120+
size_t weight = basicGraph::bEdge::INVALID_WEIGHT;
121+
if(tokens.size() > 2)
122+
{
123+
weight = stol(tokens[2]);
124+
if (weight < 0)
125+
cerr << "Warning: negative weight for the edge " << line << ".\n";
126+
}
127+
128+
new_graph->addNodesAndEdge(tokens[0], tokens[1], weight);
102129
}
103130
}
104131
buf.close();

‎src/graph.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
using namespace std;
1919

2020
namespace basicGraph {
21+
typedef enum { NOT_VISITED = 1, VISITING = 2, VISITED = 3 } NODE_MARKS;
2122
class bNode;
2223
class bEdge;
2324

@@ -46,6 +47,7 @@ namespace basicGraph {
4647
edgelist_.insert(e);
4748
return true;
4849
}
50+
void clearEdgeList() { edgelist_.clear(); }
4951
set<const bEdge*, edgeCompare>::iterator edgeBegin() const { return edgelist_.begin(); }
5052
set<const bEdge*, edgeCompare>::iterator edgeEnd() const { return edgelist_.end(); }
5153
};
@@ -73,6 +75,12 @@ namespace basicGraph {
7375
const bNode* n1() const { return n1_; }
7476
const bNode* n2() const { return n2_; }
7577
virtual bool hasWeight() const {return false; }
78+
void swap_nodes() // used to compute transpose of graph
79+
{
80+
const bNode* tmp = n1_;
81+
n1_ = n2_;
82+
n2_ = tmp;
83+
}
7684
const bNode* otherNode(const bNode* n) const
7785
{
7886
if (n1_ == n)
@@ -115,6 +123,7 @@ namespace basicGraph {
115123
set<const bEdge*, edgeCompare> edgeset_;
116124
public:
117125
bGraph(bool directed=false) : isDirected_(directed) {}
126+
bGraph(const bGraph& other);
118127
void setDirected(bool directed) { isDirected_ = directed; }
119128
bool directed() const { return isDirected_; }
120129
const bNode* findNode(string name) {
@@ -158,6 +167,7 @@ namespace basicGraph {
158167
}
159168
return e;
160169
}
170+
void addNodesAndEdge(string, string, size_t);
161171
size_t nNodes() const { return nodeset_.size(); }
162172
size_t nEdges() const { return edgeset_.size(); }
163173

‎src/heap.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ class Heap : public std::vector<T> {
5656
Heap() {}
5757
void push(const T& element);
5858
bool pop(T&);
59+
bool erase(T&);
5960
bool exists(T&);
61+
bool index(T&, size_t&);
6062
inline size_t parent_index(size_t i) { return (i - 1) >> 1; }
6163
inline size_t left_index(size_t i) { return (i << 1) + 1; }
6264
inline size_t right_index(size_t i) { return (i << 1) + 2; }
@@ -125,6 +127,38 @@ Heap<T, COMPARE>::pop(T& popped) {
125127
return true;
126128
}
127129

130+
template<typename T, class COMPARE>
131+
bool
132+
Heap<T, COMPARE>::index(T& element, size_t& idx) {
133+
134+
for (size_t i = 0; i < this->size(); i++)
135+
{
136+
if ((*this)[i] == element)
137+
{
138+
idx = i;
139+
return true;
140+
}
141+
}
142+
return false;
143+
144+
}
145+
146+
template<typename T, class COMPARE>
147+
bool
148+
Heap<T, COMPARE>::erase(T& element) {
149+
if (!this->size()) return false;
150+
151+
size_t idx;
152+
if (index(element, idx))
153+
{
154+
(*this)[idx] = (*this)[this->size() - 1];
155+
((std::vector<T>*)this)->pop_back();
156+
heapify_down(idx);
157+
return true;
158+
}
159+
return false;
160+
}
161+
128162
template<typename T, class COMPARE>
129163
bool
130164
Heap<T, COMPARE>::exists(T& element) {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /