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