首页 > 数据库 >【Leetcode1949. 坚定的友谊】使用MySQL在无向图中寻找{"CompleteTripartite", {1, 1, 3}}这个pattern

【Leetcode1949. 坚定的友谊】使用MySQL在无向图中寻找{"CompleteTripartite", {1, 1, 3}}这个pattern

时间:2024-01-22 10:07:03浏览次数:42  
标签:user2 uid degree user1 CompleteTripartite Leetcode1949 connected MySQL id

目录

  • 题目地址
  • 思路
  • 代码
  • MySQL代码
  • 逐行翻译为Pandas代码
  • 等效Cypher查询(未验证)

题目地址

https://leetcode.cn/problems/strong-friendship/

思路

就是在无向图中寻找这个pattern:

(* Mathematica *)
GraphData[{"CompleteTripartite", {1, 1, 3}}]

【Leetcode1949. 坚定的友谊】使用MySQL在无向图中寻找{"CompleteTripartite", {1, 1, 3}}这个pattern_SQL

SQL写还是比较麻烦。
更加复杂的查询还是建议把数据迁移到neo4j这样的图数据库,然后写Cypher这样的图数据库查询语句。

代码

MySQL代码

with t1 as( -- 图中找到的所有   v1-e1-v2-e2-v3 pattern
    select * from(
        select f1.user2_id as uid , f1.user1_id as one_degree_connected , f2.user1_id as two_degree_connected
        from Friendship f1 
        join Friendship f2 
        on f1.user1_id=f2.user2_id
        union 
        select f1.user2_id as uid , f1.user1_id as one_degree_connected , f2.user2_id as two_degree_connected
        from Friendship f1 
        join Friendship f2 
        on f1.user1_id=f2.user1_id
        union
        select f1.user1_id as uid , f1.user2_id as one_degree_connected , f2.user1_id as two_degree_connected
        from Friendship f1 
        join Friendship f2 
        on f1.user2_id=f2.user2_id
        union 
        select f1.user1_id as uid , f1.user2_id as one_degree_connected , f2.user2_id as two_degree_connected
        from Friendship f1 
        join Friendship f2 
        on f1.user2_id=f2.user1_id
    )tmp1
    where uid<>two_degree_connected and uid<>one_degree_connected and one_degree_connected<>two_degree_connected
    and uid<two_degree_connected
)

select uid as user1_id, two_degree_connected as user2_id
, count(distinct one_degree_connected) as common_friend
from t1

where concat(uid,",",two_degree_connected) in (select concat(user1_id,",",user2_id) from Friendship) -- 坚定的友谊要求这两人还得是朋友

group by user1_id,user2_id
having common_friend>=3
order by user1_id,user2_id,common_friend

逐行翻译为Pandas代码

import pandas as pd
pd.set_option('display.max_rows', 500)
pd.set_option('display.max_columns', 500)
pd.set_option('display.width', 1000)

def strong_friendship(friendship: pd.DataFrame) -> pd.DataFrame:
    # Step 1: Perform self-joins on the dataframe to find the v1-e1-v2-e2-v3 patterns
    # The joins are equivalent to finding one-degree and two-degree connections
    patterns = []

    # f1.user2_id = f2.user2_id
    patterns.append(
        pd.merge(friendship.rename(columns={'user1_id': 'one_degree_connected', 'user2_id': 'uid'}),
                friendship.rename(columns={'user1_id': 'two_degree_connected'}),
                left_on='one_degree_connected', right_on='user2_id')
        [['uid', 'one_degree_connected', 'two_degree_connected']]
    )

    # f1.user1_id = f2.user1_id
    patterns.append(
        pd.merge(friendship.rename(columns={'user2_id': 'one_degree_connected', 'user1_id': 'uid'}),
                friendship.rename(columns={'user2_id': 'two_degree_connected'}),
                left_on='one_degree_connected', right_on='user1_id')
        [['uid', 'one_degree_connected', 'two_degree_connected']]
    )

    # f1.user2_id = f2.user1_id
    patterns.append(
        pd.merge(friendship.rename(columns={'user1_id': 'one_degree_connected', 'user2_id': 'uid'}),
                friendship.rename(columns={'user2_id': 'two_degree_connected'}),
                left_on='one_degree_connected', right_on='user1_id')
        [['uid', 'one_degree_connected', 'two_degree_connected']]
    )

    # f1.user1_id = f2.user2_id
    patterns.append(
        pd.merge(friendship.rename(columns={'user2_id': 'one_degree_connected', 'user1_id': 'uid'}),
                friendship.rename(columns={'user1_id': 'two_degree_connected'}),
                left_on='one_degree_connected', right_on='user2_id')
        [['uid', 'one_degree_connected', 'two_degree_connected']]
    )

    # Step 2: Combine all the patterns into one DataFrame
    all_patterns = pd.concat(patterns)

    # Step 3: Drop duplicates and filter out invalid patterns
    # where uid<>two_degree_connected and uid<>one_degree_connected and one_degree_connected<>two_degree_connected
    # and uid<two_degree_connected
    filtered_patterns = all_patterns.drop_duplicates().query(
        'uid != two_degree_connected and uid != one_degree_connected and one_degree_connected != two_degree_connected and uid < two_degree_connected'
    )

    # print(f"filtered_patterns=\n{filtered_patterns}")
    
    # Group by uid and two_degree_connected and count distinct one_degree_connected
    grouped = filtered_patterns.groupby(['uid', 'two_degree_connected'])['one_degree_connected'].nunique().reset_index()
    grouped.rename(columns={'one_degree_connected': 'common_friend'}, inplace=True)
    
    # Filter pairs that are not friends, in the original dataset
    friendship_pairs = friendship.apply(lambda row: f"{row['user1_id']},{row['user2_id']}", axis=1)
    grouped['pair'] = grouped.apply(lambda row: f"{row['uid']},{row['two_degree_connected']}", axis=1)
    strong_pairs = grouped[grouped['pair'].isin(friendship_pairs)]
    
    # Filter out pairs with less than 3 common friends
    strong_pairs = strong_pairs[strong_pairs['common_friend'] >= 3]
    
    # Select required columns and sort based on the conditions
    result = strong_pairs[['uid', 'two_degree_connected', 'common_friend']].sort_values(by=['uid', 'two_degree_connected', 'common_friend'])
    
    # Rename columns to match the output of the SQL query
    result.rename(columns={'uid': 'user1_id', 'two_degree_connected': 'user2_id'}, inplace=True)
    
    return result

