六度空间

  1. 你知道吗?其实从一出生,我们就和世界上每个人都有联系,并且不超过六个人!
    这就是六度空间理论,又名六度分隔理论,意思是你至多只要通过六个人就能认识全世界的任意一个人,可以这样算:假设一个人能认识25个人或以上,那经过7次介绍之后(间隔6人),一个人可以被介绍给25的7次方,等于6103515625人,超过60亿!当然,前提假设是平均每个人能认识25个人或以上,美国科学家早在上世纪60年代就提出了这一理论,据英国《每日邮报》近日报道,美国研究人员通过精密计算进一步发展了这一理论。美国微软公司的研究人员选取了2006年某月通过微软网络发送的300亿条即时信息。计算结果显示,78%的用户可与另一用户通过6.6条信息相连。也就是说,平均通过6.6个人就能把世界上任何两个人联系起来。普通人要想与歌星麦当娜或英国女王取得联系,其实只需要7个熟人而已。研究人员埃里克·霍维茨说,“人们一直将六度分隔理论当作一个民间传说。但没想到事实的确如此。不管是美国总统还是好莱坞明星,只要找到正确的6个人,我们就能联系起来。”
    六度分割通常用来描述一个广阔的社会网络(SN),现在大部分的社会网络服务都提供了搜索功能,即搜索出一个用户到达另外一个用户的最短路径,也就是找出这两个用户之间通过最少的用户的链接。
    一般的SN提供的搜索都是4度的,也就是例如A-B-C-D-E
    称为4度的分隔。提供5度搜索和6度搜索的几乎寥寥无几,当然一方面是5,6度分隔的用户很少,大部分的用户都应该在4度内,另外一个方面是5,6度分隔的搜索在实际计算上也涉及非常大的运算量。
    【SN搜索算法】注:(已下所有都是不去除本身的)
    如果说寻找两个人之间的最小分隔的路径和寻找最短路径可以类比,那么唯一不同的是SN上每个节点的联系可以非常的广阔,不只是上下左右,而是十个甚至上百个联系。这是是一个多维空间内的最短路径的寻找。假设一个用户平均有n个好友,那么粗略估计一个用户的4度好友大约有n×n×n×n+n×n×n+n×n+n
    ~ n^4,无疑是一个非常恐怖的数目。因此采用传统的递归的方法显然是不大现实的。
    当然,事情并非这么麻烦,有简洁的方法可以加快找到用户之间的最小分隔:不单是从一个用户搜索,而是从两个用户同时搜索,而看两个用户的2度之内的用户是否有相同:
    A-B-C E-D-C
    A和E的处在在两度分隔的用户基本上数目估计都在n的平方。问题变成了比较n^2和n^2之间有没有相同,这个计算的时间等同于2×n^2的排序所需要的时间。
    【SN索引】 那么能否继续加快速度?
    当然可以,可以提前对用户的好友进行索引,对好友的好友进行索引,这样在未来进行关系的搜索时会大大加快: A: {A1} {A2}
    A1为A的好友的集合,A2为A的好友的好友的集合 E: {E1} {E2} 那么 1度分隔为: A 属于{E1},等同于E属于
    {A1} 2度分隔为: A 属于{E2},等同于E属于 {A2},{A1}{E1}有共同项。 3度分隔为: {A1}
    {E2}有共同项,等同于A属于 {E2} 4度分隔为: {A2} {E2}有共同项 【SN关系的更新】
    当然,发现是一个核心问题,另外一个问题就是更新,因为SN的关系不会是一成不变的,在一个活跃的SN社区里,每天用户之间的关系的更新更是可观。这里只考虑关系添加的例子:
    A: {A1} {A2} E: {E1} {E2} 当A 与 E
    直接建立了好友关系后,应该说整合系统的关系全都变化了,因为这个新的关系一定会导致一些关系的短路,从而导致很多现有的关系的调整。但是因为我们只存储2度分隔以内的关系,也只关心两度分隔以内的关系,因此当发生了一个新的关系后,2度内关系的变化一定是A和E本身或者他们的一度关系的用户,再远的用户将不受这个关系的影响。
    因此首先 所有{A1}的元素的二度分隔集合里要加上E,所有{E1}的元素的二度分隔集合里要加上A。
    然后是二度的修正。分别加上对方的1度。 {A2} = {A2 + E1} {E2} = {E2 + A1} 最后是一度的修正:A,
    E 的 一度{A1}{E1}需要加入E,A: {A1} = {A1 + E} {E1} = {E1 + A}
    整体操作的量大约在2n次操作,比我们通常认为的要小的多。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在C语言中实现六度空间可以使用图论中的广度优先搜索算法(BFS)。 首先,需要定义一个结构体来表示每个人,结构体中可以包含一个数组表示与其他人的关系。例如: ```c #define MAX_PEOPLE 1000 typedef struct { int id; int relations[MAX_PEOPLE]; } Person; ``` 其中,id表示每个人的唯一标识,relations数组表示与其他人的关系,如果两个人之间有联系,则在数组中相应位置记录1,否则记录0。 接下来,可以使用一个队列来实现BFS算法,遍历整个社交网络,找到任意两个人之间的最短路径长度。例如: ```c #define MAX_QUEUE_SIZE 10000 int bfs(Person people[], int start, int end) { int visited[MAX_PEOPLE] = {0}; int distance[MAX_PEOPLE] = {0}; int queue[MAX_QUEUE_SIZE]; int front = 0, rear = 0; visited[start] = 1; queue[rear++] = start; while (front != rear) { int current = queue[front++]; if (current == end) { return distance[current]; } for (int i = 0; i < MAX_PEOPLE; i++) { if (people[current].relations[i] == 1 && !visited[i]) { visited[i] = 1; distance[i] = distance[current] + 1; queue[rear++] = i; } } } return -1; // 没有找到路径 } ``` 在上述代码中,visited数组表示每个人是否已经被访问过,distance数组表示每个人到起点的距离,queue数组表示BFS算法中使用的队列。start和end表示起点和终点的标识。算法的返回值是起点到终点的最短路径长度,如果没有找到路径则返回-1。 最后,需要读入数据并构建社交网络,例如: ```c int main() { Person people[MAX_PEOPLE]; int n, m; scanf("%d %d", &n, &m); for (int i = 0; i < n; i++) { people[i].id = i; for (int j = 0; j < n; j++) { people[i].relations[j] = 0; } } for (int i = 0; i < m; i++) { int a, b; scanf("%d %d", &a, &b); people[a].relations[b] = 1; people[b].relations[a] = 1; } int start, end; scanf("%d %d", &start, &end); int distance = bfs(people, start, end); printf("%d\n", distance); return 0; } ``` 在上述代码中,n表示社交网络中的人数,m表示人与人之间的联系数,读入n个人的标识和m个联系,构建相应的关系图。start和end表示起点和终点的标识,计算它们之间的最短路径长度并输出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

京之火

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值