recommand = new Database\DBRecommand(); } /** * 計算正規化參數 * @return double 正規化參數 */ private function computeNormalizationParameter($theme_number) { $normal = 0; //正規化之後的GAMMA值 $EntitySum = 0; //實體學習點分別算權重之後的值 $VirtualSum = 0; //虛擬學習點分別算權重之後的值 $edge = $this->recommand->queryEdgeByID('0'); for($i=0;$irecommand->queryBelongByID($next_point,$theme_number); $weight = $belong["weight"]; $VirtualSum += $weight / $next_target->getLearnTime(); if($next_target->isNumberOfPeopleZero()) $Rj = 0; else $Rj = $next_target->getMj() / $next_target->getPLj(); $EntitySum += $weight * ($next_target->getS() - $Rj + 1) / ($move_time + $next_target->getLearnTime()); } return $EntitySum/$VirtualSum; } /** * 是否為可以學習的標的 * @param $target_id 標的編號 * @return bool enable or not */ private function isEnableTargetId($activityObj,$target_id) { $target = new Target\Target($target_id); if(!$activityObj->isTargetLearned($target_id)) return true; else return false; } /** * 過濾非法的標的 * * @param array $point_list 全部的標的清單 * @param StudyActivity $activityObj 學習活動物件 * @return array 合法的學習點 */ private function excludeIrregularTarget($point_list,$activityObj) { $regularTarget = array(); for($i=0;$iisEnableTargetId($activityObj,$nextPoint)) { array_push($regularTarget,$point_list[$i]); } } return $regularTarget; } /** * 推薦學習點 * @param int $current_point 目前的標的編號 * @param int $theme_number 主題編號 * @param int activity_number 學習活動編號 * @return array 學習點清單 */ public function recommand($current_point,$activity_number) { // 取得活動物件 $this->activity = new Study\StudyActivity($activity_number); // 取得主題編號 $themeID = $this->activity->getThemeId(); // 取得這次活動是否使用虛擬學習點 $enableVirtual = $this->activity->isEnableVirtual(); $this->theme = new Study\Theme($themeID); // 計算正規化參數gamma值 $this->gamma = $this->computeNormalizationParameter($themeID); // 取得這個點到所有下一個點的資訊 $pointList = $this->recommand->queryEdgeByID($current_point); // 過濾不合法的學習點 $targetList = $this->excludeIrregularTarget($pointList,$this->activity); //計算路徑的權重值 $pathCost = 0; // 實體推薦度分數 $VirtualPathCost = 0; // 虛擬學習點推薦分數 // 整理可用的學習點清單 $recommand = array(); for($i=0;$itheme->getWeightByNextTarget($next_point); // 這個學習點目前人數已滿 if($nextPoint->isFullPeople()) { $pathCost = 0; $virtualCost = RecommandPoint::ALPHA * $this->gamma * ($weight/$nextPoint->getLearnTime()); $isEntity=false; // 若啟用虛擬學習點推薦 if($enableVirtual) { // 加入可推薦的學習點清單 array_push($recommand,array("nextPoint" => $next_point, "isEntity" => $isEntity, "PathCost" => $pathCost, "VirtualCost" => $virtualCost)); } } // 這個學習點目前人數沒有滿 else { $isEntity=true; if($nextPoint->isNumberOfPeopleZero()) $Rj = 0; else $Rj = $nextPoint->getMj()/$nextPoint->getPLj(); $pathCost = RecommandPoint::ALPHA * $this->gamma * ($weight * ($nextPoint->getS()-$Rj+1)/($moveTime + $nextPoint->getLearnTime())); $virtualCost = RecommandPoint::ALPHA * $this->gamma * ($weight/$nextPoint->getLearnTime()); // 加入可推薦的學習點清單 array_push($recommand,array("nextPoint" => $next_point, "isEntity" => $isEntity, "PathCost" => $pathCost, "VirtualCost" => $virtualCost)); } } // 依照算出來的推薦度分數PathCost排序 if(count($recommand) >= 1) { foreach($recommand as $key=>$value) { $tmp[$key] = $value["PathCost"]; } array_multisort($tmp,SORT_DESC,$recommand,SORT_DESC); } return $recommand; } public function insertRecommandHistory($activity_id, $target_ids) { if( count($target_ids) > 0 ) { return $this->recommand->insertRecommandHistory($activity_id, $target_ids); } } }