Applying Recursion Routing in Computer Networks

advertisement
Applying Recursion
Routing in Computer Networks
Review
We’ve seen that recursion provides an elegant,
simple, and (sometimes) efficient way to solve
certain problems.
A recursive solution consists of:
– a base case: an instance of the problem that is
trivial to solve; and
– an induction step: a means of solving non-trivial
instances using “smaller” solutions to the problem.
Problem
A computer network is a collection of
computers, that communicate via links.
2
0
1
5
6
Links may represent
3
4
– phone lines
– coaxial cable
– infared transmissions
– microwave relays
– satellite communication links
– ...
Network Operations
If we could represent a network in software,
some of the useful operations might be:
• Initialization (presumably from a file).
• Is there a computer with id i in the network?
• Is there a link from computer i to computer j ?
• Is there a path from computer i to computer j ?
Design
We can represent the computers
in the network by assigning
each one a unique integer
value (i.e., its network id).
One way to represent the links
in a network is to use an
adjacency matrix
-- a boolean matrix in which
entry [i][j] is true if and only
if there is a link from i to j.
2
0
3
1
5
4
6
[0] [1] [2] [3] [4] [5] [6]
[0]
F
T
F
F
F
F
T
[1] T
F
T
F
F
T
F
[2]
F
T
F
T
F
F
F
[3]
F
F
T
F
T
F
F
[4]
F
F
F
T
F
T
T
[5]
F
T
F
F
T
F
F
[6] T
F
F
F
T
F
F
Class Members
We might thus begin a Network class as follows:
// Network.h
// ...
// Directives omitted
class Network
{
public:
Network(const string & fileName);
int Size() const;
bool HasComputer(int id) const;
bool HasLink(int i, int j) const;
vector<int> RouteFrom(int i, int j) const;
private:
vector<int> PathFrom(int i, int j,
vector<int> visited) const;
int mySize;
// number of computers
typedef vector<bool> Row;
vector<Row> myLinks;
// adjacency matrix
};
Initialization
For convenience, we will initialize our network using
information from a file, whose format will be:
– the first line of the file provides the number of computers
in the network; and
– each subsequent line is a pair i j indicating a bidirectional
link between computers i and j.
2
0
3
1
5
6
4

7
0
1
2
3
4
4
0
1
1
2
3
4
5
6
6
5
Constructor
We can define the class constructor as follows:
// Network.cpp
// ...
#include “Network.h”
Network::Network(const string & fileName)
{
ifstream in(fileName.data()); // open stream to file
assert(in.is_open());
// verify
int n;
in >> n;
assert(n > 0);
mySize = n;
// ...
//
//
//
//
for convenience
read number of comps
check validity
save
Constructor
// ... Network constructor (ct’d)
myLinks = vector<Row>(n,
Row(n, false));
int i, j;
for (;;)
{
in >> i >> j;
}
}
// n Rows
// of n values
// all ‘F’
// computers
// loop:
// read i, j
if (in.eof()) break;
// if done, quit
assert(i >= 0 && i < mySize);
assert(j >= 0 && j < mySize);
// check i
// check j
myLinks[i][j] = myLinks[j][i]
= true;
// set links i,j
// & j,i to ‘T’
in.close();
// close stream
Declaration
We can now declare a Network object:
Network net(inputFile);
If inputFile contains the values shown earlier,
net will be constructed as follows:
net
mySize
myLinks
[0]
7
[0] [1] [2] [3] [4] [5] [6]
F
T
F
F
F
F
T
[1] T
F
T
F
F
T
F
[2]
F
T
F
T
F
F
F
[3]
F
F
T
F
T
F
F
[4]
F
F
F
T
F
T
T
[5]
F
T
F
F
T
F
F
[6] T
F
F
F
T
F
F
The Size() Operation
The Size() operation is a simple extractor:
// ...
inline int Network::Size() const
{
return mySize;
}
The HasComputer() Operation
The HasComputer() operation is also simple:
// ...
inline bool Network::HasComputer(int id) const
{
return id >= 0 && id < mySize;
}
The HasLink() Operation
Thanks to our adjacency matrix, the HasLink()
operation is also quite simple:
// ...
inline bool Network::HasLink(int i, int j) const
{
return myLinks[i][j];
}
The RouteFrom() Operation
The RouteFrom() operation is more complicated, since
in some networks, it may be necessary to check
many links in order to find a path.
Example: How do we find the path from 5 to 4
in the following network?
2
0
3
1
5
6
4
RouteFrom()
RouteFrom(i,j) can be implemented recursively.
However, we must keep track of those nodes
we have already visited on a route...
If we pass this information via a parameter,
we should define a recursive utility function
PathFrom(i, j, visited) to do the actual work.
Defining RouteFrom()
PathFrom() makes RouteFrom() easy to define:
// ...
inline
vector<int> Network::RouteFrom(int i, int j) const
{
vector<int> visited;
return PathFrom(i, j, visited);
}
We could just make PathFrom() a public operation,
but RouteFrom() provides a more convenient interface
by not requiring the user to pass visited.
Designing PathFrom()
PathFrom(i, j, visited):
Base case: HasLink(i,j) is true.
Return a vector containing i and j.
Induction Step: HasLink(i,j) is false.
For each computer c:
If HasLink(i,c) && c has not been visited:
If there is a PathFrom(c,j)
Add i to and return that path.
Defining PathFrom()
Here is one way PathFrom() can be defined:
// ...
vector<int> Network::PathFrom(int i, int j,
vector<int> beenTo) const
{
vector<int> result;
result.push_back(i);
beenTo.push_back(i);
if (myLinks[i][j])
// base case
{
result.push_back(j);
beenTo.push_back(j);
}
// ...
Defining PathFrom() (Ct’d)
}
// ...
else
// induction step
{
for (int v = 0; v < mySize; v++)
{
if (myLinks[i][v] &&
find(beenTo.begin(), beenTo.end(), v) ==
beenTo.end())
{
vector<int> temp = PathFrom(v, j, beenTo);
if (temp.size() > 1)
{
for (int k = 0; k < temp.size(); k++)
result.push_back(temp[k]);
break;
}
}
}
}
return result;
Class Members
Our final declaration of Network is thus as follows:
// Network.h
// ...
// Directives omitted
class Network
{
public:
Network(const string & fileName);
int Size() const;
bool HasComputer(int id) const;
bool HasLink(int i, int j) const;
vector<int> RouteFrom(int i, int j) const;
private:
vector<int> PathFrom(int i, int j,
vector<int> visited) const;
int mySize;
// number of computers
typedef vector<bool> Row;
vector<Row> myLinks;
// adjacency matrix
};
Discussion
PathFrom() is not very efficient, and the path it
returns may not be the shortest path from i to j.
The graph (a set of nodes and a set of edges
connecting them) is often used to model networks.
Efficient solutions have been devised for many graphtheory problems (e.g., the shortest path problem),
providing ready-made solutions to the
corresponding networking problems.
Summary
We have barely scratched the surface of C++!
C++ is an incredibly rich programming language, that
lets the programmer specifiy precisely what he or
she wishes the computer to do.
C++ provides many other libraries, containing more
ready-made solutions to common problems.
Continue on to the next course and learn about more
features of the C++ programming language!
Download