/**
* 数值趋势测算法
* @param int $datas 数据样本
* @param int $k 测算期数
* @param int $n 平均值长度
* @return array 预测数据
* @author leeldy
*/
function cal_tendency($datas, $k = 1, $n = false) {
//数据期数
$t = count($datas);
//判断n是否满足要求
if ($n) {
if ($t < $n + $n - 1) {
exit('平均值长度n数值过大!');
}
} else {
//取最大的n值
$n = intval(($t + 1) / 2);
}
$m = array(
//一次平均值
1 => array(),
//二次平均值
2 => array()
);
//前n项和
$m_1 = 0;
//前n项一次平均值和
$m_2 = 0;
//一次平均值开始计算点下标
$n_1 = $n - 1 - 1;
//二次平均值开始计算点下标
$n_2 = $n_1 + $n - 1;
//计算平均值
for ($i = 0; $i < $t; $i++) {
//数据前n项和
$m_1 += $datas[$i];
if ($i > $n_1) {
//开始计算一次平均值
$m[1][$i] = $m_1 / $n;
//去除最前一项
$m_1 -= $datas[$i - $n + 1];
//一次平均值前n项和
$m_2 += $m[1][$i];
if ($i > $n_2) {
//计算二次平均值
$m[2][$i] = $m_2 / $n;
$m_2 -= $m[1][$i - $n + 1];
}
}
}
//计算基本值和趋势系数
$at = $m[1][$t - 1] + $m[1][$t - 1] - $m[2][$t - 1];
$bt = 2 / ($n - 1) * ($m[1][$t - 1] - $m[2][$t - 1]);
//计算趋势
$result = array($at);
$i = 0;
while (++$i < $k) {
$result[$i] = $result[$i - 1] + $bt;
}
return $result;
}
算法说明详见:
http://wiki.mbalib.com/wiki/%E8%B6%8B%E5%8A%BF%E9%A2%84%E6%B5%8B%E6%B3%95