Skip to main content

Constraint Programming language and translator for Python

Project description

cp4py

Constraint Programming language and translator for Python.

Overview

cp4py provides a unified DSL (Domain Specific Language) for constraint programming that can be translated to multiple backend solvers.

Installation

pip install cp4py

# With specific solver backends
pip install cp4py[ortools]
pip install cp4py[z3]
pip install cp4py[scip]
pip install cp4py[cvc5]
pip install cp4py[gurobi]
pip install cp4py[cplex]
pip install cp4py[cpoptimizer]

Supported Solvers

Solver Variable Types License
OR-Tools int Free
Z3 int, real Free
SCIP int, real Free
CVC5 int, real Free
Gurobi int, real Commercial
CPLEX int, real Commercial
CP Optimizer int Commercial

Language Syntax

cp4py uses prefix notation with Python lists:

Variable Declaration

["int", "x", 1, 9]        # Integer variable x in [1, 9]
["real", "x", 0.0, 1.0]   # Real variable x in [0.0, 1.0]

Comparison Operators

["<=", "x", 5]    # x <= 5
["<", "x", 5]     # x < 5
[">=", "x", 5]    # x >= 5
[">", "x", 5]     # x > 5
["==", "x", 5]    # x == 5
["!=", "x", 5]    # x != 5

Arithmetic

["+", "x", "y", "z"]              # x + y + z
["sum", "x", "y", "z"]            # x + y + z (same as +)
["sum", [2, "x"], [3, "y"], "z"]  # 2*x + 3*y + z

Logical Operators

["or", ["<=", "x", 5], [">=", "x", 10]]   # x <= 5 OR x >= 10
["and", [">=", "x", 0], ["<=", "x", 10]]  # x >= 0 AND x <= 10

Global Constraints

["alldifferent", "x", "y", "z"]  # x, y, z are all different

Objective Functions

["minimize", "x"]                      # Minimize x
["maximize", ["sum", [2, "x"], "y"]]   # Maximize 2*x + y

Usage

Basic Example: Magic Square

from cp4py import Var
from cp4py.translators.ortools import ORToolsTranslator

def magic_square_3x3():
    x = Var("x")

    def model():
        # Variables: 9 cells with values 1-9
        for i in range(3):
            for j in range(3):
                yield ["int", x(i, j), 1, 9]

        # All different
        yield ["alldifferent"] + [x(i, j) for i in range(3) for j in range(3)]

        # Row sums = 15
        for i in range(3):
            yield ["==", ["+", x(i, 0), x(i, 1), x(i, 2)], 15]

        # Column sums = 15
        for j in range(3):
            yield ["==", ["+", x(0, j), x(1, j), x(2, j)], 15]

        # Diagonal sums = 15
        yield ["==", ["+", x(0, 0), x(1, 1), x(2, 2)], 15]
        yield ["==", ["+", x(0, 2), x(1, 1), x(2, 0)], 15]

    translator = ORToolsTranslator()
    translator.translate(model())
    return translator.solve()

result = magic_square_3x3()

Knapsack Problem

from cp4py import Var
from cp4py.translators.ortools import ORToolsTranslator

def knapsack(weights, values, capacity):
    n = len(weights)
    x = Var("x")

    def model():
        for i in range(n):
            yield ["int", x(i), 0, 1]

        # Weight constraint
        yield ["<=", ["sum"] + [[weights[i], x(i)] for i in range(n)], capacity]

        # Maximize value
        yield ["maximize", ["sum"] + [[values[i], x(i)] for i in range(n)]]

    translator = ORToolsTranslator()
    translator.translate(model())
    return translator.solve()

weights = [2, 3, 4, 5, 9]
values = [3, 4, 5, 8, 10]
result = knapsack(weights, values, capacity=10)

Switching Solvers

from cp4py.translators.ortools import ORToolsTranslator
from cp4py.translators.z3 import Z3Translator
from cp4py.translators.scip import SCIPTranslator
from cp4py.translators.cvc5 import CVC5Translator
from cp4py.translators.gurobi import GurobiTranslator
from cp4py.translators.cplex import CPLEXTranslator
from cp4py.translators.cpoptimizer import CPOptimizerTranslator

# Use any translator
translator = Z3Translator()
translator.translate(model())
result = translator.solve()

Var Helper Class

The Var class helps generate indexed variable names:

from cp4py import Var

x = Var("x")
x()        # "x"
x(0)       # "x_0"
x(0, 1)    # "x_0_1"
x(2, 3, 4) # "x_2_3_4"

# With bounds (optional)
y = Var("y", lb=0, ub=100)
y.lb  # 0
y.ub  # 100

Examples

See the examples/ directory:

python examples/knapsack.py -ortools
python examples/knapsack.py -z3
python examples/knapsack.py -scip
python examples/knapsack.py -cvc5
python examples/knapsack.py -gurobi
python examples/knapsack.py -cplex
python examples/knapsack.py -cpoptimizer

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cp4py-0.1.1.tar.gz (13.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cp4py-0.1.1-py3-none-any.whl (16.5 kB view details)

Uploaded Python 3

File details

Details for the file cp4py-0.1.1.tar.gz.

File metadata

  • Download URL: cp4py-0.1.1.tar.gz
  • Upload date:
  • Size: 13.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for cp4py-0.1.1.tar.gz
Algorithm Hash digest
SHA256 2af867974cedb06050bf4546a9f75c9033f80c26454168c012dcdbfbbf2dda2f
MD5 153fa77f96ff09808b4a9c24e9483033
BLAKE2b-256 bea6e2757e92c5bca9b0c2b94bc91c6d683c1aa9eec7e8c91658fc96cc44c1af

See more details on using hashes here.

File details

Details for the file cp4py-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: cp4py-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 16.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for cp4py-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f6b335ae0ac0392fe5887f7083b5824ee73afbc42a56202782b5441e9e1c4939
MD5 e30ebc727b40963107e7d7576029ec56
BLAKE2b-256 76ae8bea123b6f6672b7772504ada20256c6d7ab8b858d5bf3532baef81119cd

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page