回溯搜索以实现约束满足问题

时间:2018-11-08 03:51:50

标签: java algorithm artificial-intelligence

对于一项家庭作业,我的目标是使用最少的剩余值,程度试探法和正向检查进行回溯搜索。需要解决布尔可满足性问题,该布尔可满足性问题由3个布尔变量集组成或彼此求和,并且每个集合的值必须为true。就目前的实现而言,我相信它将最终解决该问题,但是完成该过程所花的时间太长,最终导致Java堆内存不足错误。

通过这种方式,我的实现如下:

  • 具有每个约束的arrayList
  • 一个值数组,索引是每个为true,false或尚未赋值的变量的值,最初所有变量均未赋值。第0个元素用作标志。
  • 每个变量的域的数组:true或false,仅true,仅false或没有可能的值,最初为true或false
  • 数组的arrayList,每个数组都是一个值列表;避免两次尝试相同的事情
  • 表示变量在约束中的次数的数组:这是启发式程度

反向搜索返回一个值数组,并接受一个值数组和一个域数组

首先检查列表中的每个约束,以确保每个变量的域都能正确实现。如果它们都不起作用,则设置第0个标志并退出。此外,如果2个变量的域使第三个变量必须为true才能使语句起作用,则更改该变量的域。

在通过该步骤之后,它将检查vals数组中的每个变量是否都有分配的值,从而成功结束程序。

接下来,它将创建一个临时数组以跟踪所尝试的值,并开始循环。在内部,它将添加每个具有最小发现域(MRV)且没有值/尚未尝试的变量,将其添加到列表中,如果找不到则退出递归。然后,根据度启发式数组从变量中选择出现最多的变量。在平局上,它选择出现在平局中的最后一个,并设置一个标志,这样我们就不会在同一递归中再次尝试该变量。

仍然在循环内,如果该域不仅是false,它首先尝试将该变量的域和值设置为true,否则将其设置为false。它检查变量的值组合是否已经完成,是否重新选择。如果还没有,则将该值组合添加到列表中并执行递归步骤。如果该递归步骤返回了停止标志,则将值换回为所选变量的域和值的值,然后再次尝试,这一次将域和值设置为false,但首先将其添加到尝试的组合列表中,重新选择它是否已经存在,并重置所有尚无值的变量的域,然后执行递归步骤。如果仍然失败,则重置所选域和变量的值,并尝试在同一循环中选择其他变量。循环一旦完成或因所有组合均失败而中断,然后返回values数组。

我可以说它不是在重复自己,但是我不知道如何修复/加快我的实现以使其在合理的时间运行。

1 个答案:

答案 0 :(得分:0)

第一步是为领域创建知识模型。可以使用领域特定语言(DSL)来完成。在DSL语法中,提出了对该问题的可能解决方案。特定领域语言的副作用是必须创建可以解析该语言的语法。该语法可以相反的顺序使用,称为“生成语法”。目的是在DSL中包含尽可能多的领域知识,以使求解器更容易测试所有状态。

不幸的是,问题仅包含有关域本身的一些信息。根据说明,可以打开或关闭三个变量。这将生成2x2x2 = 8的可能状态空间,这对于域而言似乎有点容易,因为如果求解器测试出所有8个状态,则求解器将完成。因此,我想这个问题会更难解决,但在说明中未作解释。尽管如此,第一步是将问题转换为可以由语法解析的语言。