我有一个三元组列表(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
答案 0 :(得分:2)
您可以使用sparse
:
sparse(id1,id2,weight,m,m)
答案 1 :(得分:1)
如果您的问题是节点ID号是不连续的,为什么不将它们重新映射到连续的整数?您需要做的就是创建一个包含所有唯一节点ID的字典及其与新ID的对应关系。
这与您被要求使用命名节点(Australia
,Britain
,Canada
,Denmark
...)的情况完全没有区别 - 你会先将它们映射到连续的整数上。
答案 2 :(得分:1)
您可以使用GRP2IDX函数将您的ID代码转换为连续数字,ID可以是数字也可以不是,无关紧要。只需保留映射信息。
[idx1, gname1, gmap1] = grp2idx(id1);
[idx2, gname2, gmap2] = grp2idx(id2);
您可以使用gmap1(idx1)
恢复原始ID。
如果您的id1
和id2
来自同一套,则可以将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;
确认您是否拥有id1
和id2
的非唯一组合。你必须要照顾好。
答案 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);
希望这有帮助。