import sage.misc.banner
banner()
prazan graf s nula vrhova (pazite, prema našoj definiciji graf mora imati barem jedan vrh). Ovdje je uveden i graf s nula vrhova zbog jednostavnije konstrukcije kompliciranijih grafova.
G=graphs.EmptyGraph()
G
broj vrhova i bridova
G.num_verts()
G.num_edges()
vrhovi i bridovi
G.vertices()
G.edges()
G=Graph(5)
G.show(figsize=[5,3])
G.show(layout="circular",figsize=[3,3])
drukčije oznake vrhova
H=Graph([['a','b','c','d','e'], lambda i,j:False])
H.show(layout="circular",figsize=[3,3])
bez oznaka vrhova i željena veličina vrha i boje vrha
H.show(vertex_labels=False,layout="circular",vertex_size=50,vertex_color="yellow",figsize=[3,3])
H.show(layout="circular",vertex_color={"yellow":['a','d'],"red":['b'],"green":['c','e']},figsize=[3,3])
broj vrhova i bridova
H.num_verts()
H.num_edges()
vrhovi i bridovi
H.vertices()
H.edges()
K23=graphs.CompleteBipartiteGraph(2,3)
K23
K23.show()
broj vrhova i bridova
K23.num_verts()
K23.num_edges()
Vrhovi i bridovi
K23.vertices()
K23.edges()
K23.edges(labels=False)
stupnjevi vrhova
K23.degree()
K23.degree(labels=True)
K23.degree(3)
ispitivanje regularnosti
K23.is_regular()
matrica susjedstva
K23.adjacency_matrix()
matrica incidencije
K23.incidence_matrix()
K33=graphs.CompleteBipartiteGraph(3,3)
K33
K33.show()
broj vrhova i bridova
K33.num_verts()
K33.num_edges()
vrhovi i bridovi
K33.vertices()
K33.edges(labels=False)
stupnjevi vrhova
K33.degree()
K33.degree(labels=True)
K33.degree(4)
ispitivanje regularnosti
K33.is_regular()
matrica susjedstva
K33.adjacency_matrix()
matrica incidencije
K33.incidence_matrix()
K43=graphs.CompleteBipartiteGraph(4,3)
K43
K43.show()
broj vrhova i bridova
K43.num_verts()
K43.num_edges()
vrhovi i bridovi
K43.vertices()
K43.edges(labels=False)
stupnjevi vrhova
K43.degree()
K43.degree(labels=True)
K43.degree(2)
ispitivanje regularnosti
K43.is_regular()
matrica susjedstva
K43.adjacency_matrix()
matrica incidencije
K43.incidence_matrix()
P=graphs.PetersenGraph()
P
P.show(figsize=[4,4])
broj vrhova i bridova
P.num_verts()
P.num_edges()
vrhovi i bridovi
P.vertices()
P.edges(labels=False)
stupnjevi vrhova
P.degree()
P.degree(labels=True)
ispitivanje regularnosti
P.is_regular()
matrica susjedstva
P.adjacency_matrix()
matrica incidencije
P.incidence_matrix()
Kub=graphs.CubeGraph(3)
Kub.show(vertex_size=500,figsize=(4.5,4.5),layout="spring")
broj vrhova i bridova
Kub.num_verts()
Kub.num_edges()
vrhovi i bridovi
Kub.vertices()
Kub.edges(labels=False)
stupnjevi vrhova
Kub.degree()
Kub.degree(labels=True)
Kub.degree('001')
ispitivanje regularnosti
Kub.is_regular()
matrica susjedstva
Kub.adjacency_matrix()
matrica incidencije
Kub.incidence_matrix()
K5=graphs.CompleteGraph(5)
K5
K5.show()
broj vrhova i bridova
K5.num_verts()
K5.num_edges()
vrhovi i bridovi
K5.vertices()
K5.edges(labels=False)
stupnjevi vrhova
K5.degree()
K5.degree(labels=True)
ispitivanje regularnosti
K5.is_regular()
matrica susjedstva
K5.adjacency_matrix()
matrica incidencije
K5.incidence_matrix()
lista=[]
for i in range(1,20):
lista.append(graphs.CompleteGraph(i))
graphs_list.to_graphics_array(lista).show(figsize=[8,8])
graphs.CompleteGraph(25).show()
graphs.CompleteGraph(25).show(vertex_size=10,vertex_labels=False)
Kub4=graphs.CubeGraph(4)
Kub4
Kub4.show(vertex_size=400,figsize=(6,6),layout="spring")
broj vrhova i bridova
Kub4.num_verts()
Kub4.num_edges()
vrhovi i bridovi
Kub4.vertices()
Kub4.edges(labels=False)
stupnjevi vrhova
Kub4.degree()
Kub4.degree(labels=True)
Kub4.degree('1101')
ispitivanje regularnosti
Kub4.is_regular()
matrica susjedstva
Kub4.adjacency_matrix()
matrica incidencije
Kub4.incidence_matrix()
još nekoliko kocki u višim dimenzijama
graphs.CubeGraph(5).show(vertex_labels=False,vertex_size=10,figsize=(5,5),layout="spring")
graphs.CubeGraph(6).show(vertex_labels=False,vertex_size=10,figsize=(5,5),layout="spring")
graphs.CubeGraph(7).show(vertex_labels=False,vertex_size=10,figsize=(5,5),layout="spring")
komplement potpunog grafa $K_4$
K4=graphs.CompleteGraph(4)
K4.complement()
K4.complement().show(figsize=[3,3])
komplement Petersenovog grafa
Petersenov graf je već ranije spremljen u varijablu P
P.complement().show()
komplement potpunog bipartitnog grafa $K_{2,3}$
K23.complement().show(layout="spring",graph_border=True)
linijski graf potpunog grafa $K_4$
K4.line_graph().show(layout="circular")
K4.line_graph(labels=False).show(layout="circular",vertex_size=800,xmin=-1,xmax=1,ymin=-1.1,ymax=1.1)
linijski graf Petersenovog grafa
P.line_graph(labels=False).show(layout="spring",vertex_size=200)
P.line_graph(labels=False).show(layout="circular",vertex_size=500)
linijski graf poptunog bipartitnog grafa $K_{2,3}$
K23.line_graph(labels=False).show(vertex_size=800,graph_border=True)
linijski graf kubnog grafa
Kub.line_graph(labels=False).show()
Kub.line_graph().show(vertex_labels=False)
inducirani podgrafovi
podgraf1=K23.subgraph(vertices=[0,2,3,4],algorithm='add')
gr=graphics_array([K23.plot(graph_border=True),podgraf1.plot(graph_border=True)])
gr.show(figsize=[8,6])
podgraf2=P.subgraph(vertices=[0,2,3,5,7,9],algorithm='add')
podgraf3=P.subgraph(vertices=[0,2,3,5,9],algorithm='add')
gr2=graphics_array([P.plot(graph_border=True),podgraf2.plot(graph_border=True),podgraf3.plot(graph_border=True)])
gr2.show(figsize=[10,6])
brisanje vrhova
K23=graphs.CompleteBipartiteGraph(2,3)
K23_1=graphs.CompleteBipartiteGraph(2,3)
K23_1.delete_vertex(0)
K23_2=graphs.CompleteBipartiteGraph(2,3)
K23_2.delete_vertices([0,3])
gr3=graphics_array([K23.plot(graph_border=True),K23_1.plot(graph_border=True),K23_2.plot(graph_border=True)])
gr3.show(figsize=[10,6])
P=graphs.PetersenGraph()
P1=graphs.PetersenGraph()
P1.delete_vertex(9)
P2=graphs.PetersenGraph()
P2.delete_vertices([0,1,2,3,4])
gr4=graphics_array([P.plot(graph_border=True),P1.plot(graph_border=True),P2.plot(graph_border=True)])
gr4.show(figsize=[10,6])
brisanje bridova
K23=graphs.CompleteBipartiteGraph(2,3)
K23_1=graphs.CompleteBipartiteGraph(2,3)
K23_1.delete_edge(1,3)
K23_2=graphs.CompleteBipartiteGraph(2,3)
K23_2.delete_edges([(0,3),(1,2)])
gr5=graphics_array([K23.plot(graph_border=True),K23_1.plot(graph_border=True),K23_2.plot(graph_border=True)])
gr5.show(figsize=[10,6])
P=graphs.PetersenGraph()
P1=graphs.PetersenGraph()
P1.delete_edge(0,5)
P2=graphs.PetersenGraph()
P2.delete_edges([(0,5),(1,6),(2,7),(3,8),(4,9)])
gr6=graphics_array([P.plot(graph_border=True),P1.plot(graph_border=True),P2.plot(graph_border=True)])
gr6.show(figsize=[10,6])
proizvoljni podgrafovi
podgraf4=P.subgraph(vertices=range(10),edges=[(0,5),(1,6),(2,7),(3,8),(4,9)],algorithm='add')
podgraf5=P.subgraph(vertices=[5,6,7,8,9],edges=[(6,9),(5,7),(5,8)],algorithm='add')
gr7=graphics_array([P.plot(graph_border=True),podgraf4.plot(graph_border=True),podgraf5.plot(graph_border=True)])
gr7.show(figsize=[10,6])
random inducirani podgraf
ran1=P.random_subgraph(0.3)
ran2=P.random_subgraph(0.7)
gr8=graphics_array([P.plot(graph_border=True),ran1.plot(graph_border=True),ran2.plot(graph_border=True)])
gr8.show(figsize=[10,6])
unija grafova
unija=P.union(K23)
gr9=graphics_array([P.plot(graph_border=True),K23.plot(graph_border=True),unija.plot(graph_border=True)])
gr9.show(figsize=[10,6])
disjunktna unija grafova
dis_unija=P.disjoint_union(K23)
gr10=graphics_array([P.plot(graph_border=True),K23.plot(graph_border=True),dis_unija.plot(graph_border=True,layout="circular")])
gr10.show(figsize=[14,7])
Graf $G$ zadan je matricom susjedstva
$$A=\begin{bmatrix}1&1&1&1\\ 1&1&1&1\\ 1&1&1&1\\ 1&1&1&1\end{bmatrix}.$$Nacrtajte graf $G$, odredite stupnjeve njegovih vrhova, matricu incidencije i provjerite da li je regularan i jednostavni.
definicija i prikaz grafa $G$
G=Graph(matrix([[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1]]),loops=True)
G.show(graph_border=True)
stupnjevi vrhova
G.degree(labels=True)
graf $G$ je regularan
G.is_regular()
graf $G$ nije jednostavan
G.to_simple()==G
matrica incidencije
G.incidence_matrix()
Graf $G$ zadan je matricom susjedstva
$$A=\begin{bmatrix}1&2&0&2&1\\ 2&1&2&0&1\\ 0&2&1&2&1\\ 2&0&2&1&1\\ 1&1&1&1&0\end{bmatrix}.$$Nacrtajte graf $G$, odredite stupnjeve njegovih vrhova, matricu incidencije i provjerite da li je regularan i jednostavni.
definicija i prikaz grafa $G$
G=Graph(matrix([[1,2,0,2,1],[2,1,2,0,1],[0,2,1,2,1],[2,0,2,1,1],[1,1,1,1,0]]))
G.show(graph_border=True,pos={0:[0,2],1:[2,2],2:[2,0],3:[0,0],4:[1,1]})
stupnjevi vrhova
G.degree(labels=True)
graf $G$ nije regularan
G.is_regular()
Graf $G$ nije jednostavan
G.to_simple()==G
matrica incidencije
G.incidence_matrix()
Zadani su grafovi
graf1=Graph({'v1':['v2','v4','v5'],'v2':['v3'],'v3':['v5'],'v4':[],'v5':[]})
graf2=Graph({'u1':['u2','u5'],'u2':['u4'],'u3':['u4'],'u4':['u5'],'u5':[]})
matrica1=graf1.adjacency_matrix()
graf1.show(graph_border=True)
matrica2=graf2.adjacency_matrix()
grafovi su izomorfni
graf1.is_isomorphic(graf2)
dobivanje izomorfizma
graf1.is_isomorphic(graf2,certificate=True)
graf1=Graph({'v1':['v2','v4','v5'],'v2':['v3'],'v3':['v5'],'v4':[],'v5':[]})
graf2=Graph({'u1':['u2','u5'],'u2':['u4'],'u3':['u4'],'u4':['u5'],'u5':[]})
G1=graf1.networkx_graph()
G2=graf2.networkx_graph()
type(graf1),type(graf2)
type(G1),type(G2)
G1.nodes(),G2.nodes()
import networkx as nx
nx.is_isomorphic(G1,G2)
GM=nx.isomorphism.GraphMatcher(G1,G2)
type(GM)
GM.G1_nodes,GM.G2_nodes
GM.is_isomorphic()
izomorfizam grafova
GM.mapping
GM.core_1
GM.core_2
svi izomorfizmi
for u in GM.isomorphisms_iter():
print(u)
matrica permutacije
grupa=SymmetricGroup(5)
$[1,2,3,4,5] \mapsto [4,2,1,3,5]$
grupa([4,2,1,3,5])
matrica permutacije $P$ za prvi izomorfizam
grupa([4,2,1,3,5]).matrix().transpose()
$[1,2,3,4,5]\mapsto [4,5,1,3,2]$
grupa([4,5,1,3,2])
matrica permutacije $P$ za drugi izomorfizam
grupa([4,5,1,3,2]).matrix().transpose()
Dokažite da su grafovi $G_1$ i $G_2$ izomorfni tako da konstruirate jedan izomorfizam između njih.
Pronađite i njihove matrice susjedstva $A_1$ i $A_2$ takve da $i$-tom retku u pojedinoj matrici odgovara vrh $u_i$ odnosno vrh $v_i$. Pronađite matricu permutacije $P$ za koju vrijedi $PA_1P^T=A_2$.
Radit ćemo odmah s networkx modulom.
graf1=Graph({1:[3,4,5],2:[4,5,6],3:[5,6],4:[6]})
graf2=Graph({1:[2,5,6],2:[3,6],3:[4,5],4:[5,6]})
G1=graf1.networkx_graph()
G2=graf2.networkx_graph()
G1.nodes(),G2.nodes()
GM=nx.isomorphism.GraphMatcher(G1,G2)
GM.G1_nodes,GM.G2_nodes
GM.is_isomorphic()
jedan izomorfizam
GM.mapping
svi izomorfizmi
for u in GM.isomorphisms_iter():
print(u)
matrice susjedstva
graf1.adjacency_matrix()
graf2.adjacency_matrix()
matrica permutacije
pronađimo matrice permutacije za izomorfizme $\{1: 1, 2: 4, 3: 2, 4: 5, 5: 6, 6: 3\}$ i $\{1: 3, 2: 6, 3: 5, 4: 2, 5: 4, 6: 1\}$. Analogno se radi i za ostale izomorfizme.
grupa=SymmetricGroup(6)
za izomorfizam $\{1: 1, 2: 4, 3: 2, 4: 5, 5: 6, 6: 3\}$
grupa([1,4,2,5,6,3]).matrix().transpose()
za izomorfizam $\{1: 3, 2: 6, 3: 5, 4: 2, 5: 4, 6: 1\}$
grupa([3,6,5,2,4,1]).matrix().transpose()
Nacrtajte sve jednostavne neizomorfne grafove s tri vrha.
triVrha=list(graphs(3))
lista3=[g.plot(vertex_size=30,vertex_labels=False,layout="circular",graph_border=True) for g in triVrha]
graphics_array(lista3,2,2).show(figsize=[4,4])
Nacrtajte sve jednostavne neizomorfne grafove s četiri vrha.
cetiriVrha=list(graphs(4))
lista4=[g.plot(vertex_size=30,vertex_labels=False,layout="circular",graph_border=True) for g in cetiriVrha]
graphics_array(lista4,4,3)
Nacrtajte sve jednostavne neizomorfne grafove s pet vrhova.
len(list(graphs(5)))
petVrha=list(graphs(5))
lista5=[g.plot(vertex_size=30,vertex_labels=False,layout="circular",graph_border=True) for g in petVrha]
graphics_array(lista5,6,6).show(figsize=[8,8])
Da li je $G_1$ podgraf od $G_2$?
naredbom subgraph_search tražimo podgrafove u grafu s time da se na izlazu vraća inducirani podgraf koji sadrži zadani graf za kojeg smo ispitivali da li je podgraf.
gr1=Graph({0:[1,3],1:[2],2:[3]})
gr2=Graph({0:[3,4],1:[2,3],2:[3,4],3:[4]})
#gr2.relabel(list('abcde'))
gr3=gr2.subgraph_search(gr1)
gr3
Uočite da je na trećoj slici vraćen podgraf grafa s druge slike koji sadrži graf na prvoj slici. Dakle, $G_1$ je podgraf od $G_2$.
graphics_array([gr1.plot(graph_border=True,layout="circular"),gr2.plot(graph_border=True,layout="circular"),
gr3.plot(graph_border=True,layout="circular")])
$G_1$ nije inducirani podgraf od $G_2$
gr2.subgraph_search(gr1,induced=True) is None
Da li je $G_1$ podgraf od $G_2$?
gr1=Graph({0:[1,3],1:[2,3],2:[3]})
gr2=Graph({0:[4,5],1:[3,4],2:[3,4],4:[5]})
gr3=gr2.subgraph_search(gr1)
nije vraćen nikakvi podgraf pa zaključujemo da $G_1$ nije podgraf od $G_2$
print(gr3)
Da li je $G_1$ podgraf od $G_2$?
gr1=Graph({0:[2,3,4],1:[2,3,4]})
gr2=Graph({0:[1,4,5],1:[2,3,5],2:[3,4],3:[4],4:[5]})
gr3=gr2.subgraph_search(gr1,induced=False)
gr4=gr2.subgraph_search(gr1,induced=True)
$G_1$ je podgraf od $G_2$
gr3
graphics_array([gr1.plot(graph_border=True,layout="circular"),gr2.plot(graph_border=True,layout="circular"),
gr3.plot(graph_border=True,layout="circular")])
$G_1$ nije inducirani podgraf od $G_2$
print(gr4)
Implementirat ćemo funkciju podgraf koja ispituje je li graf G1 podgraf grafa G2. U slučaju da G1 nije podgraf grafa G2, funkcija vraća False, a inače će nacrtati graf G2 i na njemu crvenom bojom istaknuti podgraf G1. Opcije raspored_vrhova i laj služe samo za željeni raspored vrhova prilikom crtanja grafa. Ukoliko je G1 podgraf grafa G2, funkcija vraća samo jednu mogućnost smještanja grafa G1 na graf G2 (ukoliko ima više mogućnosti, funkcija će vratiti samo jednu mogućnost). Radi jednostavnosti implementacije, pretpostavlja se da graf s $n$ vrhova ima oznake vrhova $0,1,2,\ldots,n-1$. U protivnom algoritam neće raditi. Imajte na umu da algoritam radi grubom silom tako da prolazi kroz sve mogućnosti i uzima prvu koja je dobra tako da nije efikasan na velikim grafovima. Općenito ne postoji efikasan algoritam za taj problem.
def podgraf(G1,G2,raspored_vrhova=None,laj="circular"):
#vrhovi grafova su numerirani prirodnim brojevima i nulom
bridovi1=G1.edges(labels=False)
bridovi2=G2.edges(labels=False)
v1=G1.vertices()
v2=G2.vertices()
mogucnosti=Arrangements(v2,len(v1))
mozeX=True
for x in mogucnosti:
podgraf_bridovi=[]
podgraf_vrhovi=x
mozeX=True
for (y1,y2) in bridovi1:
if ((x[y1],x[y2]) in bridovi2) or ((x[y2],x[y1]) in bridovi2):
podgraf_bridovi.append((x[y1],x[y2]))
else:
mozeX=False
break
if mozeX: break
if not(mozeX): return False
if raspored_vrhova==None:
slika=G2.plot(graph_border=True,edge_colors={"red":podgraf_bridovi},vertex_colors={"red":podgraf_vrhovi},layout=laj)
else:
slika=G2.plot(graph_border=True,edge_colors={"red":podgraf_bridovi},vertex_colors={"red":podgraf_vrhovi},pos=raspored_vrhova)
return slika
gr1=Graph({0:[2,3,4],1:[2,3,4]})
gr2=Graph({0:[1,4,5],1:[2,3,5],2:[3,4],3:[4],4:[5]})
podgraf(gr1,gr2)
podgraf(gr1,gr2,raspored_vrhova={0:[0,1],1:[1,0],2:[2,1],3:[2,2],4:[1,3],5:[0,2]})
testirajmo našu funkciju i na prethodna dva zadatka
gr1=Graph({0:[1,3],1:[2],2:[3]})
gr2=Graph({0:[3,4],1:[2,3],2:[3,4],3:[4]})
slika=podgraf(gr1,gr2,raspored_vrhova={0:[1,-2],1:[3,-2],2:[4,1],3:[2,2],4:[0,1]})
graphics_array([gr1.plot(graph_border=True),gr2.plot(graph_border=True,pos={0:[1,-2],1:[3,-2],2:[4,1],3:[2,2],4:[0,1]}),
slika]).show(figsize=[10,7])
gr1=Graph({0:[1,3],1:[2,3],2:[3]})
gr2=Graph({0:[4,5],1:[3,4],2:[3,4],4:[5]})
podgraf(gr1,gr2)
graphics_array([gr1.plot(graph_border=True,pos={0:[0,0],1:[2,0],2:[2,2],3:[0,2]}),gr2.plot(graph_border=True,
pos={0:[0,-2],1:[3,-2],2:[6,-2],3:[6,2],4:[3,2],5:[0,2]})])
Želite li nešto više saznati o klasi Graph, možete napisati help(Graph) ili pak napisati Graph.