边缘列表中的邻接矩阵(最好在Matlab中)

时间:2012-03-22 16:34:17

标签: matlab adjacency-matrix

我有一个三元组列表(vertex1,vertex2,weight),表示加权有向图的边缘。由于原型实现是在Matlab中进行的,因此这些是作为Nx3矩阵导入的,其中N是边数。所以天真的实现是

id1 = L(:,1);
id2 = L(:,2);
weight = L(:,3);
m = max(max(id1, id2)) % to find the necessary size
V = zeros(m,m)
for i=1:m
   V(id1(i),id2(i)) = weight(i)
end

tribbles的问题是“id1”和“id2”是不连续的;他们是代码。这给了我三个问题。 (1)巨大的矩阵,有太多的“幻像”,虚假的顶点,这会扭曲与该矩阵一起使用的算法的结果;(2)我需要在所述算法的结果中恢复代码(足以说这会如果id代码连续1:m),则是微不足道的。

Matlab中的答案是可取的,但我认为我可以从其他语言的答案中恢复过来(只要它们不是预先打包的解决方案“R有一个可以执行此操作的库”)。

我是StackOverflow的新手,我希望很快能为社区做出有意义的贡献。暂时,谢谢!

编辑:如果我们在多个顶点的原点没有顶点,这将是一个解决方案。 (这意味着边缘起源列表和身份列表之间的1:1匹配)

for i=1:n
   for j=1:n
   if id1(i) >0 & i2(j) > 0
       V(i,j) = weight(i);
   end
   end
   end

5 个答案:

答案 0 :(得分:2)

您可以使用sparse

功能
sparse(id1,id2,weight,m,m)

答案 1 :(得分:1)

如果您的问题是节点ID号是不连续的,为什么不将它们重新映射到连续的整数?您需要做的就是创建一个包含所有唯一节点ID的字典及其与新ID的对应关系。

这与您被要求使用命名节点(AustraliaBritainCanadaDenmark ...)的情况完全没有区别 - 你会先将它们映射到连续的整数上。

答案 2 :(得分:1)

您可以使用GRP2IDX函数将您的ID代码转换为连续数字,ID可以是数字也可以不是,无关紧要。只需保留映射信息。

[idx1, gname1, gmap1] = grp2idx(id1);
[idx2, gname2, gmap2] = grp2idx(id2);

您可以使用gmap1(idx1)恢复原始ID。

如果您的id1id2来自同一套,则可以将grp2idx应用于他们的联盟:

[idx, gname,gmap] = grp2idx([id1; id2]);
idx1 = idx(1:numel(id1));
idx2 = idx(numel(id1)+1:end);

对于重新排序,请参阅最近的问题 - how to assign a set of coordinates in Matlab?

您可以使用ACCUMARRAY或SUB2IND来解决此问题。

V = accumarray([idx1 idx2], weight);

V = zeros(max(idx1),max(idx2)); %# or V = zeros(max(idx));
V(sub2ind(size(V),idx1,idx2)) = weight;

确认您是否拥有id1id2的非唯一组合。你必须要照顾好。

答案 3 :(得分:0)

您的第一个解决方案接近您想要的。但是,最好迭代边缘列表而不是邻接矩阵。

edge_indexes = edge_list(:, 1:2);
n_edges = max(edge_indexes(:));
adj_matrix = zeros(n_edges);
for local_edge = edge_list' %transpose in order to iterate by edge
    adj_matrix(local_edge(1), local_edge(2)) = local_edge(3);
end

答案 4 :(得分:0)

这是另一种解决方案:

首先将所有顶点id放在一起,因为图表中可能有一个接收顶点:

v_id_from = edge_list(:,1);
v_id_to = edge_list(:,2);
v_id_all = [v_id_from; v_id_to];

然后找到唯一的顶点id:

v_id_unique = unique(v_id_all);

现在您可以使用 ismember 函数来获取顶点ID与其连续索引映射之间的映射:

[~,from] = ismember(v_id_from, v_id_unique);
[~,to] = ismember(v_id_to, v_id_unique);

现在您可以使用sub2ind填充邻接矩阵:

adjacency_matrix = zeros(length(from), length(to));
linear_ind = sub2ind(size(adjacency_matrix), from, to);
adjacency_matrix(linear_ind) = edge_list(:,3);

您始终可以从映射的连续ID返回到原始顶点id:

original_vertex_id = v_id_unique(mapped_consecutive_id);

希望这有帮助。