在Ryu控制器中,使用Dijkstra算法(dial实现)计算任意两点间的最短路,并在Mininet上完成配通业务。
Ryu与Mininet相关安装与配置详见:
https://blog.csdn.net/haimianxiaojie/article/details/50705288
关于本文内所有完整代码详见:
https://github.com/PPPerry/Ryu_projects中的Dijkstra部分
本实验所用拓扑结构同系列实验(一)。
-
使用Dijkstra算法(dial实现)计算任意两点间的最短路;
拓扑仍使用给定的拓扑结构,如图所示,各个交换机与主机的序号均相同。
其中,各条边的权重由randint(1,5)进行赋值。具体可见可视化平台中的展示。
现使用Dijkstra算法(dial实现)计算任意两点间的最短路,即循环桶实现。
首先,构造桶的class。
桶:桶排序定义:桶排序 (Bucketsort)或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶子里。每个桶子再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序)。桶排序是鸽巢排序的一种归纳结果。当要被排序的数组内的数值是均匀分配的时候,桶排序使用线性时间(Θ(n))。但桶排序并不是 比较排序,他不受到 O(n log n) 下限的影响。【来源:百度百科】
可见桶排序的效率非常的高,因此利用桶来寻找最短距离标记有利于提升dijkstra算法的运行效率,不过在真正实现算法的过程中实现的桶与真正的桶排序有一定的区别,这是由dijkstra算法的特点所决定的:即每个桶里面的元素距离标记都一样;但是要保证这一点需要的是在每永久标记一次(即节点出桶一次)桶的头部要往后一个桶移动,并且要保证改变桶的头部之前要把头部桶里面的所有节点清除出桶,然后永久标记。
桶的具体实现和封装: 所有的桶结构用一个list()来维持,而一个桶也是一个list(),BucketSet类封装了需要的桶结构,并且对外暴露add(_)和pop_min()方法用于添加元素到桶中和将最小距离标记节点取出,pop_min()方法返回最小距离标记的节点集合;Bucket类是BucketSet类的私有内部类,提供add()和pop_min() 方法功能与BucketSet的两个方法类似,具体更多实现细节见代码注释。
完整的桶类封装代码见打包的BucketSet.py。
定义好桶类后,Dijkstra算法基于桶的实现代码如下。
完整代码见打包的bucket_dijkstra.py -
使用最短路由配置任意两点的通信业务;
使用Ryu连接mininet后,结果如下:
Ryu读出了所有的交换机,并发现了34个连接。
ryu将返回值record最短路(一维列表),传到路径配置中
实现效果如图:
以h1 ping -c 1 h8为例:(拓扑序号命名见前面的拓扑图)
打印出h1到h8的最短路,并配置最短路:
以pingall为例:
所有的交换机均ping通,无掉包,且均按最短路径配置。
即任意两点间的通信业务都配置成功。 -
将所有业务在可视化平台上进行展示;
利用networkx,将拓扑图与最短路径(配置的路径)进行可视化展示:
以h1 ping -c 1 h8为例:(拓扑序号命名见前面的拓扑图)
图片样式是networkx随机生成的,但拓扑以及拓扑中的权重在topo生成之后是不会变的,即从h1到h9的路径就如图中红色的路径所示。
实现networkx的部分代码如下:
完整代码见附件中的bucket_dijkstra_draw.py(增添networkx可视化的bucket_dijkstra代码)。