Skip to main content
Glama

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
NameRequiredDescriptionDefault
suppliersYes
consumersYes
costsYes

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,
        )
  • 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)}",
            }

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/dmitryanchikov/mcp-optimizer'

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