【问题标题】:How to get an evenly distributed sample from Perl array values?如何从 Perl 数组值中获取均匀分布的样本?
【发布时间】:2010-11-23 02:07:07
【问题描述】:

我有一个数组,其中包含许多介于 0 和 360 之间的值(如圆中的度数),但分布不均:

1,45,46,47,48,49,50,51,52,53,54,55,100,120,140,​​188,210,280,355

现在我需要将这些值减少到例如仅 4 个,但分布值尽可能均匀。

怎么做?

谢谢, 一月

【问题讨论】:

  • 您需要更仔细地表述您的问题。目前它几乎没有意义。

标签: arrays perl evenly


【解决方案1】:

将数字放在一个圆圈上,就像时钟一样。现在构建一个逻辑十字,比如在 12、3、6 和 9 点钟。将 12 放在第一个数字上。现在找出离 3 点、6 点和 9 点最近的数字,并在第一个数字旁边记录这三个数字的距离之和。

通过顺时针旋转十字的顶部(12 点钟点)进行迭代,直到它与下一个数字完全对齐。再次测量最接近的数字与其他三个交叉点的距离,并将该分数记录在当前 12 点钟数字旁边。

重复直到你到达你的 12 点钟一直旋转到原来的 3 点钟,此时你就完成了。分配给它的总和最小的数字决定了获胜的配置。

此解决方案可推广到任何值范围 R 您希望将集合减少到的任意数量 N 个最终点。 “十字架”上的每个点彼此相距 R/N,您只需旋转直到十字架的顶部到达下一个手臂在原始位置的位置。因此,如果您想要 6 个点,您将有一个 6 点交叉,每个 60 度,而不是一个 4 点交叉,每个 90 度。如果您的范围不同,您仍然执行相同的操作。这样你就不需要物理时钟和交叉来实现这个算法:它适用于任何 R 和 N。

从 Perl 的角度来看,我觉得这个答案很糟糕,因为我没有设法在解决方案中包含任何美元符号。 :)

【讨论】:

  • 步骤 1. 从 Perl 数组值中获取均匀分布的样本。第2步。 ???。第 3 步。$$$
【解决方案2】:

使用clustering algorithm 将您的数据划分为均匀分布的分区。然后从每个集群中获取一个随机值。以下$datafile 如下所示:

1   1
45  45
46  46
...
210 210
280 280
355 355

第一列是标签,第二列是数据。使用$K = 4 运行以下命令:

use strict; use warnings;
use Algorithm::KMeans;

my $datafile = $ARGV[0] or die;
my $K        = $ARGV[1] or 0;
my $mask     = 'N1';

my $clusterer = Algorithm::KMeans->new(
    datafile => $datafile,
    mask     => $mask,
    K        => $K,
    terminal_output => 0,
);

$clusterer->read_data_from_file();

my ($clusters, $cluster_centers) = $clusterer->kmeans();

my %clusters;

while (@$clusters) {

    my $cluster = shift @$clusters;
    my $center  = shift @$cluster_centers;

    $clusters{"@$center"} = $cluster->[int rand( @$cluster - 1)];
}

use YAML; print Dump \%clusters;

返回这个:

120: 120
199: 188
317.5: 355
45.9166666666667: 46

第一列是集群的中心,第二列是从该集群中选择的值。中心之间的距离应该根据Expectation Maximization algorithm最大化。

【讨论】:

    猜你喜欢
    • 2021-01-14
    • 2021-03-10
    • 1970-01-01
    • 1970-01-01
    • 2020-01-15
    • 1970-01-01
    • 2020-06-04
    • 2016-11-04
    • 2012-10-24
    相关资源
    最近更新 更多