谈到并行计算应用,会有人想到PageRank算法,我们有成千上万的网页分析链接关系确定排名先后,借助并行计算完成是一个很好的场景。长期以来,google的创始发明PageRank算法吸引了很多人学习研究,据说当年google创始者兴奋的找到yahoo公司,说他们找到一种更好的搜索引擎算法,但是被yahoo公司技术人员泼了冷水,说他们关心的不是更好的技术,而是搜索的盈利。后来google包装成了“更先进技术的新一代搜索引擎”的身份,逐渐取代了市场,并实现了盈利。
由于PageRank算法有非常高的知名度和普及度,我们接下来以PageRank算法为例讲述“
并行计算+数据算法”的经典搭配,并且这种“
海量数据并行处理、迭代多轮后收敛”的分析过程也跟其他的数据挖掘或者机器学习算法应用类似,能起到很好的参考作用。
下面是PageRank算法的公式:
我们其实可以直接阐述该公式本身,并介绍如何使用并行计算套用上面公式得到各网页的PageRank值,这样虽然通过并行计算方式完成了PageRank计算,但是大家仍然不明白上面的PageRank公式是怎么来的。
我们把这个PageRank算法公式先放在一边,看看一个赌钱的游戏:
有甲、乙、丙三个人赌钱,他们的输赢关系如下:
甲的钱输给乙和丙
乙的钱输给丙
丙的钱输给甲
例如,甲、乙、丙各有本钱100元,按照以上输赢关系,玩一把下来:
甲输给乙50元、输给丙50元
乙输给丙100元
丙输给甲100元
如果仅是玩一把的话很容易算出谁输谁赢
但如果他们几个维持这样的输赢关系,赢的钱又投进去继续赌,这样一轮一轮赌下去的话,最后会是什么样子呢?
我们可以写个单机程序看看,为了方便计算,初始本钱都设为1块钱,用x1,x2,x3代表甲、乙、丙:
double x1=1.0,x2=1.0,x3=1.0;
用x1_income,x2_income,x3_income代表每赌一把后各人赢的钱,根据输赢关系:
double x2_ income =x1/2.0;
double x3_ income =x1/2.0+x2;
double x1_ income =x3;
最后再把各人赢的钱覆盖掉本钱,继续往下算。完整程序如下:
// Gamble单机程序
public class Gamble
{
public static double x1=1.0,x2=1.0,x3=1.0;
public static void playgame(){
double x2_income=x1/2.0;
double x3_income=x1/2.0+x2;
double x1_income=x3;
x1=x1_income;
x2=x2_income;
x3=x3_income;
System.out.println("x1:"+x1+", x2:"+x2+", x3:"+x3);
}
public static void main(String[] args){
for(int i=0;i<500;i++){
System.out.print("第"+i+"轮 ");
playgame();
}
}
}
我们运行500轮后,看到结果如下:
我们发现,从107轮后,各人的输赢结果就一直是
x1:1.2000000000000002, x2:0.6000000000000001, x3:1.2000000000000002
...
可能你都没想到会有这么个规律,这样一直赌下去,虽然各人每轮有输有赢,但是多轮后的输赢结果居然保持平衡,维持不变了。用技术术语来说就是多轮迭代后产生了收敛,用俗话来讲,就是玩下去甲和丙是不亏的,乙不服输再继续赌下去,也不会有扳本的机会的。
我们再把输赢关系稍微改一下:
丙的钱输给甲和乙
double x2_income=x1/2.0+x3/2.0;
double x3_income=x1/2.0+x2;
double x1_income=x3/2.0;
运行10000轮后,发现又收敛了:
x1:0.6666666666666667, x2:1.0, x3:1.3333333333333333
…
不过这次就变成了“甲是输的,乙保本,丙是赢的”,
我们发现收敛的结果可用于排名,如果给他们做一个赌王排名的话,很显然:“丙排第一,乙第二、甲第三”。
那么这样的收敛是在所有情况下都会发生吗,什么情况不会收敛呢?
我们回过头观察上面的输赢关系,甲、乙、丙三人互相各有输赢,导致钱没有流走,所以他们三人才一直可以赌下去,如果把输赢关系改一下,让甲只输钱,不赢钱,如下:
double x2_income=x1/2.0+x3/2.0;
double x3_income=x1/2.0+x2;
double x1_income=0;
那么运行下来会是什么结果呢?
我们发现很多轮后,全部为0了。我们分析一下过程,第一轮后,甲的钱就输光了,没有赢得一分钱。但是乙和丙各有输赢,他们一直赌到2000多轮时,乙的钱全部输光了,甲乙都没钱投进来赌了,导致丙再也赢不到钱了,最后所有人结果都变为0了。
我们再分析一下输赢关系,甲的钱全部输给丙和乙后,丙跟乙赌,赢的多输的少,于是所有的钱慢慢都被丙赢走了,导致最后无法维持一个平衡的输赢结果。因此,如果我们要维持平衡和收敛,必须保证赢了钱的人不准走,必须又输给别人才行,让钱一直在三人圈里转不流失。换句话说,如果存在某人只输不赢,那么这个游戏就玩不下去。
赌钱游戏讲完了,我们再看看PageRank算法的公式:
上面的L(B)代表页面B指向其他页面的连接数,我们举个例子:
假设有A、B、C三张网页,他们的链接关系如下:
A包含B和C的链接
B包含C的链接
C包含A的链接
根据上面的公式,得到各网页PR值如下:
PR(B)=PR(A)/2;
PR(C)=PR(A)/2+PR(B);
PR(A)=PR(C);
可以回过头对照一下,把A、B、C改成甲、乙、丙就是上面举的赌钱游戏例子。
那么q是干吗的?公式里的q叫做逃脱因子,名字很抽象,目的就是用于解决上面赌钱游戏中“只输不赢”不收敛的问题,1-q会保证其中一个PR值为0时计算下来不会全部为0,那么加了这么一个(…)*q+1-q的关系后,整体的PR值会变化吗?
当每个页面的初始PR值为1时,0<=q<=1(计算时通常取值0.8),我们把所有页面的PR值相加看看,假设有n张网页:
PR(x1)+ PR(x2)+ …+PR(xn)
=( (PR(x2)/ L(x2)+ … )*q+1-q) + … + ( (PR(x1)/ L(x1)+ … )*q+1-q)
=(PR(x1)* L(x1)/L(x1) + PR(x2)* L(x2)/L(x2) + … + PR(xn)* L(xn)/L(xn))q + n(1-q)
=( PR(x1) + PR(x2) + … + PR(xn))*q + n - n*q
=n*q + n – n*q
= n
由于初始PR值为1,所以最后所有页面的PR值相加结果还是为n,保持不变,但是加上(…)*q+1-q的关系后,就避免了PR值为0可以寻求收敛进行排序。
当然实际应用中,这个公式还可以设计的更复杂,并可以通过高等代数矩阵旋转求解,我们这里只是为了理解原理,并不是为了做搜索算法,所以就不再深入下去了。
总结:世界的很多东西都是零和游戏,就像炒股,股民赚的钱也就是机构亏的钱,机构赚的钱也就是股民亏的钱,也许股民们应该研究一下PageRank算法,看看股市起起落落的背后是不是收敛了,收敛了说明炒下去永远别想解套,而且机构永远不会亏。
如何使用并行计算方式求PR值:
我们这里通过fourinone提供的各种并行计算模式去设计,思路方法可以有很多种。
第一次使用可以参考
分布式计算上手demo指南,开发包下载地址:
http://code.google.com/p/fourinone/
思路一:可以采取工人互相合并的机制(工人互相合并及receive使用可参见
sayhello demo),每个工人分析当前网页链接,对每个链接进行一次PR值投票,通过receive直接投票到该链接对于网页所在的工人机器上,这样经过一轮工人的互相投票,然后再统计一下本机器各网页所得的投票数得到新的PR值。但是这种方式,对于每个链接投票,都要调用一次receive到其他工人机器,比较耗用带宽,网页数量庞大链接众多时要调用很多次receive,导致性能不高。
思路二:由于求PR值的特点是输入数据大,输出数据小,也就是网页成千上万占空间多,但是算出来的PR值占空间小,我们姑且用内存可以装下。因此我们优先考虑每个工人统计各自机器上的网页,计算各链接对应网页的所得投票,然后返回工头统一合并得到各网页的PR值。
可以采用最基本的“总—分—总”并行计算模式实现(请参考
分布式计算上手demo指南)。
并行计算的拆分和合并设计如下:
可以看到:
工人负责统计各自机器上网页的各个链接的PR得票。
工头负责合并累加得到各链接对应网页的新PR值,并迭代计算。
程序实现:
PageRankWorker:是一个PageRank工人实现,为了方便演示,它通过一个字符串数组代表包括的链接(实际上应该从本地网页文件里获取)
links = new String[]{"B","C"};
然后对链接集合中的每个链接进行PR投票
for(String p:links)
outhouse.setObj(p, pr/links.length);
PageRankCtor:是一个PageRank包工头实现,它将A、B、C三个网页的PageRank初始值设置为1.00,然后通过doTaskBatch进行阶段计算,doTaskBatch提供一个栅栏机制,等待每个工人计算完成才返回,工头将各工人返回的链接投票结果合并累加:
pagepr = pagepr+(Double)prwh.getObj(page);
得到各网页新的PR值(这里取q值为1进行计算),然后连续迭代500轮计算。
运行步骤:
1、启动ParkServerDemo(它的IP端口已经在配置文件指定)
java -cp fourinone.jar; ParkServerDemo
2、运行A、B、C三个PageRankWorker,传入不同的IP和端口号
java -cp fourinone.jar; PageRankWorker localhost 2008 A
java -cp fourinone.jar; PageRankWorker localhost 2009 B
java -cp fourinone.jar; PageRankWorker localhost 2010 C
3、运行PageRankCtor
java -cp fourinone.jar; PageRankCtor
我们可以看到跟开始的单机程序的结果是一样的,同时各工人窗口依次输出了各自的PR值:
完整demo源码如下:
// ParkServerDemo
import com.fourinone.BeanContext;
public class ParkServerDemo
{
public static void main(String[] args)
{
BeanContext.startPark();
}
}
// PageRankWorker
import com.fourinone.MigrantWorker;
import com.fourinone.WareHouse;
import com.fourinone.Workman;
public class PageRankWorker extends MigrantWorker
{
public String page = null;
public String[] links = null;
public PageRankWorker(String page, String[] links){
this.page = page;
this.links = links;
}
public WareHouse doTask(WareHouse inhouse)
{
Double pr = (Double)inhouse.getObj(page);
System.out.println(pr);
WareHouse outhouse = new WareHouse();
for(String p:links)
outhouse.setObj(p, pr/links.length);//对包括的链接PR投票
return outhouse;
}
public static void main(String[] args)
{
String[] links = null;
if(args[2].equals("A"))
links = new String[]{"B","C"};//A页面包括的链接
else if(args[2].equals("B"))
links = new String[]{"C"};
else if(args[2].equals("C"))
links = new String[]{"A"};
PageRankWorker mw = new PageRankWorker(args[2],links);
mw.waitWorking(args[0],Integer.parseInt(args[1]),"pagerankworker");
}
}
// PageRankCtor
import com.fourinone.Contractor;
import com.fourinone.WareHouse;
import com.fourinone.WorkerLocal;
import java.util.Iterator;
public class PageRankCtor extends Contractor
{
public WareHouse giveTask(WareHouse inhouse)
{
WorkerLocal[] wks = getWaitingWorkers("pagerankworker");
System.out.println("wks.length:"+wks.length);
for(int i=0;i<500;i++){//500轮
WareHouse[] hmarr = doTaskBatch(wks, inhouse);
WareHouse prwh = new WareHouse();
for(WareHouse result:hmarr){
for(Iterator iter=result.keySet().iterator();iter.hasNext();){
String page = (String)iter.next();
Double pagepr = (Double)result.getObj(page);
if(prwh.containsKey(page))
pagepr = pagepr+(Double)prwh.getObj(page);
prwh.setObj(page,pagepr);
}
}
inhouse = prwh;//迭代
System.out.println("No."+i+":"+inhouse);
}
return inhouse;
}
public static void main(String[] args)
{
PageRankCtor a = new PageRankCtor();
WareHouse inhouse = new WareHouse();
inhouse.setObj("A",1.00d);//A的pr初始值
inhouse.setObj("B",1.00d);//B的pr初始值
inhouse.setObj("C",1.00d);//C的pr初始值
a.giveTask(inhouse);
a.exit();
}
}
![点击查看原始大小图片](http://dl2.iteye.com/upload/attachment/0082/2788/95f77500-8a55-3eda-91f0-83f42e78886d-thumb.png)
- 大小: 3.6 KB
![点击查看原始大小图片](http://dl2.iteye.com/upload/attachment/0082/2790/0a0950ad-cbd0-3f8f-8332-d23830d6edb8-thumb.png)
- 大小: 45.7 KB
![点击查看原始大小图片](http://dl2.iteye.com/upload/attachment/0082/2792/043e48c3-fe13-3381-aa79-b0d0bdc8d2b1-thumb.png)
- 大小: 51 KB
![点击查看原始大小图片](http://dl2.iteye.com/upload/attachment/0082/2794/ccf95055-de31-3d89-ba4e-dc3abb28cc93-thumb.png)
- 大小: 58.2 KB
![点击查看原始大小图片](http://dl2.iteye.com/upload/attachment/0082/2796/3a568462-d029-36f0-abee-0be36312f9da-thumb.png)
- 大小: 41.6 KB
![点击查看原始大小图片](http://dl2.iteye.com/upload/attachment/0082/2798/2eed1f77-3c43-3876-b4dd-e18ebd85edd1-thumb.png)
- 大小: 119.6 KB
![点击查看原始大小图片](http://dl2.iteye.com/upload/attachment/0082/2800/b6cf554c-9177-3ea7-a7ff-5d25c3fc942c-thumb.png)
- 大小: 121.4 KB
![点击查看原始大小图片](http://dl2.iteye.com/upload/attachment/0082/2802/20473eff-dd1d-30c2-9705-6dea3cb8ba9d-thumb.png)
- 大小: 130.8 KB
分享到:
相关推荐
传播染色算法利用Personalized PageRank进行染色,识别和影响潜在高风险用户。此外,时序异常挖掘结合HP滤波器和TLSTM算法捕捉异常交易,而团伙快速挖掘则通过CC和TPNet算法分析设备网络,以发现和分析欺诈团伙,...
7. **动态决策**:决策过程随时间变化,如在线学习算法或实时策略游戏中的决策。 在编程中,实现这些决策过程通常涉及到各种数据结构(如队列、栈、图)和算法(如搜索算法、最优化算法)。程序设计语言提供了丰富...
风光储直流微电网Simulink仿真模型:光伏发电、风力发电与混合储能系统的协同运作及并网逆变器VSR的研究,风光储直流微电网Simulink仿真模型:MPPT控制、混合储能系统、VSR并网逆变器的设计与实现,风光储、风光储并网直流微电网simulink仿真模型。 系统由光伏发电系统、风力发电系统、混合储能系统(可单独储能系统)、逆变器VSR?大电网构成。 光伏系统采用扰动观察法实现mppt控制,经过boost电路并入母线; 风机采用最佳叶尖速比实现mppt控制,风力发电系统中pmsg采用零d轴控制实现功率输出,通过三相电压型pwm变器整流并入母线; 混合储能由蓄电池和超级电容构成,通过双向DCDC变器并入母线,并采用低通滤波器实现功率分配,超级电容响应高频功率分量,蓄电池响应低频功率分量,有限抑制系统中功率波动,且符合储能的各自特性。 并网逆变器VSR采用PQ控制实现功率入网。 ,风光储; 直流微电网; simulink仿真模型; 光伏发电系统; 最佳叶尖速比控制; MPPT控制; Boost电路; 三相电压型PWM变换器;
以下是针对初学者的 **51单片机入门教程**,内容涵盖基础概念、开发环境搭建、编程实践及常见应用示例,帮助你快速上手。
【Python毕设】根据你提供的课程代码,自动排出可行课表,适用于西工大选课_pgj
【毕业设计】[零食商贩]-基于vue全家桶+koa2+sequelize+mysql搭建的移动商城应用
电动汽车充电背景下的微电网谐波抑制策略与风力发电系统仿真研究,电动汽车充电微电网的谐波抑制策略与风力发电系统仿真研究,基于电动汽车充电的微电网谐波抑制策略研究,包括电动汽车充电负 载模型,风电模型,光伏发现系统,储能系统,以及谐波处理模块 风力发电系统仿真 ,电动汽车充电负载模型; 风电模型; 光伏发现系统; 储能系统; 谐波处理模块; 风力发电系统仿真,电动汽车充电微电网的谐波抑制策略研究:整合负载模型、风电模型与光伏储能系统
Vscode部署本地Deepseek的continue插件windows版本
内容概要:本文详细介绍了滤波器的两个关键参数——截止频率(F0)和品质因素(Q),并探讨了不同类型的滤波器(包括低通、高通、带通和带阻滤波器)的设计方法及其特性。文章首先明确了F0和Q的基本概念及其在滤波器性能中的作用,接着通过数学推导和图形展示的方式,解释了不同Q值对滤波器频率响应的影响。文中特别指出,通过调整Q值可以控制滤波器的峰谷效果和滚降速度,进而优化系统的滤波性能。此外,还讨论了不同类型滤波器的具体应用场景,如低通滤波器适用于消除高频噪声,高通滤波器用于去除直流分量和低频干扰,而带通滤波器和带阻滤波器分别用于选取特定频段信号和排除不需要的频段。最后,通过对具体案例的解析,帮助读者更好地理解和应用相关理论。 适合人群:电子工程及相关领域的技术人员、研究人员以及高校学生,特别是那些需要深入了解滤波器设计原理的人群。 使用场景及目标:适用于从事模拟电路设计的专业人士,尤其是希望掌握滤波器设计细节和技术的应用场合。目标是让读者能够灵活运用Q值和F0来优化滤波器设计,提升系统的信噪比和选择性,确保信号的纯净性和完整性。
内容概要:本文主要讲述了利用QUARTUSⅡ进行电子设计自动化的具体步骤和实例操作,详细介绍了如何利用EDA技术在QUARTUSⅡ环境中设计并模拟下降沿D触发器的工作过程,重点探讨了系统规格设计、功能描述、设计处理、器件编译和测试四个步骤及相关的设计验证流程,如功能仿真、逻辑综合及时序仿真等内容,并通过具体的操作指南展示了电路设计的实际操作方法。此外还强调了QUARTUSⅡ作为一款集成了多种功能的综合平台的优势及其对于提高工作效率的重要性。 适用人群:电子工程、自动化等相关专业的学生或者工程师,尤其适用于初次接触EDA技术和QuartusⅡ的用户。 使用场景及目标:旨在帮助用户理解和掌握使用QUARTUSⅡ这一先进的EDA工具软件进行从概念设计到最后成品制作整个电路设计过程的方法和技巧。目标是在实际工作中能够熟练运用QUARTUSⅡ完成各类复杂电子系统的高效设计。 其他说明:文中通过具体的案例让读者更直观理解EDA设计理念和技术特点的同时也为进一步探索EDA领域的前沿课题打下了良好基础。此外它还提到了未来可能的发展方向,比如EDA工具的功能增强趋势等。
Simulink建模下的光储系统与IEEE33节点配电网的协同并网运行:光照强度变化下的储能系统优化策略与输出性能分析,Simulink模型下的光伏微网系统:光储协同,实现380v电压等级下的恒定功率并网与平抑波动,Simulink含光伏的IEEE33节点配电网模型 微网,光储系统并网运行 光照强度发生改变时,储能可以有效配合光伏进行恒定功率并网,平抑波动,实现削峰填谷。 总的输出有功为270kw(图23) 无功为0 检验可以并网到电压等级为380v的电网上 逆变侧输出电压电流稳定(图4) ,Simulink; 含光伏; 配电网模型; 微网; 光储系统; 储能配合; 恒定功率并网; 电压等级; 逆变侧输出。,Simulink光伏微网模型:光储协同并网运行,实现功率稳定输出
基于Andres ELeon新法的双馈风机次同步振荡抑制策略:附加阻尼控制(SDC)的实践与应用,双馈风机次同步振荡的抑制策略研究:基于转子侧附加阻尼控制(SDC)的应用与效能分析,双馈风机次同步振荡抑制策略(一) 含 基于转子侧附加阻尼控制(SDC)的双馈风机次同步振荡抑制,不懂就问, 附加阻尼控制 (SDC)被添加到 RSC 内部控制器的q轴输出中。 这种方法是由Andres ELeon在2016年提出的。 该方法由增益、超前滞后补偿器和带通滤波器组成。 采用实测的有功功率作为输入信号。 有关更多信息,你可以阅读 Andres ELeon 的lunwen。 附lunwen ,关键词:双馈风机、次同步振荡、抑制策略;转子侧附加阻尼控制(SDC);RSC内部控制器;Andres ELeon;增益;超前滞后补偿器;带通滤波器;实测有功功率。,双馈风机次同步振荡抑制技术:基于SDC与RSCq轴控制的策略研究
springboot疫情防控期间某村外出务工人员信息管理系统--
高效光伏并网发电系统MATLAB Simulink仿真设计与MPPT技术应用及PI调节闭环控制,光伏并网发电系统MATLAB Simulink仿真设计:涵盖电池、BOOST电路、逆变电路及MPPT技术效率提升,光伏并网发电系统MATLAB Simulink仿真设计。 该仿真包括电池,BOOST升压电路,单相全桥逆变电路,电压电流双闭环控制部分;应用MPPT技术,提高光伏发电的利用效率。 采用PI调节方式进行闭环控制,SPWM调制,采用定步长扰动观测法,对最大功率点进行跟踪,可以很好的提高发电效率和实现并网要求。 ,光伏并网发电系统; MATLAB Simulink仿真设计; 电池; BOOST升压电路; 单相全桥逆变电路; 电压电流双闭环控制; MPPT技术; PI调节方式; SPWM调制; 定步长扰动观测法。,光伏并网发电系统Simulink仿真设计:高效MPPT与PI调节控制策略
PFC 6.0高效循环加载系统:支持半正弦、半余弦及多级变荷载功能,PFC 6.0循环加载代码:支持半正弦、半余弦及多级变荷载的强大功能,PFC6.0循环加载代码,支持半正弦,半余弦函数加载,中间变荷载等。 多级加载 ,PFC6.0; 循环加载代码; 半正弦/半余弦函数加载; 中间变荷载; 多级加载,PFC6.0多级半正弦半余弦循环加载系统
某站1K的校园跑腿小程序 多校园版二手市场校园圈子失物招领 食堂/快递代拿代买跑腿 多校版本,多模块,适合跑腿,外卖,表白,二手,快递等校园服务 需要自己准备好后台的服务器,已认证的小程序,备案的域名!
【Python毕设】根据你提供的课程代码,自动排出可行课表,适用于西工大选课
COMSOL锂枝晶模型:五合一的相场、浓度场与电场模拟研究,涵盖单枝晶定向生长、多枝晶生长及无序生长等多元现象的探索,COMSOL锂枝晶模型深度解析:五合一技术揭示单枝晶至雪花枝晶的生长机制与物理场影响,comsol锂枝晶模型 五合一 单枝晶定向生长、多枝晶定向生长、多枝晶随机生长、无序生长随机形核以及雪花枝晶,包含相场、浓度场和电场三种物理场(雪花枝晶除外),其中单枝晶定向生长另外包含对应的参考文献。 ,comsol锂枝晶模型; 五合一模型; 单枝晶定向生长; 多枝晶定向生长; 多枝晶随机生长; 无序生长随机形核; 雪花枝晶; 相场、浓度场、电场物理场; 参考文献,COMSOL锂枝晶模型:多场景定向生长与相场电场分析
嵌入式大学生 点阵代码
那个有delphi12 tedgebrowser 使用的dll