import platform
platform.platform()
platform.python_version()
import networkx as nx
nx.__version__
from pylab import *
%matplotlib inline
import DSTG
def is_regular(G):
vrhovi=list(G.nodes())
r=G.degree(vrhovi[0])
for v in vrhovi.__iter__():
if G.degree(v)!=r: return False
return True
G=nx.Graph()
G.add_nodes_from(range(1,9))
G
G1=nx.empty_graph(8)
G1
G.number_of_nodes()
len(G)
G.order()
G.__len__()
G.number_of_edges()
G.size()
nx.draw(G,with_labels=True)
nx.draw_circular(G,with_labels=True)
nx.draw_random(G,with_labels=True)
P=nx.petersen_graph()
print(nx.info(P))
P.number_of_nodes()
P.number_of_edges()
nx.draw(P,with_labels=True)
nx.draw_circular(P,with_labels=True)
nx.draw_random(P,with_labels=True)
nx.draw_spring(P,with_labels=True)
nx.draw(P,node_size=400,node_color='y',node_shape='s',width=3,edge_color='r',with_labels=True)
figure(figsize=[7,7])
poz=nx.shell_layout(P,[[5,6,7,8,9],[0,1,2,3,4]])
nx.draw(P,pos=poz,with_labels=True)
P.nodes()
P.edges()
P.degree()
is_regular(P)
figure(figsize=(6,4))
cP=nx.complement(P)
nx.draw_circular(cP,with_labels=True)
figure(figsize=(8,8))
lP=nx.line_graph(P)
nx.draw_circular(lP,node_size=800,font_size=10,with_labels=True)
Pmatrica = nx.adj_matrix(P)
Pmatrica
print(Pmatrica)
Pmatrica.todense()
print(Pmatrica.todense())
nx.to_pandas_adjacency(P,dtype=int)
P.adj
P.adjacency()
list(P.adjacency())
incidence_matrix(G, nodelist=None, edgelist=None, oriented=False, weight=None)
Pincm = nx.incidence_matrix(P)
Pincm
print(Pincm)
Pincm.todense()
print(Pincm.todense())
kubniGraf=nx.cubical_graph()
kubniGraf.number_of_nodes()
kubniGraf.number_of_edges()
nx.draw(kubniGraf,with_labels=True)
kubniGraf.nodes()
list(kubniGraf.nodes())
kubniGraf.edges()
list(kubniGraf.edges())
kubniGraf.degree()
dict(kubniGraf.degree())
is_regular(kubniGraf)
nx.draw(nx.complement(kubniGraf),with_labels=True)
figure(figsize=(8,8))
nx.draw_circular(nx.line_graph(kubniGraf),node_size=800,font_size=10,with_labels=True)
nx.line_graph(kubniGraf).nodes()
list(nx.line_graph(kubniGraf).nodes())
kG_mat = nx.adj_matrix(kubniGraf)
kG_mat
print(kG_mat)
kG_mat.todense()
print(kG_mat.todense())
nx.to_pandas_adjacency(kubniGraf,dtype=int)
kubniGraf.adj
list(kubniGraf.adjacency())
kG_inc = nx.incidence_matrix(kubniGraf)
kG_inc.todense()
K10=nx.complete_graph(10)
nx.draw_circular(K10,node_size=500,with_labels=True)
K10.number_of_nodes()
K10.number_of_edges()
K10.nodes()
bridovi potpunog grafa $K_{10}$
K10.edges()
DSTG.ispis(K10.edges(),80)
K10.degree()
is_regular(K10)
figure(figsize=(6,4))
nx.draw(nx.complement(K10),with_labels=True)
figure(figsize=(12,8))
nx.draw_circular(nx.line_graph(K10),node_size=100,font_size=10)
K10_mat = nx.adj_matrix(K10)
K10_mat
print(K10_mat.todense())
nx.to_pandas_adjacency(K10,dtype=int)
K10.adj
list(K10.adjacency())
K10_inc = nx.incidence_matrix(K10)
print(K10_inc.todense())
figure(figsize=(8,8))
nx.draw_circular(nx.complete_graph(25),node_size=10)
B23=nx.complete_bipartite_graph(2,3)
figure(figsize=(6,4))
nx.draw(B23,with_labels=True)
B23.number_of_nodes()
B23.number_of_edges()
B23.nodes()
B23.edges()
B23.degree()
is_regular(B23)
nx.draw_circular(nx.complement(B23),with_labels=True)
nx.draw_circular(nx.line_graph(B23),node_size=800,font_size=10,with_labels=True)
B23_mat = nx.adj_matrix(B23)
B23_mat
print(B23_mat.todense())
nx.to_pandas_adjacency(B23,dtype=int)
B23.adj
list(B23.adjacency())
B23_inc = nx.incidence_matrix(B23)
B23_inc
print(B23_inc.todense())
nx.draw(nx.hypercube_graph(3))
nx.draw(nx.hypercube_graph(4),node_size=50)
nx.draw(nx.hypercube_graph(5),node_size=50)
Uočite, ako niste zadovoljni niti jednim razmještajem vrhova koje networkx automatski izračuna, možete sami eksplicitno unijeti koordinate pojedinih vrhova kao rječnik pridružen varijabli "pos".
nx.draw(B23,pos={0:[2,1],1:[2,3],2:[0,0],3:[0,2],4:[0,4]},
node_color=[[1,0,0],[1,0,0],[0,0,1],[0,0,1],[0,0,1]],
node_size=[300,300,600,600,600],
edge_color=[[1,0,0],[1,0,0],[1,0,0],[0,0,1],[0,0,1],[0,1,0]],
labels={0:'A',1:'B',2:'C',3:'D',4:'E'})
figure(figsize=(12,8))
subplot(121)
title("Petersenov graf",fontsize=16)
poz=nx.shell_layout(P,[[5,6,7,8,9],[0,1,2,3,4]])
nx.draw(nx.petersen_graph(),pos=poz,with_labels=True)
subplot(122)
title("Inducirani podgraf sa skupom vrhova {0,1,2,3,4}",fontsize=16)
nx.draw(nx.subgraph(nx.petersen_graph(),[0,1,2,3,4]),pos=poz,with_labels=True)
figure(figsize=(12,8))
P=nx.petersen_graph()
poz=nx.shell_layout(P,[[5,6,7,8,9],[0,1,2,3,4]])
subplot(121)
title("Petersenov graf",fontsize=16)
nx.draw(P,pos=poz,with_labels=True)
subplot(122)
title("Petersenov graf bez vrhova 0,4,6,9",fontsize=16)
P.remove_nodes_from([0,4,6,9])
nx.draw(P,pos=poz,with_labels=True)
figure(figsize=(12,8))
P=nx.petersen_graph()
poz=nx.shell_layout(P,[[5,6,7,8,9],[0,1,2,3,4]])
subplot(121)
title("Petersenov graf",fontsize=16)
nx.draw(P,pos=poz,with_labels=True)
subplot(122)
title("Petersenov graf bez bridova (1,6),(7,9),(3,4),(0,5)",fontsize=16)
P.remove_edges_from([(1,6),(7,9),(3,4),(0,5)])
nx.draw(P,pos=poz,with_labels=True)
figure(figsize=(15,8))
C6=nx.cycle_graph(6)
subplot(131)
title("Zadani graf",fontsize=16)
nx.draw_circular(C6,with_labels=True)
subplot(132)
title("Dodani vrhovi b,o,k i bridovi (b,o),(k,0)",fontsize=16)
C6.add_nodes_from('bok')
C6.add_edges_from([('b','o'),('k',0)])
nx.draw_circular(C6,with_labels=True)
subplot(133)
title("Dodan ciklus 0-o-5-0",fontsize=16)
C6.add_cycle([0,'o',5])
nx.draw_circular(C6,with_labels=True)
figure(figsize=(12,8))
C8=nx.cycle_graph(8)
subplot(121)
title("Zadani graf",fontsize=16)
nx.draw_circular(C8,with_labels=True)
subplot(122)
title("Dodani put 1-3-5-7",fontsize=16)
C8.add_path([1,3,5,7])
nx.draw_circular(C8,with_labels=True)
figure(figsize=(12,8))
C8=nx.cycle_graph(8)
subplot(121)
title("Zadani graf",fontsize=16)
nx.draw_circular(C8,with_labels=True)
subplot(122)
title("Dodana zvijezda u graf",fontsize=16)
C8.add_star(['s',1,2,3,4,5,6,7])
poz2=nx.shell_layout(C8,[['s'],[0,1,2,3,4,5,6,7]])
nx.draw(C8,pos=poz2,with_labels=True)
(grafovi moraju imati disjunktne skupove vrhova)
G=nx.complete_graph(5)
H=nx.complete_bipartite_graph(2,3)
GuH=nx.union(G,H,rename=('g','h'))
figure(figsize=(15,8))
subplot(131)
title("G",fontsize=16)
nx.draw_circular(G,with_labels=True)
subplot(132)
title("H",fontsize=16)
nx.draw_circular(H,with_labels=True)
subplot(133)
title("Unija grafova G i H",fontsize=16)
nx.draw_circular(GuH,with_labels=True)
G=nx.complete_graph(5)
H=nx.complete_bipartite_graph(2,3)
GuH=nx.disjoint_union(G,H)
figure(figsize=(15,8))
subplot(131)
title("G",fontsize=16)
nx.draw_circular(G,with_labels=True)
subplot(132)
title("H",fontsize=16)
nx.draw_circular(H,with_labels=True)
subplot(133)
title("Unija grafova G i H",fontsize=16)
nx.draw_circular(GuH,with_labels=True)
(grafovi moraju imati jednake skupove vrhova)
G=nx.complete_bipartite_graph(5,5)
H=nx.petersen_graph()
GintH=nx.intersection(G,H)
pozG=dict([(x,[x//5,x%5]) for x in G.nodes()])
pozH=nx.shell_layout(H,[[5,6,7,8,9],[0,1,2,3,4]])
figure(figsize=(15,8))
subplot(131)
title("G",fontsize=16)
nx.draw(G,pos=pozG,with_labels=True)
subplot(132)
title("H",fontsize=16)
nx.draw(H,pos=pozH,with_labels=True)
subplot(133)
title("Presjek grafova G i H",fontsize=16)
nx.draw_circular(GintH,with_labels=True)
A=matrix([[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1]])
print(A)
G=nx.from_numpy_matrix(A)
G.nodes()
list(G.edges())
G.degree()
Uočite da se ne crtaju petlje. NetworkX nema napredne metode crtanja grafova. NetworkX je modul za napredani rad s grafovima, a pritom nudi neke metode za crtanje jednostavnih grafova (u kojima nema petlji i višestrukih bridova).
figure(figsize=(6,4))
nx.draw(G,with_labels=True)
Međutim, možemo NetworkX graf pretvoriti u GraphViz format. Pritom moramo imati instalirane python module za rad s GraphVizom. To su moduli pydot i pygraphviz.
G1=nx.nx_agraph.to_agraph(G)
GraphViz crta graf i sprema sliku u datoteku u radni direktorij. Varijabla "prog" može imati sljedeće vrijednosti: dot, neato, twopi, circo, fdp. Na temelju tih vrijednosti se određuje razmještaj vrhova.
G1.draw('Gd.png',prog='dot')
from IPython.core.display import Image
Image(filename='Gd.png')
GraphViz je moćan alat za crtanje grafova. Jasno, sada su nacrtane i petlje, a bridovi nisu nužno dužine, već i krivulje tako da sam prikaz grafa lijepo vizualno izgleda.
G1.draw('Gc.png',prog='circo')
Image(filename='Gc.png')
bridovi=[(0,0),(0,1),(0,1),(0,3),(0,3),(0,4),(1,1),
(1,2),(1,2),(1,4),(2,2),(2,3),(2,3),(2,4),(3,3),(3,4)]
Z=nx.from_edgelist(bridovi,create_using=nx.MultiGraph())
list(Z.edges())
Z.nodes()
Z.degree()
nx.draw(Z,with_labels=True)
Z1=nx.nx_agraph.to_agraph(Z)
Z1.draw('Z1.png',prog='circo')
Image(filename='Z1.png')
A=matrix([[0,1,0,1,1],[1,0,1,0,0],[0,1,0,0,1],[1,0,0,0,0],[1,0,1,0,0]])
B=matrix([[0,1,0,0,1],[1,0,0,1,0],[0,0,0,1,0],[0,1,1,0,1],[1,0,0,1,0]])
G1=nx.from_numpy_matrix(A)
G2=nx.from_numpy_matrix(B)
print(A)
print(B)
figure(figsize=(8,6))
subplot(121)
title("Graf $G_1$",fontsize=16)
nx.draw(G1,with_labels=True)
subplot(122)
title("Graf $G_2$",fontsize=16)
nx.draw(G2,with_labels=True)
nx.is_isomorphic(G1,G2)
GM=nx.algorithms.isomorphism.GraphMatcher(G1,G2)
GM.is_isomorphic()
nx.isomorphism.could_be_isomorphic(G1,G2)
GM.mapping
GM.core_1
GM.core_2
for u in GM.isomorphisms_iter():
print(u)
R1=nx.gnm_random_graph(15,30)
nx.draw_circular(R1,with_labels=True)
Naredba dense_gnm_random_graph je brža od naredbe gnm_random_graph ako generiramo gusti graf, tj. graf koji ima puno bridova s obzirom na broj vrhova.
R2=nx.dense_gnm_random_graph(15,85)
nx.draw_circular(R2,with_labels=True)
Jednostavni graf s $15$ vrhova može imati najviše $\binom{15}{2}=105$ bridova. Ako napišete više bridova, generirat će se samo potpuni graf s $15$ vrhova.
R3=nx.dense_gnm_random_graph(15,120)
R3.number_of_edges()
R4=nx.gnp_random_graph(15,0.3)
nx.draw_circular(R4,with_labels=True)
R5=nx.gnp_random_graph(15,0.8)
nx.draw_circular(R5,with_labels=True)
fast_gnp_random_graph bi trebao biti brži od gnp_random_graph kada je vjerojatnost kreiranja brida mala i kada je očekivani broj bridova mali.
R6=nx.fast_gnp_random_graph(15,0.3)
nx.draw_circular(R6,with_labels=True)
R7=nx.random_regular_graph(4,15)
nx.draw_circular(R7,with_labels=True)
B1=nx.algorithms.bipartite.gnmk_random_graph(5,3,12)
B1a=nx.nx_agraph.to_agraph(B1)
B1a.draw('B1.png',prog='dot')
Image(filename='B1.png')
B2=nx.algorithms.bipartite.random_graph(5,3,0.3)
B2a=nx.nx_agraph.to_agraph(B2)
B2a.draw('B2.png',prog='dot')
Image(filename='B2.png')
S1=nx.havel_hakimi_graph([4,3,3,2,2])
nx.draw_circular(S1,with_labels=True)
S2=nx.random_degree_sequence_graph([4,3,3,2,2])
nx.draw_circular(S2,with_labels=True)
nx.is_graphical([1,2,3,4,4])
No, postoji graf s nizom stupnjeva vrhova $1,2,3,4,4$. Jasno, taj graf nije jednostavan. Dolje je naveden samo jedan takav primjer grafa koji je kreiran na slučajni način.
S3=nx.configuration_model([1,2,3,4,4])
S3a=nx.nx_agraph.to_agraph(S3)
S3a.draw('S3.png',prog='circo')
Image(filename='S3.png')
Bipartitni graf sa zadanim nizovima stupnjeva vrhova po pojedinim biparticijama. Pazite, sume stupnjeva vrhova u obje biparticije moraju biti jednake da bi takav graf postojao.
S4=nx.algorithms.bipartite.havel_hakimi_graph([3,4,2,1],[2,3,3,2])
S4a=nx.nx_agraph.to_agraph(S4)
S4a.draw('S4.png',prog='dot')
Image(filename='S4.png')
S5=nx.algorithms.bipartite.configuration_model([3,4,2,1],[8,2])
S5a=nx.nx_agraph.to_agraph(S5)
S5a.draw('S5.png',prog='dot')
Image(filename='S5.png')
skup_grafova=nx.graph_atlas_g()
graf_3vrha=[]
for g in skup_grafova.__iter__():
if g.number_of_nodes()>3: break
if g.number_of_nodes()==3:
graf_3vrha.append(g)
len(graf_3vrha)
for i in range(1,5):
subplot(2,2,i,xticks=[], yticks=[])
nx.draw_circular(graf_3vrha[i-1],with_labels=True)
axis('on')
margins(x=0.1,y=0.1)
graf_4vrha=[]
for g in skup_grafova.__iter__():
if g.number_of_nodes()>4: break
if g.number_of_nodes()==4:
graf_4vrha.append(g)
len(graf_4vrha)
figure(figsize=(6,6))
for i in range(1,12):
subplot(4,3,i,xticks=[], yticks=[])
nx.draw_circular(graf_4vrha[i-1],with_labels=True)
axis('on')
margins(x=0.15,y=0.17)
graf_5vrha=[]
for g in skup_grafova.__iter__():
if g.number_of_nodes()>5: break
if g.number_of_nodes()==5:
graf_5vrha.append(g)
len(graf_5vrha)
figure(figsize=(8,8))
for i in range(1,35):
subplot(6,6,i,xticks=[], yticks=[])
nx.draw_circular(graf_5vrha[i-1],node_size=50)
axis('on')
margins(x=0.1,y=0.1)