3.3.2 Arc Consistency Algorithms

提出用于强制执行弧一致性的有效算法一直被认为是约束推理社区的核心问题。 第一个原因是弧一致性是可能在所有求解器中使用的基本传播机制。 第二个原因是,允许提高电弧一致性效率的新思想通常可以应用于实现其他局部一致性的算法。 这就是为什么我花了一些时间来介绍已经引入的主要算法,因为我们知道所涉及的技术可以用于后续章节中提出的其他局部一致性。 我按照时间顺序演示强调了导致当前算法的增量过程。

AC3

最著名的电弧一致性算法是Mackworth在[86]中以AC3的名称提出的算法。 它被提议用于二进制规范化网络,并且实际上实现了2个一致性。 在[88]中,它在任意网络中扩展到GAC。 这个算法很容易理解。 一般符号的负担不是那么高,我把它呈现在它的一般版本中。 (见算法3.1。)

GAC3的主要组成部分是弧的修订,即域的更新和约束。wrt(with respect to)更新域D(xi)与约束c意味着删除D(xi)中与c不一致的每个值。 函数Revise(xi,c)依次取D(xi)中的每个值vi(第2行),并探索空间πX(c)\ {xi}(D),在c上寻找对vi的支持(行3)。 如果没有找到这样的支持,则从D(xi)中移除vi,并且已经改变了D(xi)的事实(第4-5行)。 如果域D(xi)已经减少,则该函数返回true,否则返回false(第6行)。实际上就是更新域,针对一个约束c,在搜索空间中看是否能找到支持它的值,没有就从域中删去这个值。

主算法是一个简单的循环,它修改弧直到没有发生变化,以确保所有域都与所有约束一致。为了避免对Revise进行太多无用的调用(如AC1或AC2等非常基本的AC算法中的情况),算法维护所有对(xi,c)的列表Q,我们不保证D (xi)与c的弧一致。在第7行中,Q填充了所有可能的对(xi,c),使得xi∈X(c)。然后,主循环(第8行)逐个挑选Q中的对(xi,c)(第9行)并调用Revise(xi,c)(第10行)。如果消除了D(xi),则算法返回false(第11行)。否则,如果D(xi)被修改,则可能是另一个变量xj的值在涉及xi和xj的约束c上失去其支持的情况。因此,所有对(xj,c)使得xi,xj∈X(c)必须再次放入Q(第12行)。当Q为空时,算法返回true(第13行),因为我们保证所有弧都已被修改,并且所有变量的所有剩余值都与所有约束一致。

命题3.27(GAC3)。 GAC3是一种完整的算法,用于实现在O(er3dr + 1)时间和O(er)空间中运行的弧一致性,其中r是约束中最大的arity。

McGregor提出了一种在AC3中传播约束的不同方式,后来命名为面向变量,而不是AC3的弧面传播策略[91]。 在D(xi)(第12行)发生变化后应该修改的所有弧都不是Q,而是放入xi。 Q包含尚未传播其域中的更改的变量。 当从Q中选择一个变量xj时,该算法会修改所有可能因为xj而导致其他缺陷的弧(xi,c)。 这个版本的AC3的实现更简单,因为Q中的元素只是变量。 但是这种不太精确的信息有一个缺点。 弧可以修改几次,而经典的AC3会修改一次。 Boussemart等人提出了McGregor算法的修改版本,通过为每个弧存储计数器来解决这个问题[28]。

从现在开始,我转而使用二进制规范化网络,因为大多数文献都使用了这种简化,我不想假设作者会选择哪种扩展。 然而,这些想法总是允许扩展到非规范化的二进制网络,并且大部分时间都允许扩展到具有非二进制约束的网络。

推论3.28(AC3)。 AC3在O(ed3)时间和O(e)空间中实现二进制网络的电弧一致性。

扫描二维码关注公众号,回复: 4296476 查看本文章

AC3的时间复杂度不是最佳的。 函数Revise不记得任何有关其计算结果以支持值的事实导致AC3执行并重做多次相同的约束检查。

eg 

AC4

AC3不是最优的,Mohr和Henderson提出AC4来改善时间复杂度[92,93]。 与AC3相反,AC4的想法是存储大量信息。 AC3在调用Revise中执行最少量的工作,只需确保xi的所有剩余值与c一致并且不记忆任何内容。 如果召回相同的修订版,要付出的代价是重做大部分工作。 AC4在预处理步骤中存储最大量的信息,以避免在删除传播期间重复几次相同的约束检查。

