138 lines
3.8 KiB
Plaintext
138 lines
3.8 KiB
Plaintext
private function gailv($weici_arr,$cur_weici,$flag=1){
|
|
|
|
$a = file_get_contents('norm.txt');
|
|
$a = $this->shape($a);
|
|
$dim =[33,11];
|
|
|
|
$xk = $weici_arr;//[5263,4960,5961,4977]; // 高校录取位次
|
|
$position_student = $cur_weici;//4936; // 学生当年位次
|
|
|
|
/**************************************************************/
|
|
$xk_average = array_sum($xk)/count($xk);
|
|
# (1) 当学生位次与高校位次差异较大时,选择不放大“方差因子”以使得求解的概率更大或更小
|
|
if($position_student <$xk_average){
|
|
$distance_factor=$position_student/$xk_average;
|
|
}else{
|
|
$distance_factor=$xk_average/$position_student;
|
|
}
|
|
//echo 'distance_factor='.$distance_factor.' ';
|
|
|
|
$enlarge_factor_sigma=$distance_factor*2+1; #方差放大因子在[1,3]之间变化
|
|
|
|
# (2)数据的倾斜程度越大,越需要降低直线斜率
|
|
$scale_step=$xk_average/2; #选取合适的x轴尺度
|
|
/*************************************************************/
|
|
|
|
// 线性规划预测当年数据
|
|
$xi_vector = [];
|
|
for($i=0;$i<=count($xk)-1;$i++){
|
|
$xi_vector[] = $i*$scale_step+$scale_step;
|
|
}
|
|
|
|
$yi_vector = $xk;
|
|
$xi_vector_average = array_sum($xi_vector)/count($xi_vector);
|
|
$yi_vector_average = array_sum($yi_vector)/count($yi_vector);
|
|
|
|
$frac_up = 0;$frac_down=0;$a_linear=0;$b_linear=0;
|
|
foreach ($xi_vector as $i => $val) {
|
|
$frac_up = $frac_up+($xi_vector[$i]-$xi_vector_average)*($yi_vector[$i]-$yi_vector_average);
|
|
$frac_down = $frac_down+($xi_vector[$i]-$xi_vector_average)*($xi_vector[$i]-$xi_vector_average);
|
|
$a_linear = $frac_up/$frac_down;
|
|
$b_linear = $yi_vector_average - $a_linear*$xi_vector_average;
|
|
}
|
|
$xk_predicted = $a_linear * (count($xk)+1)+$b_linear;
|
|
|
|
$theta_line=abs(atan($a_linear)*180/pi()); #计算直线斜率
|
|
|
|
# (2)数据的倾斜程度越大,越需要降低直线斜率
|
|
$beta_a_linear=1 - $theta_line/90;
|
|
//echo 'beta_a_linear='.$beta_a_linear.' ';
|
|
|
|
$xk_predicted = $beta_a_linear * $a_linear*($xi_vector[count($xi_vector)-1]+$scale_step)+$b_linear;
|
|
|
|
///////////////////////////////////////////////
|
|
$mu = array_sum($xk)/count($xk)*0.99999999; //样本均值
|
|
|
|
// 样本方差
|
|
$s = 0;
|
|
foreach ($xk as $val) {
|
|
$s = $s + pow(($val-$mu),2);
|
|
}
|
|
$sigma = sqrt($s/(count($xk)-1))*$enlarge_factor_sigma;
|
|
//echo 'mu='.$mu.' sigma='.$sigma;
|
|
|
|
$Z_norm = ($position_student - $mu)/$sigma; // 转换成标准正态分布
|
|
|
|
$sign_index = 1;
|
|
if($Z_norm<0){
|
|
$sign_index = -1;
|
|
$Z_norm = abs($Z_norm);
|
|
}
|
|
|
|
//使数据不超过表格行的范围
|
|
$Z_norm = $Z_norm>3.19?3.19:$Z_norm;
|
|
|
|
// 查表确定Z的值
|
|
for($i=0;$i<$dim[0];$i++){
|
|
|
|
if($Z_norm<=$a[$i][0]){
|
|
$m_row = $i-1;
|
|
break;
|
|
}else{
|
|
$m_row = $dim[0]-1;
|
|
}
|
|
}
|
|
$Z_decimal = $Z_norm - $a[$m_row][0];// 获取Z的百分位小数部分
|
|
|
|
for($j=0;$j<11;$j++){
|
|
if($Z_decimal<=$a[0][$j]){
|
|
$n_col = $j-1;
|
|
break;
|
|
}else{
|
|
$n_col = $dim[1] - 1;
|
|
}
|
|
}
|
|
|
|
//echo 'm_row='.$m_row.' n_col='.$n_col;
|
|
|
|
// 均值到Z的概率
|
|
if($n_col<10){
|
|
$x0 = $Z_decimal;
|
|
$xk = $a[0][$n_col];
|
|
$xkk = $a[0][$n_col+1];
|
|
$phi_xk = $a[$m_row][$n_col];
|
|
$phi_xkk = $a[$m_row][$n_col+1];
|
|
}else{
|
|
$x0 = $Z_decimal;
|
|
$xk = $a[0][$n_col];
|
|
$xkk = 0.1;
|
|
$phi_xk = $a[$m_row][$n_col];
|
|
$phi_xkk = $a[$m_row+1][1];
|
|
}
|
|
$P_Z_norm = ($x0-$xk)/($xkk-$xk)*$phi_xkk+($xkk-$x0)/($xkk-$xk)*$phi_xk;// 插值
|
|
//echo 'P_Z_norm='.$P_Z_norm."\r\n";
|
|
|
|
// 录取概率
|
|
$P_student = 0.5 -$sign_index*$P_Z_norm;
|
|
//echo '学生的录取概率:'.$P_student;
|
|
|
|
|
|
return $P_student;
|
|
}
|
|
|
|
private function shape($a){
|
|
$arr = explode("\n",$a);
|
|
|
|
foreach($arr as $key => $val){
|
|
$_temp = explode(' ', $val);
|
|
$item = [];
|
|
foreach($_temp as $t){
|
|
if(trim($t)==''){
|
|
continue;
|
|
}
|
|
$item[] = trim($t);
|
|
}
|
|
$arr[$key] = $item;
|
|
}
|
|
return $arr;
|
|
} |