简体   繁体   English

无需使用 Matlab 内置函数即可在无向图中查找节点的唯一邻居的有效方法

[英]Efficient method for finding unique neighbors of nodes in an undirected graph without using Matlab built-in functions

I have an undirected graph of N nodes and L links, whose structure is typically described by its adjacency matrix A with N rows and N columns.我有一个N个节点和L个链接的无向图,其结构通常由其具有N行和N列的邻接矩阵A描述。 In this adjacency matrix, the value '1' denotes a link between two nodes and, conversely, '0' denotes no links.在这个邻接矩阵中,值“1”表示两个节点之间的链接,相反,“0”表示没有链接。

I work in Matlab and want to avoid all the sophistications provided by the built-in graph() functions such as N = neighbors(G, NODEID) where G is G = graph(adjm);我在 Matlab 工作,并希望避免内置graph()函数提供的所有复杂性,例如N = neighbors(G, NODEID)其中GG = graph(adjm); and adjm the adjacency matrix.adjm邻接矩阵。

In this graph, I need to identify which unique nodes (neighbors) are connected to one or several starting nodes, labelled idx .在此图中,我需要确定哪些唯一节点(邻居)连接到一个或多个起始节点,标记为idx I'm currently using the following line of code:我目前正在使用以下代码行:

fidx = unique(ceil(find(adjm(idx,:)) / numel(idx)));

where fidx contains the neighbors (connected nodes) of a set of idx starting nodes.其中fidx包含一组idx起始节点的邻居(连接节点)。 This operation is repeated a large number of times for different nodes and after some profiling, I found that the instruction find(adjm(idx,:)) is really hindering the overall runtime.这个操作对不同的节点重复了很多次,经过一些分析,我发现指令find(adjm(idx,:))确实阻碍了整体运行时间。 My first attempt was to try to avoid find() .我的第一次尝试是尽量避免find() For example using:例如使用:

A = adjm(idx,:);
A = A(:) == 1;
V = 1:size(A,1);
idx = unique(ceil(V(A) / numel(idx)));

However, this still remains too slow for my application.但是,对于我的应用程序来说,这仍然太慢了。

What are you suggestions to reduce the runtime associated with this specific section of code?您有什么建议可以减少与此特定代码部分相关的运行时间?

Here is a minimal example:这是一个最小的例子:

%Minimal example:
f = @() get_neighb();
timeit(f)

function get_neighb()
%generate a graph with a large number of nodes N, in order to have
%computations times large enough:
N = 2e4; %number of nodes
G = round( rand(N) / 1.5 );
G = triu(G) + triu(G,1)';
adjm = G - diag(diag(G));

%for visualisation purposes:
%plot(graph(adjm));

s = size(adjm,1);

%list of some nodes to search for (randomly chosen):
n_nodes_test = 2000; %number of couples to test
%In this minimal example, we focus on searching for the neighbors of each couple (2-tuple) of
%nodes only. But 'snodes' can be single nodes or n-tuples, i.e. containing more
%than 2 nodes
snodes = [ round(linspace(1, s/2, n_nodes_test)); round(linspace(s/2, s, n_nodes_test))]';

%This section is the critical one:
for i=1:n_nodes_test
    
    idx = snodes(i,:); %assign current couple of starting nodes to 'idx'.
    
    %fidx = unique(ceil(find(adjm(idx,:)) / numel(idx)));
    %can be replaced by the following:
    A = adjm(idx,:);
    A = A(:) == 1;
    V = 1:size(A,1);
    idxf = unique(ceil(V(A) / numel(idx)));
    
    %which is similar to (using Matlab built-in 'graph' functions):
    % G = graph(adjm);
    % T = unique([neighbors(G, snodes(1,1)); neighbors(G, snodes(1,2))]);
    % here idxf' == T
end


end

You can use any , so the code will be reduced to:您可以使用any ,因此代码将简化为:

idxf = find(any(adjm(idx, :)));

Explanation:解释:
Assume that you have two logical row vectors A and B and you want to find a vector C that contains 1 where any of elements of A or B are 1 .假设您有两个逻辑行向量AB并且您想要找到一个向量C ,其中包含1 ,其中AB的任何元素都是1 In other words we want to find the unique indices of A or B where they that contain 1 .换句话说,我们想要找到包含1AB唯一索引。 We simply can use logical OR operator:我们可以简单地使用逻辑OR运算符:

C = A | B;

Equivalently you can use any function to compute C :等效地,您可以使用any function 来计算C

C = any([A;B]);

When we use idx = find(C) the indices will be unique and there is no need to use the unique function.当我们使用idx = find(C)时,索引将是唯一的,不需要使用unique function。

A second solution第二种解决方案

idxf = find(idx * adjm);

Here we can use vector by matrix multiplication idx * adjm that is equivalent to sum(adjm(idx, :)) .在这里,我们可以使用矩阵乘法idx * adjm的向量,相当于sum(adjm(idx, :))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 高效存储,查找和操作大型无向图 - Efficient storage, lookup and manipulation of a large undirected graph 在 GAP 中找到图的所有最大团的有效方法 - Efficient method of finding all maximum cliques of a graph in GAP 高效的共同邻居和使用igraph的优先依恋 - Efficient common neighbors and preferential attachment using igraph C / C ++ - 在不使用内置函数的情况下旋转数组的有效方法(作业) - C/C++ - efficient method of rotating an array without using build-in functions (homework) Neo4j Cypher路径在无向图中缓慢 - Neo4j Cypher path finding slow in undirected graph 为 sklearn 的 SVC 使用自定义 rbf 核函数比内置方法快得多 - Using a custom rbf kernel function for sklearn's SVC is way faster than built-in method Matlab重复矩阵乘法 - 循环与内置性能 - Matlab repeated matrix multiplication - loop vs built-in performances 是否有内置的matlab计算二次形式(x'* A * x)? - Is there a matlab built-in that calculates the quadratic form (x'*A*x)? Matlab,更有效的代码,用于在稀疏图中的两个节点之间查找长度小于指定长度的所有路径。 - Matlab, More efficient code to find all paths with smaller than specified length between two nodes in sparse graph. 使用Python改进从有向图投影的无向图的创建 - Improve creation of undirected graph projected from a directed one using Python
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM