如何限制约束编程中的零的数量

3 投票
1 回答
1202 浏览
提问于 2025-04-17 21:37

对于给定的 n 和 m,我会遍历所有 n 行 m 列的部分 循环矩阵,这些矩阵的元素只能是 0 或 1。我想找出是否存在一个矩阵,使得没有两个列的子集的和是相同的。在这里,当我们加列的时候,是逐个元素相加的。我的代码目前是通过 ortools 进行约束编程的。以下是我的代码。

from scipy.linalg import circulant
import numpy as np
import itertools
from ortools.constraint_solver import pywrapcp as cs

n = 4
m = 6

def isdetecting(matrix):
    solver = cs.Solver("scip")
    X = np.array([solver.IntVar(values) for i in range(matrix.shape[1])])
    X1 = X.tolist()
    for row in matrix:
        x = X[row].tolist()
        solver.Add(solver.Sum(x) == 0)
    db = solver.Phase(X1, solver.CHOOSE_FIRST_UNBOUND, solver.ASSIGN_CENTER_VALUE)
    solver.NewSearch(db)
    count = 0
#Find just one non-zero solution if there is one
    while (solver.NextSolution() and count < 2):
        solution = [x.Value() for x in X1]
        count += 1
    solver.EndSearch()
    if (count == 1):
        return True

values = [-1,0,1]
nosols = 0
for row in itertools.product([0,1],repeat = m):
    M = np.array(circulant(row)[0:n], dtype=bool)
    if isdetecting(M):
        nosols += 1
        print M.astype(int)

代码中的 values = [-1,0,1] 这一行允许解中有任意数量的零。那么我该如何指定解中允许的零的确切数量呢?

1 个回答

4

在or-tools/Python中,有一个全局约束的工具叫做solver.Count(),可以用来解决一些问题。举个例子:

 the_count = 1 # number of 0's allowed
 solver.Add(solver.Count(X1, 0,the_count))

这里的“the_count”是指在数组“X1”中允许出现的0的数量。这个数量可以是一个固定的值,也可以是一个决策变量(也就是说,你可以通过其他约束来限制这个值,或者让变量的范围自动限制这个数量,比如范围1..4就限制了出现次数在1到4之间)。

“X1”是一个需要检查的决策变量数组。第二个参数“0”是指在X中要统计的值。

使用solver.Count()的一个例子可以在这里找到:http://hakank.org/or-tools/young_tableaux.py

还有一个更通用的工具叫做solver.Distribute(也叫全局基数计数,GCC),它可以同时统计和限制多个值。你可以参考我的deBruijn序列模型,看看它是怎么用的:http://hakank.org/or-tools/debruijn_binary.py

撰写回答