/*
* Distance Vector Algorithm for C++.
*
* Created at 2020.6.13 by Esperanto.
* Copyright @ 2020 Esperanto.
* All rights reserved.
*
*/
#include <iostream>
#include <vector>
#include <iomanip>
#define INF INT_MAX
using namespace std;
class RouteItem
{
public:
int Destination_Address = -1;
int Distance = -1;
int NextHop = -1;
RouteItem(int a, int b, int c) :Destination_Address(a),
Distance(b), NextHop(c)
{
}
};
class RouteTable
{
public:
vector<RouteItem> Table;
bool isChanged = true;
};
typedef vector<vector<int>> Matrix;
typedef vector<RouteTable> NetworkInf;
void FillMatrix(Matrix& mat);
//void ShowMatrix(Matrix& mat);
void InitializeRouteTable(NetworkInf& net,Matrix& mat);
void UpdateRouteItem(RouteTable& r1, RouteTable& r2, int seq_me,int seq_you);
void UpdateNetworkInfo(NetworkInf& net, Matrix& neigh);
void ShowNetwork(NetworkInf& net,int Router_Num);
void ShowRouteItem(RouteItem& r);
int main()
{
int Router_Number = 0; //Scales of routers in this network.
cout << "How many routers in this net?" << endl;
cin >> Router_Number;
Matrix Topology(Router_Number); //Construct the topology of network.
for (int i = 0; i < Topology.size(); ++i)
{
Topology[i].resize(Router_Number); //Pre-distribute positions.
}
//Fill in distance.
FillMatrix(Topology);
//Construct the raw route table via topology.
NetworkInf Set_of_RouteTable(Router_Number);
for (int i = 0; i < Set_of_RouteTable.size(); ++i)
{
Set_of_RouteTable[i].Table.resize(Router_Number,RouteItem(-1,-1,-1));
}
InitializeRouteTable(Set_of_RouteTable, Topology);
//Construct neighbour table.
Matrix Neigh_Table;
for (int i = 0; i < Router_Number; ++i)
{
vector<int> line;
for (int j = 0; j < Router_Number; ++j)
{
if (Topology[i][j] != INF)
{
line.push_back(j);
}
}
Neigh_Table.push_back(line);
}
UpdateNetworkInfo(Set_of_RouteTable, Neigh_Table);
ShowNetwork(Set_of_RouteTable,Router_Number);
return 0;
}
void UpdateNetworkInfo(NetworkInf& net, Matrix& neigh)
{
int notFinished = 0;
do
{
notFinished = 0;
for (int i = 0; i < net.size(); ++i)
{
for (int j = 0; j < neigh[i].size(); ++j)
{
UpdateRouteItem(net[i], net[neigh[i][j]], i, neigh[i][j]);
notFinished = notFinished + net[i].isChanged;
}
}
} while (notFinished);
}
void UpdateRouteItem(RouteTable& r1, RouteTable& r2,int seq_me,int seq_you)
{
r1.isChanged = false; //Take it as unchanged.
for (int i = 0; i < r2.Table.size(); ++i) //Info from r2.
{
if (r2.Table[i].Destination_Address == seq_me ||
r2.Table[i].Destination_Address == -1)
{
continue;
}
if (r1.Table[i].Destination_Address == -1) //New info for r1.
{
r1.Table[i].Destination_Address = r2.Table[i].Destination_Address;
r1.Table[i].Distance = r2.Table[i].Distance + r2.Table[seq_me].Distance;
r1.Table[i].NextHop = seq_you;
r1.isChanged = true;
}
else //Info with same dest for r1.
{
//r2 is better.
if (r1.Table[i].Distance > r2.Table[i].Distance + r2.Table[seq_me].Distance)
{
r1.Table[i].Destination_Address = r2.Table[i].Destination_Address;
r1.Table[i].Distance = r2.Table[i].Distance + r2.Table[seq_me].Distance;
r1.Table[i].NextHop = seq_you;
r1.isChanged = true;
}
}
}
}
void FillMatrix(Matrix& mat)
{
int temp = 0;
for (int i = 0; i < mat.size(); ++i)
{
for (int j = 0; j < mat[i].size(); ++j)
{
cin >> temp;
if (temp == 0)
{
mat[i][j] = INF;
}
else
{
mat[i][j] = temp;
}
}
}
}
/*
void ShowMatrix(Matrix& mat)
{
for (int i = 0; i < mat.size(); ++i)
{
for (int j = 0; j < mat[i].size(); ++j)
{
cout << mat[i][j] << " ";
}
cout << endl;
}
}
*/
void InitializeRouteTable(NetworkInf& net,Matrix& mat)
{
for (int i = 0; i < net.size(); ++i)
{
for (int j = 0; j < mat.size(); ++j)
{
if (mat[i][j] != INF)
{
net[i].Table[j] = RouteItem(j, mat[i][j], j);
}
}
}
}
void ShowRouteItem(RouteItem& r)
{
if (r.Destination_Address != -1)
{
cout <<"┃ " << setw(2) << r.Destination_Address <<" ┃ "
<< setw(2) << r.Distance <<" ┃ " << setw(2) << r.NextHop <<" ┃"<< endl;
cout << "┣━━━━━━━━━━━━━━┫━━━━━━━━━━━━━━━┫━━━━━━━━━━━━━━━┫" << endl;
}
}
void ShowNetwork(NetworkInf& net,int Router_Num)
{
for (int i = 0; i < net.size(); ++i)
{
cout << endl;
cout << "┏━━━━━━━━━━━ Route-Table of Router " << i <<"━━━━━━━━━━━┓"<< endl;
cout << "┃━━━━━━━━━━━━━━┓━━━━━━━━━━━━━━━┓━━━━━━━━━━━━━━━┃" << endl;
cout << "┃ Dest-Net ┃" << " Distance " << "┃ NextHop ┃" << endl;
cout << "┃━━━━━━━━━━━━━━┫━━━━━━━━━━━━━━━┫━━━━━━━━━━━━━━━┃" << endl;
if (i < Router_Num-1) //Router 0-RouterNum-1
{
int j = 0;
for (j; j < net[0].Table.size() - 1; ++j)
{
ShowRouteItem(net[i].Table[j]);
}
cout << "┃ " << setw(2) << net[i].Table[j].Destination_Address << " ┃ "
<< setw(2) << net[i].Table[j].Distance << " ┃ "
<< setw(2) << net[i].Table[j].NextHop << " ┃" << endl;
cout << "┗━━━━━━━━━━━━━━┛━━━━━━━━━━━━━━━┛━━━━━━━━━━━━━━━┛" << endl;
}
else //Router Router_Num
{
int j = 0;
for (j; j < net[0].Table.size() - 2; ++j)
{
ShowRouteItem(net[i].Table[j]);
}
cout << "┃ " << setw(2) << net[i].Table[j].Destination_Address << " ┃ "
<< setw(2) << net[i].Table[j].Distance << " ┃ "
<< setw(2) << net[i].Table[j].NextHop << " ┃" << endl;
cout << "┗━━━━━━━━━━━━━━┛━━━━━━━━━━━━━━━┛━━━━━━━━━━━━━━━┛" << endl;
}
}
}
/*
e.g.1
0 11 0 0 5 0
11 0 2 0 0 6
0 2 0 3 7 0
0 0 3 0 0 1
5 0 7 0 0 4
0 6 0 1 4 0
e.g.2
0 2 0 0 0 0 6 0
2 0 7 0 2 0 0 0
0 7 0 3 0 3 0 0
0 0 3 0 0 0 0 2
0 2 0 0 0 2 1 0
0 0 3 0 2 0 0 2
6 0 0 0 1 0 0 4
0 0 0 2 0 2 4 0
*/
【Practical】DV算法C++实现(Visual Studio 2017环境)
猜你喜欢
转载自blog.csdn.net/weixin_44246009/article/details/106927919
今日推荐
周排行