2019年1月8日16:10:51

svn地址:svn://gitee.com/zxadmin/live_z    代码在code里面

<?php

/*
* 加权轮训算法
*
*
* $arr = array(
array('id' => 'A', 'weight' => 3),
array('id' => 'B', 'weight' => 3),
array('id' => 'C', 'weight' => 6),
array('id' => 'D', 'weight' => 4),
array('id' => 'E', 'weight' => 1),
);
* $arr = array(
array('id' => '192.168.1.1', 'weight' => 3),
array('id' => '192.168.1.2', 'weight' => 3),
array('id' => '192.168.1.3', 'weight' => 6),
array('id' => '192.168.1.4', 'weight' => 4),
array('id' => '192.168.1.5', 'weight' => 1),
);
*/ class ZxWeightedRoundRobin { private static $weightArray = array();
private static $currentIndex = -1; //代表上一次选择的服务器
private static $gcd; //表示集合S中所有服务器权值的最大公约数
private static $currentWeight = 0; //当前调度的权值
private static $maxWeight; //最大元素的值
private static $count; //总元素个数 public function __construct(array $weightArray) {
self::$weightArray = $weightArray;
self::$gcd = self::getGcd(self::$weightArray);
// p(self::$gcd);
} /*
*
* 算法的原理是:在服务器数组S中,首先计算所有服务器权重的最大值max(S),以及所有服务器权重的最大公约数gcd(S)。
index表示本次请求到来时,选择的服务器的索引,初始值为-1;current_weight表示当前调度的权值,初始值为max(S)。
当请求到来时,从index+1开始轮询服务器数组S,找到其中权重大于current_weight的第一个服务器,用于处理该请求。记录其索引到结果序列中。
在轮询服务器数组时,如果到达了数组末尾,则重新从头开始搜索,并且减小current_weight的值:current_weight -= gcd(S)。如果current_weight等于0,则将其重置为max(S)。
* 参考博客:https://blog.csdn.net/gqtcgq/article/details/52076997
* https://blog.csdn.net/jjavaboy/article/details/45604569
*/ public function getWeight() {
while (true) {
self::$currentIndex = ((int) self::$currentIndex + 1) % (int) self::$count;
if (self::$currentIndex == 0) {
self::$currentWeight = (int) self::$currentWeight - (int) self::$gcd;
if (self::$currentWeight <= 0) {
self::$currentWeight = (int) self::$maxWeight;
if (self::$currentWeight == 0) {
return null;
}
}
}
// p(self::$currentIndex);
if ((int) (self::$weightArray[self::$currentIndex]['weight']) >= self::$currentWeight) {
return self::$weightArray[self::$currentIndex];
}
}
} //获取最大公约数 Greatest common divisor 最大共同被除数
private static function getGcd(array $weightArray) {
if (empty($weightArray) || !is_array($weightArray)) {
throw new \Exception('数组不能为空');
}
$weight = [];
//权重只能为正整数
foreach ($weightArray as $k => $v) {
if (!is_int($v['weight']) || $v['weight'] <= 0) {
throw new \Exception('权限不合法');
}
$weight[] = $v['weight'];
}
$min = min($weight);
self::$maxWeight = max($weight);
self::$count = count($weight);
//如果最小值是1,最小公约数就必定是1
if ($min == 1) {
return 1;
}
//如果不是1,就每个元素,循环查询对最小值往下做整除处理,如果全可以整除,如果有一个不能就中断
for ($i = $min; $i > 1; $i--) {
foreach ($weight as $k1 => $v1) {
if ($v1 % $i == 0) {
$status = true;
} else {
$status = false;
break;
}
}
if ($status) {
return $i;
} else {
return 1;
}
}
} }

这个方法,我理解了最大公约数,但是 getWeight 方法还没有彻底理解,最小公约的话,就只需要修改

