Skip to main content
Glama

solve_highs_problem

Solve linear and mixed-integer programming problems using the HiGHs solver. Input problem definitions with variables, objectives, and constraints to obtain optimal solutions.

Instructions

Solve a HiGHs linear/mixed-integer programming problem.

This tool takes a HiGHs optimization problem defined with variables, objective,
and constraints, and returns a solution if one exists.

HiGHs is a high-performance linear programming solver that supports:
- Linear programming (LP)
- Mixed-integer programming (MIP)
- Both dense and sparse constraint matrices
- Various solver algorithms (simplex, interior point, etc.)

Example problem structure:
{
    "problem": {
        "sense": "minimize",
        "objective": {
            "linear": [1.0, 2.0, 3.0]
        },
        "variables": [
            {"name": "x1", "lb": 0, "ub": 10, "type": "cont"},
            {"name": "x2", "lb": 0, "ub": null, "type": "cont"},
            {"name": "x3", "lb": 0, "ub": 1, "type": "bin"}
        ],
        "constraints": {
            "dense": [
                [1, 1, 0],
                [0, 1, 1]
            ],
            "sense": ["<=", ">="],
            "rhs": [5, 3]
        }
    },
    "options": {
        "time_limit": 60.0,
        "output_flag": false
    }
}

Args:
    problem: The HiGHs problem definition with variables, objective, and constraints

Returns:
    A list of TextContent containing the solution or an error message

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
problemYes

