编辑是为了确保问题不来判断距离......我的gcdist()
例程将会这样做并且常规工作(为简洁起见, )...为了测试每个foreach
对另一个ll
对,我需要做的更多 - ll
。有没有更好的方法来比较哈希中的键彼此:
我有一个包含以下内容的哈希:
my %HASH
$HASH{"38.4486x122.7047"} = 1;
$HASH{"38.4487x122.7049"} = 10;
$HASH{"38.4489x122.7050"} = 14;
$HASH{"38.4491x122.7051"} = 20;
这个哈希主要用于确保 - 低至4分,我没有重复。我想要做的是现在确保HASH
中的所有点都不在彼此30英尺范围内......(以上是测试数据,所以这些都可能不在30英尺范围内......但是你知道我的意思。)
我有一个例程,可以获得纬度/经度点之间的距离。但这是(笨拙地)我会想到的方式:
my %HASH_NEW;
foreach my $_ll_1 (sort {$a cmp $b} keys %HASH)
{
my ($_la1,$_lo1) = split ("x",$_ll_1);
my $keep_this_one = 1;
foreach my $_ll_2 (sort {$a cmp $b} keys %HASH)
{
# so we don't compare to the current one in the loop
next if $_ll_2 eq $_ll_1;
my ($_la2,$_lo2) = split ("x",$_ll_2);
if (gcdist([$_la1,$_lo1],[$_la1,$_lo1] < ~30ft)
{
$keep_this_one = 0;
last;
}
}
if ($keep_this_one)
{
$HASH_NEW{$_ll_1} = $HASH{$_ll_1};
}
}
sub gcdist
{
my $_ll1_arrayref = shift();
my $_ll2_arrayref = shift();
# get distance between $_ll1_arrayref and $_ll2_arrayref
# return it to caller
}
现在%HASH_NEW的内容为%HASH,没有ll对在30英尺内......或者我认为这是错误的?
TIA
答案 0 :(得分:3)
在列表上迭代两次是置换,但这不是你想要的。你不在乎订单。 X和Y之间的距离与Y和X之间的距离相同,没有理由计算它两次。看看使用像Algorithm::Combinatorics之类的东西来生成要测试的对。
过去,在给定距离内倾倒第一个坐标可能会产生不良结果。让我们假设4点,一个b c d,距离是:
a <-> b = 40
a <-> c = 45
a <-> d = 25
b <-> c = 40
b <-> d = 20
c <-> d = 15
按顺序迭代对并在低于所需距离30时立即转储坐标将导致:
a thrown out; it's 25 from d
b thrown out; it's 20 from d
c thrown out, it's 15 from d
虽然您可能更愿意丢弃d,因为剩下的3个点是有效的。
我会研究迭代对的组合,计算&amp;所有组合的缓存距离,然后开始一次一个地删除具有最大数量的关闭点的数据点,直到没有超过期望的数量。