====== NetsBM - blockmodeling based on Nets ======
wdir = "C:/Users/batagelj/work/projects/BM/py"
gdir = "c:/users/batagelj/work/python/graph/Nets"
ddir = "C:/Users/batagelj/work/projects/BM/data"
import sys, os, re, json
sys.path = [gdir]+sys.path; os.chdir(wdir)
from Nets import Network as N
import numpy as np
from copy import copy, deepcopy
from timeit import default_timer as timer
from datetime import datetime
def P(net,C,Types):
n = net._info['nNodes']; nC = Types.shape[0]; size = np.zeros(nC,dtype=int)
for i in C: size[i] += 1
dCnt = np.zeros(nC); Cnt = np.zeros((nC,nC))
# Sum = np.zeros((nC,nC)); rSum = np.zeros((nC,n)); cSum = np.zeros((nC,n))
rCnt = np.zeros((nC,n)); cCnt = np.zeros((nC,n))
rPos = np.zeros((nC,nC)); cPos = np.zeros((nC,nC))
error = np.zeros((nC,nC)); btype = np.zeros((nC,nC),dtype=int)
for a in net.links():
u,v,d,r,W = net.link(a); w = W['w']; p = u-1; q = v-1
Cnt[C[p],C[q]] += 1
rCnt[C[q],p] += 1; cCnt[C[p],q] += 1
if p==q: dCnt[C[p]] += 1
rB = (rCnt>0).astype(int); cB = (cCnt>0).astype(int)
for i in range(nC):
for s in range(n):
rPos[i,C[s]] += rB[i,s]; cPos[C[s],i] += cB[i,s]
for i in range(nC):
for j in range(nC):
err = np.inf; typ = XXX
if NUL in Types[i,j]:
ert = Cnt[i,j]
if i==j: ert += min(0,size[i]-2*dCnt[i])
if ert < err: err = ert; typ = NUL
if COM in Types[i,j]:
ert = size[i]*size[j] - Cnt[i,j]
if i==j: ert += min(0,2*dCnt[i]-size[i])
if ert < err: err = ert; typ = COM
if REG in Types[i,j]:
ert = (size[j]-cPos[i,j])*size[i] +\
(size[i]-rPos[i,j])*cPos[i,j]
if ert < err: err = ert; typ = REG
if RRE in Types[i,j]:
ert = (size[i]-rPos[i,j])*size[j]
if ert < err: err = ert; typ = RRE
if CRE in Types[i,j]:
ert = (size[j]-cPos[i,j])*size[i]
if ert < err: err = ert; typ = CRE
error[i,j] = err; btype[i,j] = typ
return (np.sum(error), error, btype)
def optimize(net,C,Types,minSize):
nC = Types.shape[0]; size = np.zeros(nC,dtype=int)
for i in C: size[i] += 1
if np.min(size) 50: print(k+1,j,Er)
else: print(k+1,j,Er,"\n C :",C,"\n C*:",R[0])
end = timer(); print("time:",end - start,"s")
if bad>0: print(bad,"bad initial partitions")
if found: return Rbest
ddir = "C:/Users/batagelj/work/Python/graph/Nets/BM/dat"
net = N.loadPajek(ddir+"/class.net"); net.Info()
XXX = 0; NUL = 1; COM = 2; REG = 3; RRE = 4; CRE = 5
rng = np.random.default_rng()
n = net._info['nNodes']; nC = 3
C0 = np.array([0]*3 + [1]*3 + [2]*9, dtype='I')
===== Regular BM =====
========== RESTART: C:/Users/batagelj/work/projects/BM/py/netsBM.py ==========
NODES: n = 15 mode = 1
ARCS: multirel = False
network: test
Test
simple= False directed= True org= 1 mode= 1 multirel= False temporal= False
nodes= 15 links= 56 arcs= 56 edges= 0
>>> Types = np.array([{NUL,COM,REG}]*(nC*nC),dtype='O').reshape(nC,nC)
>>> Reg = searchBM(500,minSize=2)
netsBM: 2020-08-15 00:09:39.810269
1 0 20.0
C : [2 2 0 1 0 1 1 2 2 1 2 2 1 2 2]
C*: [2 1 0 1 1 1 1 1 0 1 2 1 1 2 1]
3 2 19.0
C : [0 1 0 2 2 0 2 2 2 2 0 1 0 2 1]
C*: [0 1 2 2 2 2 1 2 2 2 0 1 2 1 1]
6 2 17.0
C : [1 2 2 2 2 0 1 1 0 0 1 0 2 1 2]
C*: [1 2 2 2 2 2 2 2 0 0 1 0 2 1 2]
11 1 15.0
C : [1 0 0 2 2 2 2 1 0 2 2 2 2 1 2]
C*: [1 2 2 2 2 2 2 2 2 2 0 2 2 1 0]
22 0 12.0
C : [0 2 0 1 2 1 0 2 1 2 2 0 1 2 0]
C*: [2 0 1 1 1 1 0 1 1 1 2 0 1 2 0]
97 0 11.0
C : [0 0 2 0 1 2 1 2 0 2 0 1 1 0 1]
C*: [0 1 2 2 1 2 2 2 2 2 0 1 1 0 1]
time: 101.36045880062589 s
16 bad initial partitions
>>> Reg
(array([0, 1, 2, 2, 1, 2, 2, 2, 2, 2, 0, 1, 1, 0, 1]),
11.0,
array([[0., 2., 8.],
[0., 1., 0.],
[0., 0., 0.]]),
array([[1, 1, 1],
[1, 1, 3],
[1, 3, 3]]))
>>>
{{vlado:work:pics:classgreg11.png?350}}
{{vlado:work:pics:classmreg11.png?300}}
===== Structural BM =====
>>> Types = np.array([{NUL,COM}]*(nC*nC),dtype='O').reshape(nC,nC)
>>> Rez = searchBM(500)
netsBM: 2020-08-15 00:12:05.699613
1 0 34.0
C : [0 2 1 2 2 0 0 2 0 1 1 2 0 1 0]
C*: [0 0 1 2 1 2 1 2 1 1 0 2 0 0 0]
6 2 28.0
C : [2 1 1 1 0 1 0 2 1 2 2 0 2 1 1]
C*: [1 1 0 2 1 2 0 1 0 0 1 2 1 1 1]
time: 127.35457458549575 s
2 bad initial partitions
>>> Rez
(array([1, 1, 0, 2, 1, 2, 0, 1, 0, 0, 1, 2, 1, 1, 1]),
28.0,
array([[2., 6., 0.],
[9., 4., 1.],
[0., 6., 0.]]),
array([[2, 1, 1],
[2, 1, 1],
[1, 1, 2]]))
>>>
{{vlado:work:pics:classgstr28.png?350}}
{{vlado:work:pics:classmstr28.png?300}}
====== To do ======
- add the normal form of partition (done, August 15, 2020)
- collect all different (locally) minimal solutions (done, August 15, 2020)
- include undirected simple networks (done, August 15, 2020)
See [[.:gbm|Generalized blockmodeling based on Nets]].