* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download 41.Applied.Recursion
Survey
Document related concepts
Transcript
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!