我在x轴上随机放置了引脚,并知道所有这些引脚的位置。假设有n
个。我必须在x轴上将所有这些引脚移动到两个极限[A,B]
之间,以便新位置形成差异k
的算术级数。我应该这样做,SUM(|oldpos(i) - newpos(i)|) for each pin i
是最小的。为了方便起见,我现在只考虑所有引脚从/到整数位置。
我不知道这是否可以在某些最佳时间复杂度下完成。我确信的一件事是,在最佳排列之后,新位置的引脚将按照旧位置进行分类。
一种O(k.n)
方法是选择从A开始的进展(即,将第一个引脚置于A处,将每个后续引脚置于A + k,A + 2k等等)。为此计算SUM
。现在对A + 1,A + 1 + k,A + 2 + 2k处的每个引脚执行相同操作,依此类推。最低限度将是答案。
答案 0 :(得分:3)
你是对的,你可以构建一个保留秩序的解决方案。但这不一定是唯一的解决方案。请考虑以下示例,其中包含目标T1
和T2
以及源点S1
和S2
(您想要移动到目标):
T1 T2
S1 S2
如您所见,有两种解决方案:
S1
移至T1
,将S2
移至T2
S1
移至T2
并将S2
保持在T1
两种解决方案的总成本完全相同,因为您使用绝对值作为成本标准。如果你使用平方范数或其他规范,这看起来会有所不同。
现在,既然您知道输入点与目标点之间的对应关系(现在只假设从A
开始的进展),您只需优化偏移:
minimize_offset SUM_i (|T_i + offset - oldpos(i)|)
没有正式证明,解决方案是offset = median(oldpos(i) - T_i)
。直觉是两个序列的中位数必须位于相同的位置。您可以通过可视化更改偏移时发生的情况来验证。对于某些源点,成本会增加,有些会降低,具体取决于这些点到相应目标点的方向以及更改偏移的方向。关键点在于,如果两个点都没有相对于相应的目标点改变一侧,那么这些变化的绝对值都将是相同的(因为你使用了绝对值范数)。因此,如果他们的左边的对应点有多少点,因为有与他们的权利对应的点,你不能进一步降低成本,因为一旦你降低其中一个集的成本,你将增加成本其他设定金额相同。
无论如何,中位数可以用 O(n log n)用朴素的方法计算,或 O(n)用中位数中位数计算。如果获得目标点超出有效间隔的解决方案,则必须相应地截断偏移量。事实上,不需要对目标点进行初始假设(从A
开始)。您可以假设任何开始,例如0
。
顺便说一句,这听起来与a former project of mine非常相似。你可能想看看。
以下是您给定输入的示例
S = (4, 7, 9, 13, 16)
k=3.
步骤1:使用k=3
构建任意目标序列:
T = (0, 3, 6, 9, 12)
第2步:计算序列S - T
S - T = (4, 4, 3, 4, 4)
第3步:计算S - T
的中位数:
median(S - T) = 4
将此偏移添加到T
并且您有最终序列:
F = (4, 7, 10, 13, 16)
S = (4, 7, 9, 13, 16)