MCPcopy Index your code
hub / github.com/aia-uclouvain/maxicp

github.com/aia-uclouvain/maxicp @main

Chat with this repo
repository ↗ · DeepWiki ↗ · + Follow
4,515 symbols 22,356 edges 597 files 1,047 documented · 23%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Javadoc Userguide Tech Report Coverage

MaxiCP is an open-source (MIT licence) Java-based Constraint Programming (CP) solver for solving scheduling and vehicle routing problems.

It is an extended version of the MiniCP, a lightweight, open-source CP solver mostly used for teaching constraint programming.

The key features of MaxiCP are: - Improved performances (support for delta-based propagation, more efficient data structures, etc.). - Symbolic modeling layer also enabling search declaration. - Support for Embarrasingly Parallel Search. - More global constraints (e.g., bin-packing, gcc, etc.). - Sequence variables with optional visits for modeling complex vehicle routing and insertion based search heuristics, including LNS. - Conditional task interval variables including support for modeling with cumulative function expressions for scheduling problem.

Website and documentation

Installation

The official more stable releases are on maven central.

You can add this as a maven dependency to your project, those releases are committed and tagged in the releases branch:

<dependency>
    <groupId>org.maxicp</groupId>
    <artifactId>maxicp</artifactId>
    <version>0.0.2</version>
</dependency>

The javadoc of stable releases can be consulted on at this url.

If you need a dependency on the main branch (the main working branch where the next release is prepared), you can use jitpack.

The javadoc of the main branch can be consulted at this url.

Examples

The project contains two sets of example models located in different packages:

  • Raw Implementation Examples:

    • Located in: org.maxicp.cp.examples.raw
    • These examples demonstrate how to use MaxiCP's raw implementation objects directly, giving you full control over the CP solver internals.
  • Modeling API Examples:

    • Located in: org.maxicp.cp.examples.modeling
    • These examples use the high-level modeling API, which is then instantiated into raw API objects. This abstraction allows for a simpler and more expressive way to define constraint problems, while still leveraging the underlying raw API for solving.

N-Queens Example

Using Raw API

This example demonstrates how to solve the N-Queens problem using the raw API objects directly.

package org.maxicp.cp.examples.raw.nqueens;

import org.maxicp.cp.CPFactory;
import org.maxicp.cp.engine.core.CPIntVar;
import org.maxicp.cp.engine.core.CPSolver;
import org.maxicp.search.DFSearch;
import org.maxicp.search.SearchStatistics;
import static org.maxicp.cp.CPFactory.*;
import static org.maxicp.search.Searches.*;
import java.util.Arrays;

public class NQueens {
    public static void main(String[] args) {
        int n = 8;

        CPSolver cp = CPFactory.makeSolver();
        CPIntVar[] q = CPFactory.makeIntVarArray(cp, n, n);
        CPIntVar[] qL = CPFactory.makeIntVarArray(n, i -> minus(q[i],i));
        CPIntVar[] qR = CPFactory.makeIntVarArray(n, i -> plus(q[i],i));

        cp.post(allDifferent(q));
        cp.post(allDifferent(qL));
        cp.post(allDifferent(qR));


        // a more compact first fail search using selectors is given next
        DFSearch search = CPFactory.makeDfs(cp, () -> {
            CPIntVar qs = selectMin(q,
                    qi -> qi.size() > 1,
                    qi -> qi.size());
            if (qs == null) return EMPTY;
            else {
                int v = qs.min();
                return branch(() -> cp.post(eq(qs, v)),
                        () -> cp.post(neq(qs, v)));
            }
        });


        search.onSolution(() ->
                System.out.println("solution:" + Arrays.toString(q))
        );
        SearchStatistics stats = search.solve(statistics -> statistics.numberOfSolutions() == 1000);

        System.out.format("#Solutions: %s\n", stats.numberOfSolutions());
        System.out.format("Statistics: %s\n", stats);

    }
}

Using Modeling API

This example demonstrates how to solve the N-Queens problem using the high-level modeling API.

package org.maxicp.cp.examples.modeling.nqueens;


import org.maxicp.ModelDispatcher;
import org.maxicp.cp.modeling.ConcreteCPModel;
import static org.maxicp.modeling.Factory.*;
import org.maxicp.modeling.IntVar;
import org.maxicp.modeling.algebra.integer.IntExpression;
import org.maxicp.search.*;
import static org.maxicp.search.Searches.*;
import java.util.Arrays;
import java.util.concurrent.ExecutionException;
import java.util.function.Supplier;


import static org.maxicp.search.Searches.EMPTY;
import static org.maxicp.search.Searches.branch;

public class NQueens {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        int n = 12;

        ModelDispatcher model = makeModelDispatcher();

        IntVar[] q = model.intVarArray(n, n);
        IntExpression[] qL = model.intVarArray(n,i -> q[i].plus(i));
        IntExpression[] qR = model.intVarArray(n,i -> q[i].minus(i));

        model.add(allDifferent(q));
        model.add(allDifferent(qL));
        model.add(allDifferent(qR));

