LocalSolver logo
is now
Hexaly logo

We're excited to share that we are moving forward. We're leaving behind the LocalSolver brand and transitioning to our new identity: Hexaly. This represents a leap forward in our mission to enable every organization to make better decisions faster when faced with operational and strategic challenges.


Hexaly Modeler API

The modeler API allows you to interact with the virtual machine powering the LSP language: developers with prototypes written in LSP will now be able to integrate them in Python, Java, C#, and C++ environments fully. With these new bindings, you can, for example:

  • Load existing LSP files into modules and execute them.

  • Interact with functions and variables contained in modules.

  • Expose methods developed in your language of choice as LSP functions.

Thus, integrating the knapsack LSP program in a Python environment is now possible. First, we need to instantiate the API’s main class, the LSPModeler, which will enable us to interact with modules, maps, and functions. Given that the model above is available to us in a file named knapsack.lsp, we can load the module into the modeler with the following snippet:

from localsolver.modeler import *

with LSPModeler() as modeler:
    knapsack_module = modeler.load_module("knapsack", "knapsack.lsp")

This makes all variables and functions contained in knapsack.lsp available to us through the knapsack_module object (see the LSPModule reference). It also enables us to execute this module, which means running the model function and starting the resolution process. As we have seen before, we need to initialize a few variables beforehand.

To set a value for integer variables like nbItems and knapsackBound, we can do the following:

# Declares a variable named `nbItems` and sets its value to 5.
knapsack_module["nbItems"] = 5

Next, we need to input the weights and the prices. They are both collections of numbers, so they should be objects of type LSPMap:

# `weights_data` is the data we want to input.
weights_data = [5, 4, 6, 3, 1]
# `weights_map` is the LSPMap that will hold the values in the LSP program.
weights_map = modeler.create_map()

for value in weights_data:
    weights_map.append(value)

knapsack_module["weights"] = weights_map

With all variables set, we can create a solver and execute the module by calling either knapsack_module.run() or knapsack_module.runMain() depending on the LSP mode (classic or main). This method replicates the behavior we would get by executing the module from the command line, and we can pass down arguments like lsTimeLimit:

solver = modeler.create_solver()
knapsack_module.run(solver, "lsTimeLimit=10")

Once the resolution process is done, we can extract solution data:

# First we extract the LSExpression created within the LSP program.
obj_expression = knapsack_module["knapsackValue"]
# We can then extract the objective value using the regular LocalSolver Python API.
obj_value = obj_expression.value

Using the modeler API, you can thus benefit from the ease of modeling in LSP whilst still being able to integrate models in Python, Java, C#, and C++ applications.

Complete example

from localsolver.modeler import *

with LSPModeler() as modeler:
    knapsack_module = modeler.load_module("knapsack", "knapsack.lsp")

    # Declares a variable and sets its value.
    knapsack_module["nbItems"] = 8
    knapsack_module["knapsackBound"] = 102

    # Data we want to input
    weights_data = [10, 60, 30, 40, 30, 20, 20, 2]
    prices_data = [1, 10, 15, 40, 60, 90, 100, 15]
    # LSPMap that will hold the values in the LSP program
    weights_map = modeler.create_map()
    prices_map = modeler.create_map()

    for value in weights_data:
        weights_map.append(value)
    for value in prices_data:
        prices_map.append(value)

    knapsack_module["weights"] = weights_map
    knapsack_module["prices"] = prices_map

    ls = modeler.create_solver()
    knapsack_module.run(ls, "lsTimeLimit=10")

    # First we extract the LSExpression created within the LSP program.
    obj_expression = knapsack_module["knapsackValue"]
    # We can then extract the objective value using the regular LocalSolver Python API.
    obj_value = obj_expression.value
    print("The final knapsack value is", obj_value)
#include "localsolver.h"
#include "modeler/lspmodeler.h"
#include <iostream>

using namespace localsolver;
using namespace modeler;
using namespace std;

