Trying to write a code to convert a graph representation from adjacency list to adjacency matrix.
The function should input an adjacency list adj_list = [[1,2],[2],[],[0,1]]
and output the binary matrix
adj_mat = [0. 1. 1. 0]
[0. 0. 1. 0.]
[0. 0. 0. 0.]
[1. 1. 0. 0.]
However running the code
def adj_list_to_matrix(adj_list):
n = len(adj_list)
adj_matrix = np.nan * np.ones((n,n))
np.fill_diagonal(adj_matrix,0)
for i in range(n):
for j, w in adj_list[i]:
adj_matrix[i,j] = w
return adj_matrix
produces the error message
for j, w in adj_list[i]:
TypeError: cannot unpack non-iterable int object
Can anyone help resolve this issue to get a working code?
for j, w in adj_list[i]:
doesn't work because adj_list[i]
is only a list, so you can only unpack one value out of it in a for loop. It looks like you want w
to be a weighting factor, but your adjacency list doesn't have any weightings.
You can do this, assuming all the weights are 1 (I think this is what you want based on your expected output in the question).
def adj_list_to_matrix(adj_list):
n = len(adj_list)
adj_matrix = np.nan * np.ones((n,n))
np.fill_diagonal(adj_matrix,0)
for i in range(n):
for j in adj_list[i]:
adj_matrix[i,j] = 1
return adj_matrix
output
[[ 0., 1., 1., nan],
[nan, 0., 1., nan],
[nan, nan, 0., nan],
[ 1., 1., nan, 0.]])
If you want a weighted adjacency matrix, you need to put the weights in adj_list
like so:
adj_list = [{1:0.2,2:0.5},{2:1},{},{0:0.1,1:0.6}]
Then your code only requires a minor tweak to work
def adj_list_to_matrix(adj_list):
n = len(adj_list)
adj_matrix = np.nan * np.ones((n,n))
np.fill_diagonal(adj_matrix,0)
for i in range(n):
for j, w in adj_list[i].items():
adj_matrix[i,j] = w
return adj_matrix
output
[[0. , 0.2, 0.5, nan],
[nan, 0. , 1. , nan],
[nan, nan, 0. , nan],
[0.1, 0.6, nan, 0. ]]