加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

约束编程(约束程序设计 constraint programming)

(2007-06-04 11:03:00)
标签:

杂谈

1. 什么是约束程序设计?

我们还是从一个例子着手吧。
例1.
有如下的数学算式:SEND+MORE=MONEY,每个字母代表一位从0到9的数字,首位不能为0,每个字母所代表的数字不同,请问各个字母所代表的数字是多少?
这个问题有唯一解答:9567+1085=10652
这就是一个条件约束问题。解决此类问题最简单的方法可以描述为"产生并测试"。我们很容易看出这个问题
有8个字母,而每个字母又可以是从0到9,即有10种可选方案。所以总共的可选答案是8^10种。产生程序将产生这8^10种可能解答, 然后使用测试程序来测试所产生的解答的正确性。下面列出这个问题的约束条件:
1. 8个字母所代表的数字两两不同。
2. S M不能为零
3. S*1000+E*100+N*10+D + M*1000+O*100+R*10+E = M*10000 + O*1000+N*100+E*10+Y
只要产生的某种组合符合上述三个条件就可以说是找到答案了。
但是显然这种方法在多数情况下是行不通的。这是由于组合问题中通常都存在组合爆炸,例如上题中如果不是8个字母, 而是9个的话,那么可能的组合数目就是9^10,字母仅仅只多了一个,而要产生的排列却增加了3倍多。
本文将详细介绍如何编制解决此类问题的程序,不过我们不使用传统的程序设计语言,而是使用一种已经包含了完整解决方案的语言:OZ。

2.基本原理

首先来看看需要使用什么方法才能够减少测试的次数吧。我们从另外一个简单例子入手。典型的条件约束问题具有如下的形式:
它包含n个变量:V1,......,Vn, 每个变量的取值范围分别是:D1,......Dn,其中D1,......Dn都是包含有限元素的集合,通常集合中的元素都可以使用整数来表示。目标是找到一组满足约束条件C(V1,......,Vn)的解。下面是一个简单的例子:
例2.有15个变量V1,......,V15,他们的取值范围都是{1,......,15},约束条件为:V1V14很明显这个问题只有一个答案就是Vk=k。我们来看如何让电脑来解决这个问题吧。
首先使用通常的产生并测试的方法:
我们可以通过下面的方法来产生一系列的可能组合:
选择一个尚未赋值的变量,从该变量的值域中选择一个值赋给此变量,重复此步骤直到所有的变量都赋上了值。这个操作将生成一个树状结构:每个非叶节点都代表一个尚未完全赋值的状态,叶节点则代表了一种可能的组合。
满足约束条件的叶节点就是问题的解,不满足约束条件的叶节点就是失败点。在本文中我们将经常使用图形来表达这种树状结构:
其中蓝色圆形代表选择点,即非叶节点。红色方形代表失败点,绿色菱形代表解节点。为了方便起见,一棵所有叶节点都是失败点的子树使用红色三角形代表,而包括了解节点的子树则使用绿色三角形代表。

现在来看看前面的问题:一共有15个变量,每个变量的可能取值有15个,那么总共的可能组合就是15^15=437,893,890,380,859,275种, 就目前的计算机来说这是个天文数字了。

3. 交错产生和测试

前面所介绍的"产生并测试"的方法,是在完全产生了一种组合之后,再来测试这个组合。我们可以把产生和测试交错进行,这样可以极大地提高效率。在每一次选择之后都使用约束条件来判断这步选择是否合理,而不是完全产生了某种组合之后再来判断。例如在上面的例子中,当给V1和V2赋值之后,就可以立即使用V1传播和分配(Propagate and Distribute)
到目前为止,我想你应该已经认识到使用简单的"产生并测试"的方法是行不通的,而"交错产生和测试"虽然能够提高效率,但是也有它的局限性:若使用这种方法来解例2,那么搜索树将包含917477个节点。如果变量数目增加到100又会如何呢?:)
那么使用什么方法呢?我们不希望测试过程只是被动的检测某种组合是否满足条件,而希望测试过程是积极的。这就是说通过测试,我们希望缩小变量的取值范围。在前面的例子中,V1和V2的取值范围都是1到15,但是由于V1然而在通常情况下搜索是不可避免的,我们的目的是在每次搜索之前先通过约束条件尽量缩小变量的取值范围。这种方法在约束程序设计中被叫做"传播和分配(propagate and distribute)"。
传播通过简单的确定性的推导过程尽量减少可能的解的个数。当传播过程无法继续的时候,就需要进行分配。所谓分配就是进行非确定性的选择(下面将详细介绍,如果有何不明白请继续阅读),这样搜索树的尺寸能够尽量缩小,我们可以把传播的过程看作对搜索树的裁剪。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有