for ($i = $min; $i > 1; $i--) {遍历就可以

测试调用方法
$arr = array(
array('id' => 'A', 'weight' => 3),
array('id' => 'B', 'weight' => 3),
array('id' => 'C', 'weight' => 6),
array('id' => 'D', 'weight' => 4),
array('id' => 'E', 'weight' => 2),
);
$weight = new ZxWeightedRoundRobin($arr);
$a = 0;
$b = 0;
$c = 0;
$d = 0;
$e = 0;
for ($j = 0; $j < 100; $j++) {
$weightInfo = $weight->getWeight();
print_r($weightInfo);
echo $weightInfo['id'] . '----------------------weight:' . $weightInfo['weight'] . '<br/>';
if ($weightInfo['id'] == 'A') {
$a++;
}
if ($weightInfo['id'] == 'B') {
$b++;
}
if ($weightInfo['id'] == 'C') {
$c++;
}
if ($weightInfo['id'] == 'D') {
$d++;
}
if ($weightInfo['id'] == 'E') {
$e++;
}
}
echo 'A:' . $a . '<br/>';
echo 'B:' . $b . '<br/>';
echo 'C:' . $c . '<br/>';
echo 'D:' . $d . '<br/>';
echo 'E:' . $e . '<br/>';
exit;
 

PHP算法学习(2) 轮训加权算法的更多相关文章

  1. 四旋翼基础算法学习2-IMU输入滤波算法

    前言: 处理器读取陀螺仪加速度计数据后首先需要对数据进行滤波处理,此文分析比较几种常用的滤波算法. 参考学习:四轴加速度计滤波 IMU: IMU使用MPU9250(即MPU6500),设置加速度量程± ...

  2. 【算法学习笔记】Meissel-Lehmer 算法 (亚线性时间找出素数个数)

    「Meissel-Lehmer 算法」是一种能在亚线性时间复杂度内求出 \(1\sim n\) 内质数个数的一种算法. 在看素数相关论文时发现了这个算法,论文链接:Here. 算法的细节来自 OI w ...

  3. Kmeans算法学习与SparkMlLib Kmeans算法尝试

    K-means算法是最为经典的基于划分的聚类方法,是十大经典数据挖掘算法之一.K-means算法的基本思想是:以空间中k个点为中心进行聚类,对最靠近他们的对象归类.通过迭代的方法,逐次更新各聚类中心的 ...

  4. 算法学习之选择排序算法的python实现

    ——参考自<算法图解> def findSmallest(arr): # 假设第一个元素最小 smallest = arr[0] smallest_index = 0 for i in r ...

  5. 算法学习之二分查找算法的python实现

    ——参考自<算法图解> 我们假设需要查找的数组是有序的(从大到小或者从小到大),如果无序,可以在第四行后插入一句 my_list.sort() 完整代码如下 def binary_sear ...

  6. 算法学习笔记:Kosaraju算法

    Kosaraju算法一看这个名字很奇怪就可以猜到它也是一个根据人名起的算法,它的发明人是S. Rao Kosaraju,这是一个在图论当中非常著名的算法,可以用来拆分有向图当中的强连通分量. 背景知识 ...

  7. 算法学习笔记:Tarjan算法

    在上一篇文章当中我们分享了强连通分量分解的一个经典算法Kosaraju算法,它的核心原理是通过将图翻转,以及两次递归来实现.今天介绍的算法名叫Tarjan,同样是一个很奇怪的名字,奇怪就对了,这也是以 ...

  8. Python之路,Day21 - 常用算法学习

    Python之路,Day21 - 常用算法学习   本节内容 算法定义 时间复杂度 空间复杂度 常用算法实例 1.算法定义 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的 ...

  9. 数据挖掘算法学习(八)Adaboost算法

    本文不定期更新.原创文章,转载请附上链接http://blog.csdn.net/iemyxie/article/details/40423907 谢谢 Adaboost是一种迭代算法,其核心思想是针 ...

随机推荐

  1. Coursera, Big Data 3, Integration and Processing (week 1/2/3)

    This is the 3rd course in big data specification courses. Data model reivew 1, data model 的特点: Struc ...

  2. Anaconda+django安装问题

    Anaconda使用中常遇到如下问题: 如果Anaconda不是最新版本,可在Anaconda Prompt中使用如下命令更新至最新版 conda update -n base -c defaults ...

  3. windows下nginx的简单使用

    在网上是可以查得到关于nginx的一些使用,每次要用的时候都会去查一下别人的用法.既然自己用到的频率会比较高,那何不自己做个小小的笔记呢. 我使用的是windows版nginx-1.14.0,版本对命 ...

  4. matplotlib中的plt.ion()和plt.ioff()函数

    转自https://blog.csdn.net/yzy__zju/article/details/85008603 Matplotlib的显示模式默认为阻塞(block)模式,因此若想动态显示图像,则 ...

  5. [Linux]ln -al输出内容解析

    第一项的第一位是文件类型:-: 表示普通文件d: 目录b: 块特殊文件c: 字符特殊文件l:  符号链接文件p: 命名管道文件FIFOs: 套接字文件 第二项是该文件的inode的链接计数,即stat ...

  6. noj算法 8皇后打印 回溯法

    描述: 输出8皇后问题所有结果. 输入: 没有输入. 输出: 每个结果第一行是No n:的形式,n表示输出的是第几个结果:下面8行,每行8个字符,‘A’表示皇后,‘.’表示空格.不同的结果中,先输出第 ...

  7. canvas图片与img图片的相互转换

    最近在一个项目中,遇到了一个问题,需要把生成的canvas形式的二维码转换为图片,可以长按识别,保存等.查找了一些资料归纳总结了一些知识. 默认在jq库里进行,引入jquery.qrcode.min. ...

  8. 5、Filebeat工作原理

    Filebeat工作原理 Filebeat由两个主要组件组成:inputs和harvesters. 这些组件协同工作来查看最新文件内容并将事件数据发送到指定的输出.(注意与之前版本的不同,之前版本是p ...

  9. nl命令

    nl (Number of Lines) 将指定的文件添加行号标注后写到标准输出.如果不指定文件或指定文件为"-" ,程序将从标准输入读取数据. 选项: -b, --body-nu ...

  10. SQLServer中的CTE通用表表达式

    开发人员正在研发的许多项目都涉及编写由基本的 SELECT/FROM/WHERE 类型的语句派生而来的复杂 SQL 语句.其中一种情形是需要编写在 FROM 子句内使用派生表(也称为内联视图)的 Tr ...