基于聚类分析算法的数字化图书馆、图书馆管理系统
基于聚类分析算法的数字化图书馆、图书馆管理系统本系统为大学生毕业设计程序,项目涉及技术为:springboot、mybatis、mysql、vue.js、javascript、html、k-means聚类算法、maven等等。1.图书馆管理系统用户登录:2.图书馆管理系统主页:3.图书管理列表:4.图书高级检索:5.图书新增:...
·
基于聚类分析算法的数字化图书馆、图书馆管理系统
本系统为大学生毕业设计程序,项目涉及技术为:springboot、mybatis、mysql、vue.js、javascript、html、k-means聚类算法、maven等等。
1.图书馆管理系统用户登录:
2.图书馆管理系统主页:
3.图书管理列表:
4.图书高级检索:
5.图书新增:
6.图书信息编辑:
7.用户借阅图书列表:
8.图书推荐排行榜:
k-means算法java实现
package com.bskf.modules.job.utils;
import java.util.ArrayList;
import java.util.List;
public class Kcluster {
private int id;// 标识
private Kpoint center;// 中心
private List<Kpoint> members = new ArrayList<Kpoint>();// 成员
public Kcluster(int id, Kpoint center) {
this.id = id;
this.center = center;
}
public Kcluster(int id, Kpoint center, List<Kpoint> members) {
this.id = id;
this.center = center;
this.members = members;
}
public void addPoint(Kpoint newKpoint) {
members.add(newKpoint);
}
public int getId() {
return id;
}
public Kpoint getCenter() {
return center;
}
public void setCenter(Kpoint center) {
this.center = center;
}
public List<Kpoint> getMembers() {
return members;
}
@Override
public String toString() {
String toString = "Kcluster \n" + "Cluster_id=" + this.id + ", center:{" + this.center.toString() + "}";
for (Kpoint kpoint : members) {
toString += "\n" + kpoint.toString();
}
return toString + "\n";
}
}
package com.bskf.modules.job.utils;
import java.util.*;
public class KmeansRunner {
private int kNum; //簇的个数
private int iterNum = 10; //迭代次数
private int iterMaxTimes = 100000; //单次迭代最大运行次数
private int iterRunTimes = 0; //单次迭代实际运行次数
private float disDiff = (float) 0.01; //单次迭代终止条件,两次运行中类中心的距离差
private Map<Long, float[]> original_data; //用于存放,原始数据集
private static List<Kpoint> kpointList = null; //用于存放,原始数据集所构建的点集
private int len = 0; //用于记录每个数据点的维度
public KmeansRunner(int k, Map<Long, float[]> original_data) {
this.kNum = k;
this.original_data = original_data;
this.len = original_data.values().iterator().next().length;
//检查规范
check();
//初始化点集。
init();
}
/**
* 检查规范
*/
private void check() {
if (kNum == 0) {
throw new IllegalArgumentException("k must be the number > 0");
}
if (original_data == null) {
throw new IllegalArgumentException("program can't get real data");
}
}
/**
* 初始化数据集,把数组转化为Point类型。
*/
private void init() {
kpointList = new ArrayList<>();
for (Long uid : original_data.keySet()) {
kpointList.add(new Kpoint(Math.toIntExact(uid), original_data.get(uid)));
}
System.out.println(kpointList);
}
/**
* 随机选取中心点,构建成中心类。
*/
private Set<Kcluster> chooseCenterCluster() {
Set<Kcluster> kclusterSet = new HashSet<Kcluster>();
Random random = new Random();
for (int id = 0; id < kNum; ) {
int anInt = random.nextInt(kpointList.size());
Kpoint kpoint = kpointList.get(anInt);
// 用于标记是否已经选择过该数据。
boolean flag = true;
for (Kcluster kcluster : kclusterSet) {
if (kcluster.getCenter().equals(kpoint)) {
flag = false;
}
}
// 如果随机选取的点没有被选中过,则生成一个cluster
if (flag) {
Kcluster kcluster = new Kcluster(id, kpoint);
kclusterSet.add(kcluster);
id++;
}
}
return kclusterSet;
}
/**
* 为每个点分配一个类!
*/
public void cluster(Set<Kcluster> kclusterSet) {
// 计算每个点到K个中心的距离,并且为每个点标记类别号
for (Kpoint kpoint : kpointList) {
float min_dis = Integer.MAX_VALUE;
for (Kcluster kcluster : kclusterSet) {
float tmp_dis = (float) Math.min(getEuclideanDis(kpoint, kcluster.getCenter()), min_dis);
if (tmp_dis != min_dis) {
min_dis = tmp_dis;
kpoint.setClusterId(kcluster.getId());
kpoint.setDist(min_dis);
}
}
}
// 新清除原来所有的类中成员。把所有的点,分别加入每个类别
for (Kcluster kcluster : kclusterSet) {
kcluster.getMembers().clear();
for (Kpoint kpoint : kpointList) {
if (kpoint.getClusterid() == kcluster.getId()) {
kcluster.addPoint(kpoint);
}
}
}
}
/**
* 计算每个类的中心位置!
*/
public boolean calculateCenter(Set<Kcluster> kclusterSet) {
boolean ifNeedIter = false;
for (Kcluster kcluster : kclusterSet) {
List<Kpoint> kpoint_list = kcluster.getMembers();
float[] sumAll = new float[len];
// 所有点,对应各个维度进行求和
for (int i = 0; i < len; i++) {
for (int j = 0; j < kpoint_list.size(); j++) {
sumAll[i] += kpoint_list.get(j).getlocalArray()[i];
}
}
// 计算平均值
for (int i = 0; i < sumAll.length; i++) {
sumAll[i] = (float) sumAll[i] / kpoint_list.size();
}
// 计算两个新、旧中心的距离,如果任意一个类中心移动的距离大于dis_diff则继续迭代。
if (getEuclideanDis(kcluster.getCenter(), new Kpoint(sumAll)) > disDiff) {
ifNeedIter = true;
}
// 设置新的类中心位置
kcluster.setCenter(new Kpoint(sumAll));
}
return ifNeedIter;
}
/**
* 运行 k-means
*/
public Set<Kcluster> run() {
Set<Kcluster> kclusterSet = chooseCenterCluster();
boolean ifNeedIter = true;
while (ifNeedIter) {
cluster(kclusterSet);
ifNeedIter = calculateCenter(kclusterSet);
iterRunTimes++;
}
return kclusterSet;
}
/**
* 返回实际运行次数
*/
public int getIterTimes() {
return iterRunTimes;
}
/**
* 求欧式距离
*/
public static double getEuclideanDis(Kpoint p1, Kpoint p2) {
double count_dis = 0;
float[] p1_local_array = p1.getlocalArray();
float[] p2_local_array = p2.getlocalArray();
if (p1_local_array.length != p2_local_array.length) {
throw new IllegalArgumentException("length of array must be equal!");
}
for (int i = 0; i < p1_local_array.length; i++) {
count_dis += Math.pow(p1_local_array[i] - p2_local_array[i], 2);
}
return Math.sqrt(count_dis);
}
}
package com.bskf.modules.job.utils;
public class Kpoint {
private float[] localArray;
private int id;
private int clusterId; // 标识属于哪个类中心。
private float dist; // 标识和所属类中心的距离。
public Kpoint(int id, float[] localArray) {
this.id = id;
this.localArray = localArray;
}
public Kpoint(float[] localArray) {
this.id = -1; //表示不属于任意一个类
this.localArray = localArray;
}
public float[] getlocalArray() {
return localArray;
}
public int getId() {
return id;
}
public void setClusterId(int clusterId) {
this.clusterId = clusterId;
}
public int getClusterid() {
return clusterId;
}
public float getDist() {
return dist;
}
public void setDist(float dist) {
this.dist = dist;
}
@Override
public String toString() {
String result = "Point_id=" + id + " [";
for (int i = 0; i < localArray.length; i++) {
result += localArray[i] + " ";
}
return result.trim() + "] clusterId: " + clusterId + " dist: " + dist;
}
@Override
public boolean equals(Object obj) {
if (obj == null || getClass() != obj.getClass())
return false;
Kpoint kpoint = (Kpoint) obj;
if (kpoint.localArray.length != localArray.length)
return false;
for (int i = 0; i < localArray.length; i++) {
if (Float.compare(kpoint.localArray[i], localArray[i]) != 0) {
return false;
}
}
return true;
}
@Override
public int hashCode() {
float x = localArray[0];
float y = localArray[localArray.length - 1];
long temp = x != +0.0d ? Double.doubleToLongBits(x) : 0L;
int result = (int) (temp ^ (temp >>> 32));
temp = y != +0.0d ? Double.doubleToLongBits(y) : 0L;
result = 31 * result + (int) (temp ^ (temp >>> 32));
return result;
}
}
代码太多了,就不详细列举了,有需要的可以联系我,拿代码。。。
更多推荐
已为社区贡献2条内容
所有评论(0)