Solving with Qaekwy

Searchers

The SearcherType enum in Qaekwy represents different types of search algorithms used in constraint-based modelling and optimization. Search algorithms are crucial in exploring the solution space and finding feasible or optimal solutions to complex problems. Here’s a brief explanation of the provided search algorithm options:

  • Depth-First Search (DFS): This algorithm systematically explores a problem’s solution space by traversing as far as possible along a branch before backtracking. It can be efficient when there are many potential solutions close to each other.

  • Branch and Bound (BAB): Branch and Bound is an optimization algorithm that breaks down the problem into smaller subproblems and explores the solution space while pruning branches that can’t lead to better solutions than the ones already found.

  • Limited Discrepancy Search (LDS): LDS is a heuristic search algorithm that balances between depth-first search and breadth-first search. It limits the number of times a decision is revised (discrepancy) and can be useful for problems with complex constraints.

  • Portfolio-Based Search (PBS): PBS combines multiple search algorithms to improve overall performance. It dynamically selects the most suitable algorithm based on the problem’s characteristics or performance during the search.

  • Restart-Based Search (RBS): RBS resets the exploration from different points within the solution space. The restarts help the search algorithm overcome local optima and potentially find better solutions by exploring different regions of the solution landscape.

To set the searcher in your model, proceed like following:

from qaekwy.model.modeller import Modeller
from qaekwy.model.searcher import SearcherType

my_model = Modeller()
...
my_model.set_searcher(SearcherType.DFS)

Engines

Qaekwy empowers users with efficient constraint-based modelling and problem-solving capabilities engine. Whether you’re looking for direct public-cloud interaction, private standalone instance, or the ability to manage a Qaekwy Cluster environment, Qaekwy’s engines provide the flexibility you need.

However, for now only the DirectEngine is made available.

DirectEngine

The DirectEngine is a powerful component that enables seamless interaction with the Qaekwy solver engine hosted in the cloud. The DirectEngine is a convenient choice for users who want to tap into the prowess of constraint-based modelling without the overhead of infrastructure management. Through the DirectEngine, you can effortlessly create problem models, specify constraints and objectives, and request solutions from the cloud-based Qaekwy solver engine.

from qaekwy.engine import DirectEngine
from qaekwy.model.modeller import Modeller

# Create a Qaekwy DirectEngine instance
qaekwy_engine = DirectEngine()

# Create a Modeller instance
my_model = Modeller()

# ...

# Request the DirectEngine to solve the model
response = qaekwy_engine.model(model=my_model)

Engine (Coming Soon)

The Engine is an upcoming component in Qaekwy that will provide users with the capability to deploy and run the Qaekwy solver stand-alone engine on their own infrastructure. With the Engine, you’ll have the autonomy to set up and manage a standalone solver instance tailored to your requirements. This option ensures greater control, customization, and security considerations. Stay tuned for updates on the availability of the Engine feature.

ClusterEngine (Coming Soon)

The ClusterEngine is a specialized component designed to enhance the efficiency and scalability of constraint-based problem solving. While not yet available, the ClusterEngine is intended to manage the submission of problem models to a Qaekwy cluster, whether in the cloud or on-premises. This component streamlines the process of distributing and solving large-scale problems by utilizing the capabilities of cluster environments. Through the ClusterEngine, users will be able to harness parallel processing and resource allocation for faster and more effective solutions to complex problems.

As Qaekwy continues to evolve, these engine options provide you with the tools to tackle diverse problem domains with confidence, from direct cloud interaction to self-managed instances and cluster-based scalability. Keep an eye on the official documentation for updates on the availability and features of these engine components.

Solution

The solution fetching process in Qaekwy involves retrieving the outcomes of a solved problem model, represented as assignments to the variables in the form of a solution dictionary. The Solution class in Qaekwy encapsulates this solution representation and provides convenient ways to access the assigned values.

When you solve a model using a Qaekwy engine, you’ll receive a response that includes the solutions found (if any) for the problem. Each solution is represented as a list of dictionaries, where each dictionary describes a variable assignment. This list of dictionaries is passed to the Solution class to create an instance that enables easy access to the variable assignments and their values.

For instance, given a Solution instance named solution, you can access the assigned values using dictionary-style indexing or attribute access. Here’s how it works:

...
# Request the DirectEngine to solve the model
response = qaekwy_engine.model(model=my_model)

# Retrieve and print the solutions
solutions = response.get_solutions()
for solution in solutions:

    # access variable assignments through the Solution attributes:
    print(f"x = {solution.x}")
    print(f"y = {solution.y}")
    print(f"z = {solution.z}")

    # Or using dictionary-style
    print(f"x = {solution["x"]}")
    print(f"y = {solution["y"]}")
    print(f"z = {solution["z"]}")

In the Qaekwy Solution object, the names of the variables correspond directly to the names of the variables used in the Qaekwy model that was solved.

For instance, if you have a Qaekwy model with an IntegerVariable named x, the solution dictionary will also have an entry with the key x that represents the assigned value to that variable. This direct mapping makes it intuitive to retrieve and utilize the solutions, as you can conveniently access the assigned values using the variable names you’re already familiar with.