AI编程方法案例:PageRank算法实现
一、算法简单说明
PageRank算法是一种常见的网络权值迭代算法,主要用于诸如互联网网页的质量测度。基本计算原理是根据网页自身的链出将原始权值进行扩散,并通过多轮迭代获得稳定的收敛值来表征网页自身的最终权值。基本计算公式为:

其中R(u)'和R(u)分别表示网页u的新权值和上次计算的旧权值,Bu表示网页u的链入网页集合,Nv表示网页u的一个链入网页v全部的链出数量。
下面通过一个例子说明基本计算方法。假设有5个网页,链接关系如:

初始设置每个网页的权值都为0.2,即网页总数分之一。
第一轮计算为:

再加上每个网页各自的原始权值,可以得到第一轮计算后每个网页的新权值,即:

利用权值总和(为2)去除每个权值得到规范化后的权值为:

以此类推,再次使用该权值迭代进行相同的计算,反复计算后即可得到最终每个网页的权值。
二、自己实现:
将上述过程反复迭代运行,既可以选择运行100、1000等固定次数,也可以运行到前后两次权值差值小于一定阈值即可结束(本处以第二种为例):
r1, r2, r3, r4, r5 = 0.2, 0.2, 0.2, 0.2, 0.2
_r1 = 0
while abs(_r1 - r1) > 0.000001:
_r1, _r2, _r3, _r4, _r5 = r1, r2, r3, r4, r5
r1 = _r1 + _r2 / 2 + _r3 / 2 + _r5 / 2
r2 = _r2 + _r1 / 1
r3 = _r3 + _r2 / 2
r4 = _r4 + _r3 / 2 + _r5 / 2
r5 = _r5 + _r4 / 1
total = r1 + r2 + r3 + r4 + r5
r1, r2, r3, r4, r5 = r1 / total, r2 / total, r3 / total, r4 / total, r5 / total
print(r1, r2, r3, r4, r5)
三、AI实现:
有效的提示词:
我是一名计算机学生,正在学习网络计算中的PageRank算法。已知有5个网页,其链接关系如:
网页1有1个链接指向网页2,
网页2有2个链接指向网页1和网页3,
网页3有2个链接指向网页1和网页4,
网页4有1个链接指向网页5,
网页5有2个链接指向网页1和网页4
请根据标准的PageRank算法思路,无需考虑阻尼系数,具体方法是对于每个网页权值初始设为0.2,在第一轮迭代中,如果有其他网页指向,就将其权值累加过来,但是该累加值会被其他链入网页的出度均分,最后每个网页再将自身的权值和其他链入网页传入的权值累加,并最终以全部网页权值总和做分母规范化所有权值,完成第一轮迭代,再进行第二轮迭代,方法同前,反复进行,直到先后两次迭代同一网页的权值差值小于0.00001即可停止迭代,最后输出最终全部网页的权值。请写出Python代码,不要使用自定义函数、列表、字典、任何第三方模块等复杂内容,只需使用简单的逻辑控制语句即可,控制代码在20行以内。
该提示词使用了角色扮演、图例文本描述、算法要求的详细说明、强调不出现的内容(不要使用自定义函数、列表、字典、任何第三方模块)、强调要求出现的内容(只需使用简单的逻辑控制语句、代码行数)
生成的代码为:
# 初始化权值
p1, p2, p3, p4, p5 = 0.2, 0.2, 0.2, 0.2, 0.2
# 迭代直到收敛
while True:
# 计算新的权值
new_p1 = (p2 / 2) + (p3 / 2) + (p5 / 2)
new_p2 = p1 / 1
new_p3 = p2 / 2
new_p4 = (p3 / 2) + (p5 / 2)
new_p5 = p4 / 1
# 规范化权值
total = new_p1 + new_p2 + new_p3 + new_p4 + new_p5
new_p1, new_p2, new_p3, new_p4, new_p5 = new_p1/total, new_p2/total, new_p3/total, new_p4/total, new_p5/total
# 检查是否收敛
if abs(new_p1 - p1) < 0.00001 and abs(new_p2 - p2) < 0.00001 and abs(new_p3 - p3) < 0.00001 and abs(new_p4 - p4) < 0.00001 and abs(new_p5 - p5) < 0.00001:
break
# 更新权值
p1, p2, p3, p4, p5 = new_p1, new_p2, new_p3, new_p4, new_p5
# 输出最终权值
print(p1, p2, p3, p4, p5)
利用AI还可以继续优化代码。比如PageRank计算方法也可以使用矩形和向量相乘的方式来表达,如果对此不清楚,可以继续询问AI:
使用矩阵的方法也可以快速实现PageRank的计算,请使用二维列表结合相关矩阵计算PageRank的方法,给出可以引导AI生成准确代码的有效提示词
此时可以得到用于引导AI生成对应代码的提示词:
以下是可用于引导AI生成准确PageRank矩阵计算代码的有效提示词:
提示词:
请使用Python编写PageRank算法,要求如下:
使用二维列表(矩阵)存储网页链接关系,矩阵大小为5×5,其中M[i][j]表示网页j指向网页i的转移概率(列归一化)
链接关系如下:
网页1→网页2
网页2→网页1和网页3
网页3→网页1和网页4
网页4→网页5
网页5→网页1和网页4
转移矩阵构建规则:每个网页的出度为其指向的网页数,列和等于1
初始权值向量为[0.2, 0.2, 0.2, 0.2, 0.2](列向量形式)
PageRank迭代公式:R_new = M × R_old(矩阵乘向量)
每次迭代后对权值向量进行归一化(除以总和)
收敛条件:两次迭代所有网页权值差值的绝对值小于1e-5
不使用numpy等第三方库,仅用基础Python语法
使用while循环实现迭代,最后输出5个网页的最终PageRank值(保留6位小数)
这个提示词明确了矩阵构建方式、转移概率的列归一化要求、矩阵乘向量的迭代过程,能有效避免AI生成错误实现。
可以再次使用该提示词询问AI,得到的代码为:
# 构建转移矩阵 M[i][j] 表示网页j指向网页i的概率
# 列索引0-4对应网页1-5,行索引0-4对应网页1-5
M = [
[0, 1/2, 1/2, 0, 1/2], # 网页1被网页2,3,5指向
[1, 0, 0, 0, 0], # 网页2被网页1指向
[0, 1/2, 0, 0, 0], # 网页3被网页2指向
[0, 0, 1/2, 0, 1/2], # 网页4被网页3,5指向
[0, 0, 0, 1, 0] # 网页5被网页4指向
]
# 初始化权值向量
R = [0.2, 0.2, 0.2, 0.2, 0.2]
# 迭代直到收敛
while True:
# 计算新的权值向量 R_new = M × R
R_new = [
M[0][0]*R[0] + M[0][1]*R[1] + M[0][2]*R[2] + M[0][3]*R[3] + M[0][4]*R[4],
M[1][0]*R[0] + M[1][1]*R[1] + M[1][2]*R[2] + M[1][3]*R[3] + M[1][4]*R[4],
M[2][0]*R[0] + M[2][1]*R[1] + M[2][2]*R[2] + M[2][3]*R[3] + M[2][4]*R[4],
M[3][0]*R[0] + M[3][1]*R[1] + M[3][2]*R[2] + M[3][3]*R[3] + M[3][4]*R[4],
M[4][0]*R[0] + M[4][1]*R[1] + M[4][2]*R[2] + M[4][3]*R[3] + M[4][4]*R[4]
]
# 归一化
total = R_new[0] + R_new[1] + R_new[2] + R_new[3] + R_new[4]
R_new = [R_new[0]/total, R_new[1]/total, R_new[2]/total, R_new[3]/total, R_new[4]/total]
# 检查收敛条件
diff0 = abs(R_new[0] - R[0])
diff1 = abs(R_new[1] - R[1])
diff2 = abs(R_new[2] - R[2])
diff3 = abs(R_new[3] - R[3])
diff4 = abs(R_new[4] - R[4])
if diff0 < 1e-5 and diff1 < 1e-5 and diff2 < 1e-5 and diff3 < 1e-5 and diff4 < 1e-5:
break
# 更新权值向量
R = R_new
# 输出最终结果,保留6位小数
print(f"网页1: {R[0]:.6f}")
print(f"网页2: {R[1]:.6f}")
print(f"网页3: {R[2]:.6f}")
print(f"网页4: {R[3]:.6f}")
print(f"网页5: {R[4]:.6f}")
AI的生成并非总是高效,此时就需要编程者做出必要的引导,比如这里的新权值计算没有使用循环,可以继续提问:
中间计算新的权值向量 R_new = M × R的方式非常原始,请使用列表推导式计算给出间接替代实现
再次得到代码为:
# 构建转移矩阵 M[i][j] 表示网页j指向网页i的概率
M = [
[0, 1/2, 1/2, 0, 1/2],
[1, 0, 0, 0, 0],
[0, 1/2, 0, 0, 0],
[0, 0, 1/2, 0, 1/2],
[0, 0, 0, 1, 0]
]
# 初始化权值向量
R = [0.2, 0.2, 0.2, 0.2, 0.2]
# 迭代直到收敛
while True:
# 使用列表推导式计算 R_new = M × R
R_new = [sum(M[i][j] * R[j] for j in range(5)) for i in range(5)]
# 归一化
total = sum(R_new)
R_new = [x / total for x in R_new]
# 检查收敛条件
if all(abs(R_new[i] - R[i]) < 1e-5 for i in range(5)):
break
# 更新权值向量
R = R_new
# 输出最终结果
for i in range(5):
print(f"网页{i+1}: {R[i]:.6f}")
但是正如人类一样,代码并不一定正确,因此需要进行测试,测试可以看先结果并不正确。通过观察可以看出该代码缺少添加原始网页权值到更新后的网页权值。继续提示为:
归一化过程是错误,你在每轮累加迭代中需要保留以前网页自己的权值,也就是说,每个网页新的权值是以前权值加上各个其他网页通过链接传递过来的权值
最终得到的代码为:
# 构建转移矩阵 M[i][j] 表示网页j指向网页i的概率
M = [
[0, 1/2, 1/2, 0, 1/2],
[1, 0, 0, 0, 0],
[0, 1/2, 0, 0, 0],
[0, 0, 1/2, 0, 1/2],
[0, 0, 0, 1, 0]
]
# 初始化权值向量
R = [0.2, 0.2, 0.2, 0.2, 0.2]
# 迭代直到收敛
while True:
# 计算传递过来的权值(其他网页通过链接传入的部分)
incoming = [sum(M[i][j] * R[j] for j in range(5)) for i in range(5)]
# 新权值 = 旧权值 + 传入权值
R_new = [R[i] + incoming[i] for i in range(5)]
# 归一化:所有权值除以总和
total = sum(R_new)
R_new = [x / total for x in R_new]
# 检查收敛条件
diff = [abs(R_new[i] - R[i]) for i in range(5)]
if max(diff) < 1e-5:
break
# 更新权值向量
R = R_new[:]
# 输出最终结果
for i in range(5):
print(f"网页{i+1}: {R[i]:.6f}")
这种调试过程可能会因为大模型不同而不同,即使同一大模型也可能在不同时间返回结果也存在差异,因此,代码必须要进行必要的调试。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)