0

I'm struggling to work out how to effectively implement this, even though I know what I'm doing wrong. I'm trying to get my code to read an adjacency list for example an undirected, weighted graph:

[(1,5)], [(0,5), (2,7)], [(1,7)]

And then convert that to an adjacency matrix, which would return:

[0, 5, inf], [5, 0, 7], [inf, 7, 0]

The code below however returns [0, 5, inf], [5, inf, 0, inf, 7], [inf, 7, 0], and I know why this is. However, I only want to append 'inf' to the adjacency matrix in cases like [0, 5, inf] because 0 is not adjacent to 2 and thus its weight is 'inf'. What's the best solution?

def adjacency_matrix(graph_string):
    adj_list = adjacency_list(graph_string)
    n = len(adj_list)
    adj_mat = [[] for _ in range(n)]
    for i in range(n):
        for j in range(n):
            if j == i:
                adj_mat[i].append(0)
            else:
                for neighbour, weight in adj_list[i]:
                    if j == neighbour:
                        adj_mat[i].append(weight)
                        break
                    elif j != neighbour:
                        adj_mat[i].append(float('inf'))
    return adj_mat
rlyhan
  • 53
  • 2
  • 6

1 Answers1

0

The problem seems to be in the elif part

elif j != neighbour:
    adj_mat[i].append(float('inf'))

Because you only want to fill the inf for the missing edges. Using condition elif j < neighbour would be correct if you have your adj_list sorted.

However, a better solution would be initializing the adjacency matrix with zero diagonal and inf values elsewhere. And only filling the weights from adjacency list. This way you avoid thinking about non-edges.

Here is a short example how that could be implemented using numpy.

import numpy as np

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

Usage:

adj_list = [(1,5)], [(0,5), (2,7)], [(1,7)]
adj_list_to_matrix(adj_list)
matusko
  • 3,487
  • 3
  • 20
  • 31