<?php /** * Created by PhpStorm. * User: linsn 10832126@qq.com * Date: 6/29/2017 * Time: 10:25 AM */ $users = '{"Angelica": {"Blues Traveler": 3.5, "Broken Bells": 2.0, "Norah Jones": 4.5, "Phoenix": 5.0, "Slightly Stoopid": 1.5, "The Strokes": 2.5, "Vampire Weekend": 2.0}, "Bill":{"Blues Traveler": 2.0, "Broken Bells": 3.5, "Deadmau5": 4.0, "Phoenix": 2.0, "Slightly Stoopid": 3.5, "Vampire Weekend": 3.0}, "Chan": {"Blues Traveler": 5.0, "Broken Bells": 1.0, "Deadmau5": 1.0, "Norah Jones": 3.0, "Phoenix": 5, "Slightly Stoopid": 1.0}, "Dan": {"Blues Traveler": 3.0, "Broken Bells": 4.0, "Deadmau5": 4.5, "Phoenix": 3.0, "Slightly Stoopid": 4.5, "The Strokes": 4.0, "Vampire Weekend": 2.0}, "Hailey": {"Broken Bells": 4.0, "Deadmau5": 1.0, "Norah Jones": 4.0, "The Strokes": 4.0, "Vampire Weekend": 1.0}, "Jordyn": {"Broken Bells": 4.5, "Deadmau5": 4.0, "Norah Jones": 5.0, "Phoenix": 5.0, "Slightly Stoopid": 4.5, "The Strokes": 4.0, "Vampire Weekend": 4.0}, "Sam": {"Blues Traveler": 5.0, "Broken Bells": 2.0, "Norah Jones": 3.0, "Phoenix": 5.0, "Slightly Stoopid": 4.0, "The Strokes": 5.0}, "Veronica": {"Blues Traveler": 3.0, "Norah Jones": 5.0, "Phoenix": 4.0, "Slightly Stoopid": 2.5, "The Strokes": 3.0} }'; $usersArray = json_decode($users, true); $recommend = new manhattanRecommend; $recommend = $recommend->recommend('Hailey', $usersArray); echo "<pre>"; print_r($recommend); class manhattanRecommend { //實現推薦 public function recommend($username, $users) { //得到最近用戶的name $nearest = $this->computeNearestNeighbor($username, $users); $nearest = $nearest['0']['user']; $recommendations = array(); //獲得最近用戶的推薦列表 $neighborRatings = $users[$nearest]; if ($this->checkArray($neighborRatings)) { $usernameAction = $users[$username]; foreach ($neighborRatings as $name => $code) { //讀取本身沒有的 if (!isset($usernameAction[$name])) { $recommendations[] = ['name' => $name, 'score' => $code]; } } } $this->sortArrByField($recommendations, 'score', true); return $recommendations; } //計算曼哈頓距離 private function manhattan($rate1, $rate2) { $distance = 0; if ($this->checkArray($rate1)) { foreach ($rate1 as $name => $value1) { if (isset($rate2[$name])) { $value2 = $rate2[$name]; $distance += abs($value1 - $value2); } } } else { $distance = -1; } return $distance; } //返回最近距離用戶 private function computeNearestNeighbor($username, $users) { $distances = array(); if ($this->checkArray($users)) { foreach ($users as $key => $user) { if ($key == $username) { continue; } $distance = $this->manhattan($user, $users[$username]); $data = array( 'user' => $key, 'distance' => $distance, ); $distances[] = $data; } } $this->sortArrByField($distances, 'distance', false); return $distances; } /** * @param $array * @return bool * 檢查數組有效性 */ private function checkArray($array) { if (is_array($array) && count($array) > 0) { return true; } else { return false; } } /** * @param $array * @param $field * @param bool $desc * 根據數組的某個值進行排序 */ private function sortArrByField(&$array, $field, $desc = false) { $fieldArr = array(); foreach ($array as $k => $v) { $fieldArr[$k] = $v[$field]; } $sort = $desc == false ? SORT_ASC : SORT_DESC; array_multisort($fieldArr, $sort, $array); } }