我想要实现的目标是不断为一组添加更多值,并使它们尽可能远离彼此。我确定必须有几种算法来解决这个问题,但我可能只是没有用正确的术语进行搜索。如果有人可以指出我的解决方案(不需要特别有效的解决方案),这将是很好的。
有效地,给定一组值S,在Min-Max范围内,我需要在相同范围内计算新值V,使得V与S中所有值之间的距离之和最大化。 / p>
答案 0 :(得分:2)
很容易证明V的可能候选者是已存在的S值或最小值/最大值。证明:设S_1,S_2,...,S_n为S的排序顺序,包括min和max。如果你选择S_i< V< S_ {i + 1},则可以使用V = S_i或V = S_ {i + 1}来实现距离的总和,具体取决于左侧和右侧的点数。
这个观察结果产生一个O(n ^ 2)算法,该算法只检查S中的每个潜在候选者。通过预先计算前缀和来计算每个元素的O(1)中的距离之和,可以将其改进为O(n)。
通常,由于每个元素为可能值的域提供两个线性代价函数,因此可以在每个查询的O(log n)中求解。您只需要一个可以维护线性函数段列表的数据结构,并返回具有最大总和的点。具有一些聪明的扩充和延迟更新的平衡二叉搜索树可以解决这个问题。当然,这是否有必要取决于元素的数量和您希望执行的查询的数量。
答案 1 :(得分:1)
我不认为你的问题有一个解决方案,但这就是我一般会解决它的方法。首先,您需要定义一个函数sumDistance()
,它接收一个新值V
以及当前集合中的所有值,并输出V
与每个值之间的距离之和在集合中。
接下来,您可以遍历d
的{{1}}域sumDistance()
,并跟踪域中每个值Min <= d <= Max
的总和。当您遇到新的最大金额时,请记录下来。给您最大金额的V
值是您保留并添加到您的集合中的值。
可以为要添加的每个新值重复此算法。请注意,因为这实际上是一维优化问题,所以运行时间不应该太坏,所以你的第一次尝试可能已经足够了。
答案 2 :(得分:0)
假设距离为d(a,b) = |a-b|
,则min
和max
之一将始终产生最大值。
证明:
假设您的V不在终点。然后,您有n1
个较低的值和n2
更高的值。最小的总距离将至少(n1 - n2) * (max - V)
更大,最大距离将至少(n2 - n1) * (V - min)
更大。
由于n1 - n2
和n2 - n1
中至少有一个必须为非负数,因此始终可以在其中一个终点找到最大值。