等效Cypher查询(未验证)

MATCH (u1)-[:FRIENDSHIP]-(common_friend)-[:FRIENDSHIP]-(u2),
      (u1)-[:FRIENDSHIP]-(u2)
WHERE NOT (u1)-[:FRIENDSHIP]-(u2)-[:FRIENDSHIP]-(common_friend)
WITH u1, u2, COLLECT(DISTINCT common_friend) AS common_friends
WHERE SIZE(common_friends) >= 3
RETURN u1 AS user1_id, u2 AS user2_id, SIZE(common_friends) AS common_friend_count
ORDER BY user1_id, user2_id, common_friend_count



标签:user2,uid,degree,user1,CompleteTripartite,Leetcode1949,connected,MySQL,id
From: https://blog.51cto.com/u_15247503/9360646

相关文章

  • 【Leetcode 2474. 购买量严格增加的客户】[MySQL 用户变量/Pandas]面向过程编程解决严
    目录题目地址MySQL代码等效pandas代码题目地址https://leetcode.cn/problems/customers-with-strictly-increasing-purchases/description/MySQL代码#WriteyourMySQLquerystatementbelowwitht1as(selectcustomer_id,year(order_date)asmy_year,sum(price)......
  • [转帖]MySQL多版本并发控制机制(MVCC)-源码浅析
    https://zhuanlan.zhihu.com/p/144682180 MySQL多版本并发控制机制(MVCC)-源码浅析前言作为一个数据库爱好者,自己动手写过简单的SQL解析器以及存储引擎,但感觉还是不够过瘾。<<事务处理-概念与技术>>诚然讲的非常透彻,但只能提纲挈领,不能让你玩转某个真正的数据库。感谢c......
  • MySQL - 日志
    1.回滚日志(undolog)作用:保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),也即非锁定读内容:逻辑格式的日志(当delete一条记录是,记录一条对应的insert记录,反之亦然),在执行undo的时候,仅仅是将数据从逻辑上恢复至事务之前的状态释放:当事务提交......
  • django使用redis集群、连接池、MySQL连接池
    redis的相关设置CACHES={"default":{"BACKEND":"django_redis.cache.RedisCache","LOCATION":["redis://127.0.0.1:6379/1","redis://127.0.0.1:6380/1",#...],"OPTIONS":{"CLIENT_......
  • mysql 修改密码
    1、找到根目录登录msql   1)以本机为例,mysql安装目录为:usr/localhost/mysql5.7   2)cd  usr/loclahost/mysql5.7/bin    3)登录    4)查看MySQL用户2、 在mysql5.7版本中存放密码字段为authentication_string,再msyql库中#进入mysql库中mysql>......
  • 如何使用mysql.server制作sysytemctl服务
    mysql.server是MySQL的一个启动脚本,通常用于启动、停止、重启和管理MySQL服务。如果你想使用systemctl来管理MySQL服务,你需要创建一个systemd服务文件,因为systemctl是systemd的命令行工具。下面是如何创建和使用systemd服务文件来管理MySQL服务的步骤:首先找......
  • 在Java中连接8.0版本以上的Mysql数据库
    一.连接数据库在使用Java连接8.0版本以上的数据库时,可以按照如下步骤:下载需要的包,本次教程中使用的是下面这个版本。该驱动网上有许多资源,可根据自己的需求下载。建立与数据库的连接单元在合适的包下新建"DButil.java"文件并输入如下代码:importjava.sql.Connecti......
  • 使用 Canal 实时从 MySql 向其它库同步数据
    目前绝大多数项目还是采用mysql作为数据存储,对于用户访问量较高的网站来说,mysql读写性能有限,我们通常会把mysql中的数据实时同步到Redis、mongodb、elasticsearch等中间件中,应对高并发访问场景,减轻mysql压力,防止数据库宕机。在项目开发中,为了不会原有代码进行侵入,采用c......
  • mysql中的各种索引大总结
    文章目录为啥不用二叉搜索树?为啥不用平衡二叉(avl)树?为啥不用b-树?为啥用b+树?(重点)索引聚簇索引聚簇索引的局限聚集的数据的优点非聚簇索引介绍组合索引覆盖索引前缀索引前缀索引选择算法全文索引hash索引b-tree索引自适应哈希索引小咸鱼的技术窝b-tree索引使用的是b+树的数据结构,树......
  • 深度了解mysql事务mvcc实现原理
    一:事务概念:一组原子性的sql查询语句,也可以看作是一个工作单元特点:要么全部执行成功,要么全部执行失败一个有效的事务需满足的条件(ACID)原子性(Atomicity)一个事务必须被视为一个单独的内部最小的,”不可分“的工作单元,以确保事务要么全部执行,要么全部执行失败,当一个事务具有原子性的时候......