班级排课转为布尔可满足性问题[多项式时间归约]

46

我有一个理论/实践问题,目前我不知道如何处理,以下是问题:

我创建了一个SAT求解器,能够在C语言中使用遗传算法解决CNF问题,当存在模型时,它能够找到一个模型;当不存在模型时,它能够证明矛盾。

SAT问题基本上像这样的问题: enter image description here 我的目标是将这个求解器用于许多不同的NP完全问题。基本上,我将不同的问题转化为SAT问题,使用我的求解器解决SAT问题,然后将解决方案转化为原始问题可接受的解决方案。

我已经成功地解决了N*N数独和N皇后问题,但现在我的新目标是将班级排课问题简化为SAT问题,但我不知道如何形式化班级排课问题,以便容易地将其转化为SAT问题。

目标显然是在几个月内生成类似这样的时间表图片:

enter image description here

我发现这个源代码可以解决课程安排问题,但不幸的是没有对SAT进行任何简化 :/
我还找到了一些关于计划的文章(例如http://www.cs.rochester.edu/users/faculty/kautz/papers/kautz-satplan06.pdf)。
但是这篇文章中使用的计划领域定义语言对我来说似乎太过笼统,无法表示课程安排问题。 :/
有人有什么想法可以有效地规范化课程安排问题,以便将其简化为SAT,并在此之后将SAT解决方案(如果存在^^)转换为课程表吗?
我基本上对任何建议都持开放态度,目前我不知道如何表示、简化问题,以及如何将SAT解决方案转换为课程表...

后续问题: 班级排课转布尔可满足性[多项式时间约简]第二部分


1
请先将您的课程安排输入和期望输出进行规范化(或链接到已经规范化的地方)。 - amit
我正在寻找课程安排问题的最佳形式化方法,对我来说最好的意味着“最容易转换为SAT” :)目前我没有正式的输入,我的问题是要找到一个:/ - Valentin Montmirail
1个回答

74

我将尝试首先明确问题,然后尝试将其简化为SAT问题。

将班级排课问题定义为:

Input = { S1,S2,....,Sn | Si = {(x_i1, y_i1), (x_i2, y_i2) , ... , (x_ik, y_ik) | 0 <= x_ij < y_ij <= M } } 

简述:输入是一组类,每个类别是形如 (x,y) 的一组(开放的)区间
(M 是描述“星期结束”的某个常量)

输出:当且仅当存在某个集合时为 True:

R = { (x_1j1, y_1j1) , ..., (x_njn, y_njn) | for each a,b: (x_aja,y_aja) INTERSECTION (x_bjb,y_bjb) = {} }

非正式地说:当且仅当存在一些区间分配,使得每对区间的交集为空时,结果为真。


SAT约简:

为每个区间定义一个布尔变量V_ij
基于此,定义公式:

F1 = (V_11 OR V_12 OR ... OR V_1(k_1)) AND .... AND (V_n1 OR V_n2 OR ... OR V_n(k_n))

非正式地说,当且仅当每个类别的区间中至少有一个“满足”时,F1得到满足。

定义Smaller(x,y) = true 当且仅当 x <= y1
我们将使用它来确保区间不重叠。
需要注意的是,如果我们想要确保 (x1,y1) 和 (x2,y2) 不重叠,则需要:

x1 <= y1 <= x2 <= y2 OR  x2 <= y2 <= x1 <= y1

由于输入保证了 x1<=y1, x2<=y2,因此可以简化为:

y1<= x2 OR y2 <= x1

通过使用我们的小型和布尔子句:

Smaller(y1,x2) OR Smaller(y2,x1)

现在,让我们定义新的条款来处理它:
对于每一对类a、b和它们中的区间c、d(c位于a中,d位于b中)
G_{c,d} = (Not(V_ac) OR Not(V_bd) OR Smaller(y_ac,x_bd) OR Smaller(y_bd,x_ac))

简单来说,如果b或d间的任意一个未被使用 - 子句就满足了,我们可以停止处理。否则,两个间隔都被使用,我们需要确保这两个间隔之间没有重叠。


这样就保证了如果c和d都“被选择” - 它们不会重叠,并且对于每一对间隔都是如此。

现在,形成我们的最终公式:

F = F1 AND {G_{c,d} | for each c,d}

这个公式确保:

  1. 对于每个类别,至少选择一个间隔。
  2. 对于每两个间隔c和d,如果同时选中c和d,则它们不重叠。

