• C 六度空间理论的实现


    “六度空间”理论又称作“六度分隔(Six Degrees of Separation)”理论。这个理论可以通俗地阐述为:“你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过五个人你就能够认识任何一个陌生人。”如图6.4所示。


    图6.4 六度空间示意图

    “六度空间”理论虽然得到广泛的认同,并且正在得到越来越多的应用。但是数十年来,试图验证这个理论始终是许多社会学家努力追求的目标。然而由于历史的原因,这样的研究具有太大的局限性和困难。随着当代人的联络主要依赖于电话、短信、微信以及因特网上即时通信等工具,能够体现社交网络关系的一手数据已经逐渐使得“六度空间”理论的验证成为可能。

    假如给你一个社交网络图,请你对每个节点计算符合“六度空间”理论的结点占结点总数的百分比。

    输入格式说明:

    输入第1行给出两个正整数,分别表示社交网络图的结点数N (1<N<=104,表示人数)、边数M(<=33*N,表示社交关系数)。随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个结点的编号(节点从1到N编号)。

    输出格式说明:

    对每个结点输出与该结点距离不超过6的结点数占结点总数的百分比,精确到小数点后2位。每个结节点输出一行,格式为“结点编号:(空格)百分比%”。

    样例输入与输出:

    序号 输入 输出
    1
     
    10 9
    1 2
    2 3
    3 4
    4 5
    5 6
    6 7
    7 8
    8 9
    9 10
     
    170.00%
    280.00%
    390.00%
    4100.00%
    5100.00%
    6100.00%
    7100.00%
    890.00%
    980.00%
    1070.00%
    2
    10 8
    1 2
    2 3
    3 4
    4 5
    5 6
    6 7
    7 8
    9 10
     
    170.00%
    280.00%
    380.00%
    480.00%
    580.00%
    680.00%
    780.00%
    870.00%
    920.00%
    1020.00%
    3
     
    11 10
    1 2
    1 3
    1 4
    4 5
    6 5
    6 7
    6 8
    8 9
    8 10
    10 11
     
    1100.00%
    290.91%
    390.91%
    4100.00%
    5100.00%
    6100.00%
    7100.00%
    8100.00%
    9100.00%
    10100.00%
    1181.82%
    4
     
    2 1
    1 2
     
    1100.00%
    2100.00%

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    算法思路:

    1、对每个节点进行广度优先搜索

    2、搜索过程中累计访问的节点数

    3、需要记录层次,仅计算6层以内的节点数

    分析:

    1、伪码描述

    针对单个节点的BFS

     1 int BFS ( Vertex V )
     2 { 
     3 visited[V] = true; count = 1;
     4 level = 0; last = V;
     5 Enqueue(V, Q);
     6 while(!IsEmpty(Q)){ 
     7 V = Dequeue(Q);
     8 for( V 的每个邻接点 W )
     9 if( !visited[W] ) {
    10 visited[W] = true;
    11 Enqueue(W, Q); count++;
    12 tail = W;
    13 }
    14 if( V == last ) {
    15 level++; last = tail;
    16 }
    17 if( level == 6) break;
    18 }
    19 Reset(V) // 重置V的每个邻接点访问状态
    20 returncount;
    21 }

    对所有节点实现一次

    1 void SDS() {
    2 for V in G {
    3 count = BFS(V)
    4 print(count)
    5 }  
    6 }

    2、实现代码

      1 #pragma mark - 六度空间
      2 #include <math.h>
      3 #include <stdio.h>
      4 #include <stdbool.h>
      5 typedef struct {
      6 int index;
      7 bool visited;
      8 void *next;
      9 } SDSVertex;
     10 int a[10000][10000];
     11 SDSVertex v_sds[10000];
     12 int pNum = 0, edgeNum = 0;
     13 typedef struct queue {
     14 SDSVertex *front;
     15 SDSVertex *rear;
     16 } Queue;
     17 Queue *createQueue()
     18 Queue *queue = (Queue *)malloc(sizeof(Queue));
     19 queue->front = NULL;
     20 queue->rear = NULL;
     21 return queue;
     22 }
     23 void addToQueue(Queue *queue, SDSVertex *node)
     24 {
     25 if (!(queue->rear)) {
     26 queue->rear = node;
     27 } else {
     28 queue->rear->next = node;
     29 queue->rear = node;
     30 }
     31 if (!(queue->front)) {
     32 queue->front = node;
     33 }
     34 }
     35 SDSVertex *deleteFromQueue(Queue *queue)
     36 {
     37 SDSVertex *temp = queue->front;
     38 if (temp) {
     39 queue->front = queue->front->next;
     40 return temp;
     41 } else {
     42 return NULL;
     43 }
     44 }
     45 int isEmptyQueue(Queue *queue)
     46 {
     47 if (queue->front == NULL) {
     48 return 1;
     49 } else {
     50 return 0;
     51 }
     52 }
     53 int BFS_SDS(int i)
     54 {
     55 SDSVertex *v = &v_sds[i];
     56 v->visited = true;
     57 int level = 0, count = 1;
     58 SDSVertex *last = v, *tail = NULL;
     59 Queue *queue = createQueue();
     60 addToQueue(queue, v);
     61 while (!isEmptyQueue(queue)) {
     62 SDSVertex *vertex = deleteFromQueue(queue);
     63 for (int j = 1; j <= pNum; j++) {
     64 int hasEdge = a[vertex->index][j];
     65 if (hasEdge && !v_sds[j].visited) {
     66 v_sds[j].visited = true;
     67 addToQueue(queue, &v_sds[j]); count++;
     68 tail = &v_sds[j];
     69 }
     70 }
     71 if (vertex == last) {
     72 level++; last = tail;
     73 }
     74 if (level == 6) {
     75 break;
     76 }
     77 }
     78 for (int i = 1; i <= pNum; i++) {
     79 v_sds[i].visited = false;
     80 v_sds[i].next = NULL;
     81 }
     82 return count;
     83 }
     84 int main()
     85 {
     86 scanf("%d %d", &pNum, &edgeNum);
     87 for (int i = 1; i <= edgeNum; i++) {
     88 int from = 0, to = 0;
     89 scanf("%d %d", &from, &to);
     90 a[from][to] = 1;
     91 a[to][from] = 1;
     92 }
     93 for (int i = 1; i <= pNum; i++) {
     94 v_sds[i].visited = false;
     95 v_sds[i].index = i;
     96 v_sds[i].next = NULL;
     97 }
     98 int count = -1;
     99 for (int i = 1; i <= pNum; i++) {
    100 count = BFS_SDS(i);
    101 printf("%d: %.2f%%
    ", i, count * 100.0 / pNum);
    102 }
    103 }

    3、运行结果:

  • 相关阅读:
    [转]JAVA程序执行顺序,你了解了吗:JAVA中执行顺序,JAVA中赋值顺序
    [转]浅谈Java中的equals和==
    [原创]java WEB学习笔记102:Spring学习---Spring Bean配置:bean配置方式(工厂方法(静态工厂方法 & 实例工厂方法)、FactoryBean) 全类名
    [原创]java WEB学习笔记101:Spring学习---Spring Bean配置:IOC容器中bean的声明周期,Bean 后置处理器
    C# 数组之List<T>
    C# 数组之ArrayList
    C# 数组之int[]
    reverse-XNUCA-babyfuscator
    reverse-daily(1)-audio_visual_receiver_code
    Python多线程和多进程谁更快?
  • 原文地址:https://www.cnblogs.com/vijozsoft/p/5066362.html
Copyright © 2020-2023  润新知