考虑我们在一个圆圈上有N
个点。为每个点指定一个索引i = (1,2,...,N)
。现在,对于随机选择的点,我想要一个包含5
点,[two left neighbors, the point itself, two right neighbors]
的索引的向量。
见下图。
一些示例如下:
N = 18;
selectedPointIdx = 4;
sequence = [2 3 4 5 6];
selectedPointIdx = 1
sequence = [17 18 1 2 3]
selectedPointIdx = 17
sequence = [15 16 17 18 1];
对此进行编码的传统方法是将例外视为if-else
语句,正如我所做的那样:
if ii == 1
lseq = [N-1 N ii ii+1 ii+2];
elseif ii == 2
lseq = [N ii-1 ii ii+1 ii+2];
elseif ii == N-1
lseq=[ii-2 ii-1 ii N 1];
elseif ii == N
lseq=[ii-2 ii-1 ii 1 2];
else
lseq=[ii-2 ii-1 ii ii+1 ii+2];
end
其中ii
为selectedPointIdx
。
如果我考虑7
点代替5
,则效率不高。什么是更有效的方式?
答案 0 :(得分:4)
这个怎么样 -
off = -2:2
out = mod((off + selectedPointIdx) + 17,18) + 1
如果窗口大小为7
,请将off
修改为-3:3
。
它使用了subtracting 1
+ modding
+ adding back 1
的策略,同时也讨论了here
。
示例运行 -
>> off = -2:2;
for selectedPointIdx = 1:18
disp(['For selectedPointIdx =',num2str(selectedPointIdx),' :'])
disp(mod((off + selectedPointIdx) + 17,18) + 1)
end
For selectedPointIdx =1 :
17 18 1 2 3
For selectedPointIdx =2 :
18 1 2 3 4
For selectedPointIdx =3 :
1 2 3 4 5
For selectedPointIdx =4 :
2 3 4 5 6
For selectedPointIdx =5 :
3 4 5 6 7
For selectedPointIdx =6 :
4 5 6 7 8
....
For selectedPointIdx =11 :
9 10 11 12 13
For selectedPointIdx =12 :
10 11 12 13 14
For selectedPointIdx =13 :
11 12 13 14 15
For selectedPointIdx =14 :
12 13 14 15 16
For selectedPointIdx =15 :
13 14 15 16 17
For selectedPointIdx =16 :
14 15 16 17 18
For selectedPointIdx =17 :
15 16 17 18 1
For selectedPointIdx =18 :
16 17 18 1 2
答案 1 :(得分:3)
你可以使用模运算:让p成为编号为1到N的N个点之间的点。假设你想要每边都有m个邻居,你可以按如下方式得到它们:
(p - m - 1) mod N + 1
...
(p - 4) mod N + 1
(p - 3) mod N + 1
(p - 2) mod N + 1
p
(p + 1) mod N + 1
(p + 2) mod N + 1
(p + 3) mod N + 1
...
(p + m - 1) mod N + 1
代码:
N = 18;
p = 2;
m = 3;
for i = p - m : p + m
nb = mod((i - 1) , N) + 1;
disp(nb);
end
运行代码here
我希望您注意,您可能不一定通过避免使用if语句来提高性能。可能需要一个基准来解决这个问题。但是,如果您要处理成千上万的数字,这只会很重要。