偶数整数集
Even sets of integers
给定一个整数数组heights
,我想将它们拆分为n
集合,每个集合的totalHeight
(集合中值的总和)相等,或者尽可能接近。集合中的每个值之间必须有一个固定的距离gap
。集合不必具有相同数量的值。
例如,假设:
-
heights[0, 1, 2, 3, 4, 5] = [120, 78, 110, 95, 125, 95]
-
n
=3 -
gaps
=10
可能的安排是:
-
a[0, 1], b[2, 3], c[4, 5]
给出的totalHeight
值-
a = heights[0] + gap + heights[1] = 120 + 10 + 78 = 208
-
b = heights[2] + gap + heights[3] = 110 + 10 + 95 = 215
-
c = heights[4] + gap + heights[5] = 125 + 10 + 95 = 230
-
-
a[0], b[1, 2, 3], c[4, 5]
给出的totalHeight
值-
a = heights[0] = 120
-
b = heights[1] + gap + heights[2] + gap + heights[3] = 303
-
c = heights[4] + gap + heights[5] = 125 + 10 + 95 = 230
-
等等。我想找到一个组合,它能给出大小最均匀的集合。因此,在这个例子中,第一个组合更好,因为它给出的总体误差为:
max - min = 230 - 208 = 22
而第二种组合给出了183的误差。我试图用JavaScript来做这件事,但我只是在寻找某种算法的轮廓。伪代码或其他什么都很棒。如有任何帮助,我们将不胜感激。
我糟糕的尝试:显然,解决这个问题的一种方法是尝试所有可能的组合。一旦heights
变大,那就太可怕了。
我尝试的另一种方法是获得集合的预期平均高度,计算为height
/n
中值的总和。然后我试着通过尽可能接近这个平均值来分别填满每一盘。它在某些情况下可以正常工作,但速度太慢了。
注意:如果有帮助的话,我很乐意拥有对称集。例如,对于集合(a,bc),a=b。或者对于五个集合(a、b、c、d、e),a=b和c=d。我认为这将更难实现,但我可能错了。
编辑:对于任何可能感兴趣的人,我能想到的最好的算法是以下算法:
- 按降序对
heights
进行排序 - 创建
n
集合 - 将
heights
中的第一个n
值放入每组的第一个插槽中。即将CCD_ 25的最大值放在每组的开始处。在添加值时从heights
中删除这些值 - 而
heights.count
>0- 在每个
n
集合中查找最小的totalHeight
(包括gap
) - 将
heights
中的下一个值添加到此集合(并从heights
中删除该值)
- 在每个
- 最后有一些小算法,如果
totalHeight
越来越接近平均值,每个集合可以与其他集合进行x
次交换。我保持x
的小规模,因为这个过程可能会永远持续下去
这并不可怕,但显然并不完美。
看起来它是NP完全的,并且可以简化为子集和问题,或者更准确地说,可以简化为分区问题。
您的第二种方法-找到平均值(height/n),然后尝试用尽可能接近的平均值填充集合似乎是一种很好的实用方法。你说这太慢了。。。下面的实现是O(n*m-logn),其中m是集合中允许的元素的最大数量。如果m可以非常大,那么这可能非常慢,但是如果m被限制在某个范围内,那么它可以接近O(n-logn),这大约和你要得到的一样快。
Find the mean height of all values. h_mean = Sum(h) / n; O(n).
Sort all heights. O(n log n).
Examine the highest and lowest height.
Add the value which is furthest from the mean to a new set.
Remove this value from the sorted heights.
Repeat for max_number allowed in set = 1 .. m (m < n / 2)
{
Repeat:
{
If the set mean is higher than the mean.
Add the lowest value from the sorted heights.
Remove this value from the sorted heights.
If the set mean is lower than the mean
Add the highest value from the sorted heights.
Remove this value from the sorted heights.
Recalculate the set mean (taking account of the gap).
If the new set mean is further from the h_mean than the last OR
If the set has too many elements
break
}
Until all numbers are used.
Keep track of the standard deviations for this assignment.
If this assignment is the best so far, keep it.
}
这不会给出一个可证明的最佳解决方案,但它很简单,而且有很多优点…
注意,在这个算法中,所有集合都有相同数量的元素m。你可以对m的不同值重复迭代,比如2、3、4(注意m应该是N的因子)。每组的总高度约为m*mean_height。
你可能会问,如果N是素数呢
然后很明显,一套价值会低于总价值。
这是否意味着这个算法毫无用处
一点也不。它很简单,应该会产生一个很好的解决方案的第一次尝试。您可能希望首先使用此算法,然后使用优化技术(例如选择性交换要设置的高度)来细化第一个结果。
- 如何使用js将SNAPSHOT内部版本号转换为3位数的整数
- 检测个位数整数时正在转换毫秒
- 限制javascript变量的最小/最大整数
- 如何在 Javascript 中将变量的值从字符串转换为整数
- 正则表达式只允许 x 个整数
- 我想在AngularJS应用程序中创建一个输入数字框,用户不应该在该框上键入十进制数字.(一个整数输入框)
- 如何在Chartjs中制作整数比例
- 减去两个索引不同但值相同的整数
- 使用jquery从整数中减去
- 有效地获取两个区间之间的随机整数
- 为什么我的javascript程序没有将其转换为整数而不是字符串
- 带静态字符e输入的文本框数字和带javascript的负整数
- Javascript-当存在's是一个整数标记
- parseInt()方法如何返回整数
- 由于某种原因,JavaScript整数存储为未定义
- Js char数组将字符串整数视为整数
- 如何翻译MySQL查询's ResultSet转换为整数
- 计算阶乘超过了Javascript中的最大整数限制
- 如何使用 num.toString 和 str.split 查找整数的最后一位数字
- 有可能得到一个大整数实例的自然日志吗