-
Notifications
You must be signed in to change notification settings - Fork 0
/
FileUtil.cs
215 lines (193 loc) · 8.04 KB
/
FileUtil.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
using System;
using System.Collections.Generic;
using System.IO;
namespace MST
{
/// <summary>
/// Generic class to provide utility functions
/// </summary>
class Util
{
/// <summary>
/// Reads the file and creates graph nodes.
/// </summary>
/// <param name="szFileName">Name of the file.</param>
/// <param name="oGraph">The graph object</param>
public static void readFileForNodes(String szFileName, ref Graph oGraph)
{
// file should have Rows as
// "<node id> <X-co-ordinate> <Y-co-ordinate>"
StreamReader oFile = new StreamReader(szFileName);
if (oFile != null)
{
String szLine;
while (!oFile.EndOfStream)
{
szLine = oFile.ReadLine();
if (szLine.Trim().Length != 0)
{
String[] listN = szLine.Split(new char[] { ' ', '\t' });
GraphNode oNode = new GraphNode(UInt32.Parse(listN[0]),
Int32.Parse(listN[1]),
Int32.Parse(listN[2]));
oGraph.addNode(oNode);
}
}
}
}
/// <summary>
/// Reads the file and creates graph edges.
/// </summary>
/// <param name="szFileName">Name of the file.</param>
/// <param name="oGraph">The graph object.</param>
public static void readFileForEdges(String szFileName, ref Graph oGraph)
{
// file should have Rows as
// "<from-node> <to-node> <traffic in kbps>"
StreamReader oFile = new StreamReader(szFileName);
if (oFile != null)
{
String szLine;
UInt32 uStartIdx = (UInt32) oGraph.m_listEdges.Count;
while (!oFile.EndOfStream)
{
szLine = oFile.ReadLine();
if (szLine.Trim().Length != 0)
{
String[] listN = szLine.Split(new char[] { ' ', '\t' });
oGraph.addEdge(++uStartIdx,
UInt32.Parse(listN[0]),
UInt32.Parse(listN[1]),
UInt32.Parse(listN[2]));
}
}
}
}
/// <summary>
/// Calculates the euclidian distance.
/// </summary>
/// <param name="n1">The node 1.</param>
/// <param name="n2">The node 2.</param>
/// <returns>Euclidian distance.</returns>
public static Double calcEuclidianDistance(GraphNode n1, GraphNode n2)
{
Int32 nXDiff = n1.m_nX - n2.m_nX;
Int32 nYDiff = n1.m_nY - n2.m_nY;
return Math.Sqrt(nXDiff * nXDiff + nYDiff * nYDiff);
}
// contains IDs for all the edges in the path.
public static List<UInt32> listPath = new List<UInt32>();
/// <summary>
/// Determines whether 'from' and 'to' has path or connected.
/// It uses Depth first search method, by examining edges
/// This is overloaded method.
/// first method provides interfacing, while second does actual work.
/// </summary>
/// <param name="from">From GraphNode</param>
/// <param name="to">To GraphNode</param>
/// <returns>
/// <c>true</c> if [has path] ; otherwise, <c>false</c>.
/// </returns>
public static bool hasPathDFS(GraphNode from, GraphNode to)
{
List<UInt32> listEdgeIDs = new List<UInt32>();
listPath.Clear();
return hasPathDFS(from, to, from.m_nID, to.m_nID, false, listEdgeIDs);
}
// this method actually implements
/// <summary>
/// Determines whether there is any path connecting from & to.
/// </summary>
/// <param name="from">From Node.</param>
/// <param name="to">To Node.</param>
/// <param name="nFromID">The original from ID.
/// This is a recursive method, hence we need it.
/// or May be it can be stored as a class member. </param>
/// <param name="nToID">The original to ID.
/// This is a recursive method, hence we need it.
/// or May be it can be stored as a class member. </param>
/// <param name="bValidate">check to identify any loops</param>
/// <param name="listEdgeIDs">check to identify any loops.
/// This is a way we will avoid any checked Edge ID.
/// </param>
/// <returns>
/// <c>true</c> if from and to are connected otherwise, <c>false</c>.
/// </returns>
protected static bool hasPathDFS(GraphNode from, GraphNode to,
UInt32 nFromID, UInt32 nToID,
bool bValidate,
List<UInt32> listPathEdges)
{
bool bRet = false;
if (from.m_nID == nToID)
{
// we have reached destination.
bRet = true;
return bRet;
}
if (bValidate && (from.m_nID == nFromID))
{
// it should not loop;
return bRet;
}
foreach (GraphEdge e in from.m_listEdge)
{
// if we already have examined the edge, we can skip it.
if (listPathEdges.Contains(e.m_nID))
continue;
else
listPathEdges.Add(e.m_nID); // this remembers examined edges.
listPath.Add(e.m_nID);
// we have to move to the next node, if we have come from
// a 'from' node we should examine a 'to' node & if from
// a 'to' node we should examine a 'from' node for next edge.
if (from.m_nID == e.m_nodeFrom.m_nID)
bRet = Util.hasPathDFS(e.m_nodeTo, to,
nFromID, nToID,
true, listPathEdges);
else
bRet = Util.hasPathDFS(e.m_nodeFrom, to,
nFromID, nToID,
true, listPathEdges);
if (bRet == true)
break;
else
{
// bRet == false, only if recursive check fails.
// => seems like this link does not lead to the 'to' node.
// hence removing edge id.
listPath.Remove(e.m_nID);
}
}
return bRet;
}
/// <summary>
/// Generates all the possible edges for given nodes and returns them.
/// </summary>
/// <param name="listNodes">The list nodes.</param>
/// <param name="listEdges">[out]The list edges.</param>
/// <returns></returns>
public static bool generateEdgeList(SortedNodeList listNodes,
out SortedEdgeList listEdges)
{
bool bRet = false;
SortedEdgeList l_listEdges = new SortedEdgeList();
UInt32 nEdgeID = 0;
for(Int32 nFrom = 0; nFrom < listNodes.Count; ++nFrom)
{
for (Int32 nTo = nFrom+1; nTo < listNodes.Count; ++nTo)
{
// make sure it is sorted by distance.
GraphEdge e = new GraphEdge(++nEdgeID,
listNodes[nFrom],
listNodes[nTo],
0);
l_listEdges.AddSorted(e);
bRet = true;
}
}
listEdges = l_listEdges;
return bRet;
}
}
}