%run "boaz_utils.ipynb"
Often in computation we have data from the world, and a question we want to answer about these data.
To do so, we need to find a model for the data, and a way to translate our question into a mathematical question about the model

What is perhaps most surprising is that these and any many other questions, all use the same mathematical model of a graph
A graph is just a way to store connections between pairs of entities:
The graph of Kingston's roads could be composed of all street intersections, with a connection between intersection and intersection if they are directly connected by a road.
The Instagram graph is composed of all Instagram users, with a connection from user to user if follows .
The gene-symptom interaction graph is composed of all genes and all "symptoms" (also known as phenotypes: some observable differences in people), where gene is connected to symptom if there is a correlation between people having the gene and symptom .
Mathematically, a graph is a set of vertices and a set of pairs of these vertices which is known as the set of edges. We say that a vertex is connected to if the pair is in .
A graph where is an edge if and only if is also an edge is known as an undirected graph. Undirected graphs form an important special case. Otherwise if this is not promised to be the case, we say the graph is directed.
Sometimes the edges (or vertices) of the graph are labeled by a number, which we call a weight. For example in the case of the road network, we might label every road segment with the length of that segment in kilometers.
There are two main representations for graphs. We can always assume the vertices are simply identified by the numbers to for some .
The adjacency list representation is an array where is the list of all neighbors of the vertex (i.e., all such that )
The adjacency matrix representation is an two-dimensional array (i.e., matrix) such that equals if is a neighbor of and equals otherwise.
# adjacency list representation, G is a list of lists
# G[i] is a list of all vertices i is connected to
for j in G[1]:
if j==7:
return True
return False
G = [[1],[2],[3],[0]]
draw_graph(G)
G = [[3,1],[0,2],[1,3],[2,0]]
draw_graph(G)
G = [[1,2,3,4,5,6],[0],[0],[0],[0],[0],[0]]
draw_graph(G)
n = 20
cycle = [ [(i+1) % n, (i-1) % n] for i in range(n) ]
draw_graph(cycle)
def grid_neighbors(i,j,n):
if i==n-1 and j== n-1: return []
if i==n-1:
return [i*n+j+1]
if j==n-1:
return [(i+1)*n+j]
return [n*i+((j+1) % n), n*((i+1) % n)+j]
n = 5
grid = [ grid_neighbors(i,j,n) for i in range(n) for j in range(n) ]
draw_graph(grid,'grid_layout')
def neighbors(G,u):
return G[u]
def isedge(G,u,v):
for i in G[u]:
if i == v:
return True
return False
def vertices(G):
return len(G)
def addedge(G,i,j):
if not isedge(G, i, j):
G[i].append(j)
def emptygraph(n):
G = []
for i in range(n):
G.append([])
return G
neighbors(cycle,0)
isedge(cycle,4,7)
vertices(cycle)
def zeros(n): return [0 for i in range(n)]
def printmatrix(M):
for L in M:
print(L)
def list2matrix(G):
n = len(vertices(G))
M = [zeros(n) for i in range(n)]
for i in range(n):
for j in range(n):
if isedge(G,i,j):
M[i][j] = 1
else:
M[i][j] = 0
return M
Question: Write function list2matrix(G) that convertes a graph G in adj list format to adj matrix format where M[i][j] equals 1/0 based on whether i is neighbor of j
G = [[3,1],[0,2],[1,3],[2,0]]
M = list2matrix(G)
printmatrix(M)
def list2matrix(G):
n = len(vertices(G))
M = [[0 for i in range(n)] for j in range(n)]
for i in vertices(G):
for j in vertices(G):
if isedge(G,i,j):
(M[i])[j]=1
return M
G = [[1,4],[0,2],[1,3],[2,4],[3,0]]
printmatrix(list2matrix(G))
Exercise: Write a function undir that takes a graph G and outputs a graph _G that such that for every i,j the edge i->j is in G if and only if both j->i and i->j are in _G.
def undir(G):
_G = [[] for i in vertices(G)]
for i in vertices(G):
for j in neighbors(G,i):
addedge(_G,i,j)
addedge(_G,j,i)
return _G
G = [[1],[2],[0]]
undir(G)
draw_graph(undir(G))