Implementation Reference

  • The FastMCP tool handler function for 'solve_highs_problem', which receives a HiGHSProblem and delegates to the highs solver, returning JSON-formatted results.
    @app.tool("solve_highs_problem")
    async def solve_highs_problem_tool(problem: HiGHSProblem) -> list[TextContent]:
        """Solve a HiGHs linear/mixed-integer programming problem.
    
        This tool takes a HiGHs optimization problem defined with variables, objective,
        and constraints, and returns a solution if one exists.
    
        HiGHs is a high-performance linear programming solver that supports:
        - Linear programming (LP)
        - Mixed-integer programming (MIP)
        - Both dense and sparse constraint matrices
        - Various solver algorithms (simplex, interior point, etc.)
    
        Example problem structure:
        {
            "problem": {
                "sense": "minimize",
                "objective": {
                    "linear": [1.0, 2.0, 3.0]
                },
                "variables": [
                    {"name": "x1", "lb": 0, "ub": 10, "type": "cont"},
                    {"name": "x2", "lb": 0, "ub": null, "type": "cont"},
                    {"name": "x3", "lb": 0, "ub": 1, "type": "bin"}
                ],
                "constraints": {
                    "dense": [
                        [1, 1, 0],
                        [0, 1, 1]
                    ],
                    "sense": ["<=", ">="],
                    "rhs": [5, 3]
                }
            },
            "options": {
                "time_limit": 60.0,
                "output_flag": false
            }
        }
    
        Args:
            problem: The HiGHs problem definition with variables, objective, and constraints
    
        Returns:
            A list of TextContent containing the solution or an error message
        """
        result = solve_highs_problem(problem)
    
        match result:
            case Success(solution):
                return [
                    TextContent(
                        type="text",
                        text=json.dumps(
                            {
                                "status": solution.status.value,
                                "objective_value": solution.objective_value,
                                "solution": solution.solution,
                                "dual_solution": solution.dual_solution,
                                "variable_duals": solution.variable_duals,
                            }
                        ),
                    )
                ]
            case Failure(error):
                return [TextContent(type="text", text=f"Error solving problem: {error}")]
            case _:
                return [
                    TextContent(
                        type="text",
                        text="Unexpected error in solve_highs_problem_tool",
                    )
                ]
  • Pydantic schema/model defining the input structure for the solve_highs_problem tool: HiGHSProblem.
    class HiGHSProblem(BaseModel):
        """Complete HiGHS optimization problem."""
    
        problem: HiGHSProblemSpec = Field(..., description="Problem specification")
        options: HiGHSOptions | None = Field(None, description="Solver options")
  • Registration of the 'solve_highs_problem' tool using FastMCP's @app.tool decorator.
    @app.tool("solve_highs_problem")
  • Core helper function 'solve_problem' (aliased as solve_highs_problem) that implements the actual HiGHS solver logic using the highspy library.
    def solve_problem(problem: HiGHSProblem) -> Result[HiGHSOutput, str]:
        """Solve a HiGHs optimization problem."""
        try:
            # Create HiGHs instance
            h = highspy.Highs()
    
            # Always disable output for MCP server compatibility
            h.setOptionValue("output_flag", False)
            h.setOptionValue("log_to_console", False)
    
            # Apply options
            options_result = _apply_options(h, problem.options)
            if isinstance(options_result, Failure):
                return options_result
    
            problem_spec = problem.problem
            num_vars = len(problem_spec.variables)
            num_constraints = len(problem_spec.constraints.sense)
    
            # Set up objective
            obj_coeffs = np.array(problem_spec.objective.linear, dtype=float)
            if len(obj_coeffs) != num_vars:
                return Failure(
                    f"Objective coefficients length ({len(obj_coeffs)}) doesn't match number of variables ({num_vars})"
                )
    
            # Set up variable bounds
            var_lower = np.zeros(num_vars, dtype=float)
            var_upper = np.full(num_vars, highspy.kHighsInf, dtype=float)
    
            for i, var_spec in enumerate(problem_spec.variables):
                lb, ub = _get_variable_bounds(var_spec, i)
                var_lower[i] = lb
                var_upper[i] = ub
    
            # Build constraint matrix
            matrix_result = _build_constraint_matrix(problem_spec)
            if isinstance(matrix_result, Failure):
                return matrix_result
    
            rows, cols, values = matrix_result.unwrap()
    
            # Set up constraint bounds
            constraint_lower = np.zeros(num_constraints, dtype=float)
            constraint_upper = np.zeros(num_constraints, dtype=float)
    
            for i, (sense, rhs) in enumerate(
                zip(
                    problem_spec.constraints.sense,
                    problem_spec.constraints.rhs,
                    strict=False,
                )
            ):
                lb, ub = _convert_constraint_sense(sense, rhs)
                constraint_lower[i] = lb
                constraint_upper[i] = ub
    
            # Add variables
            h.addCols(
                num_vars,
                obj_coeffs,
                var_lower,
                var_upper,
                0,
                np.array([]),
                np.array([]),
                np.array([]),
            )
    
            # Set variable integrality constraints
            integrality = np.zeros(num_vars, dtype=int)  # 0 = continuous
            for i, var_spec in enumerate(problem_spec.variables):
                if var_spec.type == HiGHSVariableType.BINARY:
                    integrality[i] = 1  # 1 = integer (binary is integer with bounds 0-1)
                elif var_spec.type == HiGHSVariableType.INTEGER:
                    integrality[i] = 1  # 1 = integer
                # else: continuous (already 0)
    
            # Apply integrality constraints if any variables are integer/binary
            if np.any(integrality > 0):
                h.changeColsIntegrality(num_vars, np.arange(num_vars), integrality)
    
            # Add constraints using sparse format
            if len(rows) > 0:
                # Convert to row-wise sparse format for HiGHs
                # Group by rows and create start array
                unique_rows = np.unique(rows)
                start_array = np.zeros(num_constraints + 1, dtype=int)
    
                for row in unique_rows:
                    start_array[row] = np.sum(rows < row)
    
                start_array[-1] = len(rows)  # Final start
    
                h.addRows(
                    num_constraints,
                    constraint_lower,
                    constraint_upper,
                    len(values),
                    start_array,
                    cols,
                    values,
                )
            else:
                # No constraints case
                h.addRows(
                    num_constraints,
                    constraint_lower,
                    constraint_upper,
                    0,
                    np.array([0]),
                    np.array([]),
                    np.array([]),
                )
    
            # Set objective sense
            if problem_spec.sense == HiGHSSense.MAXIMIZE:
                h.changeObjectiveSense(highspy.ObjSense.kMaximize)
            else:
                h.changeObjectiveSense(highspy.ObjSense.kMinimize)
    
            # Solve the problem
            h.run()
    
            # Get results
            model_status = h.getModelStatus()
            solution = h.getSolution()
            info = h.getInfo()
    
            # Convert status
            status = _convert_status(model_status)
    
            # Extract solution values
            solution_values = solution.col_value if hasattr(solution, "col_value") else []
            dual_values = solution.row_dual if hasattr(solution, "row_dual") else []
            reduced_costs = solution.col_dual if hasattr(solution, "col_dual") else []
    
            # Get objective value
            objective_value = (
                info.objective_function_value
                if hasattr(info, "objective_function_value")
                else 0.0
            )
    
            return Success(
                HiGHSOutput(
                    status=status,
                    objective_value=objective_value,
                    solution=list(solution_values),
                    dual_solution=list(dual_values),
                    variable_duals=list(reduced_costs),
                )
            )
    
        except Exception as e:
            return Failure(f"Error solving HiGHs problem: {e}")

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sdiehl/usolver'

If you have feedback or need assistance with the MCP directory API, please join our Discord server