我试图从数组中找到类似的值 - 不只是一个,而是一组,而它们的元素差异的总和是最低的可能值
实施例
0 2 4 6 8 9 11 15 16 19
选择5个数字
结果:
4 6 8 9 11
或
2 4 6 8 9
两组的元素差异之和为7。
问题是我需要从2927个数字的数组中选择这样的1500个数字组,我不确定算法是否采用0-1500(索引)数组并对差异求和,然后进行i + 1直到它到达1427-2927组是有效的(最后我会检查最小的总和它属于哪个组。)
请注意,这些数字是排序的(无论ASC还是DESC都无关紧要),我正在尝试使用PostgreSQL。
提前致谢。
答案 0 :(得分:1)
PostgreSQL 9.3架构设置:
随机数据的小型数据集:
CREATE TABLE test (
id INT,
population INT
);
INSERT INTO TEST VALUES ( 1, 12 );
INSERT INTO TEST VALUES ( 2, 11 );
INSERT INTO TEST VALUES ( 3, 14 );
INSERT INTO TEST VALUES ( 4, 6 );
INSERT INTO TEST VALUES ( 5, 7 );
INSERT INTO TEST VALUES ( 6, 7 );
INSERT INTO TEST VALUES ( 7, 1 );
INSERT INTO TEST VALUES ( 8, 15 );
INSERT INTO TEST VALUES ( 9, 14 );
INSERT INTO TEST VALUES ( 10, 14 );
INSERT INTO TEST VALUES ( 11, 15 );
INSERT INTO TEST VALUES ( 12, 12 );
INSERT INTO TEST VALUES ( 13, 11 );
INSERT INTO TEST VALUES ( 14, 3 );
INSERT INTO TEST VALUES ( 15, 8 );
INSERT INTO TEST VALUES ( 16, 1 );
INSERT INTO TEST VALUES ( 17, 1 );
INSERT INTO TEST VALUES ( 18, 2 );
INSERT INTO TEST VALUES ( 19, 3 );
INSERT INTO TEST VALUES ( 20, 5 );
查询1 :
WITH ordered_sums AS (
SELECT ID,
POPULATION,
ROW_NUMBER() OVER ( ORDER BY POPULATION ) AS RN,
POPULATION - LAG(POPULATION,4) OVER ( ORDER BY POPULATION ) AS DIFFERENCE
FROM test
), minimum_rn AS (
SELECT DISTINCT FIRST_VALUE( RN ) OVER wnd AS optimal_rn
FROM ordered_sums
WINDOW wnd AS ( ORDER BY DIFFERENCE )
)
SELECT ID,
POPULATION
FROM ordered_sums o
INNER JOIN
minimum_rn m
ON ( o.RN BETWEEN m.OPTIMAL_RN - 4 AND m.OPTIMAL_RN )
<强> Results 强>:
| id | population |
|----|------------|
| 10 | 14 |
| 9 | 14 |
| 3 | 14 |
| 11 | 15 |
| 8 | 15 |
上面的查询会选择5
行 - 要将其更改为选择N
行,然后更改4
功能中的LAG
和最后一行N-1
{1}}。
答案 1 :(得分:0)
假设列表为a[1]
,a[2]
,...,a[N+M]
。
a[i+M-1]-a[i]
到i=1
的{{1}}的最小值。N+1
的值是i
个连续数字的第一个索引,其中元素差异的总和最小。理解这种算法的一个关键观察是,排序整数序列的“元素差异之和”只是第一个和最后一个元素之间的差异。例如。对于M
,它是4 6 8 9 11
。
答案 2 :(得分:0)
此解决方案应该有效。 Row_number()获取订单。自我加入+1499,然后根据对中的大小差异排序。
DECLARE @cities TABLE (
city VARCHAR(512)
,size INT
,rownum INT
)
INSERT INTO @cities
SELECT *
,row_number() OVER (
ORDER BY size
) rownum
FROM
rawdata
SELECT *
,d.size - c.size difference
FROM @cities c
INNER JOIN @cities d ON c.rownum + 1499 = d.rownum
WHERE c.rownum <=2927-1499
ORDER BY d.size - c.size