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.1‘, ‘weight‘ => 3), array(‘id‘ => ‘192.168.1.1‘, ‘weight‘ => 6), array(‘id‘ => ‘192.168.1.1‘, ‘weight‘ => 4), array(‘id‘ => ‘192.168.1.1‘, ‘weight‘ => 1), ); */ class ZxWeightedRoundRobin { private static $_weightArray = array(); private static $_i = -1; //代表上一次选择的服务器 private static $_gcd; //表示集合S中所有服务器权值的最大公约数 private static $_cw = 0; //当前调度的权值 private static $_max; //最大元素的值 private static $_n; //总元素个数 public function __construct(array $weightArray) { self::$_weightArray = $weightArray; self::$_gcd = self::getGcd(self::$_weightArray); } public function getWeight() { while (true) { self::$_i = ((int) self::$_i + 1) % (int) self::$_n; if (self::$_i == 0) { self::$_cw = (int) self::$_cw - (int) self::$_gcd; if (self::$_cw <= 0) { self::$_cw = (int) self::$_max; if (self::$_cw == 0) { return null; } } } if ((int) (self::$_weightArray[self::$_i][‘weight‘]) >= self::$_cw) { return self::$_weightArray[self::$_i]; } } } //获取最大公约数 Greatest common divisor 最大共同被除数 private static function getGcd(array $weightArray) { if (empty($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::$_max = max($weight); self::$_n = 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;
原文地址:https://www.cnblogs.com/zx-admin/p/10239570.html
时间: 2024-10-10 22:15:47