283
阿裏雲
PageRank__示例程序_圖模型_大數據計算服務-阿裏雲
PageRank 算法是計算網頁排名的經典算法:輸入是一個有向圖 G,其中頂點表示網頁,如果存在網頁 A 到網頁 B 的鏈接,那麼存在聯接 A 到 B 的邊,算法基本原理:
- 初始化:點值表示 PageRank 的 rank 值(double 類型),初始時,所有點取值為 1/TotalNumVertices
- 迭代公式:PageRank(i)=0.15/TotalNumVertices+0.85*sum,其中 sum 為所有指向 i 點的點(設為 j) PageRank(j)/out_degree(j) 的累加值
從算法基本原理可以看出,這個算法非常適合使用 OPDS Graph 程序進行求解: 每個點 j 維護其 PageRank 值,每一輪迭代都將PageRank(j)/out_degree(j) 發給其鄰接點(向其投票),下一輪迭代時,每個點根據迭代公式重新計算 PageRank 取值。
源代碼
import java.io.IOException;
import org.apache.log4j.Logger;
import com.aliyun.odps.io.WritableRecord;
import com.aliyun.odps.graph.ComputeContext;
import com.aliyun.odps.graph.GraphJob;
import com.aliyun.odps.graph.GraphLoader;
import com.aliyun.odps.graph.MutationContext;
import com.aliyun.odps.graph.Vertex;
import com.aliyun.odps.graph.WorkerContext;
import com.aliyun.odps.io.DoubleWritable;
import com.aliyun.odps.io.LongWritable;
import com.aliyun.odps.io.NullWritable;
import com.aliyun.odps.data.TableInfo;
import com.aliyun.odps.io.Text;
import com.aliyun.odps.io.Writable;
public class PageRank {
private final static Logger LOG = Logger.getLogger(PageRank.class);
public static class PageRankVertex extends
Vertex<Text, DoubleWritable, NullWritable, DoubleWritable> {
@Override
public void compute(
ComputeContext<Text, DoubleWritable, NullWritable, DoubleWritable> context,
Iterable<DoubleWritable> messages) throws IOException {
if (context.getSuperstep() == 0) {
setValue(new DoubleWritable(1.0 / context.getTotalNumVertices()));
} else if (context.getSuperstep() >= 1) {
double sum = 0;
for (DoubleWritable msg : messages) {
sum += msg.get();
}
DoubleWritable vertexValue = new DoubleWritable(
(0.15f / context.getTotalNumVertices()) + 0.85f * sum);
setValue(vertexValue);
}
if (hasEdges()) {
context.sendMessageToNeighbors(this, new DoubleWritable(getValue()
.get() / getEdges().size()));
}
}
@Override
public void cleanup(
WorkerContext<Text, DoubleWritable, NullWritable, DoubleWritable> context)
throws IOException {
context.write(getId(), getValue());
}
}
public static class PageRankVertexReader extends
GraphLoader<Text, DoubleWritable, NullWritable, DoubleWritable> {
@Override
public void load(
LongWritable recordNum,
WritableRecord record,
MutationContext<Text, DoubleWritable, NullWritable, DoubleWritable> context)
throws IOException {
PageRankVertex vertex = new PageRankVertex();
vertex.setValue(new DoubleWritable(0));
vertex.setId((Text) record.get(0));
System.out.println(record.get(0));
for (int i = 1; i < record.size(); i++) {
Writable edge = record.get(i);
System.out.println(edge.toString());
if (!(edge.equals(NullWritable.get()))) {
vertex.addEdge(new Text(edge.toString()), NullWritable.get());
}
}
LOG.info("vertex edgs size: "
+ (vertex.hasEdges() ? vertex.getEdges().size() : 0));
context.addVertexRequest(vertex);
}
}
private static void printUsage() {
System.out.println("Usage: <in> <out> [Max iterations (default 30)]");
System.exit(-1);
}
public static void main(String[] args) throws IOException {
if (args.length < 2)
printUsage();
GraphJob job = new GraphJob();
job.setGraphLoaderClass(PageRankVertexReader.class);
job.setVertexClass(PageRankVertex.class);
job.addInput(TableInfo.builder().tableName(args[0]).build());
job.addOutput(TableInfo.builder().tableName(args[1]).build());
// default max iteration is 30
job.setMaxIteration(30);
if (args.length >= 3)
job.setMaxIteration(Integer.parseInt(args[2]));
long startTime = System.currentTimeMillis();
job.run();
System.out.println("Job Finished in "
+ (System.currentTimeMillis() - startTime) / 1000.0 + " seconds");
}
}
代碼說明
PageRank 源代碼包括以下幾部分:
- 55行:定義 PageRankVertexReader 類,加載圖,將表中每一條記錄解析為一個點,記錄的第一列是起點,其他列為終點;
- 23行:定義 PageRankVertex ,其中:
- 點值表示該點(網頁)的當前 PageRank 取值;
- compute()方法使用迭代公式:PageRank(i)=0.15/TotalNumVertices+0.85*sum 更新點值;
- cleanup() 方法把點及其 PageRank 取值寫到結果表中;
- 88行:主程序(main函數),定義 GraphJob,指定 Vertex/GraphLoader等的實現,以及最大迭代次數(默認 30),並指定輸入輸出表。
最後更新:2016-09-21 11:03:08
上一篇:
單源最短距離__示例程序_圖模型_大數據計算服務-阿裏雲
下一篇:
K-均值聚類__示例程序_圖模型_大數據計算服務-阿裏雲
EcsOrder__數據類型_API參考_E-MapReduce-阿裏雲
DTS支持RAM主子賬號__訪問控製_用戶指南_數據傳輸-阿裏雲
GetRole__角色管理接口_RAM API文檔_訪問控製-阿裏雲
創建OceanBase實例__快速入門_雲數據庫 OceanBase-阿裏雲
備份恢複服務__係統架構_產品簡介_雲數據庫 RDS 版-阿裏雲
大文件上傳如何續傳__數據操作常見問題_產品使用問題_歸檔存儲-阿裏雲
4.4 多計算引擎和Hint__第四章 DML_使用手冊_分析型數據庫-阿裏雲
釋放彈性公網 IP__網絡相關接口_API 參考_雲服務器 ECS-阿裏雲
發展曆史/Release Note__產品簡介_分析型數據庫-阿裏雲
刪除服務__服務管理_用戶指南_容器服務-阿裏雲
相關內容
常見錯誤說明__附錄_大數據計算服務-阿裏雲
發送短信接口__API使用手冊_短信服務-阿裏雲
接口文檔__Android_安全組件教程_移動安全-阿裏雲
運營商錯誤碼(聯通)__常見問題_短信服務-阿裏雲
設置短信模板__使用手冊_短信服務-阿裏雲
OSS 權限問題及排查__常見錯誤及排除_最佳實踐_對象存儲 OSS-阿裏雲
消息通知__操作指南_批量計算-阿裏雲
設備端快速接入(MQTT)__快速開始_阿裏雲物聯網套件-阿裏雲
查詢API調用流量數據__API管理相關接口_API_API 網關-阿裏雲
使用STS訪問__JavaScript-SDK_SDK 參考_對象存儲 OSS-阿裏雲