【Practical】DV算法C++实现(Visual Studio 2017环境)

/*
 * 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

*/

猜你喜欢

转载自blog.csdn.net/weixin_44246009/article/details/106927919