创建权重邻接矩阵

时间:2016-04-04 15:35:37

标签: matlab graph

我需要将权重分配给图表的边缘,来自以下文章:

"用于分布式平均的快速线性迭代"作者:L。Xiao和S. Boyd "图拉普拉斯特征值的凸优化"作者:S. Boyd

我的图形的邻接矩阵(50乘50矩阵),512个非零值。

我还有一个256乘1的矢量,具有最佳权重。

对于我使用的软件,我需要一个50乘50的矩阵,边缘(i,j)的权重在邻接矩阵的相关位置(并且边缘的符号相反(j,i) ))。

我的尝试如下,但我无法正常工作。

function weights = construct_weight_mtx(weight_list, Adj)

weights = zeros(size(Adj));
positions = find(Adj);

for i=1:length(positions)/2
    if Adj(i) == 1
        weights(i) = weight_list(i);
    end
end

weights = weights - weights';

find(Adj) == find(weights);

end 

1 个答案:

答案 0 :(得分:1)

You're finding the nonzero positions in the original adjacency matrix, but you're finding all of them. To get around this, you then take only the first half of those positions.

for i=1:length(positions)/2 ...

Unfortunately, this takes the indices from complete columns rather than just the positions below the diagonal. So if your matrix was all 1's, you'd be taking:

1 1 1 0 0 ...
1 1 1 0 0 ...
1 1 1 0 0 ...
...

instead of:

1 0 0 0 0 ...
1 1 0 0 0 ...
1 1 1 0 0 ...
...

To take the correct values, we just take the lower triangular portion of Adj and then find the nonzero positions of that:

positions = find(tril(Adj));

Now we have only the 256 positions below the diagonal and we can loop over all of the positions. Next, we need to fix the assignment in the loop:

for i=1:length(positions)
    if Adj(i) == 1   %// we already know Adj(i) == 1 for all indices in positions
        weights(i) = weight_list(i);   %// we need to update weights(positions(i))
    end
end

So this becomes:

for i=1:length(positions)
    weights(positions(i)) = weight_list(i);
end

But if all we're doing is assigning 256 values to 256 positions, we can do that without a for loop:

weights(position) = weight_list;

Note that the elements of weight_list must be in the proper order with the nonzero elements of the lower-triangular portion ordered by columns.


Completed code:

function weights = construct_weight_mtx(weight_list, Adj)

weights = zeros(size(Adj));
positions = find(tril(Adj));

weights(positions) = weight_list;

weights = weights - weights.';   %// ' is complex conjugate; not a big deal here, but something to know

find(Adj) == find(weights);   %// Not sure what this is meant to do; maybe an assert?

end