许多整数之间成对距离的分布
Distribution of pairwise distances between many integers
我们有M个1到N之间的唯一整数。在现实生活中,N是几百万,M在N/10到N/3之间。我需要计算 M 个整数之间成对距离的分布。
问题的蛮力复杂度是M^2,但输出只是N个数字。所以自然的问题是是否有更快的算法。即使是像 N * sqrt(M) 这样快的算法也应该足以满足我们的目的。
该问题是以下问题的子集。我们有一个大的虚拟正方形对称矩阵,有几百万乘几百万元素。矩阵的一些行和列被屏蔽掉了。我们需要找出矩阵的每个对角线中有多少个被屏蔽掉的元素。人们可以很容易地计算出有多少个屏蔽箱与每条对角线相交。但通常被屏蔽掉的行和列会在对角线上相交,因此只会屏蔽掉一个 bin。为了避免重复计算这些,我们需要屏蔽列之间的距离成对分布。
您可以使用傅里叶变换在 O(NlogN) 中完成此操作。
这个想法是,您首先计算 M 个整数的直方图 H(x),其中 H(x) 是值 x 在您的输入中出现的次数(如果所有 M 个整数,则为 0 或 1是不同的 - 但这不是必需的)。
那么你要计算的是A(d),其中A(d)定义为正好相隔d的整数对的数量。
这可以计算为 A(d) = sum(H(x)*H(x+d) for all x)
这种类型的函数称为卷积,可以通过进行傅立叶变换、将输出乘以自身,然后计算逆变换来高效计算。需要注意适当填充,例如参见 [=10=].
如果你使用Python,这就特别容易,因为你可以调用scipy.signal.fftconvolve来完成这个操作。
我们有M个1到N之间的唯一整数。在现实生活中,N是几百万,M在N/10到N/3之间。我需要计算 M 个整数之间成对距离的分布。
问题的蛮力复杂度是M^2,但输出只是N个数字。所以自然的问题是是否有更快的算法。即使是像 N * sqrt(M) 这样快的算法也应该足以满足我们的目的。
该问题是以下问题的子集。我们有一个大的虚拟正方形对称矩阵,有几百万乘几百万元素。矩阵的一些行和列被屏蔽掉了。我们需要找出矩阵的每个对角线中有多少个被屏蔽掉的元素。人们可以很容易地计算出有多少个屏蔽箱与每条对角线相交。但通常被屏蔽掉的行和列会在对角线上相交,因此只会屏蔽掉一个 bin。为了避免重复计算这些,我们需要屏蔽列之间的距离成对分布。
您可以使用傅里叶变换在 O(NlogN) 中完成此操作。
这个想法是,您首先计算 M 个整数的直方图 H(x),其中 H(x) 是值 x 在您的输入中出现的次数(如果所有 M 个整数,则为 0 或 1是不同的 - 但这不是必需的)。
那么你要计算的是A(d),其中A(d)定义为正好相隔d的整数对的数量。
这可以计算为 A(d) = sum(H(x)*H(x+d) for all x)
这种类型的函数称为卷积,可以通过进行傅立叶变换、将输出乘以自身,然后计算逆变换来高效计算。需要注意适当填充,例如参见 [=10=].
如果你使用Python,这就特别容易,因为你可以调用scipy.signal.fftconvolve来完成这个操作。