PageRank
package com.shujia.spark.core import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} object Demo19PageRank { def main(args: Array[String]): Unit = { val conf: SparkConf = new SparkConf() .setAppName("pagerank") .setMaster("local") val sc = new SparkContext(conf) //读取数据 val pagerank: RDD[String] = sc.textFile("data/pagerank.txt") //整理数据,给每个网页一个初始的pr值 var pageRDD: RDD[(String, List[String], Double)] = pagerank.map(line => { val split: Array[String] = line.split(" ") //当前网页 val page: String = split(0) //出链列表 val list: List[String] = split(1).split(",").toList (page, list, 1.0) }) //网页编号和出链列表 val pageListRDD: RDD[(String, List[String])] = pageRDD.map(kv => (kv._1, kv._2)) //阻尼系数 val Q = 0.85 //网页的数量 val N: Long = pageRDD.count() var flag = true while (flag) { //将网页的pr值平方给出链列表 val avgPageRDD: RDD[(String, Double)] = pageRDD.flatMap { case (page: String, list: List[String], pr: Double) => val avgPr: Double = pr / list.size list.map(p => (p, avgPr)) } //计算新的pr值 var nowPrRDD: RDD[(String, Double)] = avgPageRDD .reduceByKey(_ + _) .mapValues(pr => (1 - Q) / N + Q * pr) //增加阻尼系数 //将每个网页的出链列表关联回去 val joinRDD: RDD[(String, (Double, List[String]))] = nowPrRDD.join(pageListRDD) //整理数据 val resultRDD: RDD[(String, List[String], Double)] = joinRDD.map { case (page: String, (pr: Double, list: List[String])) => (page, list, pr) } /** * 计算每个网页新的pr值和上一次pr值,差值的平均值 * */ //上一次网页的pr值 val lastPrRDD: RDD[(String, Double)] = pageRDD.map(kv => (kv._1, kv._3)) //计算网页pr 差值 val prJoinRDD: RDD[(String, (Double, Double))] = nowPrRDD.join(lastPrRDD) val prChaRDD: RDD[Double] = prJoinRDD.map { case (page: String, (noePr: Double, lastPr: Double)) => Math.abs(lastPr - noePr) } //计算差值平均值 val avgPr: Double = prChaRDD.sum() / prChaRDD.count() println("差值平均值:" + avgPr) //如果差值平均值小于阈值,跳出循环 if (avgPr < 0.001) { flag = false } //第二次计算使用第一次的结果 pageRDD = resultRDD } pageRDD.foreach(println) } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能