I have a problem in the Berkeley Python book for Numerical Methods (pulls questions from a MATLAB book) however, I have found several errors in the answers, so I am posting the problem with its sample output. I found a MATLAB solution online, but I am not sure how to convert this because I am not sure if the sample output is telling me the correct information. So, I want to know if the output is correct and then how to reason about converting this to a pyton solution. For example, how can (4) be a possible index if the lists are length 4 and there are 4 lists?
Let C be a square connectivity array containing zeros and ones. We say that point i has a connection to point j , or i is connected to j , if C[i,j]=1. Note that connections in this context are one-directional, meaning C[i,j] is not necessarily the same as C[j,i]. For example, think of a one-way street from point A to point B. If A is connected to B, then B is not necessarily connected to A.
Write a function my_connectivity_mat_2_dict(C, names), where C is a connectivity array and names is a list of strings that denote the name of a point. That is, names[i] is the name of the name of the i-th point.
The output variable node should be a dict with the key as the string in names and value is a vector containing the indices, j, such that C[i,j]=1. In other words, it is a list of points that point i is connected to.
Sample output:
C = [[0, 1, 0, 1], [1, 0, 0, 1], [0, 0, 0, 1], [1, 1, 1, 0]]
names = ['Los Angeles', 'New York', 'Miami', 'Dallas']
# Output: node['Los Angeles'] = [2, 4]
# node['New York'] = [1, 4]
# node['Miami'] = [4]
# node['Dallas'] = [1, 2, 3]
node = my_connectivity_mat_2_dict(C, names)
MATLAB solution:
% Function [node] = myConnectivityMat2Struct(C, names)
function [node] = Chapter5Exercise13(C, names)
% Objective: Construct a Adjacency List from Adjacency Matrix (from nodes of unidirected graph).
% Input:
% C - NxN one-directional connectivity matrix.
% names - string array with names of points.
% Output:
% node - struct with fields: name and a row vector: neighbors containing indexes j for which C(i, j) = 1.
% Author: Chris B. Kirov
% Date: 30.08.2017
for i = 1 : length(names) % traverse all names
node(i).name = names(i); % create node; assign name
for j = 1 : size(C, 2)
if (C(i, j) == 1)
node(i).neighbors(end 1) = j; % add connected neigbours
end
end
end
end
CodePudding user response:
Python arrays start at 0, but in mathematics and in MATLAB, indexing start at 1. That's why in the output, 4 is the right answer sometimes.
Here is some Python functions that would do what you want:
C = [[0, 1, 0, 1], [1, 0, 0, 1], [0, 0, 0, 1], [1, 1, 1, 0]]
names = ['Los Angeles', 'New York', 'Miami', 'Dallas']
# Two loops as in MATLAB
def my_connectivity_mat_2_dict(C, names):
connections = dict()
for i, city in enumerate(names):
connections[city] = []
for j in range(len(C[i])):
if C[i][j]:
connections[city].append(j 1)
return connections
# With a list comprehension
def my_connectivity_mat_2_dict(C, names):
connections = dict()
for i, city in enumerate(names):
connections[city] = [j 1 for j in range(len(C[i])) if C[i][j]]
return connections
# Even shorter, but hard to understand what it's doing
def my_connectivity_mat_2_dict(C, names):
return dict((city, [j 1 for j in range(len(C[i])) if C[i][j]]) for i, city in enumerate(names))
node = my_connectivity_mat_2_dict(C, names)
print(node)