大家好,

首先,我不是想创建一个社交网络,Facebook足够大! (漫画)
我选择了这个问题作为例子,因为它完全符合我正在做的事情.

想象一下,我在MySQL中有一个用户表和一个带有“朋友请求”的user_connections表.如果是这样,它会是这样的:

Users Table:

userid  username
1       John
2       Amalia
3       Stewie
4       Stuart
5       Ron
6       Harry
7       Joseph
8       Tiago
9       Anselmo
10      Maria


User Connections Table:

userid_request  userid_accepted
2               3
7               2
3               4
7               8
5               6
4               5
8               9
4               7
9               10
6               1
10              7
1               2

现在我想在朋友之间找到圈子,并创建一个结构数组,并将该圆圈放在数据库上(没有一个数组可以包含与另一个数组相同的朋友).

Return Example:

    // First Circle of Friends
    Circleid => 1
    CircleStructure => Array(
        1 => 2,2 => 3,3 => 4,4 => 5,5 => 6,6 => 1,)
    // Second Circle of Friends
    Circleid => 2
    CircleStructure => Array(
        7 => 8,8 => 9,9 => 10,10 => 7,)

我试图想到一个算法来做到这一点,但我认为这将需要很多的处理时间,因为它会随机搜索数据库,直到它关闭一个圆圈.

PS:圆的最小结构长度为3个连接,限制为100(因此守护程序不会搜索整个数据库)

编辑:

我想到这样的事情:

function browse_user($userget='random',$users_history=array()){

    $user = user::get($userget);

    $users_history[] = $user['userid'];

    $connections = user::connection::getByUser($user['userid']);
    foreach($connections as $connection){
        $userid = ($connection['userid_request']!=$user['userid']) ? $connection['userid_request'] : $connection['userid_accepted'];

        // Start the circle array
        if(in_array($userid,$users_history)) return array($user['userid'] => $userid);

        $res = browse_user($userid,$users_history);

        if($res!==false){
            // Continue the circle array
            return $res + array($user['userid'] => $userid);
        }
    }

  return false;
}

while(true){

    $res = browse_user();

    // Yuppy,friend circle found!
    if($res!==false){
            user::circle::create($res);
    }

    // Start from scratch again!
}

该功能的问题是它可以搜索整个数据库,而不会找到最大的圈子或最佳匹配.

阿尔弗雷德·戈多伊的答案是非常有用的,因为处理应该逐步完成.我会尝试梳理出一些具体的细节.

我会谈论“边缘”连接的“节点”,而不是“人”是“朋友”.循环从3到4(或n到n 1)节点不是真的不是这样.几个边缘,不形成循环,可以被新的边缘关闭并形成一个新的循环.

相反(或者)作为循环列表,我们应该保留边缘链的列表.例如假设这个连接表:

userid_request  userid_accepted
2               7
3               7
3               8

那么链表应该包含:

chainid  start  end  length
1        2      3    2
1        2      8    3
2        7      8    2

这个结构允许您记录和检索任何长度的链,并给定链的两端,使用id和length进行跟踪.它需要空间…但是,这是您为图形搜索周期的内存成本.它可以简化,取决于你想做什么;详细说明.

顺便说一下,我假设图形是无向的 – 换句话说,一个从一个节点到另一个节点的边缘都是双向的.在连接中,具有最低ID的节点将始终是“请求”,并且“接受”端的最高ID.

添加新节点时,要维护链表,查看新节点是否关闭链循环.它涉及几个查询.我给你一个

假设在连接表中添加了一个新条目:

userid_request  userid_accepted
@new_request    @new_accepted

您可以使用查询来选择任何此类循环.你已经知道了新的链接和它的两个节点,所以你只是寻找一个关闭它的链条:

select chainid,length
from chain
where (start = @new_request and end = @new_accepted)
or (end = @new_request and start = @new_accepted)

(请注意,由于图形未定向,您必须查找两个周期配置).

为了维护链表,每次添加一个边:

>查找节点延长的现有链
>寻找长度为2的新链.

然后当节点被删除时,您应该取出相应的链和循环 – 链表将足够大.

