Files
2024-09-27 01:32:49 +08:00

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;
}