Perl 如何将曲线拟合到直方图分布?

Perl 如何将曲线拟合到直方图分布?,perl,integer,equation,curve-fitting,data-partitioning,Perl,Integer,Equation,Curve Fitting,Data Partitioning,前几天有人通过电子邮件问我一个关于整数分区的问题(因为我发布了一个Perl模块integer::Partition来生成它们),我无法回答 背景:这里是所有7的整数分区(每行的总和等于7) 现在,如果我们查看每个分区的长度,并计算每个分区的长度: 1 1 2 3 3 4 4 3 5 2 6 1 7 1 。。。我们看到一个分区的长度为1(7),一个分区的长度为7(1)。有4个分区的长度为3:(511),(421),(331),(322) 对于较大数量的N,如果绘制分区长度分布图,则会出现一条不对

前几天有人通过电子邮件问我一个关于整数分区的问题(因为我发布了一个Perl模块integer::Partition来生成它们),我无法回答

背景:这里是所有7的整数分区(每行的总和等于7)

现在,如果我们查看每个分区的长度,并计算每个分区的长度:

1 1
2 3
3 4
4 3
5 2
6 1
7 1
。。。我们看到一个分区的长度为1(7),一个分区的长度为7(1)。有4个分区的长度为3:(511),(421),(331),(322)

对于较大数量的N,如果绘制分区长度分布图,则会出现一条不对称曲线,向原点倾斜。如果您感到好奇,请绘制以下N=40的分区长度计数图

120 133 478 1115 1945 2738 3319 3589 3590 3370 3036 2637 2241 1861 1530 1236 995 790 627 490 385 297 231 176 135 101 77 56 42 30 22 15 11 5 2 1

如果您对生成这些分布计数感兴趣,下面是我使用的代码:

#! /usr/local/bin/perl

use strict;
use warnings;

use Integer::Partition;

my $n = shift || 1;

while (1) {
    my $start = time;
    my $i = Integer::Partition->new($n);
    my %size;
    while (my $p = $i->next) {
        $size{scalar @$p}++;
    }

    open my $out, '>>', "bucket-count.out";
    for my $s (sort {$a <=> $b} keys %size) {
        print $out "$n\t$s\t$size{$s}\n";
    }
    close $out;
    my $delta = time - $start;
    print "$n\t$delta secs\n";
    ++$n;
}
#/usr/local/bin/perl
严格使用;
使用警告;
使用整数::分区;
我的$n=班次| | 1;
而(1){
我的$start=时间;
my$i=Integer::Partition->new($n);
我的%尺寸;
while(my$p=$i->next){
$size{scalar@$p}++;
}
打开我的$out,“>>”,“bucket count.out”;
对于我的$s(排序{$a$b}键%size){
打印$out“$n\t$s\t$size{$s}\n”;
}
收尾美元;
my$delta=时间-$start;
打印“$n\t$delta secs\n”;
++$n;
}
(注意:在我的计算机上,N=90大约需要10分钟才能生成)

所以我的问题是:什么方程可以用来匹配观测到的分布曲线?它是高斯分布(高斯分布是非对称的吗?)还是泊松分布,或者其他什么


如何为N求解它?如果我记得高中时的数学,我可以通过求导数与0的交点来确定峰值。如何生成导数?我在网上搜索过,但我得到的都是深奥的数学论文。我只需要一些代码:)

我认为泊松分布是一个合理的估计。假设你的问题现在变成了一个最大频率k,给定N。我认为你有两种方法:

  • 从数学的角度来理解它(我会先看看,但这可能不是一个特别好的方向)
  • 假设它是泊松分布,并测量任意给定N的峰值,如上面所述
  • 一旦你有了峰值(k),估算λ应该很简单(试几次),你就有了曲线

    另一种方法是用python处理整个问题,并在numpy或scipy板上询问:-)


    HTH

    峰值是一回事,但如果曲线已知,它也会对“整数N有多少个长度为M的分区”的问题给出合理的答案,其中1#! /usr/local/bin/perl use strict; use warnings; use Integer::Partition; my $n = shift || 1; while (1) { my $start = time; my $i = Integer::Partition->new($n); my %size; while (my $p = $i->next) { $size{scalar @$p}++; } open my $out, '>>', "bucket-count.out"; for my $s (sort {$a <=> $b} keys %size) { print $out "$n\t$s\t$size{$s}\n"; } close $out; my $delta = time - $start; print "$n\t$delta secs\n"; ++$n; }