使用Barabási-Albert模型计算和难以理解的无标度网络

时间:2018-08-18 22:43:01

标签: c++ r graph igraph

我正在尝试实现一种算法,用于生成Barabási-Albert (BA) model之后的图形。在此模型下,度分布遵循幂律:

P(k)〜k ^-λ

λ等于3的地方。

为简单起见,我将集中在我使用var query = {'_id': id}; var inc = {'$inc':{'threads.$[t].' + [numberShift] + '.services.$[s].logInCounter':newValCounter}}; var arrayFilters = {arrayFilters: [{'t.number': tNumber, 's.name':name}]}; Item.findOneAndUpdate(query, inc, arrayFilters); 函数的R代码上。但是,我得到的网络带有λ!=3。似乎这是一个广泛涉及的主题(example question 1eq2eq3),但我一直找不到令人满意的解决方案。

在R中,我使用igraph函数按照BA模型生成图。在下面的可复制示例中,我设置了

igraph:::sample_pa

该图实际上似乎是无标度的,给出 gamma = 0.72±0.21 的阶为100,而 gamma = 0.68±0.24 的阶为10,000,相似的结果也有所不同参数 m 。但是该指数明显不同于预期的gamma = 3。

实际上,我试图用另一种语言(C ++,请参见下面的代码)实现此模型,但是我得到的指数小于3的结果相似。因此,我想知道这是否是对BA模型的常见误解或先前符合幂定律分布的计算中存在一些错误,这与通常期望的BA模型的正常行为相反。

如果有人对C ++感兴趣或更加熟悉,请参阅下面的附录。

附录:C ++代码 为了理解下面的代码,假设一个对象类# Initialize set.seed(1234) order = 100 v_degrees = vector() for (i in 1:10000) { g <- sample_pa(order, power=3, m=8) # Get degree distribution d = degree(g, mode="all") dd = degree_distribution(g, mode="all", cumulative=FALSE) d = 1:max(d) probability = dd[-1] nonzero.position = which(probability !=0) probability = probability[nonzero.position] d = d[nonzero.position] # Fit power law distribution and get gamma exponent reg = lm (log(probability) ~ log(d)) cozf = coef(reg) power.law.fit = function(x) exp(cozf[[1]] + cozf[[2]] * log(x)) gamma = -cozf[[2]] v_degrees[i] = gamma } 和一个Graph函数在作为参数传递的两个顶点之间创建了一条边。下面,我给出两个相关功能的代码 BA_step build_BA

BA_step

connect

build_BA

void Graph::BA_step (int ID, int m, std::vector<double>& freqs) {
  std::vector<int> connect_history;
  vertices.push_back(ID);

  // Connect node ID to a random node i with pi ~ ki / sum kj
  while (connect_history.size() < m) {
      double U (sample_prob()); // gets a value in the range [0,1)
      int index (freqs[freqs.size()-1]);
      for (int i(0); i<freqs.size(); ++i) {
          if (U<=freqs[i]/index && !is_in(connect_history, i)) { // is_in checks if i exists in connect_history
              connect(ID, i);
              connect_history.push_back(i);
              break;
          }
      }
  }

  // Update vector of absolute edge frequencies
  for (int i(0); i<connect_history.size(); ++i) {
      int index (connect_history[i]);
      for (int j(index); j<freqs.size(); ++j) {
          ++freqs[j];
      }
  }
  freqs.push_back(m+freqs[freqs.size()-1]);
  }

1 个答案:

答案 0 :(得分:1)

两件事可能会有所帮助:

sample_pa参数以获得指数alpha = 3

确实是power = 1m = 1(请在该维基百科文章中对照igraph :: sample_pa文档检查定义--- power参数并不表示力量的程度,法律分布)。

功率定律很难估计

仅在度数分布上运行OLS / LM即可为您提供接近于0而不是3的指数(换句话说,被低估了)。相反,如果您使用igraph::power_law_fit较高的xmin命令,则会得到接近3的答案。请查看Aaron Clauset's page and publications以获取有关估计功率定律的更多信息。确实,您需要为每个度分布估计一个最佳x-min。

有些代码会更好一些:

library(igraph)
set.seed(1234)
order = 10000
v_degrees = vector()
for (i in 1:100) {
  g <- sample_pa(order, power = 1, m = 1)
  d <- degree(g, mode="all")
  v_degrees[i] <- fit_power_law(d, ceiling(mean(d))+100) %>% .$alpha
}
v_degrees %>% summary()
##   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##  2.646   2.806   2.864   2.873   2.939   3.120

请注意,我组成了要使用的x分钟(ceiling(mean(d))+100)。进行更改将改变您的答案。