【问题标题】:Trying to set up a constraint on MiniZinc with array of sets尝试使用一组集合对 MiniZinc 设置约束
【发布时间】:2020-04-24 08:57:36
【问题描述】:

我收到了一个问题,我应该在哪里创建一组团队,只有一个简单的约束,即有两个集合数组,其中两个成员必须在一起,哪些不应该在一起。我是 Minizinc 的新手,所以我很难处理带有一组集合的决策变量。团队的大小也必须为 n。

例如:

GroupsThatMustBePaired = [{1,3},{4,5}]
GroupsThatShouldNot = [{2,3}]

Output = [{1,3},{4,5},{2,6}..etc]

有什么帮助吗?

【问题讨论】:

    标签: arrays constraint-programming minizinc


    【解决方案1】:

    一开始使用集合变量可能会有点棘手,但如果你能回到你在数学中学习集合的时候,那么这些概念应该非常熟悉。

    以下是如何编写模型的示例。它有一些额外的限制来确保“团队”包含每个人,没有人两次,并具有最大容量 包括“all_disjoint.mzn”;

    set of int: MEMBERS = 1..6;
    set of int: GROUPS = 1..3;
    array[int] of set of MEMBERS: GroupsThatMustBePaired = [{1,3},{4,5}];
    array[int] of set of MEMBERS: GroupsThatShouldNot = [{2,3}];
    
    array[GROUPS] of var set of MEMBERS: teams;
    
    % Team members can only be part of one team
    constraint all_disjoint(teams);
    % Everyone must be part of a team
    constraint array_union(teams) = MEMBERS;
    % Maximal number of people per group
    constraint forall(g in GROUPS) ( card(teams[g]) <= 2 );
    
    % Eliminate bad groups
    constraint forall(g in GROUPS, i in index_set(GroupsThatShouldNot)) (
      not (GroupsThatShouldNot[i] subset teams[g])
    );
    
    % Enforce good groups
    constraint forall(i in index_set(GroupsThatMustBePaired)) (
      exists(g in GROUPS) (
        GroupsThatMustBePaired[i] subset teams[g]
      )
    );
    

    如果您想更改此模型,请注意:大多数求解器不直接支持设置变量,而是将此模型转换为使用布尔变量。这不一定更糟,但如果您认为使用布尔变量可以更轻松地表达问题,请记住这一点。

    在这种特殊情况下,您可能需要考虑使用整数变量。这个问题可以看作是分配问题,其中成员被分配到团队中。这考虑了团队成员而不是团队的观点。尽管这可能会使 subset 约束更难编写,但这种结构将不再需要 all_disjointarray_union 约束,因为我们知道每个人都会在一个团队中,没有人会在多个团队中。在这种情况下,card(基数)集约束可以替换为 global_cardinality_low_up 整数约束。

    【讨论】:

    • 非常感谢!这是一个很大的帮助。你知道我可以用什么资源来练习更多吗?特别是使用设置变量。
    • 您可以查看 MiniZinc 教程中的设置示例:minizinc.org/doc-2.4.3/en/modelling2.html#set-constraints。 MiniZinc 的一般实践来自于实际制作模型。我认为专注于建模而不是 MiniZinc 的特定方面是明智的。如果您在 MiniZinc 方面没有太多经验,Coursera 上的三门 MiniZinc 课程是一个很好的起点
    • 嘿,非常感谢!我还有一个简单的问题。我正在计算锦标赛的总比赛,一名球员与另一名互补非常好的球员组队。所以我们有 EffectiveGroup = {[4,5], [6]}。竞争是根据有效性组中有多少人配对来计算的。因此,如果玩家 1(第 i 行对应于玩家 i)与 4 和 5 组队,则得分为 2。我想做相交,但我遇到了如何迭代它的问题。有什么想法吗?
    • @DavidGoliath 欢迎来到 SO;由于答案解决了您的问题,请接受它 - 请参阅What should I do when someone answers my question?
    猜你喜欢
    • 2014-11-18
    • 1970-01-01
    • 2017-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-02
    • 2018-10-23
    • 1970-01-01
    相关资源
    最近更新 更多