Skip to content

Commit

Permalink
Merge pull request #183 from cyderize/feature/cumulatives
Browse files Browse the repository at this point in the history
Add support for the cumulatives constraint for MiniZinc
  • Loading branch information
zayenz committed Nov 13, 2023
2 parents 2e1359e + 396e5d1 commit 3a29c3e
Show file tree
Hide file tree
Showing 13 changed files with 737 additions and 2 deletions.
8 changes: 8 additions & 0 deletions Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -1168,6 +1168,14 @@ FLATZINCTESTSRC0 = \
test/flatzinc/blocksworld_instance_1.cpp \
test/flatzinc/blocksworld_instance_2.cpp \
test/flatzinc/cumulatives.cpp \
test/flatzinc/cumulatives_full_1.cpp \
test/flatzinc/cumulatives_full_2.cpp \
test/flatzinc/cumulatives_full_3.cpp \
test/flatzinc/cumulatives_full_4.cpp \
test/flatzinc/cumulatives_full_5.cpp \
test/flatzinc/cumulatives_full_6.cpp \
test/flatzinc/cumulatives_full_7.cpp \
test/flatzinc/cumulatives_full_8.cpp \
test/flatzinc/cutstock.cpp \
test/flatzinc/eq20.cpp \
test/flatzinc/factory_planning_instance.cpp \
Expand Down
7 changes: 7 additions & 0 deletions changelog.in
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ Date: 2020-??-??
[DESCRIPTION]
Let's see.

[ENTRY]
Module: flatzinc
What: change
Rank: minor
[DESCRIPTION]
Expose the full cumulatives scheduling constraint to MiniZinc.

[ENTRY]
Module: flatzinc
What: bug
Expand Down
22 changes: 22 additions & 0 deletions gecode/flatzinc/mznlib/fzn_cumulatives.mzn
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
include "fzn_cumulatives_decomp.mzn";

predicate fzn_cumulatives(array[int] of var int: s,
array[int] of var int: d,
array[int] of var int: r,
array[int] of var int: m,
array[int] of var int: b,
bool: upper,
int: min_m) =
if is_fixed(b) then
% Propagator only supports fixed bounds
gecode_cumulatives(s, d, r, [m_i - min_m | m_i in m], fix(b), upper)
else
fzn_cumulatives_decomp(s, d, r, m, b, upper)
endif;

