用sql写每年的第三周_用sql写迭代算法-用spark sql划分连通图

facce1c9b408209e9a38a04a6c284c48.png

一、问题描述

1.1 问题场景化描述

小时候你可能遇到过这种情况,一不小心在游戏厅惹到了别人,然后就约放学后校门口等着。

1224fc2517ab298bccab9c631efb3ff1.png

结果两人都找了一自己认识的小团体在校门口对峙,紧张的气氛中,有的人发现对面的团体中有认识的人,结果约架便成了约烧烤,两个团体都互相认识了。

a2f6dfd5509fcd47e96a3a74fc667398.png

如果每个人都有个标签,贴在身上,比如都叫“XX帮”,就能避免约架的流程是吧。

1.2 问题概念模型

上面的问题,我们用图来表示。图是由节点和边构成,点就是某个同学,边就代表是否认识。给你一个图,将图中互相认识的人都打上同一个标签,也就是处于同一个连通图的节点打上同一个标签。

比如下图所示的一个图,有9个点,很多条边。

52829e9c9fd1adc7f9f94eed7edbb516.png

1.3 问题物理模型

在hive数据表relation中,存储两两的关系:

user:string , friend:string

比如1.2的图就可以表示成下表

c8a51114c2ae279d1aaafd3944b50722.png

问题就变成了生成一张表名为user_group,记录每个user的标签。

user:string , group:string

二、解决方案

2.1 场景化解决方案

为了解决这个问题:

  • 首先第一天每个人都成立一个以自己为帮主的帮派,在自己肩上贴上帮主名字。
  • 然后第二天大家都去上学,观察自己认识的人中都加入了哪些帮派,偷偷记下来。
  • 放学回到家,就把记下来的帮主姓名按字母顺序排序,加入排第一个的帮派,第二天去上学的时候贴上帮主名字。
  • 这样很多天之后,大家发现认识的人都统一了帮主。

约架时两帮人说出自己的帮主,帮主不一样大家肯定都互相不认识的,直接打就是。

2.2 解决方案概念模型

这就是社群发现,可以使用标签传播算法(LAP):每一轮将标签按边的权值传播到临近节点,每个节点收到传播过来的标签后更新自己的标签,经过多轮传播直到收敛。

具体就不多说了,感兴趣的同学可以搜索一下。

2.3 sql物理实现

基于1.3的表我们有下面的解法:

  • 由于是无向图,得把反向关系的数据补全,构造表all_relation:
spark.sql("""
select user,friend as group
from relation
union
select friend as user, user as group
from relation
""").registerTempTable("all_relation")
  • 计算标签的更新路径
while True:
    # 每个人把认识的人的帮主都记下来,选帮主
    propagation_map = spark.sql("""
    select distinct user as source,
      least(user, min(group)) target,
      count(1) c
    from all_relation
    group by user
    having source!=target
    """).cache()

    #如果每个人认识的人中都只公认了只有一个帮主就不再计算
    propagation_count = propagation_map.filter("c>1").count()
    if(propagation_count==0):
        break
    propagation_map.registerTempTable("propagation_map")

    # 更新认识的人的帮主
    all_relation = spark.sql("""
    select distinct all_relation.user,
        nvl(propagation_map.target,all_relation.group) group
    from all_relation
    left join propagation_map
    on all_relation.group=propagation_map.source
    """).registerTempTable("all_relation")
  • 结果就是 all_relation 这张表

三、一些思考

  1. 这个模式和比特币的共识模式很像,都是先建立一套规则让每个节点按照这个规则操作,最后能让所有节点达成共识。
  2. sql这样的模式和一般的通用语言不一样,天生带有并行性。
  3. 对于本文的这种描述方式大家觉得咋样。

更多文章欢迎关注:

曾二爷​www.zhihu.com
7176c02d9ae8ed0a6ff04b9d572dd247.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值