我有两组间隔:一组间隔为“正”,例如0到100;另一个包含介于-100和0之间的“负”间隔。 每组中的间隔不一定是唯一的(在这种情况下,“集合”可能是比“set”更好的单词),并且可以重叠。例如,正集是
{[0,10],[5,15],[5,15],[10,15],[10,20],[25,40]}
,负集是
{[-15,0],[ - 15,-5],[ - 20,-15],[ - 30,-25]}
每个组内的相邻非重叠区间(即一个右端点等于另一个的左端点的区间)可以组合形成更长的区间,例如[0,10] + [10,20] = [0,20]和[-15,0] + [ - 20,-15] = [ - 20,0],但[0,10]和[5, 15] 不能合并为[0,15]。
如果正和负间隔跨越绝对数量完全相同的范围,则可以相互抵消,例如, [5,15] + [ - 15,-5] = 0和[0,10] + [10,20] + [ - 15,0] + [ - 20,-15] = [0,20] + [ -20,0] = 0.
我正在寻找一种有效的算法,用于以最小化剩余间隔的总组合长度的方式连接和取消间隔。在这个例子中,剩余的总长度= len([5,15])+ len([10,15])+ len([25,40])+ len([ - 30,-25])= 10 + 5 + 15 + 5 = 35。
也许这类问题已经在文献或这里的某处得到解决(我找不到任何东西,但也许只是因为我不知道如何以正式方式制定它),所以我会感谢参考和链接;或者这里发布的解决方案当然也足够了。
以下是我对可以采取的(非常)高级步骤的初步想法。这个想法是,如果左端点与某个负间隔的右端点匹配,或者如果其中一个是正端点,那么左端点与某个负间隔的左端点匹配的正间隔“可能会被取消”。它的相邻区间“可能会被取消”。
让我们使用两个集合的正数表示区间的左(l
)和右(r
)个终点,称它们为l+
/ l-
和{ {1}} / r+
表示正/负集。设置r-
。
查找所有左端点,S = 0
和所有右端点,l+ = l- = l
。对于每个此类r+ = r- = r
和每个l
,请找到r
和n_l = min{number of positive intervals with l+ = l; number of negative intervals with l- = l}
。
从n_r = min{number of positive intervals with r+ = r; number of negative intervals with r- = r}
的匹配左端点l_min
中找出最小的{l}
,并从匹配的右端组中找到最大的Step 1
来自r_max
的{{1}}点。保留完全落在{r}
和Step 1
之间的所有间隔,以便在接下来的步骤中进一步处理。计算l_min
)。
按升序对左端点的每个集合中的间隔进行排序。
在每个左端点,按照长度按降序排列间隔。
从最左侧的点r_max
开始循环所有正间隔。
将时间间隔的右端点与S = S + (the total length of the intervals which do not fall entirely between the two bounds l_min and r_max
中匹配的右端点l_min
进行比较。
如果找不到r
中的匹配项,则查找下一个间隔,其左端点等于当前间隔的右端点。
如果找到Step 2
中的时间间隔,则使用它返回Step 6
。
如果找不到Step 7
中的间隔,则将当前间隔的长度添加到长度Step 6
之和。将与当前间隔的左端点对应的Step 7
减1:S
。如果得到的新值n_l
则转到n_l := n_l - 1
。如果n_l = 0
,则转到Step 2
并使用与当前间隔相同的左端点的下一个间隔。从进一步的步骤中删除当前间隔。
如果找到n_l > 0
中的匹配项,则使用否定时间间隔转到Step 5
。
正在进行中......
[...]
对于每个集合(正S +和负S-)构建最长可能的区间组合,将非唯一区间视为相同。假设存在N_C +和N_C-可能的不同组合,每个组合在与k + = 1..N_C +和k- = 1..N_C-连接之后包含N_k +和N_k-间隔。
比较两组之间的这些组合(从包含最长区间的组合开始)消除/取消重合的区域。
计算剩余总长度。
显然,上面有许多细节需要填写,但是在这一点上我甚至不确定这种方法是否能保证找到最小的解决方案。