有一组{(a_i,b_i) with i = 1, ..., n}
段0 <= a_i < b_i <= 1
必须排列在N行[0,1]
上而不重叠。
例如,如果某个集可以包含{(0.35,0.41), (0.40,0.43), (0.47,0.88)}
和N >= 2
,则可以排列这些段而不会重叠。由于N = 1
不可能,因为第一段和第二段重叠。
对于必须放置一个段的行没有任何约束,一个可能的算法如下:根据它们的起点a_i
对段进行排序,然后将它们一个接一个地放在{{{}之一上1}}行。如果无法将细分N
放置在任何行上而不与任何已放置的细分重叠,则表示没有解决方案。
如果某些细分受限制必须放在线上,会怎么样?例如,段a_i
可能只放在第3行,而其中一段将其写为(a_2,b_2)
。
以下是一种可能的情况:(a_2,b_2;3)
和{(0.45,0.56;-), (0.48,0.67;-), (0.66,0.70;2), (0.68,0.71;-)}
。
如果将第一个段放在第一行上,则第二个段必须在第二个行上,第三个段不能满足约束。相反,如果第一个线段放在第二条线上,则第二个线段在第一条线上,第三条线在第二条线上实现约束,第二条线在第一条线上。
我尝试了什么
尝试每种符合约束条件的组合。在最后一个示例中N = 2
在第一个没有任何重叠之后,程序返回组合,这是问题的解决方案。当然它有效,当然它很慢。
画一条标有点的行{1,2}x{1,2}x{2}x{1,2}
,这些点是至少一个段的边界。构建由两个连续点组成的间隔列表[0,1]
。对于I
的每个元素,请获取涵盖它的细分的I
列表。对于S
的每个子集S'
,构建集S
等于允许的行号的并集。例如A'
,S' = {(0.5,0.6;1,2), (0.4,0.7;2)}
。如果A' = {1, 2}
的基数小于A'
的基数,则无法解决问题。不幸的是,情况并非总是如此。
扫描点S'
中的每个间隔,并根据其他线段的约束删除无法放置线段的线条。例如,如果某个段在第2行受到约束,则对于与其具有交集的任何其他段,这不是一个选项。继续扫描间隔列表,直到不再可能减少为止。然后使用2.
中的基本算法和可能组合的子集。
绘制大小为1.
的方形矩阵A
(n
为段数)。如果n
重叠,则a_ij
等于1
,0
如果不重叠,则<= N
。根据段是否具有约束,仅允许对矩阵的特定操作(如果交换两行,则必须交换相同的列,具有约束的段不能任意交换)。如果可以获得具有多个对角块I
的矩阵,该矩阵是单位矩阵,那么就有解决方案。不确定它是否可行,也不合理。
考虑S
中定义的S'
,A'
,2.
和A'
。如果S'
的基数小于A'
的基数,则中止(无解)。如果S'
的基数等于A'
的基数,请从{em>与S'
的每个元素相交的段中删除I
的行号}。
继续扫描N = 3
,直到无法再减少为止。 如果程序没有中止到这一点,那么问题仍然存在吗?(是的,但不仅仅是那些)
例如,S = {(0.5,0.6;1,2), (0.4,0.7;2), (0.5,0.6;1,2,3)}
,S' = {(0.5,0.6;1,2), (0.4,0.7;2)}
。其中一个子集是A' = {1,2}
,其中一个具有S'
。 A'
的基数等于{1,2}
的基数,因此必须从不在S'
中的每个段允许的行中删除S = {(0.5,0.6;1,2), (0.4,0.7;2), (0.5,0.6;3)}
。获得S' = {(0.4,0.7;2)}
。对2
执行相同操作,S = {(0.5,0.6;1), (0.4,0.7;2), (0.5,0.6;3)}
将从第一个段中删除,其中一个获得N = 2
,这是(单个可能的)解决方案。
反例:对于{(0.5,0.6;-), (0.55,0.7;-), (0.65,0.8;-)}
和{1,2}x{1,2}x{1,2}
,并非5.
的每个组合都是解决方案。原因与(真)解的对称性有关。如果在算法的每次完整运行之后,将其中一个段固定在其允许的一条线上(从而打破对称性)并重新运行算法,则可以获得该建议集的解决方案。
以这种方式可以总是得到一个解决方案(当它存在时)或者程序在没有解决时中止吗?
如果n
正确,是否可以从n-1
段的解决方案中计算x
段的解决方案?
Obeservations(来自评论和我)
强制某些细分在特定行上的约束可以放宽一点,因为在完成解决方案之后,您可以完全自由地重新编号行,而无需更改单行上的细分< / em>重叠与否。因此,例如,如果两个段应该在第5行,那么所有这些意味着它们必须位于同一行;如果一个片段应该在第3行,而另一个片段在第7行,所有这些意味着它们必须位于不同的行。
如果任何细分未覆盖任何点[0,x]
,问题可能会分为2行[x,1]
和[0,1]
长以及两组不同细分的问题。因此,必须假设{{1}}中的每个点都被至少一个段覆盖。
答案 0 :(得分:0)
我认为此问题可以转换为Vertex Coloring:
让每个线段成为无向图中的顶点。如果相应的段重叠,则两个顶点之间将具有边缘。因此,我们需要为每个顶点(段)分配一个颜色(行号),这样两个相邻的顶点就不会有相同的颜色(两个段在同一行上不重叠)。
约束的变化可以描述为List Coloring。