近期再写一个网络仿真器,里面參考了Max-MinFairness算法,这是一种比較理想、公平的带宽分配算法。其思路主要例如以下:首先是算法的准备,考察某一时刻的网络中全部的flow,因为每条flow都有其各个link,因此能够得到各个link上全部流经的flow,然后開始迭代,各个link都把capacity平均分给全部流经的flow,接着每条flow的速度就等于其最小link分配的带宽,然后每条link的剩余带宽就等于link的capacity减去全部流经的flow的速度的总和,再然后把link的剩余带宽作为capacity又一次进行上面的迭代,直至全部flow在迭代中获得的带宽都小于一个阈值时,算法结束,带宽分配完毕。

让我们来分析这个算法并考虑怎样加速该算法的运行速度。首先,对于一些bottleneck的link,流经其的flow早早就不能分配带宽了,因此假设发如今某个迭代中某条link可以分配的带宽已经小于阈值,那么在下一轮迭代,全部流经其的flow都不再考察,即使某些flow并非以该link为bottleneck,因此,算法结束的条件可以改为当全部flow都不再考察的时候。这样对不正确呢,让我们分析一下。以该link为bottleneck的flow自然不用说了,所谓的bottleneck就是可以获取的带宽最小的link,那么最小的link已经不能分配带宽了,该flow自然不再考察。但不是以该link作为bottleneck的flow呢,它们有更小带宽的link,可是假设该link不是你的bottleneck,已经不能分配带宽了,那就刚不用说更小带宽的link了,所以这些flow也应该不再考察。好,算法的解说和分析就到这儿了,以下就是算法的实现,笔者採用的Java语言。

public Map<Integer, List<TrafficState>> run() {
Map<Integer, List<TrafficState>> resultMap = new HashMap<Integer, List<TrafficState>>();
int current = 0;
// PrintWriter resultWriter = new PrintWriter(resultFileName);
while (current < runtime) {
List<Integer> runningFlowList = new ArrayList<Integer>();
// the first traverse,add the new flows and remove the shopped flow
for (int i = 0; i < graph.traffics.size(); i++) {
Traffic currentTraffic = graph.traffics.get(i);
int starttime = currentTraffic.start;
if (starttime <= current && !currentTraffic.isStopped) {
List<Integer> linksList = currentTraffic.links;
if (currentTraffic.totlesize == 0) {
// start a new flow
currentTraffic.totlesize = currentTraffic.flowsize;
currentTraffic.leftsize = currentTraffic.totlesize;
for (Integer linkno : linksList) {
graph.links.get(linkno).trafficList
.add(currentTraffic);
}
}
// calculate the transfer bytes in a epoch
currentTraffic.epochsize = currentTraffic.speed
* ((float) period / 1000);
currentTraffic.leftsize -= currentTraffic.epochsize; if (currentTraffic.leftsize <= 0
|| currentTraffic.end == current) {
// no more flowsize or time is up,stop it
currentTraffic.isStopped = true;
for (Integer linkno : linksList) {
graph.links.get(linkno).trafficList
.remove(currentTraffic);
}
} else
runningFlowList.add(i);
}
}
// print the measurement
if (printTimeSet.contains(current)) {
List<TrafficState> stateList = new ArrayList<TrafficState>();
for (Traffic traffic : graph.traffics) {
//not the stop flows and the start ones just now
if (!traffic.isStopped && traffic.totlesize != 0
&& traffic.speed != 0) {
TrafficState state = new TrafficState();
state.setBytes(traffic.epochsize);
state.setDestination(traffic.destination);
state.setSource(traffic.source);
state.setThruput(traffic.speed);
String pathString = traffic.source;
int lastNode = Integer.parseInt(traffic.source);
for (Integer linkno : traffic.links) {
if (lastNode == graph.links.get(linkno).source) {
pathString += ","
+ graph.links.get(linkno).target;
lastNode = graph.links.get(linkno).target;
} else {
pathString += ","
+ graph.links.get(linkno).source;
lastNode = graph.links.get(linkno).source;
}
// pathString += "," +
// graph.links.get(linkno).target;
}
state.setPathString(pathString);
state.setStarttime(traffic.start);
state.setFlowsize(traffic.flowsize);
state.setEndtime(traffic.end);
stateList.add(state);
}
}
resultMap.put(current, stateList);
}
// initialize all the links and traffics
for (Link link : graph.links) {
link.leftCapacity = link.capacity;
}
for (Traffic traffic : graph.traffics) {
traffic.speed = 0;
}
Set<Integer> finishedTrafficSet = new HashSet<Integer>();
// the second traverse,set the throughput of each flow in next
// iteration
while (finishedTrafficSet.size() < runningFlowList.size()) {
for (int i = 0; i < runningFlowList.size(); i++) {
if (!finishedTrafficSet.contains(runningFlowList.get(i))) {
Traffic currentTraffic = graph.traffics
.get(runningFlowList.get(i));
currentTraffic.increSpeed = Float.MAX_VALUE;
Link minLink = null;
for (Integer linkno : currentTraffic.links) {
Link currentLink = graph.links.get(linkno);
int existFlowNum = 0;// the number of exist flows
for (Traffic traffic : currentLink.trafficList) {
if (traffic.increSpeed != 0
|| traffic.speed == 0) {
existFlowNum++;
}
}
float currentLinkSpeed = (float) currentLink.leftCapacity
/ (float) existFlowNum;
if (currentLinkSpeed < currentTraffic.increSpeed) {
currentTraffic.increSpeed = currentLinkSpeed;
minLink = currentLink;
}
}
if (currentTraffic.increSpeed > 5)
currentTraffic.speed += currentTraffic.increSpeed;
else {
currentTraffic.increSpeed = 0;
if (minLink != null) {
for (Traffic traffic : minLink.trafficList) {
traffic.increSpeed = 0;
finishedTrafficSet.add(graph.traffics
.indexOf(traffic));
}
} else
finishedTrafficSet.add(runningFlowList.get(i));
}
}
}
// link left capacity decrease the traffic increase throughput
for (Link link : graph.links) {
for (Traffic traffic : link.trafficList) {
link.leftCapacity -= traffic.increSpeed;
}
}
}
current += period;
}
// resultWriter.close();
return resultMap;
}