AC4在算法3.2中给出。它计算每个三元组(xi,vi,xj)的计数器counter[xi,vi,xj],其中cij∈C和vi∈D(xi)。这个计数器最终会说明vi对cij有多少支持。 AC4还构建列表S [xj,vj],其中包含cij上(xj,vj)支持的所有值。在初始化阶段,AC4对所有约束执行所有可能的约束检查。每次在cij上找到(xi,vi)的支持vj∈D(xj)时,计数器[xi,vi,xj]递增,并且将(xi,vi)加到S [xj,vj](第3行)和5)。每次在没有约束支持的情况下找到值时,它将从域中删除并放入列表Q以供将来传播(第4行)。初始化完成后,我们进入传播循环(第7行),其中包括传播Q中值的删除结果。对于从Q(第8行)中选取的每个值(xj,vj),我们只需要递减计数器[xi,vi,xj]用于每个值(xi,vi)∈S[xj,vj]以使计数器保持最新(第11行)。如果counter [xi,v i,x j]达到零,这意味着(xj,v j)是cij上(xi,v i)的最后一个支持。 (xi,v i)被移除并放入列表Q(第12和13行)。当Q为空时,我们知道域中剩余的所有值在其所有约束上都具有非零计数器,因此弧一致。

AC4是后来被称为“细粒度”算法[126]的类别中的第一个算法,因为它们在值的级别上执行传播(通过列表Q)。 “粗粒度”算法(例如AC3)在约束(或弧)的水平上传播,这不太精确并且可能涉及不必要的工作

命题3.30(AC4) AC4在O(ed2)时间和O(ed2)空间中实现二进制归一化网络的电弧一致性。 它的时间复杂度是最佳的。

 We observe that the propagation of the deletion of (y,3) did not require any constraint check. It required traversals of S[..] lists and updates of counters

虽然在时间上是最佳的,但AC4不仅遭受其高空间复杂性。 其非常昂贵的初始化阶段本身可能会过时。 实际上,我们可以非正式地说AC4具有最佳的最坏情况时间复杂度,但它几乎总是达到这种最坏情况。 华莱士在[120]中讨论了这个问题。 此外,即使初始化阶段已完成,AC4也会保持一个如此准确的过程视图,以便花费大量精力更新其计数器并遍历其列表。 这在例3.31中可见,其中(y,3)的移除引起S [y,3]的遍历和计数器更新,而所有剩余值都具有支持。AC4的初始化成本太高了

由Mohr和Masini在[93]中提出的非二进制版本GAC4处于3.3.1节中给出的最优O(erdr)时间复杂度,其中r是所有约束中最大的arity。

AC6

Bessiere和Cordier提出了AC6,这是AC3的laziness和AC4的eagerness之间的妥协[15,14]。 AC6背后的动机是保持AC4的最佳最坏情况时间复杂度,并且一旦找到第一个支持就停止搜索对约束值的支持,如在AC3的修订中所做的那样。 此外,AC6保持比AC4更轻的数据结构。 实际上,AC6中的想法不是计算值对约束的所有支持,而只是为了确保它至少有一个

AC6仅需要列表S,其中S [xj,vj]包含(xj,vj)是当前支持的所有值。 也就是说,(xi,vi)∈S[xj,vj]当且仅当vj是cij上vi的第一个支持。

与AC4一样,AC6是一种细粒度算法,因为它沿着值传播。 当移除的值(xj,v j)没有机会在D(xi)中引发另一个移除时,即当D(xi)∩S[xj,v j] =∅时,它不会重新考虑约束cij。

AC2001

在诸如AC4或AC6的细粒度算法中,传播是以变量的值为导向的。 删除值(xj,vj)直接通过Q传播到值(xi,vi),该值具有(xj,vj)作为支持(即,在S [xj,vi]上的值(xi,vi)])。粗粒度算法是面向弧的算法。 它们不会将值清除的后果传播到其他变量值。虽然粗粒度算法的传播方式不太精确,但它们具有双重优势。 首先,约束求解器的体系结构(参见3.8节)通常支持面向弧的传播,而不是面向值的传播。 其次,所有细粒度算法都需要支持值的列表S [..]作为数据结构,实现和维护起来更复杂。 这些是AC2001的动机,AC2001是第一个(也是唯一的)最优粗粒度算法[24,126,25]。

AC2001遵循与AC3相同的框架,但通过在每个约束上存储每个值的最小支持(如AC6)来实现最优化。 但是,此信息的存储和使用方式与AC6中的方式不同。 AC2001不使用列表S [xj,v j]来存储具有vj作为cij上最小支持的(xi,v i)。 它使用包含vj的指针Last [xi,vi,xj]

AC2001与AC3的不同之处仅在于其修订功能和初始化阶段,需要将指针Last [xi,v i,x j]初始化为小于minD(xj)的某个虚拟值。 在Revise2001(算法3.4)中,当发现D(xj)中的值vj支持cij上的(xi,v i)时,AC2001将vj分配给Last [xi,v i,x j](第4行)。 下一次(xi,cij)将被修改,仅当Last [xi,v i,x j]不再在D(xj)(第2行)时,才会寻求(xi,v i)的支持。 更重要的是,获得最优性是因为D(xj)中小于Last [xi,v i,x j]的值不再被检查,因为它们在先前对Revise2001的调用中已经未成功检查(第3行)。

