Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vue.js/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
检测值是否在彼此的范围内并取一个中点-MATLAB_Matlab - Fatal编程技术网

检测值是否在彼此的范围内并取一个中点-MATLAB

检测值是否在彼此的范围内并取一个中点-MATLAB,matlab,Matlab,下稿自: 我目前正在使用randi生成一个随机数,然后从中减去并添加第二个数-使用poissrnd生成: for k=1:10 a = poissrnd(200,1); b(k,1) = randi([1,20000]); c(k,1:2) = [b(k,1)-a,b(k,1)+a]; end c = sort(c); c提供以下格式的输出: 823 1281 5260 5676 5372 5760 5379 5779 6808 7244 6869 729

下稿自:

我目前正在使用
randi
生成一个随机数,然后从中减去并添加第二个数-使用
poissrnd
生成:

for k=1:10
a = poissrnd(200,1);
b(k,1) = randi([1,20000]);
c(k,1:2) = [b(k,1)-a,b(k,1)+a];
end
c = sort(c);
c
提供以下格式的输出:

823     1281
5260    5676
5372    5760
5379    5779
6808    7244
6869    7293
9203    9653
12197   12563
14411   14765
15302   15670
基本上是在
b
中选择的点周围+/-
a
的边界

然后,我想设置一个附加变量(即d=2000),该变量用作阈值,通过该阈值匹配值,然后进行合并。考虑了边界-当d=2000时,上述值的输出为:

1052
7456
13933
边界823-1281不在任何其他值的2000范围内,因此取中点-反映原始值。下一个中点位于5260和9653之间,因为随着时间的推移,每个连续值都在它之前的值的2000范围内,直到9653为止。同样的逻辑也适用于取12197和15670之间的中点

是否有一种快速简便的方法来调整链接问题中给出的答案,以处理两栏格式的问题

编辑(以便更清楚):

b =
849
1975
8336
9599
12057
12983
13193
13736
16887
18578

c =
662     1036
1764    2186
8148    8524
9386    9812
11843   12271
12809   13157
12995   13391
13543   13929
16687   17087
18361   18795
c
中保存的值可以被认为是划分直线上“块”的边界。检查每个边界,看是否有任何东西位于它的2000范围内(黑线)

只要任何一条黑线接触到一个红色块,整个红色块就会全部合并到同一个合并块中。这就是为什么计算的第一个中点值为1052-从前两个边界发出的两条黑线不会触及任何东西。但是,下一组块都彼此接触。这会将它们全部合并到合并中,以使中点位于9653和5260=7456之间

从12197开始的区块超出了前一个区块的范围,因此它保持独立。我没有展示所有的街区

编辑2@Esteban:

b =
849
1975
8336
9599
12057
12983
13193
13736
16887
18578

c =
662     1036
1764    2186
8148    8524
9386    9812
11843   12271
12809   13157
12995   13391
13543   13929
16687   17087
18361   18795
然后,脚本将生成以下结果:

8980
12886
17741
事实上应该是:

1424
8980
12886
17741
因此,它只是缺少第一个值-如果没有发生合并,则在两个值之间取中点。有时这似乎有效,但有时却不行

例如,在这里它起作用(当测试值设置为1000而不是2000时):


无法100%确定它是否适用于您的所有样品。。。但这是我提出的代码,它至少适用于您示例中的数据:

value=2000;

indices = find(abs(c(2:end,1)-c(1:end-1,2))>value);
indices = vertcat(indices, length(c));

li = indices(1:end-1)+1;
ri = indices(2:end);
if li(1)==2
    li=vertcat(1,li);
    ri=vertcat(1,ri);
end

result = floor((c(ri,2)+c(li,1))/2)

它不是很干净,当然可以用更少的行来完成,但是它很容易理解并且可以工作,而且由于您的
c
将很小,我认为没有必要进一步优化它,除非您将它运行数百万次。

看看这是否适合您-

th = 2000   %// threshold

%// Column arrays
col1 = c(:,1)
col2 = c(:,2)

%// Position of "group" shifts
grp_changes = diff([col2(1:end-1,:) col1(2:end,:)],[],2)>th

%// Start and stop positions of shifts
stops = [grp_changes ; 1]
starts = [1 ; stops(1:end-1)]

%// Finally the mean of shift positions, which is the desired output
out = floor(mean([col1(starts~=0) col2(stops~=0)],2))

它不应该是5260和7293吗,因为7293在5260的2000范围内?另外,
c
是否总是排序?它是累积的-因此,虽然您正确地认为7293在5260的2000范围内,但7293也在9203的2000范围内。一旦它穿过一对数字,它就使用外部边界。7293不在9653的2000范围内,但该值仍用于中点,因为7293+2000超过9203。是的-c总是被排序的。另外,你的c有多大,就像你的应用程序中的典型大小一样?好的,我还有一个问题想理解这里的“algo”-它不是应该是12197和14765吗,因为14765在12563之外是2000+?
c
永远不会那么大-最多可能是50对数字。独立评估每个数字的阈值(d=2000)。12197不在14411的2000范围内,但12563在-这会导致12197-12563之间的整个块包含在值链中合并。然后,每当检查当前正在检查的值是否在2000范围内没有值时,该链就会停止。基本上,它与您在链接问题中提供的答案相同,只是现在它使用了2列而不是1列。我应该补充的是,12197-12563(或任何一对)之间的值可以被视为一个不可分割的点“块”,要么作为一个整体合并,要么根本不合并。有趣的方法!它适用于迄今为止我测试过的所有数据。这可能有点棘手,因为它最终会进入另一个循环,并且会运行很多次。事实上,在进一步测试后,它并没有按照预期工作。它似乎正确地检测到合并,但它返回的结果是它在合并链中匹配的最后一对之间的中点,而不是合并链开始和结束之间的中点。你能发布它不工作的数据集以及结果应该是什么吗?我唯一不明白的是,这就是为什么在不起作用的数据集中,缺少的中点介于(1764-2186)和(662-2186)之间似乎是完美的!谢谢