predicate gecode_cumulatives(array[int] of var int: s,
array[int] of var int: d,
array[int] of var int: r,
array[int] of var int: m,
array[int] of int: b,
bool: upper);
74 changes: 74 additions & 0 deletions gecode/flatzinc/registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1323,6 +1323,80 @@ namespace Gecode { namespace FlatZinc {

void p_cumulatives(FlatZincSpace& s, const ConExpr& ce,
AST::Node* ann) {
if (ce.size() == 6) {
// Full cumulatives call
IntVarArgs start = s.arg2intvarargs(ce[0]);
IntVarArgs duration = s.arg2intvarargs(ce[1]);
IntVarArgs resources = s.arg2intvarargs(ce[2]);
IntVarArgs machine = s.arg2intvarargs(ce[3]);
IntArgs bound = s.arg2intargs(ce[4]);
bool upper = ce[5]->getBool();
int n = start.size();

if (duration.assigned()) {
IntArgs durationI(n);
for (int i = n; (i--) != 0;) {
durationI[i] = duration[i].val();
}
IntVarArgs end(n);
for (int i = n; (i--) != 0;) {
end[i] = expr(s, start[i] + durationI[i]);
}
if (machine.assigned()) {
IntArgs machineI(n);
for (int i = n; (i--) != 0;) {
machineI[i] = machine[i].val();
}
if (resources.assigned()) {
IntArgs resourcesI(n);
for (int i = n; (i--) != 0;) {
resourcesI[i] = resources[i].val();
}
cumulatives(s, machineI, start, durationI, end, resourcesI, bound, upper, s.ann2ipl(ann));
} else {
cumulatives(s, machineI, start, durationI, end, resources, bound, upper, s.ann2ipl(ann));
}
} else if (resources.assigned()) {
IntArgs resourcesI(n);
for (int i = n; (i--) != 0;) {
resourcesI[i] = resources[i].val();
}
cumulatives(s, machine, start, durationI, end, resourcesI, bound, upper, s.ann2ipl(ann));
} else {
cumulatives(s, machine, start, durationI, end, resources, bound, upper, s.ann2ipl(ann));
}
} else {
IntVarArgs end(n);
for (int i = n; (i--) != 0;) {
end[i] = expr(s, start[i] + duration[i]);
}
if (machine.assigned()) {
IntArgs machineI(n);
for (int i = n; (i--) != 0;) {
machineI[i] = machine[i].val();
}
if (resources.assigned()) {
IntArgs resourcesI(n);
for (int i = n; (i--) != 0;) {
resourcesI[i] = resources[i].val();
}
cumulatives(s, machineI, start, duration, end, resourcesI, bound, upper, s.ann2ipl(ann));
} else {
cumulatives(s, machineI, start, duration, end, resources, bound, upper, s.ann2ipl(ann));
}
} else if (resources.assigned()) {
IntArgs resourcesI(n);
for (int i = n; (i--) != 0;) {
resourcesI[i] = resources[i].val();
}
cumulatives(s, machine, start, duration, end, resourcesI, bound, upper, s.ann2ipl(ann));
} else {
cumulatives(s, machine, start, duration, end, resources, bound, upper, s.ann2ipl(ann));
}
}
return;
}

IntVarArgs start = s.arg2intvarargs(ce[0]);
IntVarArgs duration = s.arg2intvarargs(ce[1]);
IntVarArgs height = s.arg2intvarargs(ce[2]);
Expand Down
4 changes: 2 additions & 2 deletions test/flatzinc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ namespace Test { namespace FlatZinc {
std::string cmd("fzn-gecode");
int argc = static_cast<int>(_cmdlineOpt.size()) + 1;
std::vector<char*> argv(argc);
argv[0] = cmd.data();
argv[0] = const_cast<char*>(cmd.data());
for (int i = 1; i < argc; ++i) {
argv[i] = _cmdlineOpt[i-1].data();
argv[i] = const_cast<char*>(_cmdlineOpt[i-1].data());
}
fznopt.parse(argc, argv.data());
}
Expand Down
84 changes: 84 additions & 0 deletions test/flatzinc/cumulatives_full_1.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Main authors:
* Jason Nguyen <[email protected]>
*
* Copyright:
* Jason nguyen, 2023
*
* This file is part of Gecode, the generic constraint
* development environment:
* http://www.gecode.org
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

#include "test/flatzinc.hh"

namespace Test { namespace FlatZinc {

namespace {
/// Helper class to create and register tests
class Create {
public:

/// Perform creation and registration
Create(void) {
(void) new FlatZincTest("cumulatives_full::1",
R"FZN(
var 1..10: s1 :: output_var;
var 1..10: s2 :: output_var;
var 0..1: m1 :: output_var;
var 0..2: m2 :: output_var;
var 3..4: d1;
var 1..5: d2;
var 2..3: r1;
var 2..5: r2;
var 4..14: e1;
var 2..15: e2;
var 4..15: ms :: output_var;
constraint gecode_int_element(m1, 0, [3, 4], d1);
constraint gecode_int_element(m2, 0, [1, 5], d2);
constraint gecode_int_element(m1, 0, [3, 2], r1);
constraint gecode_int_element(m2, 0, [5, 2], r2);
constraint gecode_cumulatives([s1, s2], [d1, d2], [r1, r2], [m1, m2], [4, 6], true);
constraint int_lin_eq([1, 1, -1], [s1, d1, e1], 0);
constraint int_lin_eq([1, 1, -1], [s2, d2, e2], 0);
constraint array_int_maximum(ms, [e1, e2]);
solve minimize ms;
)FZN",
R"OUT(m1 = 0;
m2 = 1;
ms = 6;
s1 = 1;
s2 = 1;
----------
==========
)OUT");
}
};

Create c;
}

}}

// STATISTICS: test-flatzinc
80 changes: 80 additions & 0 deletions test/flatzinc/cumulatives_full_2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Main authors:
* Jason Nguyen <[email protected]>
*
* Copyright:
* Jason nguyen, 2023
*
* This file is part of Gecode, the generic constraint
* development environment:
* http://www.gecode.org
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

#include "test/flatzinc.hh"

namespace Test { namespace FlatZinc {

namespace {
/// Helper class to create and register tests
class Create {
public:

/// Perform creation and registration
Create(void) {
(void) new FlatZincTest("cumulatives_full::2",
R"FZN(
var 1..10: s1 :: output_var;
var 1..10: s2 :: output_var;
var 3..4: d1;
var 1..5: d2;
var 2..3: r1;
var 2..5: r2;
var 4..14: e1;
var 2..15: e2;
var 4..15: ms :: output_var;
constraint gecode_int_element(s1, -1, [3, 4, 3, 4, 3, 4, 3, 4, 3, 4], d1);
constraint gecode_int_element(s2, -1, [1, 5, 4, 2, 1, 5, 4, 2, 1, 5], d2);
constraint gecode_int_element(s1, -1, [3, 2, 3, 2, 3, 2, 3, 2, 3, 2], r1);
constraint gecode_int_element(s2, -1, [5, 2, 4, 3, 5, 2, 4, 3, 5, 2], r2);
constraint gecode_cumulatives([s1, s2], [d1, d2], [r1, r2], [0, 1], [4, 6], true);
constraint int_lin_eq([1, 1, -1], [s1, d1, e1], 0);
constraint int_lin_eq([1, 1, -1], [s2, d2, e2], 0);
constraint array_int_maximum(ms, [e1, e2]);
solve minimize ms;
)FZN",
R"OUT(ms = 4;
s1 = 1;
s2 = 2;
----------
==========
)OUT");
}
};

Create c;
}

}}

// STATISTICS: test-flatzinc
80 changes: 80 additions & 0 deletions test/flatzinc/cumulatives_full_3.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Main authors:
* Jason Nguyen <[email protected]>
*
* Copyright:
* Jason nguyen, 2023
*
* This file is part of Gecode, the generic constraint
* development environment:
* http://www.gecode.org
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

#include "test/flatzinc.hh"

namespace Test { namespace FlatZinc {

namespace {
/// Helper class to create and register tests
class Create {
public:

/// Perform creation and registration
Create(void) {
(void) new FlatZincTest("cumulatives_full::3",
R"FZN(
var 1..10: s1 :: output_var;
var 1..10: s2 :: output_var;
var 0..1: m1 :: output_var;
var 0..2: m2 :: output_var;
var 2..3: r1;
var 2..5: r2;
var 4..14: e1;
var 2..15: e2;
var 4..15: ms :: output_var;
constraint gecode_int_element(m1, 0, [3, 2], r1);
constraint gecode_int_element(m2, 0, [5, 2], r2);
constraint gecode_cumulatives([s1, s2], [3, 5], [r1, r2], [m1, m2], [4, 6], true);
constraint int_lin_eq([1, -1], [s1, e1], -3);
constraint int_lin_eq([1, -1], [s2, e2], -5);
constraint array_int_maximum(ms, [e1, e2]);
solve minimize ms;
)FZN",
R"OUT(m1 = 0;
m2 = 1;
ms = 6;
s1 = 1;
s2 = 1;
----------
==========
)OUT");
}
};

Create c;
}

}}

// STATISTICS: test-flatzinc
Loading

0 comments on commit 3a29c3e

Please sign in to comment.