int main(int argc, char** argv) {
    LSPModeler modeler;
    LSPModule knapsackModule = modeler.loadModule("knapsack", "knapsack.lsp");

    // Declares a variable and sets its value.
    knapsackModule.setInt("nbItems", 8);
    knapsackModule.setInt("knapsackBound", 102);

    // Data we want to input
    vector<int> weights {10, 60, 30, 40, 30, 20, 20, 2};
    vector<int> prices {1, 10, 15, 40, 60, 90, 100, 15};
    // LSPMap that will hold the values in the LSP program
    LSPMap weightsMap = modeler.createMap();
    LSPMap pricesMap = modeler.createMap();

    for (int value : weights)
        weightsMap.addInt(value);
    for (int value : prices)
        pricesMap.addInt(value);

    knapsackModule.setMap("weights", weightsMap);
    knapsackModule.setMap("prices", pricesMap);

    LocalSolver ls = modeler.createSolver();
    vector<string> arguments {"lsTimeLimit=10"};
    knapsackModule.run(ls, arguments);

    // First we extract the LSExpression created within the LSP program.
    LSExpression objExpression = knapsackModule.getExpression("knapsackValue");
    // We can then extract the objective value using the regular LocalSolver C++ API.
    int objValue = objExpression.getValue();
    cout << "The final knapsack value is " << objValue << endl;

    return 0;
}
using System;
using System.Collections.Generic;
using localsolver;
using localsolver.modeler;

public class ModelerTest : IDisposable
{
    public void Dispose() {}

    public static void Main(string[] args)
    {
        LSPModeler modeler = new LSPModeler();
        LSPModule knapsackModule = modeler.LoadModule("knapsack", "knapsack.lsp");

        // Declares a variable and sets its value.
        knapsackModule.SetInt("nbItems", 8);
        knapsackModule.SetInt("knapsackBound", 102);

        // Data we want to input
        List<int> weights = new List<int>() {10, 60, 30, 40, 30, 20, 20, 2};
        List<int> prices = new List<int>() {1, 10, 15, 40, 60, 90, 100, 15};
        // LSPMap that will hold the values in the LSP program
        LSPMap weightsMap = modeler.CreateMap();
        LSPMap pricesMap = modeler.CreateMap();

        foreach (int value in weights)
            weightsMap.AddInt(value);
        foreach (int value in prices)
            pricesMap.AddInt(value);

        knapsackModule.SetMap("weights", weightsMap);
        knapsackModule.SetMap("prices", pricesMap);

        LocalSolver ls = modeler.CreateSolver();
        List<string> arguments = new List<string>() {"lsTimeLimit=10"};
        knapsackModule.Run(ls, arguments);

        // First we extract the LSExpression created within the LSP program.
        LSExpression objExpression = knapsackModule.GetExpression("knapsackValue");
        // We can then extract the objective value using the regular LocalSolver C# API.
        long objValue = objExpression.GetValue();
        Console.WriteLine("The final knapsack value is " + objValue);
    }
}
import java.util.Arrays;
import java.util.List;
import localsolver.*;
import localsolver.modeler.*;

public class ModelerTest {
    public static void main(String[] args) {
        try (LSPModeler modeler = new LSPModeler()) {
            LSPModule knapsackModule = modeler.loadModule("knapsack", "knapsack.lsp");

            // Declares a variable and sets its value.
            knapsackModule.setInt("nbItems", 8);
            knapsackModule.setInt("knapsackBound", 102);

            // Data we want to input
            List<Integer> weights = Arrays.asList(10, 60, 30, 40, 30, 20, 20, 2);
            List<Integer> prices = Arrays.asList(1, 10, 15, 40, 60, 90, 100, 15);
            // LSPMap that will hold the values in the LSP program
            LSPMap weightsMap = modeler.createMap();
            LSPMap pricesMap = modeler.createMap();

            for (int value : weights)
                weightsMap.addInt(value);
            for (int value : prices)
                pricesMap.addInt(value);

            knapsackModule.setMap("weights", weightsMap);
            knapsackModule.setMap("prices", pricesMap);

            LocalSolver ls = modeler.createSolver();
            List<String> arguments = Arrays.asList("lsTimeLimit=10");
            knapsackModule.run(ls, arguments);

            // First we extract the LSExpression created within the LSP program.
            LSExpression objExpression = knapsackModule.getExpression("knapsackValue");
            // We can then extract the objective value using the regular LocalSolver Java API.
            long objValue = objExpression.getValue();
            System.out.println("The final knapsack value is " + objValue);

        } catch (Exception ex) {
            System.err.println(ex);
            ex.printStackTrace();
            System.exit(1);
        }
    }
}