当我知道有解决方案时,约束报告为不满足(菜鸟错误?)
Constraints reported as UNSATISFIABLE when I know there is a solution (rookie error?)
作为第一次使用 MiniZinc 的用户,我曾尝试用它编写一个我已经知道解决方案的逻辑难题。但是,当我尝试编写所有拼图线索和 运行 代码时,它会报告 =====UNSATISFIABLE=====
。下面的代码 运行s 但如果两个注释掉的约束中的任何一个未被注释,则找不到解决方案。
很可能是我在某处犯了错误,但我正在努力寻找它。非常感谢任何帮助!
% Christmas Puzzle 2021
include "alldifferent.mzn";
% There are 9 reindeer numbered 1 to 9 and there are 9 different types of food.
% The reindeer fly on three test flights and are fed one of the foods prior to
% each test flight.
set of int: REINDEER = 1..9;
set of int: FOOD = 1..9;
set of int: FLIGHT = 1..3;
% Each reindeer has a favourite food
array[REINDEER] of var FOOD: favourite;
array[FLIGHT, REINDEER] of var FOOD: fed;
%%% CLUES %%%
% Reindeer 2’s favourite food is 4
constraint favourite[2] == 4;
% Before test flight 1, reindeer 2 was given food 4
constraint fed[1, 4] == 4;
% Before test flight 2, reindeer 2 was given food 4
constraint fed[2, 4] == 4;
% Before test flight 3, reindeer 2 was given food 6
constraint fed[3, 4] == 6;
% Before test flight 3, a total of 4 reindeer were given the wrong food
constraint count([fed[3, r] - favourite[r] | r in REINDEER], 0, 5);
% Reindeer 4’s favourite food is a factor of 607
constraint favourite[4] == 1;
% Reindeer 4 was given the same food before all three test flights.
constraint fed[1, 4] == fed[2, 4];
% =====UNSATISFIABLE=====
%constraint fed[1, 4] == fed[3, 4];
% Before test flight 1, reindeer 8 was given food 3
constraint fed[1, 8] == 3;
% Before test flight 1, a total of 2 reindeer were given the wrong food.
constraint count([fed[1, r] - favourite[r] | r in REINDEER], 0, 7);
% Before test flight 1, reindeer 9 was given food 6
constraint fed[1, 9] == 6;
% Before test flight 2, reindeer 9 was given food 5
constraint fed[2, 9] == 5;
% Before test flight 3, reindeer 9 was given food 1
constraint fed[3, 9] == 1;
% Before test flight 2, reindeer 4 was not given food 9
constraint fed[2, 4] != 9;
% Before test flight 2, 2 reindeer were given the wrong food
% =====UNSATISFIABLE=====
%constraint count([fed[2, r] - favourite[r] | r in REINDEER], 0, 7);
% Reindeer 1 was given food 1 before all three test flights
constraint fed[1, 1] == 1;
constraint fed[2, 1] == 1;
constraint fed[3, 1] == 1;
% Before test flight 2, all the reindeer were given different foods
constraint all_different([fed[2, r] | r in REINDEER]);
% Before test flight 1, reindeer 7 was not given food 7
constraint fed[1, 7] != 7;
% Before test flight 2, reindeer 8 was given food 2
constraint fed[2, 8] == 2;
% Before test flight 3, reindeer 5 was not given food 7
constraint fed[3, 5] !=7;
% Before test flight 3, 3 reindeer had the food equal to their number
constraint count([fed[3, r] - r | r in REINDEER], 0, 3);
% Before test flight 3, reindeer 7 was given food that is a factor of 148
constraint fed[3, 7] == 1 \/ fed[3, 7] == 2 \/ fed[3, 7] == 4;
% Before test flight 3, reindeer 7 was not given food 1
constraint fed[3, 7] != 1;
% Before test flight 3, no reindeer was given food 2
constraint forall([fed[3, r] != 2 | r in REINDEER]);
% Before test flight 1, reindeer 7 was not given food 9
constraint fed[1, 7] != 9;
solve satisfy;
output [
"Favourites = ", show(favourite), "\n",
"Test flight 1 = ", show([fed[1, r] | r in REINDEER]), "\n",
"Test flight 2 = ", show([fed[2, r] | r in REINDEER]), "\n",
"Test flight 3 = ", show([fed[3, r] | r in REINDEER]), "\n"
];
请注意,以下结果应该满足所有线索:
Favourites = [1, 4, 3, 1, 9, 6, 8, 3, 5]
Test flight 1 = [1, 4, 3, 7, 9, 6, 8, 3, 6]
Test flight 2 = [1, 4, 3, 7, 9, 6, 8, 2, 5]
Test flight 3 = [1, 6, 3, 7, 9, 6, 4, 3, 1]
我不知道是否有通过从该解决方案向后工作以查看未满足哪些约束(如果有)的调试方法。
第一个约束中有一些拼写错误,可能是 copy/paste 个问题。以下是更改:
% Before test flight 1, reindeer 2 was given food 4
% constraint fed[1, 4] == 4; % ORIG
constraint fed[1, 2] == 4; % hakank
% Before test flight 2, reindeer 2 was given food 4
% constraint fed[2, 4] == 4; % ORIG
constraint fed[2, 2] == 4; % hakank
% Before test flight 3, reindeer 2 was given food 6
% constraint fed[3, 4] == 6; % ORIG
constraint fed[3, 2] == 6; % hakank
现在模型输出唯一解:
Favourites = [1, 4, 3, 1, 9, 6, 8, 3, 5]
Test flight 1 = [1, 4, 3, 7, 9, 6, 8, 3, 6]
Test flight 2 = [1, 4, 3, 7, 9, 6, 8, 2, 5]
Test flight 3 = [1, 6, 3, 7, 9, 6, 4, 3, 1]
----------
==========
有一种方法可以在 MiniZinc 中系统地调试 UNSAT 模型:使用 findMUS 求解器(MUS=Minimal Unsatisfiable Subsets)。它可能会显示冲突的地方。在此处查看有关 findMUS 的更多信息:https://www.minizinc.org/doc-2.5.5/en/find_mus.html
实际上我首先尝试了 findMUS,但在这种情况下并没有太大帮助。相反,我查看了所有线索并与约束条件进行了比较。
以下模型按预期工作:
% Christmas Puzzle 2021
include "alldifferent.mzn";
% There are 9 reindeer numbered 1 to 9 and there are 9 different types of food.
% The reindeer fly on three test flights and are fed one of the foods prior to
% each test flight.
set of int: REINDEER = 1..9;
set of int: FOOD = 1..9;
set of int: FLIGHT = 1..3;
% Each reindeer has a favourite food
array[REINDEER] of var FOOD: favourite;
array[FLIGHT, REINDEER] of var FOOD: fed;
%%% CLUES %%%
% Reindeer 2’s favourite food is 4
constraint favourite[2] == 4;
% Before test flight 1, reindeer 2 was given food 4
% constraint fed[1, 4] == 4;
% changed reindeer from 4 to 2
constraint fed[1, 2] == 4;
% Before test flight 2, reindeer 2 was given food 4
% constraint fed[2, 4] == 4;
% changed reindeer from 4 to 2
constraint fed[2, 2] == 4;
% Before test flight 3, reindeer 2 was given food 6
% constraint fed[3, 4] == 6;
% changed reindeer from 4 to 2
constraint fed[3, 2] == 6;
% Before test flight 3, a total of 4 reindeer were given the wrong food
% constraint count([fed[3, r] - favourite[r] | r in REINDEER], 0, 5);
constraint 4 == sum([fed[3, r] != favourite[r] | r in REINDEER]);
% Reindeer 4’s favourite food is a factor of 607
% 607 is a prime number
constraint favourite[4] == 1;
% Reindeer 4 was given the same food before all three test flights.
% constraint fed[1, 4] == fed[2, 4];
% =====UNSATISFIABLE=====
% constraint fed[1, 4] == fed[3, 4];
constraint forall([fed[1, 4] == fed[f, 4] | f in FLIGHT]);
% Before test flight 1, reindeer 8 was given food 3
constraint fed[1, 8] == 3;
% Before test flight 1, a total of 2 reindeer were given the wrong food.
% constraint count([fed[1, r] - favourite[r] | r in REINDEER], 0, 7);
constraint 2 == sum([fed[1, r] != favourite[r] | r in REINDEER]);
% Before test flight 1, reindeer 9 was given food 6
constraint fed[1, 9] == 6;
% Before test flight 2, reindeer 9 was given food 5
constraint fed[2, 9] == 5;
% Before test flight 3, reindeer 9 was given food 1
constraint fed[3, 9] == 1;
% Before test flight 2, reindeer 4 was not given food 9
constraint fed[2, 4] != 9;
% Before test flight 2, 2 reindeer were given the wrong food
% =====UNSATISFIABLE=====
%constraint count([fed[2, r] - favourite[r] | r in REINDEER], 0, 7);
constraint 2 == sum([fed[2, r] != favourite[r] | r in REINDEER]);
% Reindeer 1 was given food 1 before all three test flights
constraint fed[1, 1] == 1;
constraint fed[2, 1] == 1;
constraint fed[3, 1] == 1;
% Before test flight 2, all the reindeer were given different foods
constraint all_different([fed[2, r] | r in REINDEER]);
% Before test flight 1, reindeer 7 was not given food 7
constraint fed[1, 7] != 7;
% Before test flight 2, reindeer 8 was given food 2
constraint fed[2, 8] == 2;
% Before test flight 3, reindeer 5 was not given food 7
constraint fed[3, 5] !=7;
% Before test flight 3, 3 reindeer had the food equal to their number
% constraint count([fed[3, r] - r | r in REINDEER], 0, 3);
constraint 3 == sum([fed[1, r] == r | r in REINDEER]);
% Before test flight 3, reindeer 7 was given food that is a factor of 148
% 148 = 2 x 2 x 37 = 4 x 37 = 1 x 148
% constraint fed[3, 7] == 1 \/ fed[3, 7] == 2 \/ fed[3, 7] == 4;
constraint fed[3, 7] in {1, 2, 4};
% Before test flight 3, reindeer 7 was not given food 1
constraint fed[3, 7] != 1;
% Before test flight 3, no reindeer was given food 2
constraint forall([fed[3, r] != 2 | r in REINDEER]);
% Before test flight 1, reindeer 7 was not given food 9
constraint fed[1, 7] != 9;
solve satisfy;
output [
"Favourites = ", show(favourite), "\n",
"Test flight 1 = ", show([fed[1, r] | r in REINDEER]), "\n",
"Test flight 2 = ", show([fed[2, r] | r in REINDEER]), "\n",
"Test flight 3 = ", show([fed[3, r] | r in REINDEER]), "\n"
];
作为第一次使用 MiniZinc 的用户,我曾尝试用它编写一个我已经知道解决方案的逻辑难题。但是,当我尝试编写所有拼图线索和 运行 代码时,它会报告 =====UNSATISFIABLE=====
。下面的代码 运行s 但如果两个注释掉的约束中的任何一个未被注释,则找不到解决方案。
很可能是我在某处犯了错误,但我正在努力寻找它。非常感谢任何帮助!
% Christmas Puzzle 2021
include "alldifferent.mzn";
% There are 9 reindeer numbered 1 to 9 and there are 9 different types of food.
% The reindeer fly on three test flights and are fed one of the foods prior to
% each test flight.
set of int: REINDEER = 1..9;
set of int: FOOD = 1..9;
set of int: FLIGHT = 1..3;
% Each reindeer has a favourite food
array[REINDEER] of var FOOD: favourite;
array[FLIGHT, REINDEER] of var FOOD: fed;
%%% CLUES %%%
% Reindeer 2’s favourite food is 4
constraint favourite[2] == 4;
% Before test flight 1, reindeer 2 was given food 4
constraint fed[1, 4] == 4;
% Before test flight 2, reindeer 2 was given food 4
constraint fed[2, 4] == 4;
% Before test flight 3, reindeer 2 was given food 6
constraint fed[3, 4] == 6;
% Before test flight 3, a total of 4 reindeer were given the wrong food
constraint count([fed[3, r] - favourite[r] | r in REINDEER], 0, 5);
% Reindeer 4’s favourite food is a factor of 607
constraint favourite[4] == 1;
% Reindeer 4 was given the same food before all three test flights.
constraint fed[1, 4] == fed[2, 4];
% =====UNSATISFIABLE=====
%constraint fed[1, 4] == fed[3, 4];
% Before test flight 1, reindeer 8 was given food 3
constraint fed[1, 8] == 3;
% Before test flight 1, a total of 2 reindeer were given the wrong food.
constraint count([fed[1, r] - favourite[r] | r in REINDEER], 0, 7);
% Before test flight 1, reindeer 9 was given food 6
constraint fed[1, 9] == 6;
% Before test flight 2, reindeer 9 was given food 5
constraint fed[2, 9] == 5;
% Before test flight 3, reindeer 9 was given food 1
constraint fed[3, 9] == 1;
% Before test flight 2, reindeer 4 was not given food 9
constraint fed[2, 4] != 9;
% Before test flight 2, 2 reindeer were given the wrong food
% =====UNSATISFIABLE=====
%constraint count([fed[2, r] - favourite[r] | r in REINDEER], 0, 7);
% Reindeer 1 was given food 1 before all three test flights
constraint fed[1, 1] == 1;
constraint fed[2, 1] == 1;
constraint fed[3, 1] == 1;
% Before test flight 2, all the reindeer were given different foods
constraint all_different([fed[2, r] | r in REINDEER]);
% Before test flight 1, reindeer 7 was not given food 7
constraint fed[1, 7] != 7;
% Before test flight 2, reindeer 8 was given food 2
constraint fed[2, 8] == 2;
% Before test flight 3, reindeer 5 was not given food 7
constraint fed[3, 5] !=7;
% Before test flight 3, 3 reindeer had the food equal to their number
constraint count([fed[3, r] - r | r in REINDEER], 0, 3);
% Before test flight 3, reindeer 7 was given food that is a factor of 148
constraint fed[3, 7] == 1 \/ fed[3, 7] == 2 \/ fed[3, 7] == 4;
% Before test flight 3, reindeer 7 was not given food 1
constraint fed[3, 7] != 1;
% Before test flight 3, no reindeer was given food 2
constraint forall([fed[3, r] != 2 | r in REINDEER]);
% Before test flight 1, reindeer 7 was not given food 9
constraint fed[1, 7] != 9;
solve satisfy;
output [
"Favourites = ", show(favourite), "\n",
"Test flight 1 = ", show([fed[1, r] | r in REINDEER]), "\n",
"Test flight 2 = ", show([fed[2, r] | r in REINDEER]), "\n",
"Test flight 3 = ", show([fed[3, r] | r in REINDEER]), "\n"
];
请注意,以下结果应该满足所有线索:
Favourites = [1, 4, 3, 1, 9, 6, 8, 3, 5]
Test flight 1 = [1, 4, 3, 7, 9, 6, 8, 3, 6]
Test flight 2 = [1, 4, 3, 7, 9, 6, 8, 2, 5]
Test flight 3 = [1, 6, 3, 7, 9, 6, 4, 3, 1]
我不知道是否有通过从该解决方案向后工作以查看未满足哪些约束(如果有)的调试方法。
第一个约束中有一些拼写错误,可能是 copy/paste 个问题。以下是更改:
% Before test flight 1, reindeer 2 was given food 4
% constraint fed[1, 4] == 4; % ORIG
constraint fed[1, 2] == 4; % hakank
% Before test flight 2, reindeer 2 was given food 4
% constraint fed[2, 4] == 4; % ORIG
constraint fed[2, 2] == 4; % hakank
% Before test flight 3, reindeer 2 was given food 6
% constraint fed[3, 4] == 6; % ORIG
constraint fed[3, 2] == 6; % hakank
现在模型输出唯一解:
Favourites = [1, 4, 3, 1, 9, 6, 8, 3, 5]
Test flight 1 = [1, 4, 3, 7, 9, 6, 8, 3, 6]
Test flight 2 = [1, 4, 3, 7, 9, 6, 8, 2, 5]
Test flight 3 = [1, 6, 3, 7, 9, 6, 4, 3, 1]
----------
==========
有一种方法可以在 MiniZinc 中系统地调试 UNSAT 模型:使用 findMUS 求解器(MUS=Minimal Unsatisfiable Subsets)。它可能会显示冲突的地方。在此处查看有关 findMUS 的更多信息:https://www.minizinc.org/doc-2.5.5/en/find_mus.html
实际上我首先尝试了 findMUS,但在这种情况下并没有太大帮助。相反,我查看了所有线索并与约束条件进行了比较。
以下模型按预期工作:
% Christmas Puzzle 2021
include "alldifferent.mzn";
% There are 9 reindeer numbered 1 to 9 and there are 9 different types of food.
% The reindeer fly on three test flights and are fed one of the foods prior to
% each test flight.
set of int: REINDEER = 1..9;
set of int: FOOD = 1..9;
set of int: FLIGHT = 1..3;
% Each reindeer has a favourite food
array[REINDEER] of var FOOD: favourite;
array[FLIGHT, REINDEER] of var FOOD: fed;
%%% CLUES %%%
% Reindeer 2’s favourite food is 4
constraint favourite[2] == 4;
% Before test flight 1, reindeer 2 was given food 4
% constraint fed[1, 4] == 4;
% changed reindeer from 4 to 2
constraint fed[1, 2] == 4;
% Before test flight 2, reindeer 2 was given food 4
% constraint fed[2, 4] == 4;
% changed reindeer from 4 to 2
constraint fed[2, 2] == 4;
% Before test flight 3, reindeer 2 was given food 6
% constraint fed[3, 4] == 6;
% changed reindeer from 4 to 2
constraint fed[3, 2] == 6;
% Before test flight 3, a total of 4 reindeer were given the wrong food
% constraint count([fed[3, r] - favourite[r] | r in REINDEER], 0, 5);
constraint 4 == sum([fed[3, r] != favourite[r] | r in REINDEER]);
% Reindeer 4’s favourite food is a factor of 607
% 607 is a prime number
constraint favourite[4] == 1;
% Reindeer 4 was given the same food before all three test flights.
% constraint fed[1, 4] == fed[2, 4];
% =====UNSATISFIABLE=====
% constraint fed[1, 4] == fed[3, 4];
constraint forall([fed[1, 4] == fed[f, 4] | f in FLIGHT]);
% Before test flight 1, reindeer 8 was given food 3
constraint fed[1, 8] == 3;
% Before test flight 1, a total of 2 reindeer were given the wrong food.
% constraint count([fed[1, r] - favourite[r] | r in REINDEER], 0, 7);
constraint 2 == sum([fed[1, r] != favourite[r] | r in REINDEER]);
% Before test flight 1, reindeer 9 was given food 6
constraint fed[1, 9] == 6;
% Before test flight 2, reindeer 9 was given food 5
constraint fed[2, 9] == 5;
% Before test flight 3, reindeer 9 was given food 1
constraint fed[3, 9] == 1;
% Before test flight 2, reindeer 4 was not given food 9
constraint fed[2, 4] != 9;
% Before test flight 2, 2 reindeer were given the wrong food
% =====UNSATISFIABLE=====
%constraint count([fed[2, r] - favourite[r] | r in REINDEER], 0, 7);
constraint 2 == sum([fed[2, r] != favourite[r] | r in REINDEER]);
% Reindeer 1 was given food 1 before all three test flights
constraint fed[1, 1] == 1;
constraint fed[2, 1] == 1;
constraint fed[3, 1] == 1;
% Before test flight 2, all the reindeer were given different foods
constraint all_different([fed[2, r] | r in REINDEER]);
% Before test flight 1, reindeer 7 was not given food 7
constraint fed[1, 7] != 7;
% Before test flight 2, reindeer 8 was given food 2
constraint fed[2, 8] == 2;
% Before test flight 3, reindeer 5 was not given food 7
constraint fed[3, 5] !=7;
% Before test flight 3, 3 reindeer had the food equal to their number
% constraint count([fed[3, r] - r | r in REINDEER], 0, 3);
constraint 3 == sum([fed[1, r] == r | r in REINDEER]);
% Before test flight 3, reindeer 7 was given food that is a factor of 148
% 148 = 2 x 2 x 37 = 4 x 37 = 1 x 148
% constraint fed[3, 7] == 1 \/ fed[3, 7] == 2 \/ fed[3, 7] == 4;
constraint fed[3, 7] in {1, 2, 4};
% Before test flight 3, reindeer 7 was not given food 1
constraint fed[3, 7] != 1;
% Before test flight 3, no reindeer was given food 2
constraint forall([fed[3, r] != 2 | r in REINDEER]);
% Before test flight 1, reindeer 7 was not given food 9
constraint fed[1, 7] != 9;
solve satisfy;
output [
"Favourites = ", show(favourite), "\n",
"Test flight 1 = ", show([fed[1, r] | r in REINDEER]), "\n",
"Test flight 2 = ", show([fed[2, r] | r in REINDEER]), "\n",
"Test flight 3 = ", show([fed[3, r] | r in REINDEER]), "\n"
];