快速和简单的约束规划涉及向量(数组)

fast and simple constraint programming involving vectors (arrays)

本文关键字:向量 数组 规划 简单 约束      更新时间:2023-10-16

我有很多很多向量,我需要用一些非常基本的一阶逻辑来检查数字的重复。

我可以使用十字路口,但那被证明太慢了。我想我可以把它变成位问题。完整的整数集合是已知的,并且每个向量/数组都可以用bitset表示,但是我只能找到一半的解。

我目前使用循环和向量相交,但事实证明,对于我需要检查的问题数量来说,它太慢了。

举个简单的例子:

E: 1 2
F: 2 4
M: 1 3
N: 4 5  
A: 5 6

我想确定的问题是,总是使用较大的格式:

(E || F) && (M || N) && A -> which is proven as possible by selecting F,M,A.

我需要验证上述内容是否可以不重复。

是否有一种方法可以检查像这样的向量/数组,比900万次循环更快?约束库是唯一的选择吗?

为了澄清:

容器是std::vector。

向量包含任意整数。

我需要一个问题一个问题地检查它们,以确定完整的整数集。

使用指定的条件逻辑来选择整个向量,会发生重复吗?所使用的条件操作符总是只能是"与"answers"或"。我列出的问题是一个简化的版本,但这就是它的全部内容。只是大小不同而已。

我不太关心的输出…它可以是一个布尔值,另一个可能重复的向量,等等。我在努力寻找适合这项工作的工具,而不是浪费时间。

在我目前的设置中,我会通过分析像A这样的强制项目并删除与…相交的任何东西来解决这个问题。(在这种情况下,N…然后我将再次循环,并对M执行相同的过程,这现在是一个强制选择,并删除E,留下f。

如果我正确理解这个问题,这是一个集分割问题,其中来自某个"宇宙"的值(即集合中的所有值)应该被选择,以便一个值只是在所选集合中的一个。对于这是一个特定的条件,集合的可能组合是可能的。

我已经在MiniZinc(一个非常高级的约束编程系统,请参阅我的MiniZinc页面获取更多信息和进一步链接:http://www.hakank.org/minizinc/)中实现了上述(简单)问题。

模型在这里:http://www.hakank.org/minizinc/set_partition_stackoverflow.mzn全文复制如下:

<>之前包括"globals.mzn";Int: n = 5;组数%array [1 . .N] of set of int: s =({1,2}, % e{2,4}, % f{1,3}, % m{4,5}, % n{5,6} % a];%所有值("宇宙")Set of int: values = {j | I in 1..N, j in s[i]};%决策变量array [1 . .N]的var bool: x;%要选择的集合(以s为单位)array [1 . .N]的var值集:xs;%选择的集合解决满足;%最小化所选集合的数量%求解最小化sum(i in 1..n) (bool2int(card(xs[i])> 0));约束%条件% (e || f) && (m || n) && a((x[1] /x[2])/(x[3] /x[4])/ x[5])/Forall (i in 1..n) (%如果选择了这个集合(在x[i]中),将s[i]放在xs[i]中(x[i] xs[i] = s[i])/ %确保未选中的集合在xs中表示为{}(not(x[i]) card(xs[i]) = 0))确保只在一个集合中选择一个值Partition_set ([xs[i] | i in 1..]n],值);输出("x: " ++ show(x) ++ "n" ++"xs: " ++ show(xs) ++ "n"];之前

这个问题只有一个解决方案:

<>之前X:[假,真,真,假,真]x: [{}, {2,4}, {1,3}, {}, 5..6]之前

,其中"x"是一个布尔数组,如果一个集合应该被选中或不被选中,"xs"包含被选中的集合(如果一个集合没有被选中,则元素为{},即空)。集合的划分是用partition_set函数完成的,该函数确保一个值在一个集合中,并且宇宙中的所有值(集合"值")都在某个集合中。

我不确定这个MiniZinc模型是否有帮助,但如果没有别的,你可能会把它看作一种灵感。此外,条件的处理在这个模型中是硬编码的,所以这里没有处理。

基于c++的CP系统Gecode (http://www.gecode.org/)支持设置变量和分区约束(在Gecode中称为"disjoint"),尽管我还没有针对这个问题测试过它。下面是一个如何在标准分区问题中使用"disjoint"的示例:http://www.hakank.org/gecode/set_partition.cpp .