solve_transportation_problem_tool
Solve transportation problems by optimizing shipping routes between suppliers and consumers to minimize costs using OR-Tools.
Instructions
Solve transportation problem using OR-Tools.
Args:
suppliers: List of supplier dictionaries with 'name' and 'supply' keys
consumers: List of consumer dictionaries with 'name' and 'demand' keys
costs: 2D cost matrix where costs[i][j] is cost of shipping from supplier i to consumer j
Returns:
Dictionary with solution status, flows, total cost, and execution time
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| suppliers | Yes | ||
| consumers | Yes | ||
| costs | Yes |
Implementation Reference
- The @mcp.tool()-decorated handler function implementing the tool logic by delegating to solve_transportation_problem.@mcp.tool() def solve_transportation_problem_tool( suppliers: list[dict[str, Any]], consumers: list[dict[str, Any]], costs: list[list[float]], ) -> dict[str, Any]: """ Solve transportation problem using OR-Tools. Args: suppliers: List of supplier dictionaries with 'name' and 'supply' keys consumers: List of consumer dictionaries with 'name' and 'demand' keys costs: 2D cost matrix where costs[i][j] is cost of shipping from supplier i to consumer j Returns: Dictionary with solution status, flows, total cost, and execution time """ return solve_transportation_problem( suppliers=suppliers, consumers=consumers, costs=costs, )
- src/mcp_optimizer/mcp_server.py:139-139 (registration)Call to register_assignment_tools which registers the solve_transportation_problem_tool on the MCP server.register_assignment_tools(mcp)
- Core helper function that performs detailed input validation, supply-demand balance check, and solves the transportation problem using ORToolsSolver.def solve_transportation_problem( suppliers: list[dict[str, Any]], consumers: list[dict[str, Any]], costs: list[list[float]], ) -> dict[str, Any]: """Solve transportation problem using OR-Tools.""" try: # Validate input if not suppliers: return { "status": "error", "total_cost": None, "flows": [], "execution_time": 0.0, "error_message": "No suppliers provided", } if not consumers: return { "status": "error", "total_cost": None, "flows": [], "execution_time": 0.0, "error_message": "No consumers provided", } # Validate supplier format for i, supplier in enumerate(suppliers): if not isinstance(supplier, dict): return { "status": "error", "total_cost": None, "flows": [], "execution_time": 0.0, "error_message": f"Supplier {i} must be a dictionary", } if "name" not in supplier or "supply" not in supplier: return { "status": "error", "total_cost": None, "flows": [], "execution_time": 0.0, "error_message": f"Supplier {i} must have 'name' and 'supply' fields", } # Validate consumer format # type: ignore[unreachable] for i, consumer in enumerate(consumers): if not isinstance(consumer, dict): return { "status": "error", "total_cost": None, "flows": [], "execution_time": 0.0, "error_message": f"Consumer {i} must be a dictionary", } if "name" not in consumer or "demand" not in consumer: return { "status": "error", "total_cost": None, "flows": [], "execution_time": 0.0, "error_message": f"Consumer {i} must have 'name' and 'demand' fields", } # Validate cost matrix dimensions # type: ignore[unreachable] if len(costs) != len(suppliers): return { "status": "error", "total_cost": None, "flows": [], "execution_time": 0.0, "error_message": f"Cost matrix dimensions: rows ({len(costs)}) must match suppliers count ({len(suppliers)})", } for i, row in enumerate(costs): if len(row) != len(consumers): return { "status": "error", "total_cost": None, "flows": [], "execution_time": 0.0, "error_message": f"Cost matrix row {i} length ({len(row)}) must match consumers count ({len(consumers)})", } # Check for negative supply/demand for supplier in suppliers: if supplier["supply"] < 0: return { "status": "error", "total_cost": None, "flows": [], "execution_time": 0.0, "error_message": "Supply must be non-negative", } for consumer in consumers: if consumer["demand"] < 0: return { "status": "error", "total_cost": None, "flows": [], "execution_time": 0.0, "error_message": "Demand must be non-negative", } # Check supply-demand balance total_supply = sum(supplier["supply"] for supplier in suppliers) total_demand = sum(consumer["demand"] for consumer in consumers) if abs(total_supply - total_demand) > 1e-6: return { "status": "error", "total_cost": None, "flows": [], "execution_time": 0.0, "error_message": f"Total supply ({total_supply}) must equal total demand ({total_demand})", } # Create solver and solve from mcp_optimizer.solvers import ORToolsSolver solver = ORToolsSolver() result = solver.solve_transportation_problem( suppliers=suppliers, consumers=consumers, costs=costs, ) # Add shipments as alias for flows for backward compatibility if "flows" in result: result["shipments"] = result["flows"] logger.info(f"Transportation problem solved with status: {result.get('status')}") return result except Exception as e: logger.error(f"Error in solve_transportation_problem: {e}") return { "status": "error", "total_cost": None, "flows": [], "execution_time": 0.0, "error_message": f"Failed to solve transportation problem: {str(e)}", }