Как вычислить энтропию графа?
У меня есть набор случайно сгенерированных формальные графы, и я хотел бы вычислить энтропию каждого из них. Тот же вопрос в разных словах: у меня несколько сетей, и я хочу рассчитать информационное содержание каждой из них.
вот два источника, содержащие формальные определения графа entropy:
http://www.cs.washington.edu/homes/anuprao/pubs/CSE533Autumn2010/lecture4.pdf (документ PDF)
http://arxiv.org/abs/0711.4175v1
код, который я ищу, принимает график в качестве входных данных (как список ребер или матрицу смежности) и выводит несколько битов или другую меру информационного содержания.
потому что я не могу найти реализацию этого нигде, я собираюсь закодировать это с нуля на основе формальных определений. Если кто-то уже решил эту проблему и готов поделиться кодом, это будет дико оцененный.
3 ответов
в итоге я использовал разные статьи для определения энтропии графа:
информационная теория сложных сетей: об эволюции и архитектурных ограничениях
Р. В. подошва и С. Вальверде (2004)
и
энтропия сети на основе конфигурации топологии и ее вычисления в случайных сетях
Х. Б. Ван, Х. У. Ван И т. Чжоу
код для вычисления каждого из них приведен ниже. Код предполагает, что у вас есть неориентированный, невзвешенный граф без петель. Он принимает матрицу смежности в качестве входных данных и возвращает количество энтропии в битах. Он реализован в R и использует пакет sna.
graphEntropy <- function(adj, type="SoleValverde") {
if (type == "SoleValverde") {
return(graphEntropySoleValverde(adj))
}
else {
return(graphEntropyWang(adj))
}
}
graphEntropySoleValverde <- function(adj) {
# Calculate Sole & Valverde, 2004 graph entropy
# Uses Equations 1 and 4
# First we need the denominator of q(k)
# To get it we need the probability of each degree
# First get the number of nodes with each degree
existingDegrees = degree(adj)/2
maxDegree = nrow(adj) - 1
allDegrees = 0:maxDegree
degreeDist = matrix(0, 3, length(allDegrees)+1) # Need an extra zero prob degree for later calculations
degreeDist[1,] = 0:(maxDegree+1)
for(aDegree in allDegrees) {
degreeDist[2,aDegree+1] = sum(existingDegrees == aDegree)
}
# Calculate probability of each degree
for(aDegree in allDegrees) {
degreeDist[3,aDegree+1] = degreeDist[2,aDegree+1]/sum(degreeDist[2,])
}
# Sum of all degrees mult by their probability
sumkPk = 0
for(aDegree in allDegrees) {
sumkPk = sumkPk + degreeDist[2,aDegree+1] * degreeDist[3,aDegree+1]
}
# Equivalent is sum(degreeDist[2,] * degreeDist[3,])
# Now we have all the pieces we need to calculate graph entropy
graphEntropy = 0
for(aDegree in 1:maxDegree) {
q.of.k = ((aDegree + 1)*degreeDist[3,aDegree+2])/sumkPk
# 0 log2(0) is defined as zero
if (q.of.k != 0) {
graphEntropy = graphEntropy + -1 * q.of.k * log2(q.of.k)
}
}
return(graphEntropy)
}
graphEntropyWang <- function(adj) {
# Calculate Wang, 2008 graph entropy
# Uses Equation 14
# bigN is simply the number of nodes
# littleP is the link probability. That is the same as graph density calculated by sna with gden().
bigN = nrow(adj)
littleP = gden(adj)
graphEntropy = 0
if (littleP != 1 && littleP != 0) {
graphEntropy = -1 * .5 * bigN * (bigN - 1) * (littleP * log2(littleP) + (1-littleP) * log2(1-littleP))
}
return(graphEntropy)
}
Если у вас есть взвешенный график, хорошим началом будет сортировка и подсчет всех Весов. Затем вы можете использовать формулу-log (p)+log (2) (http://en.wikipedia.org/wiki/Binary_entropy_function) определить количество битов, необходимых для кода. Может быть, это не работает, потому что это двоичная функция энтропии?
можно использовать энтропия Кернера (=энтропия Шеннона, примененная к графу). Хорошим ориентиром для литературы является здесь. Обратите внимание, однако, что вычисление в целом NP-трудно (по глупой причине, что вам нужно искать все подмножества вершин).