import platform
platform.platform()
platform.python_version()
import networkx as nx
nx.__version__
from pylab import *
%matplotlib inline
import DSTG
from IPython.core.display import Image
P=nx.petersen_graph()
poz=nx.shell_layout(P,[[5,6,7,8,9],[0,1,2,3,4]])
nx.draw(P,pos=poz,with_labels=True)
nx.write_adjlist(P,"petersen.adjlist")
nx.write_edgelist(P,"petersen.edgelist")
nx.write_multiline_adjlist(P,"petersen.multiadjlist")
dat=open("petersen.adjlist",'r')
d1=dat.read()
dat.close()
dat=open("petersen.edgelist",'r')
d2=dat.read()
dat.close()
dat=open("petersen.multiadjlist",'r')
d3=dat.read()
dat.close()
print(d1)
print(d2)
print(d3)
Z1=nx.read_adjlist("petersen.adjlist")
Z2=nx.read_edgelist("petersen.edgelist")
Z3=nx.read_multiline_adjlist("petersen.multiadjlist")
Gornje funkcije imaju i neke dodatne parametre. Npr., create_using govori kakvu vrstu grafa treba napraviti (graf, multigraf, digraf, multidigraf).Po defaultu je create_using=nx.Graph()
Z1=nx.read_adjlist("petersen.adjlist",create_using=nx.Graph())
Z1
Z2
Z3
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())
nx.write_adjlist(Z,"multigraf.adjlist")
nx.write_edgelist(Z,"multigraf.edgelist")
nx.write_multiline_adjlist(Z,"multigraf.multiadjlist")
dat=open("multigraf.adjlist",'r')
m1=dat.read()
dat.close()
dat=open("multigraf.edgelist",'r')
m2=dat.read()
dat.close()
dat=open("multigraf.multiadjlist",'r')
m3=dat.read()
dat.close()
print(m1)
print(m2)
print(m3)
G1=nx.read_adjlist("multigraf.adjlist",create_using=nx.MultiGraph())
G1viz=nx.nx_agraph.to_agraph(G1)
G1viz.draw('G1.png',prog='dot')
Image(filename='G1.png')
graf1=nx.read_adjlist("graf1.adjlist",nodetype=int)
graf1.nodes()
datoteka1=open("graf1.adjlist")
print(datoteka1.read())
datoteka1.close()
pozicije1={1:(0,2),2:(0,0),3:(2,2),4:(1,1),5:(2,0),6:(3,1)}
nx.draw(graf1,pos=pozicije1,with_labels=True)
graf1str=nx.read_adjlist("graf1.adjlist")
graf1str.nodes()
pozicije1str={'1':(0,2),'2':(0,0),'3':(2,2),'4':(1,1),'5':(2,0),'6':(3,1)}
nx.draw(graf1str,pos=pozicije1str,with_labels=True)
graf2=nx.read_adjlist("graf2.adjlist",create_using=nx.MultiGraph(),nodetype=int)
graf2.nodes()
graf2.edges()
datoteka2=open("graf2.adjlist")
print(datoteka2.read())
datoteka2.close()
graf2viz=nx.nx_agraph.to_agraph(graf2)
graf2viz.draw('G2.png',prog='circo')
Image(filename='G2.png')
graf3=nx.read_adjlist("graf3.adjlist",nodetype=int)
datoteka3=open("graf3.adjlist")
print(datoteka3.read())
datoteka3.close()
pozicije3={1:(0,2),2:(2,2),3:(4,2),4:(4,0),5:(2,0),6:(0,0),7:(-0.5,1),8:(4.5,1)}
nx.draw(graf3,pos=pozicije3,with_labels=True)
graf1.number_of_edges(),graf2.number_of_edges(),graf3.number_of_edges()
def EmptyQ(G):
if G.number_of_edges()==0:
return True
else:
return False
EmptyQ(graf1),EmptyQ(graf2),EmptyQ(graf3)
graf1.number_of_selfloops(),graf2.number_of_selfloops(),graf3.number_of_selfloops()
graf1.is_multigraph(),graf2.is_multigraph(),graf3.is_multigraph()
graf1.is_directed(),graf2.is_directed(),graf3.is_directed()
nx.is_bipartite(graf1),nx.is_bipartite(graf2),nx.is_bipartite(graf3)
nx.is_bipartite(nx.cubical_graph())
nx.bipartite.sets(nx.cubical_graph())
skup=nx.bipartite.sets(nx.cubical_graph())
lista1=[x for x in skup[0]]
lista2=[x for x in skup[1]]
lista1,lista2
nx.is_connected(graf1),nx.is_connected(graf2),nx.is_connected(graf3)
nx.number_connected_components(graf1),nx.number_connected_components(graf2),nx.number_connected_components(graf3)
G=nx.complete_graph(5)
H=nx.complete_bipartite_graph(2,3)
U=nx.disjoint_union(G,H)
nx.draw_circular(U,with_labels=True)
nx.number_connected_components(U)
list(nx.connected_components(U))
list(nx.connected_components(graf1))
V=list(nx.connected_component_subgraphs(U))
nx.draw(V[0],with_labels=True)
nx.draw(V[1],with_labels=True)
def CompleteQ(G):
if G.number_of_selfloops()>0: return False
if len(set(G.edges()))!=G.number_of_edges(): return False
if G.number_of_edges()!=(G.number_of_nodes()**2-G.number_of_nodes())/2:
return False
else:
return True
CompleteQ(graf1),CompleteQ(graf2),CompleteQ(graf3)
CompleteQ(nx.petersen_graph()),CompleteQ(nx.complete_graph(8))
graf4=nx.read_adjlist("graf4.adjlist",create_using=nx.MultiGraph(),nodetype=int)
graf4viz=nx.nx_agraph.to_agraph(graf4)
graf4viz.draw('G4.png',prog='circo')
Image(filename='G4.png')
CompleteQ(graf4)
def SimpleQ(G):
if G.number_of_selfloops()>0: return False
if len(set(G.edges()))!=G.number_of_edges():
return False
else:
return True
SimpleQ(graf1),SimpleQ(graf2),SimpleQ(graf3),SimpleQ(graf4),SimpleQ(nx.petersen_graph())
list(dict(graf1.degree()).values())
def RegularQ(G):
if len(list(dict(graf1.degree()).values()))==1:
return (True,G.degree().values()[0])
else:
return False
RegularQ(graf1),RegularQ(graf2),RegularQ(graf3),RegularQ(graf4),RegularQ(nx.complete_graph(8)),RegularQ(nx.petersen_graph())
def AcyclicQ(G):
if G.number_of_edges()==G.number_of_nodes()-nx.number_connected_components(G):
return True
else:
return False
AcyclicQ(graf1), AcyclicQ(graf2), AcyclicQ(graf3), AcyclicQ(nx.path_graph(7))
def TreeQ(G):
if nx.number_connected_components(G)==1 and G.number_of_edges()==G.number_of_nodes()-1:
return True
else:
return False
TreeQ(graf1),TreeQ(graf2),TreeQ(graf3),TreeQ(nx.star_graph(5))
nx.is_eulerian(graf1), nx.is_eulerian(graf2), nx.is_eulerian(graf3)
nx.is_eulerian(nx.complete_graph(11)), nx.is_eulerian(nx.complete_graph(10))
DSTG.ispis(list(nx.eulerian_circuit(graf3)),80)
list(graf1.neighbors(2))
[n for n in graf1.neighbors(2)]
list(graf3.neighbors(4))
[n for n in graf3.neighbors(4)]
nx.shortest_path_length(graf2,3,1)
nx.shortest_path_length(graf2,2,5)
nx.shortest_path(graf2,3,1)
nx.shortest_path(graf2,2,5)
nx.shortest_path(graf3,1,7)
nx.shortest_path_length(graf2,2)
nx.shortest_path_length(graf2,4)
nx.shortest_path_length(graf3,1)
nx.shortest_path(graf2,2)
nx.shortest_path(graf2,4)
nx.shortest_path(graf3,1)
nx.single_source_shortest_path(graf2,4)
list(nx.shortest_path_length(graf1))
list(nx.shortest_path_length(graf2))
list(nx.shortest_path_length(graf3))
nx.shortest_path(graf1)
nx.shortest_path(graf2)
nx.shortest_path(graf3)
nx.eccentricity(graf1)
nx.eccentricity(graf2)
nx.eccentricity(graf3)
nx.eccentricity(graf2,1)
nx.radius(graf1)
nx.radius(graf2)
nx.radius(graf3)
nx.diameter(graf1)
nx.diameter(graf2)
nx.diameter(graf3)
DSTG.struk(graf1)
DSTG.struk(graf2)
DSTG.struk(graf3)
Ovdje je dana samo naivna implementacija koja daje sve rezne bridove grafa. Jednostavno se prolazi kroz sve bridove grafa i ako brisanjem brida novi graf ima više komponenata povezanosti od početnog grafa, tada je taj obrisani brid rezni brid. Kasnije ćemo dati efikasniju implementaciju koja ne prolazi kroz sve bridove grafa jer se koristi činjenica da je neki brid u povezanom grafu rezni ako i samo ako pripada svakom razapinjućem stablu tog grafa. Za male grafove je i ova naivna implementacija zadovoljavajuća.
Postoji i gotova naredba u NetworkX modulu koja daje sve rezne bridove u jednostavnom grafu.
def rezni_bridovi(G):
rezni=[]
for brid in G.edges():
graf=G.copy()
graf.remove_edge(*brid)
if nx.number_connected_components(graf)>nx.number_connected_components(G):
rezni.append(brid)
return rezni
rezni_bridovi(graf1)
list(nx.algorithms.bridges(graf1))
rezni_bridovi(graf2)
rezni_bridovi(graf3)
list(nx.algorithms.bridges(graf3))
koliko najmanje bridova treba ukloniti iz grafa da on postane nepovezan
DSTG.minimum_edge_cut(graf1)
nx.edge_connectivity(graf1)
bridovi1 = nx.minimum_edge_cut(graf1)
bridovi1
G1 = graf1.copy()
G1.remove_edges_from(bridovi1)
list(nx.connected_components(G1))
DSTG.minimum_edge_cut(graf2)
nx.edge_connectivity(graf2)
nx.minimum_edge_cut(graf2)
DSTG.minimum_edge_cut(graf3)
nx.edge_connectivity(graf3)
nx.minimum_edge_cut(graf3)
G3 = graf3.copy()
G3.remove_edges_from([(1,2),(6,5)])
list(nx.connected_components(G3))
koliko najmanje vrhova treba ukloniti iz grafa da on postane nepovezan
nx.node_connectivity(graf1)
nx.minimum_node_cut(graf1)
list(nx.all_node_cuts(graf1))
list(nx.biconnected_components(graf1))
nx.node_connectivity(graf2)
list(nx.all_node_cuts(graf2))
list(nx.biconnected_components(graf2))
nx.node_connectivity(graf3)
nx.minimum_node_cut(graf2)
list(nx.all_node_cuts(graf3))
list(nx.biconnected_components(graf3))
Zadana je matrica susjedstva $A=\begin{bmatrix}1&2&1&0\\ 2&0&1&0\\ 1&1&0&0\\ 0&0&0&0\end{bmatrix}$, čiji su vrhovi redom $v_1, v_2, v_3, v_4$.
A=np.matrix([[1,2,1,0],[2,0,1,0],[1,1,0,0],[0,0,0,0]])
A1=np.matrix([[1,1,1,0],[1,0,1,0],[0,0,0,0],[0,0,0,0]])
G=nx.MultiGraph(A1)
H=nx.relabel_nodes(G,{0:'v1',1:'v2',2:'v3',3:'v4'})
H.number_of_selfloops()
list(H.selfloop_edges())
H.degree()
Hviz=nx.nx_agraph.to_agraph(H)
Hviz.draw('H.png',prog='circo')
Image(filename='H.png')
print(A**2)
(A**2)[0,1]
(A**2)[0,3]
print(A**3)
(A**3)[0,1]
(A**3)[0,3]
Ovdje je pokazano kako na lagani način možemo generirati graf kojim se modelira problem konjićeve ture na $m\times n$ ploči. Vi možete ići korak dalje i implementirati neki algoritam koji će u zadanom grafu pronaći Hamiltonov ciklus, ukoliko je zadani graf Hamiltonov.
import itertools
def konjic_skok(m,n):
vrhovi=list(itertools.product(range(1,m+1),range(1,n+1)))
bridovi=[(i,j) for i in vrhovi for j in vrhovi if (abs(i[0]-j[0])==1 and abs(i[1]-j[1])==2) or
(abs(i[0]-j[0])==2 and abs(i[1]-j[1])==1)]
G=nx.Graph()
G.add_nodes_from(vrhovi)
G.add_edges_from(bridovi)
return G
def pozicije_konjic(m,n):
pozicije={}
for i in range(1,m+1):
for j in range(1,n+1):
pozicije[(i,j)]=(i,j)
return pozicije
figure(figsize=(7,5))
nx.draw(konjic_skok(3,3),pos=pozicije_konjic(3,3),node_size=1100,node_color='cyan',with_labels=True)
figure(figsize=(8,8))
nx.draw(konjic_skok(8,8),pos=pozicije_konjic(8,8),node_size=300,node_color='yellow',edgecolors='black')
figure(figsize=(12,10))
nx.draw(konjic_skok(15,12),pos=pozicije_konjic(15,12),node_size=200,node_color='yellow',edgecolors='black')