1. 在500*500的场景中,随机生成N(可设置)个节点(节点坐标x, y);考虑节点的信号覆盖半径为R(可设置);如果两个节点之间的欧氏距离小于等于R,则认为这两个节点可以直接通信(有一条直接相连的边),生成网络拓扑图。
2. 在生成的网络拓扑图里,设定源节点和目的节点。
3. 利用距离矢量路由算法(DV)和链路状态路由算法(LS),在源节点和目的节点之间找到一条合适的路由并显示。
一、创建路由表
package cn.xue.controllers.DVandLSRouter;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Table {
public int endId;//目的路由的id
public int distance;
public int nextJumpId;//下一跳路由器id
}
二 、创建路由器
package cn.xue.controllers.DVandLSRouter;
import lombok.ToString;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ToString
public class Router {
public int id;
public double x;
public double y;
public HashMap<Integer,Integer> neighbors; //前面是路由id,后面是距离
public List<Table> tableListDV; //DV算法完成的路由表
public List<Table> tableListLS; //LS算法完成的路由表
public Router(){
tableListDV=new ArrayList<Table>();
tableListLS=new ArrayList<Table>();
neighbors =new HashMap<Integer, Integer>();
}
public void init(){ //初始化路由表
Table own = new Table();
own.setEndId(id);
own.setDistance(0);
own.setNextJumpId(id);
tableListDV.add(own);
tableListLS.add(own);
for(Integer key: neighbors.keySet()){
Table table = new Table();
table.setEndId(key);
table.setDistance(neighbors.get(key));
table.setNextJumpId(key);
tableListDV.add(table);
tableListLS.add(table);
}
}
public void receive(int sId,List<Table> tables){ //更新路由表
for(Table sTable:tables){ //接收的表
boolean isExist = false;
for(Table rTable:tableListDV){ //自己的表
if(sTable.getEndId() == rTable.getEndId()){
isExist = true;
int dis = sTable.getDistance()+neighbors.get(sId);
if(rTable.nextJumpId == sId){ //下跳地址与来源路由相同
if(dis < rTable.getDistance()){ //距离不同时才更新
rTable.setNextJumpId(dis);
}
}else{ //下跳地址与来源路由不同
if(dis < rTable.getDistance()){
rTable.setDistance(dis);
rTable.setNextJumpId(sId); //更新距离和下一跳地址
}
}
break; //找到便跳出循环
}
}
if(!isExist){ //目的网络不存在,添加
Table nTable = new Table();
nTable.setEndId(sTable.endId);
nTable.setDistance(sTable.getDistance()+neighbors.get(sId));
nTable.setNextJumpId(sId);
tableListDV.add(nTable);
}
}
}
}
三、初始化和DV算法与LS算法的实现
package cn.xue.controllers.DVandLSRouter;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class DVandLSmain {
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
System.out.println("请输入节点的个数:");
int RCount = scanner.nextInt();
System.out.println("请输入节点的信号覆盖半径:");
int R = scanner.nextInt();
List<Router> routerList = new ArrayList<Router>();
//初始化路由位置
for(int i =0;i<RCount;i++){
Router r =new Router();
r.id=i;
r.x=(double) (Math.random()*500);
r.y=(double) (Math.random()*500);
routerList.add(r);
}
//初始化路由器的邻居关系和表
for (Router r1 :routerList) {
for(Router r2: routerList){
double temp =(double)Math.pow(r1.x-r2.x,2)+(double) Math.pow(r1.y-r2.y,2);
double disR = (double)Math.sqrt(temp); //获取节点间的距离
if(disR < R && disR !=0){ //判断是否是邻居
if(r2.neighbors.size()!=0){
if(r2.neighbors.get(r1.id) !=null){
r1.neighbors.put(r2.id,r2.neighbors.get(r1.id));//放入邻居表,方便后面发送
}
}else{
int distance = (int)(Math.random()*15)+1;
r1.neighbors.put(r2.id,distance);
}
}
}
r1.init(); //初始化路由表
System.out.println(r1.toString());
}
//DV算法 每个路由器给自己的邻居发送自己的路由表
for(int i =0;i<routerList.size();i++){
for(Router r1 : routerList){
for(Integer key : r1.neighbors.keySet()){
for(Router r2 :routerList){
if(r2.id == key){
r2.receive(r1.id,r1.tableListDV);
}
}
}
}
}
//LS算法 每个路由器查找最小路径
for(Router r1:routerList){
List<Router> known = new ArrayList<Router>();
known.add(r1);
while(known.size() < routerList.size()){
int minNum = -1;
int minDis = -1;
int minNextJumpId = -1;
for(Table table:r1.tableListLS){
boolean isExist = false;
for(Router k : known){ //判断是否确定距离路由
if(table.endId == k.id){
isExist = true;
break;
}
}
if(!isExist){ //获取剩余路由中最小距离的
if(minNum < 0 || table.getDistance() < minDis){
minNum = table.getEndId();
minDis = table.getDistance();
minNextJumpId = table.getNextJumpId();
}
}
}
if(minDis < 0){
break;
}else{
for(Router r2 : routerList){
if(r2.id == minNum){ //获取最小距离路由
for(Integer key : r2.neighbors.keySet()){ //最小距离路由的邻居
int dis =minDis+r2.neighbors.get(key);
boolean isExist = false;
for(Table table : r1.tableListLS){ //判断r1表中是否已有此路由的邻居
if(table.endId == key){
if(table.distance > dis){ //存在且新距离小于老距离
table.setDistance(dis);
table.setNextJumpId(minNextJumpId);
}
isExist = true;
break;
}
}
if(!isExist){
Table table = new Table();
table.setEndId(key);
table.setDistance(dis);
table.setNextJumpId(minNextJumpId);
r1.tableListLS.add(table);
}
}
known.add(r2);
break;
}
}
}
}
}
System.out.println("------DV算法路由表------");
for(Router r :routerList){
System.out.println("-----路由器"+r.id+"号路由表----");
System.out.println("目的路由 距离 下一跳路由");
for(Table table:r.tableListDV){
System.out.println(" "+table.endId+" "+table.getDistance()+" "+table.getNextJumpId());
}
}
System.out.println("------LS算法路由表------");
for(Router r :routerList){
System.out.println("-----路由器"+r.id+"号路由表----");
System.out.println("目的路由 距离 下一跳路由");
for(Table table:r.tableListLS){
System.out.println(" "+table.endId+" "+table.getDistance()+" "+table.getNextJumpId());
}
}
}
}