) C% P; k) v8 V0 O/ C: c' H$cos = array();5 q5 i6 g8 U7 R" a. T
$cos[0] = 0; " x, m4 m# f$ A! b$fm1 = 0; 6 x' `6 _0 q/ f//开始计算cos* R7 X- i* T3 h4 g: ^% f: \
//计算分母1,分母1是第一个公式里面 “*”号左边的内容,分母二是右边的内容3 A, y% H$ |' K$ N
for($i=1;$i<9;$i++){+ ^! B, z, `8 R6 ^6 _) G6 M% j
if($array[5][$i] != null){//$array[5]代表Leo 7 e) Y7 \2 }: \& y' \$ {+ G9 t $fm1 += $array[5][$i] * $array[5][$i];% e5 l8 W, m$ d4 Q$ d# f/ f
}0 k; J# D4 }9 e6 M+ ^
} 2 {# q/ Z% ] i# v4 ^ 3 D1 x. ?9 r6 z; c$fm1 = sqrt($fm1); ; p% n9 [1 G, u0 \7 N! A& H1 A' W% u% \0 m. f3 E
for($i=0;$i<5;$i++){) r' A8 {' z5 Z
$fz = 0; 2 G5 N% `1 O! }: K$ |" H $fm2 = 0; / |7 c" w' S- M* A- [- X echo "Cos(".$array[5][0].",".$array[$i][0].")="; r% L% y/ P+ V4 s % k* w( q; S: d7 ~; P" C
for($j=1;$j<9;$j++){ 0 _* H# H5 V4 x //计算分子) f* }4 b- Z" o
if($array[5][$j] != null && $array[$i][$j] != null){ 4 j* G9 J( R) q9 Q' [8 \ $fz += $array[5][$j] * $array[$i][$j];, ?# Z& R* s/ c
} , m9 R, i2 @) ]* V //计算分母2. c3 n4 x. a* O8 I: d
if($array[$i][$j] != null){ & q) g6 r0 R; i+ i( L $fm2 += $array[$i][$j] * $array[$i][$j]; o' J$ u4 B$ B5 ?5 E } " G! Z" c" A* H: |! X% K' R }; X& G/ `0 ^& f" v0 e
$fm2 = sqrt($fm2); 9 K* T5 C0 M+ |% r; E8 B, p $cos[$i] = $fz/$fm1/$fm2;7 Z: ?7 e! W# Q2 H& t1 x0 N
echo $cos[$i]."<br/>";8 N7 M* W7 v) n& w: f& a8 W
} ! Q4 _3 M" G$ R% T6 P9 [: R4 N) }" o
这一步得到的结果是酱紫: 1 a& `8 r0 o- F. }! P' G* j0 e& Q 8 S) A, Y" |% X2 S- N. K: A将求好的Cos值排序,采用快排代码如下(百度copy而来): 4 M9 O8 d! w0 m7 X& R: X/ u9 R, `4 n' O L
/ h) f* B v( t4 a) ]. @$ t# v' ^
//对计算结果进行排序,凑合用快排吧先7 c* W; ]1 B/ t- |. V" M
function quicksort($str){ 4 o* t1 ?' \( t0 i if(count($str)<=1) return $str;//如果个数不大于一,直接返回9 X' a D# Y# M9 @9 a) _4 ]
$key=$str[0];//取一个值,稍后用来比较; # h+ K6 X9 U% A6 |# o $left_arr=array();( x- J# o! F [: `- c# K
$right_arr=array();+ g4 l; Q4 @. j, a
( ?+ d, Z- x* B
for($i=1;$i<count($str);$i++){//比$key大的放在右边,小的放在左边;% x: }3 ?! R. X1 V" {! E& y3 T
if($str[$i]>=$key) ; |( {# \$ o4 J2 i; N$ K) U $left_arr[]=$str[$i]; & k( S9 Z7 e3 X4 c. D else 9 B% r6 |9 F0 I, x* K& e) `- [! _ $right_arr[]=$str[$i]; 2 M/ F6 u# n2 j }: B2 }0 F1 `% W. i4 ^% F- C
$left_arr=quicksort($left_arr);//进行递归; ( U5 E @! C, C0 f" c, E, s0 g $right_arr=quicksort($right_arr);9 W n- c8 G/ c
return array_merge($left_arr,array($key),$right_arr);//将左中右的值合并成一个数组; & j* b/ ~: j5 V& }}% E/ @" Q' L9 Z' b% [1 z
- j& h* ]# H& A8 K
$neighbour = array();//$neighbour只是对cos值进行排序并存储 7 H! _* e$ c2 q0 Y8 E* S6 r$neighbour = quicksort($cos);0 f. }) E- P+ R6 A& f
; o6 |6 M# L' d' i/ J% A, ~* f* |6 P* j+ J2 w( j1 c' W
这里的$neighbour数组仅仅存储了从大到小排序好的Cos值,并没有与人联系起来。这个问题还要解决。 % f% b7 B9 K8 w- [5 c ( a0 D, n" o% p选出Cos值最高的3个人,作为Leo的邻居: a& _* @! h- S3 f, V
\( p% Q! H% J# C9 Y [//$neighbour_set 存储最近邻的人和cos值 ' x. ~! a, ~/ k5 |$neighbour_set = array(); ; M' s7 z$ Z* i0 z+ p# ]for($i=0;$i<3;$i++){' N& E: k0 G% w
for($j=0;$j<5;$j++){2 Y5 o) X7 Y4 _9 Q6 ^. O
if($neighbour[$i] == $cos[$j]){7 N* c" n3 ^4 R w4 ^8 i
$neighbour_set[$i][0] = $j;+ x6 J* T! s8 n
$neighbour_set[$i][1] = $cos[$j];0 A& x+ c5 O3 b% z0 L. _/ b
$neighbour_set[$i][2] = $array[$j][6];//邻居对f的评分+ N% N; |; ~1 d& \1 v! b5 o
$neighbour_set[$i][3] = $array[$j][7];//邻居对g的评分 * G5 p5 E& m7 m5 S# {; A4 I {$ _ $neighbour_set[$i][4] = $array[$j][8];//邻居对h的评分( p/ b3 h# s% Q2 R/ q' |- L! d
} `* f$ s7 V- K7 b" _. Y
} ; J5 @- E1 Z! k$ Y2 a4 \! k! V1 U) k} 5 X$ W! ^- s3 O1 ~! V' r% nprint_r($neighbour_set);: ^8 M# B# Q) S4 N( d) R
echo "<p><br/>"; # i2 O: ]% ~( ^( D" ]+ W Q: S# D4 a F3 r$ P# @, |
这一步得到的结果是酱紫:* c; {, D" i4 l _5 h3 c0 x
: A I: F E5 z* p
+ E# w8 A' J" k& Z% j+ j% Y$ n1 G. m1 @! J
转存失败重新上传取消9 d. L$ z6 O0 d
# O2 d' I& w4 |* m5 x% e
这是一个二维数组,数组第一层的下标为0,1,2,代表3个人。第二层下标0代表邻居在数据表中的顺序,比如Jhon是表中的第0个人;下标1代表Leo和邻居的Cos值;下标2,3,4分别代表邻居对f,g,h的评分。2 u2 V$ |+ f& c+ k/ Z, H
# w. U4 w4 q5 n& |1 @开始进行预测,计算Predict代码如下: 2 I$ f. @% w- q8 v( c! G8 l d$ F! J4 h+ |' N
我是分别计算Leo对f,g,h的预测值。在此有一个问题,就是如果有的邻居对f,g,h的评分为空,那么该如何处理。比如Jhon和Mary对h的评分就为空。本能的想到用if判断一下,如果为空则跳过这组计算,不过这样处理是否合理,有待考虑。以下代码并没有写出这个if判断。 + u. H* a4 E5 v! Y! @/ l; n* N6 O( c1 L$ w
//计算Leo对f的评分 % E2 @3 W' h9 s& B: S- [& n$p_arr = array();* X! V9 ?5 g1 X% W. ^5 j$ V
$pfz_f = 0; 2 G3 p7 N. A5 d5 m3 j$pfm_f = 0;7 ~2 s! r& [- m w, ^& v9 @; c% n! |
for($i=0;$i<3;$i++){. r' z( w/ J" _* d
$pfz_f += $neighbour_set[$i][1] * $neighbour_set[$i][2];* t8 O9 Z$ K& c- _- A/ F+ D8 z! Q
$pfm_f += $neighbour_set[$i][1]; , o | z& k, A' O; |} 4 t+ T7 `# N6 L) f& z$p_arr[0][0] = 6; , V ~6 Z3 V( j' n$p_arr[0][1] = $pfz_f/sqrt($pfm_f); 6 F. t4 w( S9 r* {0 h! wif($p_arr[0][1]>3){ * [2 h' n0 _+ e8 k$ V echo "推荐f";" R5 N$ h6 \0 g0 b$ R2 A2 q$ A* B
} % f% @, ^- D- {* s2 t + D1 J3 I3 ~: Y& l0 P//计算Leo对g的评分: `6 |5 P! Z% F k, C; ^5 M
$pfz_g = 0; y7 {* o: Q- x& h1 h7 k3 V$pfm_g = 0;: n, T: _/ m3 p+ V
for($i=0;$i<3;$i++){ - T d& u1 ]% {& Y& c" m" C. F $pfz_g += $neighbour_set[$i][1] * $neighbour_set[$i][3]; . W8 C- U" S3 i1 i $pfm_g += $neighbour_set[$i][1];/ ^! g$ S6 k+ G, C. k
$p_arr[1][0] = 7;3 s7 M; ]5 B7 C9 A+ p3 z3 X
$p_arr[1][1] = $pfz_g/sqrt($pfm_g);' u+ m P* D% P
}, V4 l4 T/ q; c9 ]* N
if($p_arr[0][1]>3){ 6 x5 x$ w' r4 F3 u: ~6 @3 ^, O% d2 [ echo "推荐g"; 2 n$ j0 r$ \5 I} ! ? y8 T: o2 a) H: J" c' g% j" g, s1 I4 C+ m/ H
//计算Leo对h的评分2 I4 Q( B+ K2 I9 t6 Q, X
$pfz_h = 0;+ p- O6 h5 D$ B+ T7 \; J1 K+ H$ a5 H
$pfm_h = 0;+ a9 @( b% U* g0 B8 P8 v: N: r
for($i=0;$i<3;$i++){. f& J }: J* @: h, \" [0 V
$pfz_h += $neighbour_set[$i][1] * $neighbour_set[$i][4]; & u- k' w" f. o1 g $pfm_h += $neighbour_set[$i][1]; : _8 z2 U# T; A; u, w# r6 v $p_arr[2][0] = 8;8 h# W. U) l0 m9 n0 h0 D& M
$p_arr[2][1] = $pfz_h/sqrt($pfm_h);# b, @0 I" w: r4 w4 @ c0 a
} + u# Z% D& G$ a V0 Q5 kprint_r($p_arr);; W) U* l# U! H( H% F9 x
if($p_arr[0][1]>3){& B* y% O' [3 G2 f9 A
echo "推荐h"; ( B* P/ M _6 M2 T3 v6 V5 A. I( P} ; i9 Q2 \7 F9 e# X: }, N2 W; E; I! N. H, q& p y9 l# T; W
$p_arr是对Leo的推荐数组,其内容类似如下;: @; H/ f1 P4 V+ m