PageRank算法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
最后面是源代码,前面是简单的原理介绍
转载请注明出处: /32167163.html
曾经在网上找了很多关于PageRank的论文,基本上都是介绍原理的,没有找到计算过程的具体实现的源代码,前一阵公司有需要于是写了一个,比较简单(没有反作弊,Blog链接的处理,黑洞的处理都没有管),就是用极限编程的思想用最快的速度实现了一个个人感觉计算效率还不错,(没分块,其实前期分块后对后续的计算过程也是一样的了P4 3.0,512M),1700万网页迭代一次需要25秒钟的样子.
SortMap.dat是一个链接关系文件,已经按照DocID(每个网页的唯一编号,64位整型)进行排序了.基本上对这样的大文件排序都是进行分割,排序,归并实现的(大家有兴趣的话我下次将排序源代码也贴上来).如果您手头没有这样的链接数据话/labs/dl/t-link.html(互联网语料链接关系库),这个里面可以提取,然后就是排序,然后就是下面的源代码计算,你就能看到传说中的PageRank了.Good Luck!
PageRank计算实现原理 PageRank基本原理 可能有点帮助吧,中文的PageRank学习笔记
后面是计算PageRank的源代码,希望大家喜欢:(这里贴源代码确实太难看了 )
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "../FileSort/Sort.h" //一个实现快速排序的文件,后面需要排序的函数都在这个文件中
#define BLOCKSIZE (64*1024*1024)
//#define GROUP 8
#define LENGTHOFSINGLE 8
#define OUTDEGREESIZE 2048
#pragma pack(1)
using namespace std;
//实现二分查找功能
template
size_t binaryFind(type_key *begin,type_key *end,const type_key &value)
{
if(begin>=end) return end-begin;
//unsigned __int64 size = sizeof(type_key);
//long len = (end-begin);
int total = (end-begin);
int low=0;
int high=total-1;
int mid=0;
unsigned __int64 temp = 0;
while(low<=high)
{
mid = (low+high)/2;
temp = *(begin+mid);
if(temp==value)
{
return mid;
}
if(temp>value)
{
high=mid-1;
continue;
}
else
{
low=mid+1;
continue;
}
}
return total;
}
//完成将DocID转换成Index的过程,以后每次迭代不用再进行查找,算是中间的辅助函数
unsigned int BuildIndex(FILE * mapFile)
{
cout<<"start to build index"<
if (countFile==NULL)
{
cout<<"count.dat can not open,please check the file"<
}
unsigned int total;
unsigned int MaxOutDegree;
fread(&total,4,1,countFile);
fread(&MaxOutDegree,4,1,countFile);
fclose(countFile);
cout<<"total is :\t"<
{
unsigned __
int64 *index = new unsigned __int64[total];
char *sons = new char[MaxOutDegree*(LENGTHOFSINGLE+1)];
FILE *indexMap = fopen("indexMap.dat","wb");
FILE *DocIDIndex = fopen("DocID.index","wb");
unsigned __int64 DocID;
int outDegree;
for(size_t i=0;i
fread(index+i,LENGTHOFSINGLE,1,mapFile);
fread(&outDegree,4,1,mapFile);
fread(sons,LENGTHOFSINGLE+1,outDegree,mapFile);
}
cout<<"end of read file"<
rewind(mapFile);
size_t position;
for(size_t i=0;i
fread(&DocID,LENGTHOFSINGLE,1,mapFile);
fread(&outDegree,4,1,mapFile);
fread(sons,LENGTHOFSINGLE+1,outDegree,mapFile);
fwrite(&i,4,1,indexMap);
fwrite(&outDegree,4,1,indexMap);
for (int j=0;j
//fread(sons,LENGTHOFSINGLE+1,1,mapFile);
DocID = *(unsigned __int64 *)(sons+j*(LENGTHOFSINGLE+1));
position = binaryFind(index,index+total,DocID);
if (position != total)
{//找到
fwrite(&position,4,1,indexMap);
}
else fwrite(&total,4,1,indexMap);
}
}
fcloseall();
delete []index;
delete []sons;
}
cout<<"over build the index"<
}
int main(int argc, char *argv[])
{
ofstream fout("log.txt");
FILE *file = NULL;
if(argc>=2)
file = fopen(argv[1],"rb");
else
file = fopen("F:\\ren\\SortMap.dat","rb");
if(file==NULL)
cout<<"--------can not open the file--------"<
unsigned int start,end;
start = GetTickCount();
size_t total=BuildIndex(file);
end = GetTickCount();
cout<<"Build index lost:\t"<
if (total<1)
{
cout<<"BuildIndex Error and the program exit"<
}
size_t DocID=0;
int outDegree = 0;
fclose(file);
file = fopen("indexMap.dat","rb");
FILE *DocIDIndex = fopen("DocID.Index","rb");
cout<<"start the total is:"<
{ //真正实现的计算过程
unsigned int * sons = new unsigned int[1];
start = GetTickCount();
float *pageRank = new float[total];
float *prTmp = new float[total];
for (size_t i=0;i
pageRank[i] = 1.0f;
prTmp[i] = 0.0f;
}
end = GetTickCount();
cout<<"end of index:"<
ofstream fout("pagerank.txt");
float fatherRank = 1;
const float alpha = 0.85f;
size_t position = total;
size_t index=0;
for (size_t iter=0;iter<30;++iter)
{
rewind(file);
start = GetTickCount();
for (size_t i=0;i
fread(&DocID,4,1,file);
fread(&outDegree,4,1,file);
if (outDegree==0)
{
continue;
}
fatherRank = pageRank[i]/outDegree;
for (int k=0;k
fread(sons,4,1,file);
if (total > *sons && *sons>=0)
{
prTmp[ *sons ] += fatherRank;
}
}
}
for (int i=0;i
prTmp[i] = 0.15f + alpha*prTmp
[i];
pageRank[i] = prTmp[i];
prTmp[i] = 0.0f;
}
end = GetTickCount();
cout<<">>>>>>>>>>>>>>>"<<(iter+1)<<"\t"<
delete []prTmp;
delete []sons;
cout<<"over is writing"<
fwrite(pageRank,4,total,PageRankList);
delete []pageRank;
}
fout.close();
fclose(file);
fclose(DocIDIndex);
fcloseall();
cout<<"-------over----------"<
}
目前关于个性化PageRank,其他的常见方法还有模型化PageRank(modular PageRank)和BlockRank等。这些方法在具体的计算方法上,主要的特点体现在从效率的角度上对算法进行了必要的优化。
关于加速PageRank算法的先前研究内容主要使用稀疏性图结构技术,比如Arasu等提出的观点,他们不仅仅单纯使用上次迭代循环产生值来计算本轮循环值,也使用本轮循环已经产生的值来加速本轮循环的计算。甚至提出了Web网络的蝴蝶结结构,并将其用于PageRank值的有效计算中。然而这些方法并不具有很大的实用性,主要原因在于算法要求对Web网络矩阵进行排序,这个操作需要按照深度搜索优先的原则进行网络遍历,这显然是一种代价极大的运算。最近Kamvar等也提出一些算法,使用连续中间循环来推断真实PageRank更好的估计值,但是仍然存在受PageRank算法初始参数影响的不足之处。
目前对于Web网络图结构的分析主要关注于研究图的属性,如节点的分布、网页链接的情况和Web网页图结构的建模等。然而,对于这些研究并没有强调如何有效利用这些属性来加快超链分析。
不少学者提出了一些改进做法,如Raghavan和Garcia-Molina等利用主机名称或者URL隐含的Web结构来代表Web图更为成功的做法也有很多,如Jeh和Widom通过有限修改网页的权值来表达的个性化网页权重,这个重要性权值可以反映用户指定的初始兴趣网页。由于对个性化视图的计算需要反复遍历整个Web图结构中的网页,这只有在运行期间才能实现,所以事先计算和存储所有的个性化视图并不现实。他们利用新的图论结果和技术构建出表达个性化视图的“偏好向量”(partial vector),它可以在不同用户的个性化视图中共享,同时关于它的计算和存储花费与视图数量的多少呈现出合理的比例。在计算中,还可以采用递增式计算,这就使得在查询期间利用偏好向量去构建个性化视图是可行的。这个偏好向量即为个性化PageRank向量(personalized PageRank vector,PPV),通俗地说,PPV是种Web网页的个性化视图。按照这个PPV来对网页结果进行排序可以有效地表达用户的偏好。
简单地看,每个PPV的长度都为咒,即Web的网页数量。但是由于从一个固定的
角度循环计算PPV需要多次遍历Web网页图,这显然是不可能作为一种在线响应用户查询的方式。从另一个角度来看,所有PPV向量的总数量会达到2n(n为网页总数),这显然又过于巨大而无法实现离线存储。所以,必须将p集合中出现的网页限制为hub网页集合H的子集。H集合通常包含一些用户最为感兴趣的网页。在实践中,H集合可以是具有较高PageRank值的网页集合(重要网页)、在人工分类目录中的网页(如Yahoo和Open Directory)、特定企业或程序的重要网页等。H集合可以看成是计算个性化的基础。这种基于PPV的计算方式,不像传统的方式,能够和H集合大小成良好的比例缩放关系,并且这种技术也可以在更大的PPV集合上取得近似的效果,满足一些对于任意偏好网页集合的个性化计算要求。
除此以外,还有一些在计算效果上进行改进的算法。
如一种较为成功的做法是BlockRank方法,它主要是充分利用Web网页间链接结构呈现一种块状结构的特征来改进算法效率。关于Web网络块状结构的特征,已有很多学者进行了论证。例如,据Bharat等的分析,通过对比分析Web网络的链接结构,可以发现近80%左右的网页超链都是同一站点主机内部不同网页间形成的,而不同主机站点间网页的超链比重仅为20%左右。如果去除无用的死链接,这一比重表现得更加不平衡,近似于9:l。进一步将考察范围限定在域名级别后,上述的两个比重都有明显的增加,一为84:16,二为95:5,不平衡性明显加剧。一般在一个主机站点内,大部分的超链由于导航和站点安排,往往会在几个关键的网页上具有较多的内部链接。例如,高校站点内一般会对诸如图书馆、教务处和学生处等网页产生很高的链接比重。其实这种内部链接较高、外部链接较低的情况在不同级别的Web网页图结构中广泛存在,产生了明显的块化现象,而且大部分的块结构都远远小于整个Web的图结构。
这种Web网络所具有的块化结构有助于快速计算PageRank,同时为表达个性化PageRank提供了良好的基础。这个算法的思路大体描述如下:先对每个主机的网页计算本地化的PageRank值,得到在主机内部的相对重要权值。这些本地化的PageRank向量可以进一步按照不同Web网页块的相对重要程度加权形成全局PageRank值的近似值,然后将此PageRank向量作为标准PageRank算法的起始向量。不可否认,个性化PageRank虽然是个非常吸引人的主意,但是它需要对大规模的PageRank向量进行有效的迭代计算,而使用BlockRank算法和对冲浪者的随机冲浪行为做简单的限制就可以有效地减少个性化PageRank值的计算复杂度。这个限制就是当他厌倦时,他并不是从
诸多网页中选择,而是从主机站点中进行选择。也就是说,此时无需考察冲浪者跳转的网页,而只考虑跳转的站点。这时构造的个性化向量具有的维度就是Web网络中主机的个数K,并且向量的元素值也反映冲浪者对不同主机的偏好程度。有了这个限制,本地化PageRank向量就无需针对不同的个性化用户而改变。事实上,本地化的PageRank向量也不会因为矩阵B结构的改变而改变,只有BlockRank向量6才会因为不同的个性化特征而改变,因此只需对每个基于块结构的个性化PageRank向量进行重新计算。
应该说,不论从理论上看,还是从实践上看,利用个性化PageRank来实现搜索引擎的个性化服务是个非常可行的选择,适应Web网络资源对信息检索提出的特点要求。它不仅在推荐结果内容上综合考虑网页客观性权重这个重要指标,而且该方法性能较高,主要计算工作都在离线阶段完成。然而,这些现有的个性化PageRank技术都需要用户登录并主动提交个性化信息,却忽略了用户对Web网页的理解,没有挖掘用户使用行为,收集用户个性化信息的方式不自然,这显然加重了用户的使用负担。所以,虽然说节省了用户挑选相关网页的时间,但是用户却需要花更多的时间去实现搜索个性化。由此可以看出,探讨获取用户个性化信息的其他有效形式将是提高此方法效果的关键所在,本书也主要对此进行研究,探寻更好的个性化信息收集和表达方法以适用于个性化PageRank算法中,该方法较为客观和全面。
文章来自: 站长网() 详文参考:/article/20081103/112865.shtml
您还未登录 ! 我的应用 登录 注册
论坛首页 → Java编程和Java企业应用版 → OO → PageRank算法的原理和源代码实现(java)全部 Hibernate Spring Struts iBATIS 企业应用 设计模式 DAO 领域模型 OO Tomcat SOA JBoss Swing 浏览 1622 次主题:PageRank算法的原理和源代码实现(java)精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
chencang 等级: 初级会员
文章: 9
积分: 40
来自: 扬州
发表时间:2008-07-30 关键字: pagerank, java引用 相关文章:
[出错:]做好双向一对多关连后的查询问题
趣味编程:24点算法实现
各种数组排序方法总结
推荐圈子: Pipboy
更多相关推荐 参考文章:
理论:竹笋炒肉:Google的PageRank算法学习 /archives/000199.html
算法: PageRank算法的原理和源代码实现(C++)/60220486.html
模仿上面这个算法实现了java版的计算,我写的这个性能不好,3496987篇网页迭代1次居然需要3分钟左右,贴出来希望高手帮我指点改正。
Java代码
p
ackage pagerank;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Hashtable;
/*
linkmaptest.txt内容为
d00000-0 d00000-0 d00000-1 d00000-2
d00000-1 d00000-2 d00000-1
d00000-2 d00000-0
d00000-3
*/
public class PageRank {
public static void main(String[] args) throws Exception {
String[] linesarr;
Hashtable
int total = 0;
int father, son;
int outdegree = 0;
// 读取文件,得到docid,计算链接总数total,outdegree在迭代的时候计算
File linkfile = new File("E:/larbin/linkmaptest.txt");
BufferedReader linkinput = new BufferedReader(new FileReader(linkfile));
String line = linkinput.readLine();
while (line != null) {
++total;
linesarr = line.split(" ");
if (linesarr.length > 0) {
// outdegree = linesarr.length - 1;
// for(int j = 1; j <= linesarr.length - 1; ++j) {
// if(linesarr[j].equals(linesarr[0]))
// outdegree--;
// }
if (linesarr[0] != null) {
docIDandNum.put(linesarr[0], total);
// System.out.println("链接" + linesarr[0] + "的出度为" + outdegree);
}
}
linesarr = null;
line = linkinput.readLine();
}
linkinput.close();
// System.out.println("链接总数为:" + total);
if (total > 0) {
// pageRank[]存放PR值
float[] pageRank = new float[total + 1];
// 链入页面的计算总和
float[] prTmp = new float[total + 1];
// 设置pageRank[]初始值为1.0f
for (int i = 1; i <= total; ++i) {
pageRank[i] = 1.0f;
prTmp[i] = 0.0f;
}
// 当前页面的PR值
float fatherRank = 1f;
// 阻尼系数d或称为alpha
float alpha = 0.85f;
// 进行10次迭代
for (int iterator = 0; iterator < 10; iterator++) {
long startTime = System.currentTimeMillis();
linkinput = new BufferedReader(new FileReader(linkfile));
line = linkinput.readLine();
// 读出docid和outdegree和sons
while (line != null) {
linesarr = line.split(" ");
if (linesarr.length > 0) {
outdegree = linesarr.length - 1;
for (int j = 1; j <= linesarr.length - 1; ++j) {
// 指向自身的链接无效,不计算在内
if (linesarr[j].equals(linesarr[0]))
outdegree--;
}
}
if (outdegree > 0) {
father = (int) docIDandNum.get(linesarr[0]);
// 对应公式中的pr(Ti)/c(Ti),Ti为指向father的页面
fatherRank = pageRank[father] / outdegree;
for (int k = 1; k <= linesarr.length - 1; ++k) {
if (linesarr[k].equals(linesarr[0])) {
continue;
}
son = docIDandNum.get(linesarr[k]);
if (total >= son && son >= 0) {
prTmp[son] += fatherRank;
}
}
}
linesarr = null;
line = linkinput.readLine();
}
// 准备下次迭代的初始值
for (int i = 1; i <= total; ++i) {
// PR公式1
// prTmp[i] = 0.15f + alpha * prTmp[i];
// PR公式2
prTmp[i] = 0.15f / total + alpha * prTmp[i];
// 每次迭代后的真正pr值
pageRank[i] = prTmp[i];
prTmp[i] = 0.0f;
}
// 打印出每次迭代值,此操作耗费时间和内存
// for (int i = 1; i <= total; ++i)
// System.out.print(pageRank[i] + " \t ");
// System.out.println(" ");
linkinput.close();
long endTime = System.currentTimeMillis();
System.out.println("第" + iterator + "次迭代耗时" + (endTime - startTime) + "ms");
}
//最终PR值输出至文件
BufferedWriter newlink = new BufferedWriter(new FileWriter(
new File("E:/larbin/pageranktest.txt")));
for (int i = 1; i <= total; ++i) {
// System.out.println(docIDandNum.toString());
newlink.write(String.valueOf(pageRank[i]));
newlink.newLine();
}
newlink.flush();
newlink.close();
pageRank = null;
prTmp = null;
}
}
}
package pagerank;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.uti
l.Hashtable;
/*
linkmaptest.txt内容为
d00000-0 d00000-0 d00000-1 d00000-2
d00000-1 d00000-2 d00000-1
d00000-2 d00000-0
d00000-3
*/
public class PageRank {
public static void main(String[] args) throws Exception {
String[] linesarr;
Hashtable
int total = 0;
int father, son;
int outdegree = 0;
// 读取文件,得到docid,计算链接总数total,outdegree在迭代的时候计算
File linkfile = new File("E:/larbin/linkmaptest.txt");
BufferedReader linkinput = new BufferedReader(new FileReader(linkfile));
String line = linkinput.readLine();
while (line != null) {
++total;
linesarr = line.split(" ");
if (linesarr.length > 0) {
// outdegree = linesarr.length - 1;
// for(int j = 1; j <= linesarr.length - 1; ++j) {
// if(linesarr[j].equals(linesarr[0]))
// outdegree--;
// }
if (linesarr[0] != null) {
docIDandNum.put(linesarr[0], total);
// System.out.println("链接" + linesarr[0] + "的出度为" + outdegree);
}
}
linesarr = null;
line = linkinput.readLine();
}
linkinput.close();
// System.out.println("链接总数为:" + total);
if (total > 0) {
// pageRank[]存放PR值
float[] pageRank = new float[total + 1];
// 链入页面的计算总和
float[] prTmp = new float[total + 1];
// 设置pageRank[]初始值为1.0f
for (int i = 1; i <= total; ++i) {
pageRank[i] = 1.0f;
prTmp[i] = 0.0f;
}
// 当前页面的PR值
float fatherRank = 1f;
// 阻尼系数d或称为alpha
float alpha = 0.85f;
// 进行10次迭代
for (int iterator = 0; iterator < 10; iterator++) {
long startTime = System.currentTimeMillis();
linkinput = new BufferedReader(new FileReader(linkfile));
line = linkinput.readLine();
// 读出docid和outdegree和sons
while (line != null) {
linesarr = line.split(" ");
if (linesarr.length > 0) {
outdegree = linesarr.length - 1;
for (int j = 1; j <= linesarr.length - 1; ++j) {
// 指向自身的链接无效,不计算在内
if (linesarr[j].equals(linesarr[0]))
outdegree--;
}
}
if (outdegree > 0) {
father = (int) docIDandNum.get(linesarr[0]);
// 对应公式中的pr(Ti)/c(Ti),Ti为指向father的页面
fatherRank = pageRank[father] / outdegree;
for (int k = 1; k <= linesarr.length - 1; ++k) {
if (linesarr[k].equals(linesarr[0])) {
continue;
}
son = docIDandNum.get(linesarr[k]);
if (total >= son && son >= 0) {
prTmp[son] += fatherRank;
}
}
}
linesarr = null;
line = linkinput.readLine();
}
// 准备下次迭代的初始值
for (int i = 1; i <= total; ++i) {
// PR公式1
// prTmp[i] = 0.15f + alpha * prTmp[i];
// PR公式2
prTmp[i] = 0.15f / total + alpha * prTmp[i];
// 每次迭代后的真正pr值
pageRank[i] = prTmp[i];
prTmp[i] = 0.0f;
}
// 打印出每次迭代值,此操作耗费时间和内存
// for (int i = 1; i <= total; ++i)
// System.out.print(pageRank[i] + " \t ");
// System.out.println(" ");
linkinput.close();
long endTime = System.currentTimeMillis();
System.out.println("第" + iterator + "次迭代耗时" + (endTime - startTime) + "ms");
}
//最终PR值输出至文件
BufferedWriter newlink = new BufferedWriter(new FileWriter(
new File("E:/larbin/pageranktest.txt")));
for (int i = 1; i <= total; ++i) {
// System.out.println(docIDandNum.toString());
newlink.write(String.valueOf(pageRank[i]));
newlink.newLine();
}
newlink.flush();
newlink.close();
pageRank = null;
prTmp = null;
}
}
}
学java有段时间了,但是总感觉自己不着道,第一次在论坛发帖,也希望大家指出我的很多不规范的地方,给我些改正的建议,分享些经验给新手们,(比如有什么好的书适合我,在编程习惯技巧等方面我应该如何去改正以便更加规范些),谢谢。
声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
下载免费的 IBM DB2 Express-C 数据库
在繁琐中挣扎还是简化自主管理?
5月份Struts 2.0最新技术专题系列讲座
返回顶楼 最后修改:2009-03-24
yining 等级:
文章: 12
积分: 252
发表时间:2008-07-30 引用 做个profiling看看瓶颈在哪里,实在不行就先用NIO替换一下吧。
返回顶楼 0 0 请登录后投票
shellkk 等级: 初级会员
文章: 28
积分: 35
来自: 上海
发表时间:2008-07-30 引用 这个速度很正常
返回顶楼 0 0 请登录后投票
phz50 等级: 初级会员
文章: 6
积分: 40
来自: 杭州
发表时间:2008-10-31 引用 这个好像写得很不错啊,不过我还是没能看太明白,想问一下linkmaptest.txt文件里面的内容是什么意思呢?
返回顶楼 0 0 请登录后投票
frenchmay 等级:
文章: 232
积分: 340
来自: 杭州
发表时间:2008-11-01 引用 编码风格不是很好,面向对象的一些原则还没有搞清楚
建议回归基础
返回顶楼 0 0 请登录后投票
chencang 等级: 初级会员
文章: 9
积分: 40
来自: 扬州
发表时间:2008-11-20 引用 frenchmay 写道
编码风格不是很好,面向对象的一些原则还没有搞清楚建议回归基础
嗯,谢谢建议
返回顶楼 0 0 请登录后投票
chencang 等级: 初级会员
文章: 9
积分: 40
来自: 扬州
发表时间:2008-11-20 引用 phz50 写道
这个好像写得很不错啊,不
过我还是没能看太明白,想问一下linkmaptest.txt文件里面的内容是什么意思呢?
就是页面之间的链接关系啊
返回顶楼 0 0 请登录后投票
mayday85 等级:
文章: 528
积分: 110
来自: 污点星狗屎国
发表时间:2008-11-20 引用 对, 怎么全堆到main里了
返回顶楼 0 0 请登录后投票
plantegg 等级: 初级会员
文章: 1
积分: 30
来自: 北京
发表时间:2008-12-02 引用 这么晦涩的代码也给你翻译过来了,呵呵
你这性能有比较大的问题
检查IO,有没有反复读?
检查一些反复调用的计算
原始代码中BuildIndex很有用的,你再瞅瞅
返回顶楼 0 0 请登录后投票
论坛首页 → Java编程和Java企业应用版 → OO
跳转论坛:Java编程和Java企业应用 Web前端技术:AJAX和RIA 移动编程和手机应用开发 Ruby Python PHP Microsoft .Net 综合技术 入门讨论 软件开发和项目管理 行业应用 厂商论坛 招聘求职 海阔天空 中港软件硕士不参加统考国家承认学位 首页
新闻
论坛
问答
知识库
博客
圈子
招聘
服务
搜索
Java
AJAX
Ruby
Python
敏捷
MySQL
图书
Oracle
Dorado
普元
广告服务 JavaEye黑板报 关于我们 联系我们 友情链接 ? 2003-2009 . All rights reserved. 上海炯耐计算机软件有限公司 [ 沪ICP备05023328号 ] 您正在搜索 pagerank算法源代码 [ X ]关键字已在页面上高亮显示
您可能对下列文章也感兴趣
研究pagerank
Java版PageRank及网站收录情况查 ...
站内搜索更多 pagerank算法源代码