-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* 0.4 (#60) (#61) * change readme, changelog.md and enum example according to actual version * migrate to ruff from flake8 * fix pyproject.toml * support var parametrization, add both float case to get_wider_type * fix doc, update changelog.md * add readthedocs.yaml * add libfuse install step, as it is required by app image and not presented anymore * add sphinx-apidoc command as pre_build for readthedocs * install libfuse every time * install package in doc builder * rename test job * add changelog.md * add test for fixation constraints --------- Co-authored-by: Artsiom Kaltovich <[email protected]> * 0.4 (#60) (#64) * 0.4 (#60) * change readme, changelog.md and enum example according to actual version * migrate to ruff from flake8 * fix pyproject.toml * support var parametrization, add both float case to get_wider_type * fix doc, update changelog.md * add readthedocs.yaml * add libfuse install step, as it is required by app image and not presented anymore * add sphinx-apidoc command as pre_build for readthedocs * install libfuse every time * install package in doc builder * rename test job * add changelog.md * add test for fixation constraints --------- Co-authored-by: Artsiom Kaltovich <[email protected]> * fix version in ci (#62) Co-authored-by: Artsiom Kaltovich <[email protected]> --------- Co-authored-by: Artsiom Kaltovich <[email protected]> * fix changelog * add alldifferent_except * add alldifferent_except test * add table doc example --------- Co-authored-by: Artsiom Kaltovich <[email protected]>
- Loading branch information
1 parent
89fee17
commit 9ac2bd1
Showing
12 changed files
with
230 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
Table | ||
===== | ||
|
||
The table constraint is used to specify if one dimensional array | ||
should be equal to any row of two dimensional array. | ||
|
||
Model | ||
----- | ||
|
||
We will recreate the example of the choosing dishes model from | ||
`minizinc <https://www.minizinc.org/doc-2.5.4/en/predicates.html#table>`_ | ||
documentation. | ||
|
||
Python Model | ||
------------ | ||
|
||
.. testcode:: | ||
|
||
import enum | ||
import zython as zn | ||
|
||
|
||
class Food(enum.IntEnum): | ||
icecream = 1 | ||
banana = 2 | ||
chocolate_cake = 3 | ||
lasagna = 4 | ||
steak = 5 | ||
rice = 6 | ||
chips = 7 | ||
brocolli = 8 | ||
beans = 9 | ||
|
||
|
||
class Feature(enum.IntEnum): | ||
name = 0 | ||
energy = 1 | ||
protein = 2 | ||
salt = 3 | ||
fat = 4 | ||
cost = 5 | ||
|
||
|
||
DD = [ | ||
[Food.icecream.value, 1200, 50, 10, 120, 400], | ||
[Food.banana.value, 800, 120, 5, 20, 120], | ||
[Food.chocolate_cake.value, 2500, 400, 20, 100, 600], | ||
[Food.lasagna.value, 3000, 200, 100, 250, 450], | ||
[Food.steak.value, 1800, 800, 50, 100, 1200], | ||
[Food.rice.value, 1200, 50, 5, 20, 100], | ||
[Food.chips.value, 2000, 50, 200, 200, 250], | ||
[Food.brocolli.value, 700, 100, 10, 10, 125], | ||
[Food.beans.value, 1900, 250, 60, 90, 150], | ||
] | ||
|
||
|
||
class MyModel(zn.Model): | ||
def __init__( | ||
self, | ||
food, | ||
mains, | ||
sides, | ||
desserts, | ||
dd, | ||
min_energy, | ||
min_protein, | ||
max_salt, | ||
max_fat, | ||
): | ||
self.food = food | ||
self.mains = zn.Set(mains) | ||
self.sides = zn.Set(sides) | ||
self.desserts = zn.Set(desserts) | ||
self.dd = zn.Array(dd) | ||
self.main = zn.Array(zn.var(int), shape=len(Feature)) | ||
self.side = zn.Array(zn.var(int), shape=len(Feature)) | ||
self.dessert = zn.Array(zn.var(int), shape=len(Feature)) | ||
self.budget = zn.var(int) | ||
|
||
self.constraints = [ | ||
self.mains.contains(self.main[Feature.name]), | ||
self.sides.contains(self.side[Feature.name]), | ||
self.desserts.contains(self.dessert[Feature.name]), | ||
self.main[Feature.energy] + self.side[Feature.energy] + self.dessert[Feature.energy] >= min_energy, | ||
self.main[Feature.protein] + self.side[Feature.protein] + self.dessert[Feature.protein] >= min_protein, | ||
self.main[Feature.salt] + self.side[Feature.salt] + self.dessert[Feature.salt] <= max_salt, | ||
self.main[Feature.fat] + self.side[Feature.fat] + self.dessert[Feature.fat] <= max_fat, | ||
self.budget == self.main[Feature.cost] + self.side[Feature.cost] + self.dessert[Feature.cost], | ||
|
||
zn.table(self.main, self.dd), | ||
zn.table(self.side, self.dd), | ||
zn.table(self.dessert, self.dd), | ||
] | ||
|
||
|
||
model = MyModel( | ||
Food, | ||
mains={Food.lasagna, Food.steak, Food.rice}, | ||
sides={Food.chips, Food.brocolli, Food.beans}, | ||
desserts={Food.icecream, Food.banana, Food.chocolate_cake}, | ||
dd=DD, | ||
min_energy=3300, | ||
min_protein=500, | ||
max_salt=180, | ||
max_fat=320, | ||
) | ||
result = model.solve_minimize(model.budget) | ||
menu = [Food(result[dish][Feature.name]) for dish in ("main", "side", "dessert")] | ||
print(menu, result["budget"]) | ||
|
||
|
||
.. testoutput:: | ||
|
||
[<Food.rice: 6>, <Food.brocolli: 8>, <Food.chocolate_cake: 3>] 825 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
from collections import Counter | ||
|
||
import pytest | ||
|
||
import zython as zn | ||
|
||
|
||
class TestBothParams: | ||
def test_ok_none(self): | ||
zn.alldifferent([0, 2]) | ||
|
||
def test_ok_except0(self): | ||
zn.alldifferent([0, 2], except0=True) | ||
|
||
def test_ok_except_(self): | ||
zn.alldifferent([0, 2], except_={1, }) | ||
|
||
def test_both_not_ok(self): | ||
with pytest.raises(ValueError, match="Arguments `except0` and `except_` can't be set at the same time"): | ||
zn.alldifferent([0, 2], except0=True, except_={1, }) | ||
|
||
|
||
class TestExceptTypes: | ||
# python set is tested by doctest | ||
def test_zn_set(self): | ||
class MyModel(zn.Model): | ||
def __init__(self): | ||
self.a = zn.Array(zn.var(range(1, 4)), shape=4) | ||
self.except_ = zn.Set([1, 2, 3]) | ||
self.constraints = [zn.alldifferent(self.a, except_=self.except_), zn.sum(self.a) == 7] | ||
model = MyModel() | ||
result = model.solve_satisfy() | ||
assert Counter(result["a"]) == {3: 1, 2: 1, 1: 2} | ||
|
||
def test_zn_var_set(self): | ||
with pytest.raises(ValueError, match="Minizinc doesn't support set of var as `except_` argument"): | ||
zn.alldifferent([1, 2, 3], except_=zn.Set(zn.var(range(3)))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters