Author | Message |
---|---|
Kasutiryo
Posts: 6
|
Posted 19:35 Nov 06, 2019 |
I am trying to make a constraint where for example constraint n > 3
such that n for x in set of elements 1..N {
if the element[x] satisfies some statement then n++
}
Is something like this possible in minizinc? This is my code so far, but it doesn't work of course since I'm not quite sure how to represent the statement above in a constraint. % skyscrapers https://www.conceptispuzzles.com/index.aspx?uri=puzzle/skyscrapers
include "alldifferent.mzn"; int: N = 4; array[1..N, 1..N] of var 1..N: board; % Each row must have all different numbers
constraint forall(i in 1..N) (alldifferent( board[i, 1..N] )); % Each column must have all different numbers
constraint forall(j in 1..N) (alldifferent( board[1..N, j] )); /* My first thought in order to figure out the number of visable skyscrapers within a column and row in a specified order matches the number given is to count how many numbers in a column or row, is greater than the first element in the column or row. For example, in following row...
2 -> | 3 1 2 4 |
Starting from the left hand side...
1 > 3 = False
2 > 3 = False
4 > 3 = True
Since, we can safely assume that the first element/skyscraper in the row is always going to visable we can start with number_of_visable_skyscrapers = 1. And with every element greater than the first one, we can add one two that number.
In which the constraint will be something like: if element[1,2] > element [1,1] then number_of_visable++
1 2
| |
V V
| _, _, _, _ |
| _, _, _, _ | <-2
1-> | _, _, _, _ |
| _, _, _, _ |
^
|
3
*/
% facing south, there should be 1 visable skyscrapers from the north to the south of column 3
constraint x > 1 forall(i in 1..N)(if board[i,3] >= board[1,3] then x++ endif) % facing south, there should be 2 visable skyscrapers from the north to the south of column 4
% facing north, there should be 3 visable skyscrapers from the south to the north of column 3
% facing east, there should be 1 visable skyscraper from the west to east of row 3
% facing west, there should be 2 visable skyscrapers from the east to west of row 2
Last edited by Kasutiryo at
19:50 Nov 06, 2019.
|
rabbott
Posts: 1649
|
Posted 21:11 Nov 06, 2019 |
Assume you have an array of ints and want to know how many of them are greater than the first element. Will this help?
P.S. Don't think in terms of x++. That's for procedural languages. MiniZinc is purely declarative. Last edited by rabbott at
21:32 Nov 06, 2019.
|
Kasutiryo
Posts: 6
|
Posted 13:33 Nov 08, 2019 |
Thanks that helps a lot. I've managed to get these similar constraints working correctly (not including the commented ones out). % facing south, there should be 1 visible skyscraper from the north to the south of column 3. This sum should be zero as the first element board[1,3] will always visible. However, the elements board[2,3], board[3,3], board[4,3] should not be greater than the first element. Therefore if no elements are greater than the first, then no other skyscraper is visible besides the first.
constraint 0 == sum([board[i,3] > board[1,3] | i in 2..N]); % facing south, there should be 2 visible skyscrapers from the north to the south of column 4
constraint 1 == sum([board[i,4] > board[1,4] | i in 2..N]); % facing north, there should be 3 visible skyscrapers from the south to the north of column 3
% constraint 2 == sum([board[i,3] > board[4,3] | i in N-1..1]);
% facing east, there should be 1 visible skyscraper from the west to east of row 3
constraint 0 == sum([board[3,i] > board[3,1] | i in 2..N]); % facing west, there should be 2 visible skyscrapers from the east to west of row 2
% constraint 1 == sum([board[2,i] > board[2,4] | i in N-1..1]);
Running the model gives me the following 2D array: | 1, 2, 4, 3 |
| 2, 1, 3, 4 | | 4, 3, 2, 1 | | 3, 4, 1, 2 | The constraints that aren't commented out are satisfied just right as seen in the array given. However, when I try to find the iterate the row/column from the end (left side for rows, bottom end for columns) to the start, it gives me this: Compiling skyscrapers.mzn
WARNING: model inconsistency detected
in binary '=' operator expression Running skyscrapers.mzn
=====UNSATISFIABLE===== Finished in 130msec
I tried using the following: constraint 2 == sum([board[i,3] > board[4,3] | i in {3,2,1}]); This works. Why doesn't the other method work? Does minizinc now allow to generate numbers from X -> Y where Y < X Last edited by Kasutiryo at
13:36 Nov 08, 2019.
|