        Supplier<Runnable[]> branching = () -> {
            IntExpression qs = selectMin(q,
                    qi -> qi.size() > 1,
                    qi -> qi.size());
            if (qs == null)
                return EMPTY;
            else {
                int v = qs.min();
                return branch(() -> model.add(eq(qs, v)), () -> model.add(neq(qs, v)));
            }
        };

        ConcreteCPModel cp = model.cpInstantiate();
        DFSearch dfs = cp.dfSearch(branching);
        dfs.onSolution(() -> {
            System.out.println(Arrays.toString(q));
        });
        SearchStatistics stats = dfs.solve();
        System.out.println(stats);

    }
}

Citing MaxiCP

If you use MaxiCP in your research, please cite it as follows:

@misc{maxicp,
  title        = {{maxicp: A Not So Mini Constraint Programming Solver}},
  author       = {Pierre Schaus and Guillaume Derval and Augustin Delecluse and Laurent Michel and Pascal Van Hentenryck},
  year         = {2026},
  howpublished = {\url{http://www.maxicp.org/}},
}

Recommended IDE: IntelliJ IDEA

We recommend using IntelliJ IDEA to develop and run the MaxiCP project.

Steps to Import MaxiCP into IntelliJ:

  1. Clone the Repository: Open a terminal and run the following command to clone the repository: bash git clone https://github.com/aia-uclouvain/maxicp.git

  2. Open project in IDEA: Launch IntelliJ IDEA. Select File > Open and navigate to the maxicp folder you cloned. Open the pom.xml file.

  3. Running the tests:

    From the IntelliJ IDEA editor, navigate to the src/test/java directory. Right-click then select Run 'All Tests' to run all the tests.

    From the terminal, navigate to the root directory of the project and run the following command: bash mvn test

Extension points exported contracts — how you extend this code

ConstraintFactory (Interface)
This interface creates the appropriate constraint to populate tests. [19 implementers]
src/test/java/org/maxicp/cp/engine/constraints/ConstraintFactory.java
DecisionVarsProvider (Interface)
Implemented by constraints and expression nodes that know which of their sub-expressions play an "index / choice" role a [28 …
src/main/java/org/maxicp/modeling/DecisionVarsProvider.java
ConstraintFromRecord (Interface)
Utility class to automagically compute the scope of a record constraint. Only works with some basic types: - {@code Expr [28 …
src/main/java/org/maxicp/modeling/constraints/helpers/ConstraintFromRecord.java
CumulFunction (Interface)
Represents a Cumulative Function as described in Reasoning with conditional time-intervals. part ii: An algebraica [21 …
src/main/java/org/maxicp/modeling/algebra/scheduling/CumulFunction.java
CPCumulFunction (Interface)
CP implementation of a Cumulative Function @author Pierre Schaus, Charles Thomas, Augustin Delecluse [14 implementers]
src/main/java/org/maxicp/cp/engine/constraints/scheduling/CPCumulFunction.java
StateEntry (Interface)
A StateEntry is aimed to be stored by a StateManager to revert some state [9 implementers]
src/main/java/org/maxicp/state/StateEntry.java

Core symbols most depended-on inside this repo

post
called by 1078
src/main/java/org/maxicp/cp/engine/core/CPSolver.java
min
called by 696
src/main/java/org/maxicp/cp/engine/core/CPIntVar.java
max
called by 571
src/main/java/org/maxicp/cp/engine/core/CPIntVar.java
makeIntVar
called by 502
src/main/java/org/maxicp/cp/CPFactory.java
add
called by 451
src/main/java/org/maxicp/modeling/ModelProxy.java
getSolver
called by 379
src/main/java/org/maxicp/cp/engine/core/CPSeqVar.java
contains
called by 351
src/main/java/org/maxicp/cp/engine/core/CPIntVar.java
insert
called by 346
src/main/java/org/maxicp/cp/engine/core/CPSeqVar.java

Shape

Method 3,824
Class 596
Interface 75
Enum 17
Function 3

Languages

Java100%
Python1%

Modules by API surface

src/main/java/org/maxicp/cp/engine/core/CPSeqVarImpl.java93 symbols
src/main/java/org/maxicp/cp/CPFactory.java91 symbols
src/main/java/org/maxicp/modeling/Factory.java57 symbols
src/test/java/org/maxicp/cp/engine/core/CPSeqVarTest.java50 symbols
src/main/java/org/maxicp/modeling/xcsp3/XCSP3.java47 symbols
src/main/java/org/maxicp/cp/engine/core/CPIntervalVarImpl.java47 symbols
src/test/java/org/maxicp/cp/engine/constraints/scheduling/GeneralizedCumulativeConstraintTest.java40 symbols
src/main/java/org/maxicp/cp/engine/core/CPSeqVarViewFlip.java38 symbols
src/main/java/org/maxicp/cp/engine/constraints/scheduling/GeneralizedCumulativeSweepMin.java37 symbols
src/main/java/org/maxicp/cp/engine/core/CPSeqVar.java36 symbols
src/main/java/org/maxicp/cp/engine/constraints/scheduling/GeneralizedCumulativeSweepMax.java36 symbols
src/test/java/org/maxicp/cp/engine/constraints/seqvar/CumulativeTest.java35 symbols

For agents

$ claude mcp add maxicp \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact