基于 SpringBoot + Vue 的前后端分离游戏资讯平台,使用 Shiro 进行权限控制,使用 JWT 作为交互 token,使用 Aspectj 进行切面编程,使用 Spring Data Jpa 方便进行数据库操作,使用 Druid 作为数据库连接池,使用 MySQL 作为数据库;前端使用 element-ui 作为组件库,使用 bootstrap-vue 进行响应式编程,使用 vue-ueditor-wrap 来作为文本编辑器,使用 vuex 来存储状态信息,使用 axios 请求后端接口数据。
进行推荐
package com.tidalcoast.application.util;
import com.tidalcoast.application.entity.GameInfo;
import com.tidalcoast.application.entity.NewsInfo;
import com.tidalcoast.application.entity.User;
import com.tidalcoast.application.service.ipml.GameInfoServiceImpl;
import com.tidalcoast.application.service.ipml.NewsInfoServiceImpl;
import com.tidalcoast.application.service.ipml.UserServiceImpl;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.*;
/**
* @Author: tidalcoast
* @Date: 2022/4/22 13:31
* @Description 计算相似度
*/
@Component
public class UserCFUtil {
class MapSortedMap implements Comparator<Map.Entry<Long, Double>> {
//从大到小降序
@Override
public int compare(Map.Entry<Long, Double> o1, Map.Entry<Long, Double> o2) {
return o2.getValue().compareTo(o1.getValue());
}
}
@Resource
private UserServiceImpl userService;
@Resource
private GameInfoServiceImpl gameInfoService;
@Resource
private NewsInfoServiceImpl newsInfoService;
// private static Scanner scanner = new Scanner(System.in);
//建立用户稀疏矩阵,用于用户相似度计算
private static int[][] sparseMatrix;
//存储每一个用户对应的不同物品总数
private static Map<Long, Integer> userItemLength = new HashMap<>();
//建立物品到用户的倒排表
private static Map<Long, Set<Long>> itemUserCollection = new HashMap<>();
//辅助存储物品的集合
private static Set<Long> items = new HashSet<>();
//辅助储存每一个用户的用户ID映射
private static Map<Long, Integer> userID = new HashMap<>();
//辅助储存每一个ID对应的用户映射
private static Map<Integer, Long> idUser = new HashMap<>();
/**
* 初始化方法
*
* @param num 稀疏矩阵的长和宽
*/
private static void init(int num) {
sparseMatrix = new int[num][num];
userItemLength = new HashMap<>();
itemUserCollection = new HashMap<>();
items = new HashSet<>();
userID = new HashMap<>();
idUser = new HashMap<>();
}
public List<Long> calculateFriendLike(Long userId) {
List<Long> resultList = new ArrayList<>();
//获取好友列表
List<User> friendList = userService.getFriendListByUserId(userId);
User u = userService.findUserById(userId);
if (u == null) {
return resultList;
}
friendList.add(u);
int N = friendList.size();
init(N);
if (N > 1) {
for (int i = 0; i < N; i++) {
//获取用户Id
Long uid = friendList.get(i).getId();
//根据用户id获取收藏的游戏
List<GameInfo> likeGames = gameInfoService.getAllGameInfoLikeByUserId(uid);
Long[] user_item = new Long[likeGames.size() + 1];
user_item[0] = uid;
for (int x = 0; x < likeGames.size(); x++) {
user_item[x + 1] = likeGames.get(x).getId();
}
int length = user_item.length;
userItemLength.put(user_item[0], length - 1);
//用户ID与稀疏矩阵建立对应关系
userID.put(user_item[0], i);
idUser.put(i, user_item[0]);
//userId
System.out.println(userID.toString());
//idUser
System.out.println(idUser.toString());
//建立物品--用户倒排表
for (int j = 1; j < length; j++) {
if (items.contains(user_item[j])) {
//如果已经包含物品--用户映射,直接添加对应的用户
itemUserCollection.get(user_item[j]).add(user_item[0]);
} else {
//否则创建对应物品--用户集合映射
items.add(user_item[j]);
//创建物品--用户的倒排关系
itemUserCollection.put(user_item[j], new HashSet<>());
itemUserCollection.get(user_item[j]).add(user_item[0]);
}
}
}
System.out.println(itemUserCollection.toString());
//计算相似度矩阵【稀疏】
Set<Map.Entry<Long, Set<Long>>> entrySet = itemUserCollection.entrySet();
for (Map.Entry<Long, Set<Long>> setEntry : entrySet) {
Set<Long> commonUsers = setEntry.getValue();
for (Long user_u : commonUsers) {
for (Long user_v : commonUsers) {
if (user_u.equals(user_v)) {
continue;
}
//计算用户u与用户v都有正反馈的物品总数
sparseMatrix[userID.get(user_u)][userID.get(user_v)] += 1;
}
}
}
System.out.println(userItemLength.toString());
// System.out.println("输入想要查询相似度的用户");
//计算用户之间的相似度【余弦相似性】
int recommendUserId = userID.get(userId);
//存储该用户好友相似度的Map
Map<Long, Double> degreeMap = new HashMap<>();
for (int j = 0; j < sparseMatrix.length; j++) {
if (j != recommendUserId) {
double userLikeDegree = sparseMatrix[recommendUserId][j] /
Math.sqrt(userItemLength.get(idUser.get(recommendUserId)) * userItemLength.get(idUser.get(j)));
System.out.println(idUser.get(recommendUserId) + "--" + idUser.get(j) +
"相似度:" + userLikeDegree);
degreeMap.put(idUser.get(j), userLikeDegree);
}
}
//对map中的数据根据相似度进行排序
List<Map.Entry<Long, Double>> entryList = new ArrayList<>(degreeMap.entrySet());
entryList.sort(new MapSortedMap());
//只返回用户id
for (Map.Entry<Long, Double> entry : entryList) {
if (entry.getValue() > 0.5){
//只推荐相似度大于0.5的好友
resultList.add(entry.getKey());
}
}
}
return resultList;
}
public List<Long> calculateInfoLike(Long userId) {
List<Long> resultList = new ArrayList<>();
//获取好友列表
List<User> friendList = userService.getFriendListByUserId(userId);
User u = userService.findUserById(userId);
if (u == null) {
return resultList;
}
friendList.add(u);
int N = friendList.size();
init(N);
if (N > 1) {
for (int i = 0; i < N; i++) {
//获取用户Id
Long uid = friendList.get(i).getId();
//根据用户id获取收藏的资讯
List<NewsInfo> likeNewsInfos = newsInfoService.getNewsInfoLikedByUserId(uid);
Long[] user_item = new Long[likeNewsInfos.size() + 1];
user_item[0] = uid;
for (int x = 0; x < likeNewsInfos.size(); x++) {
user_item[x + 1] = likeNewsInfos.get(x).getId();
}
int length = user_item.length;
userItemLength.put(user_item[0], length - 1);
//用户ID与稀疏矩阵建立对应关系
userID.put(user_item[0], i);
idUser.put(i, user_item[0]);
//userId
System.out.println(userID.toString());
//idUser
System.out.println(idUser.toString());
//建立物品--用户倒排表
for (int j = 1; j < length; j++) {
if (items.contains(user_item[j])) {
//如果已经包含物品--用户映射,直接添加对应的用户
itemUserCollection.get(user_item[j]).add(user_item[0]);
} else {
//否则创建对应物品--用户集合映射
items.add(user_item[j]);
//创建物品--用户的倒排关系
itemUserCollection.put(user_item[j], new HashSet<>());
itemUserCollection.get(user_item[j]).add(user_item[0]);
}
}
}
System.out.println(itemUserCollection.toString());
//计算相似度矩阵【稀疏】
Set<Map.Entry<Long, Set<Long>>> entrySet = itemUserCollection.entrySet();
for (Map.Entry<Long, Set<Long>> setEntry : entrySet) {
Set<Long> commonUsers = setEntry.getValue();
for (Long user_u : commonUsers) {
for (Long user_v : commonUsers) {
if (user_u.equals(user_v)) {
continue;
}
//计算用户u与用户v都有正反馈的物品总数
sparseMatrix[userID.get(user_u)][userID.get(user_v)] += 1;
}
}
}
System.out.println(userItemLength.toString());
//计算指定用户recommendUser的物品推荐度
//存储该用户物品相似度的Map
Map<Long, Double> degreeMap = new HashMap<>();
for (Long item : items) {
//遍历每一件物品
//得到喜爱当前物品的所有用户集合
Set<Long> users = itemUserCollection.get(item);
if (!users.contains(userId)) {
double itemRecommendDegree = 0.0;
for (Long user : users) {
//推荐度计算公式
itemRecommendDegree += sparseMatrix[userID.get(userId)][userID.get(user)] /
Math.sqrt(userItemLength.get(userId) * userItemLength.get(user));
}
System.out.println("物品" + item + "对" + userId + "的相似度为" + itemRecommendDegree);
degreeMap.put(item, itemRecommendDegree);
}
}
//对map中的数据根据相似度进行排序
List<Map.Entry<Long, Double>> entryList = new ArrayList<>(degreeMap.entrySet());
entryList.sort(new MapSortedMap());
//只返回id
for (Map.Entry<Long, Double> entry : entryList) {
resultList.add(entry.getKey());
}
}
if (resultList.size() >= 5) {
return resultList;
}
//如果推荐数不足五个,则用点击量最高的资讯进行补充
List<NewsInfo> topNews = newsInfoService.getNewsInfoOrderByClickCountsTopTen();
for (NewsInfo n : topNews) {
if (resultList.size() >= 5) {
break;
}
if (!resultList.contains(n.getId())) {
resultList.add(n.getId());
}
}
return resultList;
}
public List<Long> calculateGameLike(Long userId) {
List<Long> resultList = new ArrayList<>();
//获取好友列表
List<User> friendList = userService.getFriendListByUserId(userId);
User u = userService.findUserById(userId);
if (u == null) {
return resultList;
}
friendList.add(u);
int N = friendList.size();
init(N);
if (N > 1) {
for (int i = 0; i < N; i++) {
//获取用户Id
Long uid = friendList.get(i).getId();
//根据用户id获取收藏的游戏
List<GameInfo> likeGames = gameInfoService.getAllGameInfoLikeByUserId(uid);
Long[] user_item = new Long[likeGames.size() + 1];
user_item[0] = uid;
for (int x = 0; x < likeGames.size(); x++) {
user_item[x + 1] = likeGames.get(x).getId();
}
int length = user_item.length;
userItemLength.put(user_item[0], length - 1);
//用户ID与稀疏矩阵建立对应关系
userID.put(user_item[0], i);
idUser.put(i, user_item[0]);
//userId
System.out.println(userID.toString());
//idUser
System.out.println(idUser.toString());
//建立物品--用户倒排表
for (int j = 1; j < length; j++) {
if (items.contains(user_item[j])) {
//如果已经包含物品--用户映射,直接添加对应的用户
itemUserCollection.get(user_item[j]).add(user_item[0]);
} else {
//否则创建对应物品--用户集合映射
items.add(user_item[j]);
//创建物品--用户的倒排关系
itemUserCollection.put(user_item[j], new HashSet<>());
itemUserCollection.get(user_item[j]).add(user_item[0]);
}
}
}
System.out.println(itemUserCollection.toString());
//计算相似度矩阵【稀疏】
Set<Map.Entry<Long, Set<Long>>> entrySet = itemUserCollection.entrySet();
for (Map.Entry<Long, Set<Long>> setEntry : entrySet) {
Set<Long> commonUsers = setEntry.getValue();
for (Long user_u : commonUsers) {
for (Long user_v : commonUsers) {
if (user_u.equals(user_v)) {
continue;
}
//计算用户u与用户v都有正反馈的物品总数
sparseMatrix[userID.get(user_u)][userID.get(user_v)] += 1;
}
}
}
System.out.println(userItemLength.toString());
//计算指定用户recommendUser的物品推荐度
//存储该用户物品相似度的Map
Map<Long, Double> degreeMap = new HashMap<>();
for (Long item : items) {
//遍历每一件物品
//得到喜爱当前物品的所有用户集合
Set<Long> users = itemUserCollection.get(item);
if (!users.contains(userId)) {
double itemRecommendDegree = 0.0;
for (Long user : users) {
//推荐度计算公式
itemRecommendDegree += sparseMatrix[userID.get(userId)][userID.get(user)] /
Math.sqrt(userItemLength.get(userId) * userItemLength.get(user));
}
System.out.println("物品" + item + "对" + userId + "的相似度为" + itemRecommendDegree);
degreeMap.put(item, itemRecommendDegree);
}
}
//对map中的数据根据相似度进行排序
List<Map.Entry<Long, Double>> entryList = new ArrayList<>(degreeMap.entrySet());
entryList.sort(new MapSortedMap());
//只返回游戏id
for (Map.Entry<Long, Double> entry : entryList) {
resultList.add(entry.getKey());
}
}
//当用户没有好友的时候,无法计算相似度进行推荐
//如果用户有设定喜欢的游戏类型,则优先推荐喜欢类型的游戏
if (u.getLikeGameTypeId() != null) {
//获取所有该类型游戏
List<GameInfo> likeTypeGames = gameInfoService.getGamesByTypeId(u.getLikeGameTypeId());
for (GameInfo g : likeTypeGames) {
if (!resultList.contains(g.getId())) {
resultList.add(g.getId());
}
if (resultList.size() >= 10) {
break;
}
}
}
if (resultList.size() >= 10) {
return resultList;
}
//如果推荐数不足十个,则用评分最高的游戏进行补充
List<GameInfo> topGames = gameInfoService.getAllGameInfoOrderByRateTopTen();
for (GameInfo g : topGames) {
if (resultList.size() >= 10) {
break;
}
if (!resultList.contains(g.getId())) {
resultList.add(g.getId());
}
}
return resultList;
// 输出稀疏矩阵
// for (int[] sparseMatrix1 : sparseMatrix) {
// for (int i : sparseMatrix1) {
// System.out.print(i + " # ");
// }
// System.out.println();
// }
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("输入用户总数");
int N = scanner.nextInt();
//建立用户稀疏矩阵,用于用户相似度计算
int[][] sparseMatrix = new int[N][N];
//存储每一个用户对应的不同物品总数
Map<Long, Integer> userItemLength = new HashMap<>();
//建立物品到用户的倒排表
Map<Long, Set<Long>> itemUserCollection = new HashMap<>();
//辅助存储物品的集合
Set<Long> items = new HashSet<>();
//辅助储存每一个用户的用户ID映射
Map<Long, Integer> userID = new HashMap<>();
//辅助储存每一个ID对应的用户映射
Map<Integer, Long> idUser = new HashMap<>();
System.out.println("输入用户物品的映射集合 以空格间隔");
scanner.nextLine();
for (int i = 0; i < N; i++) {
String[] scan_items = scanner.nextLine().split(" ");
Long[] user_item = new Long[scan_items.length];
for (int x = 0; x < scan_items.length; x++) {
user_item[x] = Long.parseLong(scan_items[x]);
}
int length = user_item.length;
userItemLength.put(user_item[0], length - 1);
//用户ID与稀疏矩阵建立对应关系
userID.put(user_item[0], i);
idUser.put(i, user_item[0]);
//建立物品--用户倒排表
for (int j = 1; j < length; j++) {
if (items.contains(user_item[j])) {
//如果已经包含物品--用户映射,直接添加对应的用户
itemUserCollection.get(user_item[j]).add(user_item[0]);
} else {
//否则创建对应物品--用户集合映射
items.add(user_item[j]);
//创建物品--用户的倒排关系
itemUserCollection.put(user_item[j], new HashSet<>());
itemUserCollection.get(user_item[j]).add(user_item[0]);
}
}
}
System.out.println(itemUserCollection.toString());
//计算相似度矩阵【稀疏】
Set<Map.Entry<Long, Set<Long>>> entrySet = itemUserCollection.entrySet();
for (Map.Entry<Long, Set<Long>> setEntry : entrySet) {
Set<Long> commonUsers = setEntry.getValue();
for (Long user_u : commonUsers) {
for (Long user_v : commonUsers) {
if (user_u.equals(user_v)) {
continue;
}
//计算用户u与用户v都有正反馈的物品总数
sparseMatrix[userID.get(user_u)][userID.get(user_v)] += 1;
}
}
}
System.out.println(userItemLength.toString());
System.out.println("输入想要查询相似度的用户");
Long recommendUser = Long.parseLong(scanner.nextLine());
System.out.println(userID.get(recommendUser));
//计算用户之间的相似度【余弦相似性】
int recommendUserId = userID.get(recommendUser);
for (int j = 0; j < sparseMatrix.length; j++) {
if (j != recommendUserId) {
System.out.println(idUser.get(recommendUserId) + "--" + idUser.get(j) +
"相似度:" + sparseMatrix[recommendUserId][j] /
Math.sqrt(userItemLength.get(idUser.get(recommendUserId)) * userItemLength.get(idUser.get(j))));
}
}
//计算指定用户recommendUser的物品推荐度
for (Long item : items) {
//遍历每一件物品
//得到喜爱当前物品的所有用户集合
Set<Long> users = itemUserCollection.get(item);
if (!users.contains(recommendUser)) {
double itemRecommendDegree = 0.0;
for (Long user : users) {
//推荐度计算公式
itemRecommendDegree += sparseMatrix[userID.get(recommendUser)][userID.get(user)] /
Math.sqrt(userItemLength.get(recommendUser) * userItemLength.get(user));
}
System.out.println("物品" + item + "对" + recommendUser + "的相似度为" + itemRecommendDegree);
}
}
// 输出稀疏矩阵
for (int[] sparseMatrix1 : sparseMatrix) {
for (int i : sparseMatrix1) {
System.out.print(i + " # ");
}
System.out.println();
}
//userId
System.out.println(userID.toString());
//idUser
System.out.println(idUser.toString());
scanner.close();
}
}
首页轮播
最新资讯
推荐游戏
热门游戏
最新游戏
游戏
资讯
评论
收藏
后台管理
用户信息
登录
注册