Max-Min Fairness带宽分配算法的更多相关文章

  1. 关于STL库中的max min swap

    嗯...   不得不说c++中的STL库是一个神奇的东西   可以使你的代码显得更加简洁....   今天就只讲STL中的三个鬼畜:   max       min       swap   具体操作 ...

  2. TLFS 内存分配算法详解

    文章目录 1. DSA 背景介绍 1.1 mmheap 1.2 mmblk 2. TLFS 原理 2.1 存储结构 2.2 内存池初始化 2.3 free 2.4 malloc 参考资料 1. DSA ...

  3. webrtc中的带宽自适应算法

    转自:http://www.xuebuyuan.com/1248366.html webrtc中的带宽自适应算法分为两种: 1, 发端带宽控制, 原理是由rtcp中的丢包统计来动态的增加或减少带宽,在 ...

  4. 6.组函数(avg(),sum(),max(),min(),count())、多行函数,分组数据(group by,求各部门的平均工资),分组过滤(having和where),sql优化

     1组函数 avg(),sum(),max(),min(),count()案例: selectavg(sal),sum(sal),max(sal),min(sal),count(sal) from ...

  5. 从集合中查找最值得方法——max(),min(),nlargest(),nsmallest()

    从集合中查找最值得方法有很多,常用的方法有max(),min(),nlargest(),nsmallest()等. 一.max()和min() 1.1 入门用法 直接使用max(),min(),返回可 ...

  6. day12 max min zip 用法

    max min ,查看最大值,最小值 基础玩法 l = [1,2,3,4,5] print(max(l)) print(min(l)) 高端玩法 默认字典的取值是key的比较 age_dic={'al ...

  7. max,min,Zip函数(十一)

    zip函数,拉链,传两个有序的参数,将他们一一对应为元祖形式 max,min比较默认比较一个元素,处理的是可迭代对象,相当于for循环取出每个元素进行比较,注意:不同类型之间不可比较 #!/usr/b ...

  8. group by与avg(),max(),min(),sum()函数的关系

    数据库表: create table pay_report(     rdate varchar(8),     --日期     region_id varchar(4),    --地市      ...

  9. Kafka集群副本分配算法解析

    副本分配算法如下: 将所有N Broker和待分配的i个Partition排序. 将第i个Partition分配到第(i mod n)个Broker上. 将第i个Partition的第j个副本分配到第 ...

随机推荐

  1. Django环境搭建(二)

    web框架 本质就是socket服务端 socket服务端:是计算机科学家在TCP/IP基础上进行封装,暴露出一个接口socket,就是一个收发数据的一个接口. 对于真实的web程序来说分为两部分:服 ...

  2. css函数——calc()和attr()

    css也有函数?好吧,我孤陋寡闻了.这里记录一下学习情况. calc()函数 定义:用于动态计算长度值 支持版本:css3 运算符前后都需要保留一个空格,例如:width: calc(100% - 1 ...

  3. (转)iptables详细教程:基础、架构、清空规则、追加规则、应用实例

    转自:http://lesca.me/archives/iptables-tutorial-structures-configuratios-examples.html iptables防火墙可以用于 ...

  4. js进阶 13-2 jquery动画滑动效果哪些注意事项

    js进阶 13-2 jquery动画滑动效果哪些注意事项 一.总结 一句话总结:滑动里面这里up是隐藏,down是显示. 1.jquery动画默认的两个切换效果是什么(swing默认和linear的区 ...

  5. 【47.76%】【Round #380B】Spotlights

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  6. 学习jquery.pagewalkthroung.js插件记录点

    1.53行:options = $.extend(true, {}, $.fn.pagewalkthrough.defaults, options); $.extend的作用是把第二个对象合并到第一个 ...

  7. 【48.51%】【poj 1611】The Suspects

    Time Limit: 1000MS Memory Limit: 20000K Total Submissions: 34447 Accepted: 16711 Description Severe ...

  8. JAVA中try-catch异常逃逸

    有时候一些小的细节,确实比较纠结,对于try-catch-finally代码块中代码依次执行,当try中有exception抛出时,将会有catch拦截并执行,如果没有catch区块,那么except ...

  9. Havel-Hakimi定理 hdu2454 / poj1695 Havel-Hakimi定理

    Havel-Hakimi定理 当年一度热门出如今ACM赛场上的算法. 算法定义: Havel-Hakimi定理主要用来判定一个给定的序列是否是可图的. 2.首先介绍一下度序列:若把图 G 全部顶点的度 ...

  10. Fragment之一:Fragment入门 分类: H1_ANDROID 2013-11-15 18:16 2799人阅读 评论(2) 收藏

    参考自张泽华视频 Fragment是自Android3.0后引入的特性,主要用于在不同的屏幕尺寸中展现不同的内容. Fragment必须被嵌入Activity中使用,总是作为Activity的组成部分 ...