Skip to content

Commit c454998

Browse files
author
Oleg Sh
committed
Support multigraph for find all pathes
1 parent 89378d1 commit c454998

20 files changed

Lines changed: 324 additions & 66 deletions

algorithm/PrintAllPaths.cpp

Lines changed: 120 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@
44
#include <unordered_map>
55
#include <iostream>
66
#include <cstring>
7+
#include <iterator>
8+
#include <string>
9+
10+
#include "IAlgorithmFactory.h"
711

812
// UTILITY FUNCTIONS DEFINITIONS
913
// FUNCTION TO CHECK IF THE NODE IS NOT VISITED
1014

11-
int isNotVisited(ObjectId x, const std::vector<ObjectId> & path)
15+
static int isNotVisited(ObjectId x, const std::vector<ObjectId> & path)
1216
{
1317
int size = path.size();
1418
for (int i = 0; i < size; i++)
@@ -23,6 +27,17 @@ int isNotVisited(ObjectId x, const std::vector<ObjectId> & path)
2327
void PrintAllPaths::pushResult(const std::vector<ObjectId> &path)
2428
{
2529
m_path.push_back(path);
30+
for (int i = 0; i < path.size(); i ++)
31+
{
32+
if (i % 2 == 0)
33+
{
34+
m_nodes.insert(path.at(i));
35+
}
36+
else
37+
{
38+
m_edges.insert(path.at(i));
39+
}
40+
}
2641
}
2742

2843
// FUNCTION GETTING NUMBER OF RESULT AVAILABLE IN m_path VECTOR
@@ -98,31 +113,9 @@ void PrintAllPaths::SetParameter(const AlgorithmParam* param)
98113

99114
bool PrintAllPaths::Calculate()
100115
{
101-
std::queue<std::vector<ObjectId>> q;
102-
std::vector<ObjectId> path;
103-
path.push_back(m_source);
104-
q.push(path);
105-
while (!q.empty())
106-
{
107-
path = q.front();
108-
q.pop();
109-
ObjectId last = path[path.size() - 1];
110-
if (last == m_target) // IF WE REACH DESTINATION THEN WE PUSH THE RESULT
111-
{
112-
pushResult(path);
113-
}
114-
for (IndexType i = 0; i < m_pGraph->GetConnectedNodes(last); i++) // LOOP THROUGH CONNECTED NODES OF LAST VERTEX
115-
{
116-
ObjectId v = m_pGraph->GetConnectedNode(last, i); // GET EACH OF THE CONNECTED NODES
117-
if (isNotVisited(v, path))
118-
{
119-
std::vector<ObjectId> new_path(path); // IF NODE IS NOT VISISTED THEN WE PUSH THE VERTEX ONTO NEW RESULT FOR NEXT ITERATIONS
120-
new_path.push_back(v);
121-
q.push(new_path);
122-
}
123-
}
124-
}
125-
return true;
116+
return m_pGraph->IsMultiGraph() ?
117+
CalculateMultiGraph() :
118+
CalculateNormalGraph();
126119
}
127120

128121
IndexType PrintAllPaths::GetResultCount() const
@@ -143,9 +136,24 @@ AlgorithmResult PrintAllPaths::GetResult(IndexType index) const
143136
{
144137
if (index < subgraph.size())
145138
{
146-
result.type = ART_NODES_PATH;
147-
m_pGraph->GetNodeStrId(subgraph[index], result.strValue, sizeof(result.strValue));
148-
return result;
139+
if (index % 2 == 0)
140+
{
141+
result.type = ART_NODES_PATH;
142+
m_pGraph->GetNodeStrId(subgraph[index], result.strValue, sizeof(result.strValue));
143+
return result;
144+
}
145+
else
146+
{
147+
result.type = ART_EDGES_PATH;
148+
m_pGraph->GetEdgeStrId(subgraph[index], result.strValue, sizeof(result.strValue));
149+
if (result.strValue[0] == 0)
150+
{
151+
std::string s = std::to_string(subgraph[index]);
152+
char const *str = s.c_str();
153+
strncpy(result.strValue, str, s.length() + 1);
154+
}
155+
return result;
156+
}
149157
}
150158
else if (index == subgraph.size())
151159
{
@@ -159,49 +167,106 @@ AlgorithmResult PrintAllPaths::GetResult(IndexType index) const
159167

160168
IndexType PrintAllPaths::GetHightlightNodesCount() const
161169
{
162-
IndexType res = 0;
163-
for (auto& path : m_path)
164-
res += path.size();
165-
166-
return res;
170+
return m_nodes.size();
167171
}
168172

169173
ObjectId PrintAllPaths::GetHightlightNode(IndexType index) const
170174
{
171-
for (auto& subgraph : m_path)
175+
if (index > m_nodes.size())
172176
{
173-
if (index < subgraph.size())
174-
{
175-
return subgraph[index];
176-
}
177-
index -= subgraph.size();
177+
return -1;
178178
}
179179

180-
return -1;
180+
return *std::next(m_nodes.begin(), index);
181181
}
182182

183183
IndexType PrintAllPaths::GetHightlightEdgesCount() const
184184
{
185-
IndexType res = 0;
186-
for (auto& path : m_path)
187-
res += path.size() - 1;
188-
189-
return res;
185+
return m_edges.size();
190186
}
191187

192188
NodesEdge PrintAllPaths::GetHightlightEdge(IndexType index) const
193189
{
190+
if (index > m_edges.size())
191+
{
192+
return NodesEdge();
193+
}
194+
195+
ObjectId edge_id = *std::next(m_edges.begin(), index);
196+
auto edge_nodes = m_pGraph->GetEdgeData(edge_id);
197+
194198
NodesEdge edge;
195-
for (auto& subgraph : m_path)
199+
edge.source = edge_nodes.source;
200+
edge.target = edge_nodes.target;
201+
edge.edgeId = edge_id;
202+
203+
return edge;
204+
}
205+
206+
bool PrintAllPaths::CalculateNormalGraph()
207+
{
208+
std::queue<std::vector<ObjectId>> q;
209+
std::vector<ObjectId> path;
210+
path.push_back(m_source);
211+
q.push(path);
212+
while (!q.empty())
196213
{
197-
if (index < subgraph.size() - 1)
214+
path = q.front();
215+
q.pop();
216+
ObjectId last = path[path.size() - 1];
217+
if (last == m_target) // IF WE REACH DESTINATION THEN WE PUSH THE RESULT
198218
{
199-
edge.source = subgraph[index];
200-
edge.target = subgraph[index + 1];
201-
edge.edgeId = m_pGraph->GetEdge(edge.source, edge.target);
202-
break;
219+
pushResult(path);
220+
}
221+
for (IndexType i = 0; i < m_pGraph->GetConnectedNodes(last); i++) // LOOP THROUGH CONNECTED NODES OF LAST VERTEX
222+
{
223+
ObjectId v = m_pGraph->GetConnectedNode(last, i); // GET EACH OF THE CONNECTED NODES
224+
if (isNotVisited(v, path))
225+
{
226+
std::vector<ObjectId> new_path(path); // IF NODE IS NOT VISISTED THEN WE PUSH THE VERTEX ONTO NEW RESULT FOR NEXT ITERATIONS
227+
auto edge = m_pGraph->GetEdge(last, v);
228+
new_path.push_back(edge);
229+
new_path.push_back(v);
230+
q.push(new_path);
231+
}
203232
}
204-
index -= subgraph.size() - 1;
205233
}
206-
return edge;
207-
}
234+
return true;
235+
}
236+
237+
bool PrintAllPaths::CalculateMultiGraph()
238+
{
239+
const IMultiGraph* multiGraph = m_pAlgorithmFactory->CreateMultiGraph(m_pGraph);
240+
241+
std::queue<std::vector<ObjectId>> q;
242+
std::vector<ObjectId> path;
243+
path.push_back(m_source);
244+
q.push(path);
245+
while (!q.empty())
246+
{
247+
path = q.front();
248+
q.pop();
249+
ObjectId last = path[path.size() - 1];
250+
if (last == m_target) // IF WE REACH DESTINATION THEN WE PUSH THE RESULT
251+
{
252+
pushResult(path);
253+
}
254+
for (IndexType i = 0; i < multiGraph->GetConnectedNodes(last); i++) // LOOP THROUGH CONNECTED NODES OF LAST VERTEX
255+
{
256+
ObjectId v = multiGraph->GetConnectedNode(last, i); // GET EACH OF THE CONNECTED NODES
257+
if (isNotVisited(v, path))
258+
{
259+
auto edges_number = multiGraph->GetEdgesNumber(last, v);
260+
for (IndexType e = 0; e < edges_number; e++)
261+
{
262+
ObjectId edge = multiGraph->GetEdge(last, v, e);
263+
std::vector<ObjectId> new_path(path);
264+
new_path.push_back(edge);
265+
new_path.push_back(v);
266+
q.push(new_path);
267+
}
268+
}
269+
}
270+
}
271+
return true;
272+
}

algorithm/PrintAllPaths.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "IGraph.h"
77
#include <vector>
88
#include <map>
9+
#include <set>
910
#include <unordered_map>
1011
#include <stdio.h>
1112

@@ -16,6 +17,9 @@ class PrintAllPaths : public BaseAlgorithm
1617
ObjectId m_target; // OBJECT ID STORING DESTINATION
1718
std::vector<std::vector<ObjectId>> m_path; // VECTOR THAT STORES FINAL RESULT
1819

20+
std::set<ObjectId> m_nodes;
21+
std::set<ObjectId> m_edges;
22+
1923
void pushResult(const std::vector<ObjectId> & path); // UTITLITY FUNCTION TO PUSH RESULTS ON m_path
2024
IndexType GetResultCountUtility() const; // UTITLITY FUNCTION THAT COUNTS NUMBER OF ELEMENTS IN RESULT
2125

@@ -32,6 +36,8 @@ class PrintAllPaths : public BaseAlgorithm
3236
// RETURNS SHORT NAME OF THE ALGORITHM
3337
virtual const char* GetShortName() const override { return "prnpaths"; }
3438

39+
bool IsSupportMultiGraph() const override { return true; }
40+
3541
// GET ALL THE PARAMETERS
3642
virtual bool EnumParameter(IndexType index, AlgorithmParam* outParamInfo) const override;
3743

@@ -60,6 +66,12 @@ class PrintAllPaths : public BaseAlgorithm
6066

6167
virtual void UnitTest() const override {}
6268

69+
private:
70+
71+
bool CalculateNormalGraph();
72+
73+
bool CalculateMultiGraph();
74+
6375
};
6476

6577
#endif
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
5+
http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
6+
7+
<key id="d1" for="edge" attr.name="weight" attr.type="double">
8+
<default>10.0</default>
9+
</key>
10+
<graph id="G" edgedefault="undirected">
11+
<node id="n0"/>
12+
<node id="n1"/>
13+
<node id="n2"/>
14+
<edge source="n0" target="n1" id="e0">
15+
<data key="d1">40.0</data>
16+
</edge>
17+
<edge source="n1" target="n0" id="e3">
18+
<data key="d1">4.0</data>
19+
</edge>
20+
<edge source="n2" target="n1" id="e1">
21+
<data key="d1">1.0</data>
22+
</edge>
23+
<edge source="n2" target="n1" id="e2"/>
24+
</graph>
25+
</graphml>
26+
27+
<!--
28+
n0=n1=n2
29+
-->
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Result is 4 (n0-><e0>->n1-><e1>->n2 | n0-><e0>->n1-><e2>->n2 | n0-><e3>->n1-><e1>->n2 | n0-><e3>->n1-><e2>->n2)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
5+
http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
6+
7+
<key id="d1" for="edge" attr.name="weight" attr.type="double">
8+
<default>10.0</default>
9+
</key>
10+
<graph id="G" edgedefault="undirected">
11+
<node id="n0"/>
12+
<node id="n1"/>
13+
<node id="n2"/>
14+
<node id="n3"/>
15+
16+
<edge source="n0" target="n1" id="e0">
17+
<data key="d1">40.0</data>
18+
</edge>
19+
<edge source="n1" target="n0" id="e3">
20+
<data key="d1">4.0</data>
21+
</edge>
22+
<edge source="n2" target="n1" id="e1">
23+
<data key="d1">1.0</data>
24+
</edge>
25+
<edge source="n2" target="n1" id="e2"/>
26+
<edge source="n2" target="n3" id="e4"/>
27+
<edge source="n1" target="n3" id="e5"/>
28+
</graph>
29+
</graphml>
30+
31+
<!--
32+
n0=n1=n2-n3
33+
|-----|
34+
-->

0 commit comments

Comments
 (0)