关于中介中心性--一个不注重实现效率但是易于理解的个人实现

    首先,中介中心性是个啥?它是一个对于图中顶点重要程度的度量标准。那么它度量哪个方面的重要程度呢?

    我们可以使用身边社交网络来做一个例子。这个有点像是我们身边那种社交达人,我们认识的不少朋友可能都是通过他/她认识的,这个人起到了中介的作用。那么这个人的中介中心性就是很高的。

    严格意义上来表述,中介中心性指的是一个结点担任其它两个结点之间最短路的桥梁的次数。一个结点充当“中介”的次数越高,它的中介中心度就越大。如果要考虑标准化的问题,可以用一个结点承担最短路桥梁的次数除以所有的路径数量。这个就是什么是中介中心性,计算一个节点的介于中心性的方式就是对于这个图中的任意两个其他顶点,用这个结点承担这两个顶点间最短路桥梁的次数除以所有的路径数量,然后将这些所有的任意两个顶点组合计算出的值,求和,就是最后的结果。

    怎么说呢,当时遇到这个问题第一感觉就是,说起来计算过程挺清晰的,但是对于如何实现完全手足无措。

    这里首先要解决的问题是,我们虽然都熟练掌握Dijkstra算法和Floyd算法,可以计算任意两点的最短路径的长度,但是计算最短路径的条数并不会。。。

    我们可以根据一个我们很容易发现的事实设计出一个可行的算法,当然这个算法的实现效率不够高,但是它足够易于理解。

    首先是有这样一个关系。对于任意的两个顶点u,v,这两个顶点的一条最短路径经过了顶点a,b,c。。。那么从u到v的最短路径的条数,等于:u到a的最短路径的条数乘以a到v的最短路径的条数,u到b的最短路径的条数乘以b到v的最短路径的条数,u到b的最短路径的条数乘以b到v的最短路径的条数。。。以上这些所有值之和。

    这个关系应该是很容易理解的,严格的数学证明不是我擅长的东西,我只能说显而易见它是对的。

    那么接下来的实现就很简单了啊,很容易发现根据我们找到的这个基本的性质,我们只要求出几个原子的点对之间的最短路径的条数,那么就可以通过不断地合并求出任意的两个点对之间的最短路径的条数。这本质上是一个分治策略的实现,同时我们需要设计出好的用于存储每一步的计算结果的动态规划的数据结构。最终得到的代码如下:

    

/**
   * 用于计算一个图某顶点的betweennessCentrality.
   * @param g 待计算的图,它必须是一个非空的图.
   * @param v 待计算的图g中的顶点,它必须是图g中存在的一个顶点.
   * @return 一个正的浮点数,它表示待计算的图g中顶点v的betweennessCentrality.
   */
  public static double betweennessCentrality(Graph<Vertex, Edge> g, Vertex v) {
    double num = 0;
    List<Vertex> myListV = new ArrayList<Vertex>();
    for (Vertex mv : g.vertices()) {
      myListV.add(mv);
    }
    int n = myListV.size();
    double[][] dm = new double[n][n];
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        dm[i][j] = 1000;
      }
    }
    for (int i = 0; i < n; i++) {
      dm[i][i] = 0;
    }
    List<Edge> myListE = new ArrayList<Edge>();
    for (Edge me : g.edges()) {
      if (!(me instanceof HyperEdge)) {
        myListE.add(me);
      }
    }
    for (Edge me : myListE) {
      int a = myListV.indexOf(me.getVertices().get(0));
      int b = myListV.indexOf(me.getVertices().get(1));
      if (me instanceof DirectedEdge) {
        dm[a][b] = 1;
        dm[b][a] = 1;
      }
      if (me instanceof UndirectedEdge) {
        dm[a][b] = 1;
        dm[b][a] = 1;
      }
    }
    int[][] nb = new int[n][n];
    for (int i = 0; i < n; i++) {
      int[] notem = new int[n];
      int[] numm = new int[n];
      for (int ii = 0; ii < n; ii++) {
        notem[ii] = -1;
        numm[ii] = 0;
      }
      notem[i] = 0;
      numm[i] = 1;
      for (int j = 0; j < n - 1; j++) {
        for (int ii = 0; ii < n; ii++) {
          for (int jj = 0; jj < n; jj++) {
            if (notem[ii] == j && (notem[jj] == -1 || notem[jj] > j) && dm[ii][jj] == 1) {
              notem[jj] = j + 1;
              numm[jj] = numm[jj] + numm[ii];
            }
          }
        }
      }
      for (int j = 0; j < n; j++) {
        nb[i][j] = numm[j];
      }
    }
    int c = myListV.indexOf(v);
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < i; j++) {
        if (i != j && i != c && j != c) {
          num = num + nb[i][c] * nb[c][j] / nb[i][j];
        }
      }
    }
    return num;
  }

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BSP(Bulk Synchronous Parallel)是一种并行计算模型,在这个模型下,计算被划分成多个超级步骤,每个超级步骤包含若干个并行计算任务。加权中介中心性算法可以通过BSP模型来实现,具体步骤如下: 1. 初始时,将图分成若干个数据块,每个数据块包含若干个节点和边。每个任务只处理自己所负责的数据块。 2. 在第一步中,每个任务计算出自己负责的节点到其他节点的最短路径。可以使用Dijkstra算法或Bellman-Ford算法实现。同时,每个任务统计出自己负责的节点对其他节点的最短路径数量。 3. 在第二步中,每个任务将自己的结果发送给其它任务,以便进行全局汇总。每个任务将自己负责的节点对其他节点的最短路径数量发送给其它任务,并接收其它任务发送过来的结果。每个任务接收到其它任务的结果后,将其结果合并到自己的结果中。 4. 在第三步中,每个任务计算出自己负责的节点的加权中介中心性。具体计算方法为,对于每个节点v,计算所有最短路径经过v的节点对(v, w)的贡献度,贡献度的计算公式为:`C(v, w) = (sigma(v, w) / sigma) * (1 + delta(w, v)) * w(v, w)`,其中sigma(v, w)表示节点v到节点w的最短路径数量,sigma表示所有最短路径的数量,delta(w, v)表示从节点w开始,到节点v的最短路径经过的节点的介数中心性之和,w(v, w)表示节点v到节点w之间的边权重。 5. 在第四步中,每个任务将自己计算出的结果发送给其它任务,以便进行全局汇总。每个任务将自己负责的节点的加权中介中心性发送给其它任务,并接收其它任务发送过来的结果。每个任务接收到其它任务的结果后,将其结果合并到自己的结果中。 6. 最后,所有任务将自己的结果汇总,得到图的全局加权中介中心性。 需要注意的是,在BSP模型中,每个超级步骤之间都需要进行同步,以保证各个任务的计算结果是一致的。同步过程可以使用Barrier或Gather/Scatter等技术来实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值