Skip to content

Commit 065e5b1

Browse files
authored
Add constraint programming sets (#21)
1 parent 24c6980 commit 065e5b1

File tree

9 files changed

+1176
-9
lines changed

9 files changed

+1176
-9
lines changed

README.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ called _MathOptFormat_ with the file extension `.mof.json`.
55

66
MathOptFormat is rigidly defined by the [JSON schema](http://json-schema.org/)
77
available at
8-
[`https://jump.dev/MathOptFormat/schemas/mof.1.0.schema.json`](https://jump.dev/MathOptFormat/schemas/mof.1.0.schema.json).
8+
[`https://jump.dev/MathOptFormat/schemas/mof.1.1.schema.json`](https://jump.dev/MathOptFormat/schemas/mof.1.1.schema.json).
99

1010
It is intended for the schema to be self-documenting. Instead of modifying or
1111
adding to this documentation, clarifying edits should be made to the
@@ -66,8 +66,8 @@ Encoded into the MathOptFormat file format, this example becomes:
6666
```json
6767
{
6868
"version": {
69-
"major": 0,
70-
"minor": 6
69+
"major": 1,
70+
"minor": 1
7171
},
7272
"variables": [{"name": "x"}],
7373
"objective": {
@@ -253,6 +253,16 @@ Here is a summary of the sets defined by MathOptFormat.
253253
| `"NormSpectralCone"` | (t, X) ∈ {R^{1+row_dim×column_dim}: t ≥ σ₁(X)} | {"type": "NormSpectralCone", "row_dim": 1, "column_dim": 2} |
254254
| `"NormNuclearCone"` | (t, X) ∈ {R^{1+row_dim×column_dim}: t ≥ Σᵢ σᵢ(X)} | {"type": "NormNuclearCone", "row_dim": 1, "column_dim": 2} |
255255
| `"Complements"` | The set corresponding to a mixed complementarity constraint. Complementarity constraints should be specified with an AbstractVectorFunction-in-Complements(dimension) constraint. The dimension of the vector-valued function `F` must be `dimension`. This defines a complementarity constraint between the scalar function `F[i]` and the variable in `F[i + dimension/2]`. Thus, `F[i + dimension/2]` must be interpretable as a single variable `x_i` (e.g., `1.0 * x + 0.0`). The mixed complementarity problem consists of finding `x_i` in the interval `[lb, ub]` (i.e., in the set `Interval(lb, ub)`), such that the following holds: 1. `F_i(x) == 0` if `lb_i < x_i < ub_i`; 2. `F_i(x) >= 0` if `lb_i == x_i`; 3. `F_i(x) <= 0` if `x_i == ub_i`. Classically, the bounding set for `x_i` is `Interval(0, Inf)`, which recovers: `0 <= F_i(x) ⟂ x_i >= 0`, where the `` operator implies `F_i(x) * x_i = 0`. | {"type": "Complements", "dimension": 2} |
256+
| `"AllDifferent"` | The set {x in Z^d} such that no two elements in x take the same value and dimension=d. | {"type": "AllDifferent", "dimension": 2} |
257+
| `"BinPacking"` | The set `{x in Z^d}` where `d = length(w)`, such that each item `i` in `1:d` of weight `w[i]` is put into bin `x[i]`, and the total weight of each bin does not exceed `c`. | {"type": "BinPacking", "capacity": 3.0, "weights": [1.0, 2.0, 3.0]} |
258+
| `"Circuit"` | The set `{x in {1..d}^d}` that constraints `x` to be a circuit, such that `x_i = j` means that `j` is the successor of `i`, and `dimension = d`. | {"type": "Circuit", "dimension": 3} |
259+
| `"CountAtLeast"` | The set `{x in Z^{d_1 + d_2 + ldots d_N}}`, where `x` is partitioned into `N` subsets (`{x_1, ldots, x_{d_1}}`, `{x_{d_1 + 1}, ldots, x_{d_1 + d_2}}` and so on), and at least `n` elements of each subset take one of the values in `set`. | {"type": "CountAtLeast", "n": 1, "partitions": [2, 2], "set": [3]} |
260+
| `"CountBelongs"` | The set `{(n, x) in Z^{1+d}}`, such that `n` elements of the vector `x` take on of the values in `set` and `dimension = 1 + d`. | {"type": "CountBelongs", "dimension": 3, "set": [3, 4, 5]} |
261+
| `"CountDistinct"` | The set `{(n, x) in Z^{1+d}}`, such that the number of distinct values in `x` is `n` and `dimension = 1 + d`. | {"type": "CountDistinct", "dimension": 3} |
262+
| `"CountGreaterThan"` | The set `{(c, y, x) in Z^{1+1+d}}`, such that `c` is strictly greater than the number of occurances of `y` in `x` and `dimension = 1 + 1 + d`. | {"type": "CountGreaterThan", "dimension": 3} |
263+
| `"Cumulative"` | The set `{(s, d, r, b) in Z^{3n+1}}`, representing the `cumulative` global constraint, where `n == length(s) == length(r) == length(b)` and `dimension = 3n + 1`. `Cumulative` requires that a set of tasks given by start times `s`, durations `d`, and resource requirements `r`, never requires more than the global resource bound `b` at any one time. | {"type": "Cumulative", "dimension": 10} |
264+
| `"Path"` | Given a graph comprised of a set of nodes `1..N` and a set of arcs `1..E` represented by an edge from node `from[i]` to node `to[i]`, `Path` constrains the set `(s, t, ns, es) in (1..N)times(1..E)times{0,1}^Ntimes{0,1}^E`, to form subgraph that is a path from node `s` to node `t`, where node `n` is in the path if `ns[n]` is `1`, and edge `e` is in the path if `es[e]` is `1`. The path must be acyclic, and it must traverse all nodes `n` for which `ns[n]` is `1`, and all edges `e` for which `es[e]` is `1`. | {"type": "Path", "from": [1, 1, 2, 2, 3], "to": [2, 3, 3, 4, 4]} |
265+
| `"Table"` | The set `{x in R^d}` where `d = size(table, 2)`, such that `x` belongs to one row of `table`. That is, there exists some `j` in `1:size(table, 1)`, such that `x[i] = table[j, i]` for all `i=1:size(table, 2)`. | {"type": "Table", "table": [[1, 1, 0], [0, 1, 1]]} |
256266

257267
### Nonlinear functions
258268

examples/biobjective.mof.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"description": "The problem: [min{2x - y + 1, -y}]",
33
"version": {
44
"major": 1,
5-
"minor": 0
5+
"minor": 1
66
},
77
"variables": [{
88
"name": "x"

examples/cpsat.mof.json

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
{
2+
"description": "A constraint programming problem",
3+
"version": {
4+
"major": 1,
5+
"minor": 1
6+
},
7+
"variables": [{
8+
"name": "x"
9+
}, {
10+
"name": "y"
11+
}, {
12+
"name": "z"
13+
}],
14+
"objective": {
15+
"sense": "feasibility"
16+
},
17+
"constraints": [{
18+
"function": {
19+
"type": "VectorOfVariables",
20+
"variables": ["x", "y"]
21+
},
22+
"set": {
23+
"type": "AllDifferent",
24+
"dimension": 2
25+
}
26+
},{
27+
"function": {
28+
"type": "VectorOfVariables",
29+
"variables": ["x", "y", "z"]
30+
},
31+
"set": {
32+
"type": "BinPacking",
33+
"capacity": 3.0,
34+
"weights": [1.0, 2.0, 3.0]
35+
}
36+
},{
37+
"function": {
38+
"type": "VectorOfVariables",
39+
"variables": ["x", "y"]
40+
},
41+
"set": {
42+
"type": "Circuit",
43+
"dimension": 2
44+
}
45+
},{
46+
"function": {
47+
"type": "VectorOfVariables",
48+
"variables": ["x", "y", "y", "z"]
49+
},
50+
"set": {
51+
"type": "CountAtLeast",
52+
"n": 1,
53+
"partitions": [2, 2],
54+
"set": [3]
55+
}
56+
},{
57+
"function": {
58+
"type": "VectorOfVariables",
59+
"variables": ["x", "x", "y", "z"]
60+
},
61+
"set": {
62+
"type": "CountBelongs",
63+
"dimension": 3,
64+
"set": [3, 4, 5]
65+
}
66+
},{
67+
"function": {
68+
"type": "VectorOfVariables",
69+
"variables": ["x", "y", "z"]
70+
},
71+
"set": {
72+
"type": "CountDistinct",
73+
"dimension": 3
74+
}
75+
},{
76+
"function": {
77+
"type": "VectorOfVariables",
78+
"variables": ["x", "y", "z"]
79+
},
80+
"set": {
81+
"type": "CountGreaterThan",
82+
"dimension": 3
83+
}
84+
},{
85+
"function": {
86+
"type": "VectorOfVariables",
87+
"variables": ["x", "x", "y", "z"]
88+
},
89+
"set": {
90+
"type": "Cumulative",
91+
"dimension": 4
92+
}
93+
},{
94+
"function": {
95+
"type": "VectorOfVariables",
96+
"variables": ["x", "y", "z"]
97+
},
98+
"set": {
99+
"type": "Path",
100+
"from": [1, 1, 2, 2, 3],
101+
"to": [2, 3, 3, 4, 4]
102+
}
103+
},{
104+
"function": {
105+
"type": "VectorOfVariables",
106+
"variables": ["x", "y", "z"]
107+
},
108+
"set": {
109+
"type": "Table",
110+
"table": [[0, 1, 1], [1, 1, 0]]
111+
}
112+
}]
113+
}

examples/milp.mof.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"description": "The problem: min{x | x + y >= 1, x ∈ [0, 1], y ∈ {0, 1}}",
33
"version": {
44
"major": 1,
5-
"minor": 0
5+
"minor": 1
66
},
77
"variables": [{
88
"name": "x",

examples/nlp.mof.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"description": "The problem: min{2x + sin(x)^2 + y}.",
33
"version": {
44
"major": 1,
5-
"minor": 0
5+
"minor": 1
66
},
77
"variables": [{
88
"name": "x"

examples/quadratic.mof.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"description": "The problem: min{x^2 + x * y + y^2}",
33
"version": {
44
"major": 1,
5-
"minor": 0
5+
"minor": 1
66
},
77
"variables": [{
88
"name": "x"

examples/vector.mof.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"description": "The problem: min{0 | [1 2; 3 4][x, y] + [5, 6] ∈ R+.",
33
"version": {
44
"major": 1,
5-
"minor": 0
5+
"minor": 1
66
},
77
"variables": [{
88
"name": "x"

python/mof.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import os
44

55

6-
SCHEMA_FILENAME = '../schemas/mof.1.0.schema.json'
6+
SCHEMA_FILENAME = '../schemas/mof.1.1.schema.json'
77

88
def validate(filename):
99
with open(filename, 'r', encoding='utf-8') as io:

0 commit comments

Comments
 (0)