php – 如何找到用户之间的连接,所以我可以创建一个封闭的朋友圈子?的更多相关文章

  1. 深度解析swift中的String

    String是我们最常用到的语言元素,swift中的String初看起来相当简洁、易用,真正大量使用时,却有点摸不着头脑。直到看完了这篇文章,才算真正的明白了String的奥妙之处。每个Character所占用的内存空间不定,注定了String不能用普通的数组来存储内容,实际用的是双向链表。String.Index既然String是个双向链表,那么,访问其中的某个元素,或者substring,就要用指针了。NSRange和RangeNsstring中对于字符串区间,可以用NSRange来表示,而Strin

  2. Swift 中数组和链表的性能

    尽管如此,我觉得链表的例子非常有意思,而且值得实现和把玩,它有可能会提升数组reduce方法的性能。同时我认为Swift的一些额外特性很有趣:比如它的枚举可以灵活的在对象和具体方法中自由选择,以及“默认安全”。这本书未来的版本可能就会用Swift作为实现语言。拷贝数组消耗的时间是线性的。使用链表还有其他的代价——统计链表节点的个数所需要的时间是统计数组元素个数时间的两倍,因为遍历链表时的间接寻址方式是需要消耗时间的。

  3. swift算法手记-10

    所有操作都以对数随机化的时间进行。每个更高层都充当下面列表的"快速跑道",这里在层i中的元素按某个固定的概率p出现在层i+1中。1------4---61---3-4---6------91-2-3-4-5-6-7-8-9-10结构实例要查找一个目标元素,起步于头元素和顶层列表,并沿着每个链表搜索,直到到达小于或的等于目标的最后一个元素。通过跟踪起自目标直到到达在更高列表中出现的元素的反向查找路径,在每个链表中预期的步数显而易见是1/p。通过选择不同p值,就可以在查找代价和存储代价之间作出权衡。

  4. Java链表超详细讲解(通俗易懂,含源码)

    链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的,下面这篇文章主要给大家介绍了关于Java链表超详细讲解的相关资料,本文讲解的内容通俗易懂,含源码,需要的朋友可以参考下

  5. PHP实现合并两个排序链表的方法

    这篇文章主要介绍了PHP实现合并两个排序链表的方法,涉及php针对链表的遍历、判断、排序等相关操作技巧,需要的朋友可以参考下

  6. Java链表数据结构及其简单使用方法解析

    这篇文章主要介绍了Java链表数据结构及其简单使用方法解析,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下

  7. JavaScript实现双向链表过程解析

    这篇文章主要介绍了利用JavaScript实现双向链表以及它的封装和常用操作,文中的示例代码讲解详细,对日常的学习和工作都有一定的价值,快来和小编一起学习吧

  8. React Fiber 链表操作及原理示例详解

    这篇文章主要为大家介绍了React Fiber 链表操作原理详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  9. PHP链表操作简单示例

    这篇文章主要介绍了PHP链表操作,结合简单实例形式分析了php链表的定义与使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下

  10. PHP实现链表的定义与反转功能示例

    这篇文章主要介绍了PHP实现链表的定义与反转功能,结合实例形式分析了PHP链表的基本定义、添加、移除、遍历以及两种反转操作相关实现技巧,需要的朋友可以参考下

随机推荐

  1. PHP个人网站架设连环讲(一)

    先下一个OmnihttpdProffesinalV2.06,装上就有PHP4beta3可以用了。PHP4给我们带来一个简单的方法,就是使用SESSION(会话)级变量。但是如果不是PHP4又该怎么办?我们可以假设某人在15分钟以内对你的网页的请求都不属于一个新的人次,这样你可以做个计数的过程存在INC里,在每一个页面引用,访客第一次进入时将访问时间送到cookie里。以后每个页面被访问时都检查cookie上次访问时间值。

  2. PHP函数学习之PHP函数点评

    PHP函数使用说明,应用举例,精简点评,希望对您学习php有所帮助

  3. ecshop2.7.3 在php5.4下的各种错误问题处理

    将方法内的函数,分拆为2个部分。这个和gd库没有一点关系,是ecshop程序的问题。会出现这种问题,不外乎就是当前会员的session或者程序对cookie的处理存在漏洞。进过本地测试,includes\modules\integrates\ecshop.php这个整合自身会员的类中没有重写integrate.php中的check_cookie()方法导致,验证cookie时返回的username为空,丢失了登录状态,在ecshop.php中重写了此方法就可以了。把他加到ecshop.php的最后面去就可

  4. NT IIS下用ODBC连接数据库

    $connection=intodbc_connect建立数据库连接,$query_string="查询记录的条件"如:$query_string="select*fromtable"用$cur=intodbc_exec检索数据库,将记录集放入$cur变量中。再用while{$var1=odbc_result;$var2=odbc_result;...}读取odbc_exec()返回的数据集$cur。最后是odbc_close关闭数据库的连接。odbc_result()函数是取当前记录的指定字段值。

  5. PHP使用JpGraph绘制折线图操作示例【附源码下载】

    这篇文章主要介绍了PHP使用JpGraph绘制折线图操作,结合实例形式分析了php使用JpGraph的相关操作技巧与注意事项,并附带源码供读者下载参考,需要的朋友可以参考下

  6. zen_cart实现支付前生成订单的方法

    这篇文章主要介绍了zen_cart实现支付前生成订单的方法,结合实例形式详细分析了zen_cart支付前生成订单的具体步骤与相关实现技巧,需要的朋友可以参考下

  7. Thinkphp5框架实现获取数据库数据到视图的方法

    这篇文章主要介绍了Thinkphp5框架实现获取数据库数据到视图的方法,涉及thinkPHP5数据库配置、读取、模型操作及视图调用相关操作技巧,需要的朋友可以参考下

  8. PHP+jquery+CSS制作头像登录窗(仿QQ登陆)

    本篇文章介绍了PHP结合jQ和CSS制作头像登录窗(仿QQ登陆),实现了类似QQ的登陆界面,很有参考价值,有需要的朋友可以了解一下。

  9. 基于win2003虚拟机中apache服务器的访问

    下面小编就为大家带来一篇基于win2003虚拟机中apache服务器的访问。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. Yii2中组件的注册与创建方法

    这篇文章主要介绍了Yii2之组件的注册与创建的实现方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下

返回
顶部