MiniZinc

MiniZinc is a high-level constraint modelling language that allows you to easily express and solve discrete optimisation problems.

Latest release: 2.10.0 (changelog)

MiniZinc is developed at Monash University with support from OPTIMA.

AimeeAlidaArvilBeulaCiaraColonDarbyDianaDonnaDulceEliasElvieErnstEssieGreenJeradJesseJimmyJodieJulieKatieKeionKelsiKizzyLarryLeafyLloydLymanMableMartyMerleMetroMistiMykelNeliaNevinPaulaSheriTeddyWayne
Table seating allocation
MonTueWedThuFri
Aimee
Night
Evening
Day
Evening
Beula
Evening
Day
Evening
Night
Evening
Ciara
Day
Evening
Night
Darby
Evening
Evening
Night
Ernst
Night
Evening
Evening
Day
Green
Evening
Evening
Day
Night
Jesse
Day
Day
Day
Night
Katie
Day
Day
Evening
Day
Lloyd
Day
Day
Night
Evening
Mable
Night
Day
Day
Evening
Nevin
Evening
Day
Day
Evening
Day
Paula
Night
Evening
Evening
Day
Rostering
Vehicle routing

Try MiniZinc

Try one of the examples, or write your own model.

Why choose MiniZinc?

  • High-level language

    Model constraint satisfaction and optimisation problems using readable, intuitive logical constructs, with full type safety.

  • Solver independent

    Run the same model using a variety of different solver technologies, without being locked into a particular solver.

  • Pre-defined constraints

    MiniZinc features a large library of pre-defined constraints, making modelling complex relationships simple.

  • Fully featured development environment

    Use the MiniZinc IDE to write and run models, visualise search and solutions, profile performance and more.

  • In-depth learning materials

    MiniZinc has comprehensive documentation, including the tutorial, several courses, the user manual, and library documentation.

  • Integrate MiniZinc into your project

    MiniZinc can be embedded into Python and JavaScript programs, and can even be used entirely from within the browser.

Latest Release

MiniZinc 2.10.0

Released 23 July 2026

  • Add support for named arguments. Function calls can now refer to arguments by name, in addition to the usual positional arguments. The parameter names of the global constraints in the standard library have been revised so that they read well as named arguments (now that named arguments make them part of the public interface). It is now a type error to declare two overloads of a function or predicate that a call supplying all of its arguments by name could not tell apart, i.e. two overloads that give the same name and type to every parameter that has to be supplied. Named arguments are available for user-defined and library operations. The low-level operations a solver supports natively (those declared without a body) remain positional-only for now, until solver libraries have converged on a common set of parameter names; calling one by name is an error. The new --warn-non-authoritative-names option helps solver implementers audit their libraries against the standard-library names ahead of that change.
  • Add support for default values for function and parameter arguments.
  • Add support for set cardinality declarations using the syntax set(e) of T: s;. When e has type int or var int, this desugars to an additional card(s) = e constraint; when e has type set of int or var set of int, it desugars to card(s) in e. The syntax works for tuple- and record-typed sets as well as arrays (and arrays of arrays) of sets.
  • Add support for index-dependent array declarations, where an index list entry of the form c in S binds the name c in the element type's domain expression — for example array[c in 1..n] of var 1..f(c): x;. The per-element domain is desugared into an additional constraint and works for tuple- and record-typed elements as well as arrays of arrays; it also composes with the set(e) of T cardinality syntax.
  • Make the list type behave like a real 1-based array type. It is now syntactic sugar for array [1..infinity] of T. Checks ensure that only 1-based arrays match the list type.
  • Allow par tuples and records to be optional. opt makes the tuple or record optional as a whole (it is either a complete value or <>); it does not distribute into the fields, so opt record(int: a) remains a different type from record(opt int: a). Accessing a field of an optional tuple or record yields an optional value. var opt tuples and records remain type errors, including when the var comes from a field, since a tuple or record with any var field is itself var.
  • And many more changes and bugfixes!

See the full changelog.

Get your MiniZinc stickers, mugs, t-shirts etc. (sold at cost price)!