小提示:这个公式允许从每个类别中选择多个间隔,但是如果存在某个t>1的解决方案,则可以轻松删除t-1个间隔而不改变解决方案的正确性。

最终,所选择的间隔是我们定义的布尔变量V_ij。


示例:

Alebgra = {(1,3),(3,5),(4,6)} Calculus = {(1,4),(2,5)}

定义 F:

F1 = (V1,1 OR V1,2 OR V1,3) AND (V2,1 OR V2,2)

定义G的:

G{A1,C1} = Not(V1,1) OR Not(V2,1) OR  4 <= 1 OR 3 <= 1 //clause for A(1,3) C(1,4)
         = Not(V1,1) OR Not(V2,1) OR false = 
         = Not(V1,1) OR Not(V2,1)
G{A1,C2} = Not(V1,1) OR Not(V2,2) OR  3 <= 2 OR 5 <= 1 // clause for A(1,3) C(2,5)
         = Not(V1,1) OR Not(V2,2) OR false = 
         = Not(V1,1) OR Not(V2,2)
G{A2,C1} = Not(V1,2) OR Not(V2,1) OR  5 <= 1 OR 4 <= 3 //clause for A(3,5) C(1,4)
         = Not(V1,2) OR Not(V2,1) OR false = 
         = Not(V1,2) OR Not(V2,1)
G{A2,C2} = Not(V1,2) OR Not(V2,2) OR  5 <= 2 OR 5 <= 3 // clause for A(3,5) C(2,5)
         = Not(V1,2) OR Not(V2,2) OR false = 
         = Not(V1,2) OR Not(V2,2)
G{A3,C1} = Not(V1,3) OR Not(V2,1) OR  4 <= 4 OR 6 <= 1 //clause for A(4,6) C(1,4)
         = Not(V1,3) OR Not(V2,1) OR true= 
         = true
G{A3,C2} = Not(V1,3) OR Not(V2,2) OR  6 <= 2 OR 5 <= 4 // clause for A(4,6) C(2,5)
         = Not(V1,3) OR Not(V2,2) OR false = 
         = Not(V1,3) OR Not(V2,2)

现在我们可以展示最终的公式:

    F = (V1,1 OR V1,2 OR V1,3) AND (V2,1 OR V2,2) 
        AND  Not(V1,1) OR Not(V2,1) AND Not(V1,1) OR Not(V2,2)
        AND  Not(V1,2) OR Not(V2,1) AND Not(V1,2) OR Not(V2,2)
        AND  true AND Not(V1,3) OR Not(V2,2)

上述条件只有在以下情况下得以满足:
V1,1 = false
V1,2 = false
V1,3 = true
V2,1 = true
V2,2 = false

这代表着课程时间安排:代数=(4,6); 微积分=(1,4),如所期望的。


(1)可以很容易地计算为公式的常数,这样的常数有多项式数量。


我真的希望我没有犯错,这不是一个微不足道的简化,请在发现任何问题时进行评论。 - amit
非常感谢您的回复 :) 但我必须承认,我不认为我理解您所说的一切 :D您的正式化确实是最简单的,因此更容易转换为SAT :) 我了解如何从SAT解决方案中获得规划结果。但是,您能否给出一个小例子,例如2个类和3个时间段。我知道会有2 * 3 = 6个布尔变量; 但CNF文件会是什么样子? - Valentin Montmirail
1
@ValentinMontmirail 我更新了答案,并提供了一个简单的例子,其中包含2个类和3.2个间隔。请注意,在这种情况下,变量的数量为3+2。子句的数量几乎是O(#variables^2) - amit
嗨@Amit,我编写了您的方法,并且它在一天内(从N到M)完美运行。但是,我将您的方法推广到不仅限于1天(从N到M),而是1周(从N到5 * M),出现了问题:问题没有足够的约束力,因此有时会说两个相同的类是正确的(但实际上不应该是这样)。我认为这是因为在CNF中它说Vi_1 OR Vi_2 OR ... 但是没有任何东西表明如果Vi_1为真,则Vi_j应该为假... : / 您有解决此问题的想法吗? :/ - Valentin Montmirail
q= (-_- ) 嗯...没有源代码就没意思了,S1x_i1x_ij是什么???至少,请有人编辑一下并用实际的数学和/或代数替换伪代码(比如,我还是不明白下划线的含义)。 - Top-Master
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接