Skip to main content
Glama

solve_highs_problem

Solve HiGHS linear and mixed-integer programming problems by defining variables, objectives, and constraints. Obtain solutions for LP and MIP using simplex, interior point, or other algorithms.

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

  • MCP tool handler: @app.tool decorated async function 'solve_highs_problem_tool' that processes HiGHSProblem input, invokes the solver, and formats output as TextContent list.
    @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 BaseModel defining the input schema 'HiGHSProblem' used by the tool handler.
    class HiGHSProblem(BaseModel): """Complete HiGHS optimization problem.""" problem: HiGHSProblemSpec = Field(..., description="Problem specification") options: HiGHSOptions | None = Field(None, description="Solver options")
  • Core solver implementation: 'solve_problem' function (imported as solve_highs_problem) that constructs and solves the HiGHS optimization problem using the highspy library, returns Result[HiGHSOutput, str]. Includes helper functions like _build_constraint_matrix, _apply_options, etc.
    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}")
  • Supporting Pydantic schema 'HiGHSProblemSpec' nested within HiGHSProblem, defining core problem structure (sense, objective, variables, constraints).
    class HiGHSProblemSpec(BaseModel): """Problem specification for HiGHs.""" sense: HiGHSSense = Field(..., description="Optimization sense") objective: HiGHSObjective = Field(..., description="Objective function") variables: list[HiGHSVariable] = Field(..., description="Variable specifications") constraints: HiGHSConstraints = Field(..., description="Constraint specifications")
  • Tool registration decorator @app.tool registering the 'solve_highs_problem' handler with FastMCP app.
    @app.tool("solve_highs_problem")

Other Tools

Related Tools

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