3.3.3 Other Improvements

我已经介绍了在网络上实施弧一致性的主要技术。 存在其他类型的技术以降低电弧一致性的成本。 它们通常被添加到上面提出的一种弧一致性算法中以改善其性能。 我不能详尽无遗,但这里有两种技术。

Bidirectionality双向

约束被认为是多向的,因为当发现元组τ在约束c上支持(xi,vi)时,它也支持同一约束上的任何(xj,vj)∈τ。多方向的二进制版本是 称为双向性。 这个属性看起来很明显,并没有像目前为止提供的算法那样多。

事实上,AC3在修改修改xi(xi,c)中的xi(算法3.1中的第12行)后避免将(xj,c)置于Q中时部分使用它:从D(xi)中删除的值vi没有支持 c,因此删除它不能丢弃对D(xj)中的值的支持。

Gaschnig建议更明确地使用双向性。 算法DEE [62]是AC3的扩展,它使用'Revise-both'程序按顺序处理Revise(xi,cij)和Revise(xj,cij)。 作为第一步,Revise-both执行与Revise(xi,cij)相同的工作,但此外,标记D(xj)中的每个值,该值在D(xi)中支持值。 一旦检查了xi的所有值,修改 - 都修改cj上的xj,只查找对D(xj)的未标记值的支持。 在第一阶段标记的值保证有支持。 DEE不会将这些标记存储在从Revise到另一个的调用中。 此外,在传播阶段,电弧通常一次仅在一个方向上进行修正,这降低了DEE的增益。

双向性在AC7中被广泛使用[18,19],AC6的扩展。 由于AC6支持的值列表和其他指针,AC7完全利用了双向性。 这意味着只有在cji(vj,vi)从未检查cj(vj,vi)的同时在cji上寻找对(xj,vj)的支持时,才会执行约束检查cij(vi,vj) 并且不存在vj∈D(xj)使得cji(vj,vi)已经被成功检查为(xj,vj)的支持。 在IlogSolver [71]中使用非二进制版本的AC7 [23]来传播一般约束。 至于GAC4,它以最佳的O(erdr)时间复杂度运行。

Lecoutre等人提出了AC2001的几个扩展,允许将AC7中使用的技术适应粗粒度算法[81]。 AC3.2是一种在正约束检查上部分利用双向性的算法。 AC3.3充分利用正约束检查的双向性。 AC3.2 *和AC3.3 *是AC3.2和AC3.3的扩展,它们也利用负约束检查的双向性,如AC7。 广泛的实验表明,AC3.3是最佳标准的一致性,而AC3.2在搜索过程中保持最佳。

Ordering the propagation list

另一种改善强制弧一致性所需时间的方法是首先修改将修剪最多或最便宜修改的弧。 在他们关于这个主题的开创性论文中,Wallace和Freuder提出了几种启发式方法来重新排列AC3中的传播列表[121]。 在他们分析的不同启发式方法中,最好的似乎是首先选择弧(xi,cij),使得要修改的变量xj具有最小的域。

Gent等人将弧度一致性应用于[65]中定义的“约束性”的一般标准。 他们建议首先选择最小化电弧一致性约束κac的电弧[64]。 他们表明,这种启发式方法是减少约束检查次数的好方法,但计算量很大。 有趣的是,他们的标准的近似值给出了Wallace和Freuder提出的一些良好的启发式算法。

最近由Boussemart等人提出了关于粗粒度弧一致性算法的排序启发式的最全面的研究。在[28]。他们不仅研究了启发式方法来重新排序传播列表Q,还研究了我们放入其中的信息类型。 Q可以是要修改的弧列表,如在常规AC3(弧定向修订版)中,其域已经被修改为McGregor版本(面向变量的版本)的变量列表,或者具有变量的约束列表他们的计划修改。变量列表比弧列表短得多,他们表明,当结合面向变量的实现时,启发式处理Q的时间较少。由于McGregor的算法遭受冗余修订(参见第3.3.2小节),Boussemart等人提出了一个修改版本,它避免了这些冗余修订,同时保留了面向变量修订的优势。至于保存约束检查,他们发现几个与Wallace和Freuder或van Dongen [121,113]已经提出的启发式相近的启发式算法表现出良好的性能。其中,他们建议采用面向变量的粗粒度算法实现(他们用AC3.2进行实验),其中具有最小域的变量首先从Q中选取。

猜你喜欢

转载自blog.csdn.net/weixin_38354912/article/details/84632675
arc