Order Fulfillment

Order fulfillment

A how-to guide for specifying the input and output schemas in order fulfillment.

The order fulfillment app is available in one modeling language as a Mixed Integer Problem (MIP). You can also choose to make customizations to the model by instantiating the app first.

Once you have the code locally, you can customize the model, run it locally and deploy it to Nextmv Platform.

Input

The input schema is a JSON payload defining the items, distribution centers, carrier capacities, and carrier delivery costs . Nextmv's tools are designed to operate directly on business data (in JSON) to produce decisions that are actionable by software systems. This makes decisions more interpretable and easier to test. It also makes integration with data warehouses and business intelligence platforms significantly easier. An input contains the following components:

Field nameRequiredData typeSI UnitDescriptionExample
carton_volumeYesfloatNAThe volume of a carton.{"carton_volume": 2.0}
itemsYesarray of itemNAThe items which need to be fulfilled.See item
distribution_centersYesarray of distribution_centerNAThe distribution centers available.{"depot": 0}
carrier_capacitiesYesmap of string to map of string to floatNAThe capacities of each distribution center and carrier combination.{"carrier_capacites": {"distribution_center_1": "carrier1": 10.0, "carrier2": 25.0}}
carrier_delivery_costsYesmap of string to map of string to map of string to array of floatNAThe cost of each carrier and distribution center combination by weight tier.{"carrier_delivery_costs": "distribution_center_1": {"carrier1": {"weight_tiers": [2,3], "weight_rate": [1.2, 3.4]}}}

Item

Field nameRequiredData typeSI UnitDescriptionExample
item_idYesstringNAThe ID of the item.{"item_id": "book"}
quantityYesfloatNAThe quantity needed of the item.{"quantity": 5}
unit_volumeYesfloatNAThe volume per unit of item.{"unit_volume": 0.1}
unit_weightYesfloatNAThe quantity needed of the item.{"unit_weight": 0.6}

Distribution center

Field nameRequiredData typeSI UnitDescriptionExample
distribution_center_idYesstringNAThe ID of the distribution center.{"distribution_center_id": "distribution_center_1"}
handling_costYesfloatNAThe handling cost at the distribution center.{"handling_cost": 1}
inventoryYesmapNAThe inventory of each item available at the distribution center.{"inventory": {"book": 8, "sneaker": 5}}

Here you can find a sample .json with the input schema:

{
  "carton_volume": 2.0,
  "items": [
    {
      "item_id": "book",
      "quantity": 5,
      "unit_volume": 0.1,
      "unit_weight": 0.6
    },
    {
      "item_id": "sneaker",
      "quantity": 2,
      "unit_volume": 0.2,
      "unit_weight": 0.8
    },
    {
      "item_id": "hydrating gel",
      "quantity": 12,
      "unit_volume": 0.1,
      "unit_weight": 0.01
    },
    {
      "item_id": "pressure cooker",
      "quantity": 2,
      "unit_volume": 0.4,
      "unit_weight": 1.5
    },
    {
      "item_id": "mattress",
      "quantity": 2,
      "unit_volume": 3,
      "unit_weight": 6.5
    }
  ],
  "distribution_centers": [
    {
      "distribution_center_id": "distribution_center_1",
      "handling_cost": 1,
      "inventory": {
        "book": 0,
        "sneaker": 8,
        "hydrating gel": 4,
        "pressure cooker": 3,
        "mattress": 5
      }
    },
    {
      "distribution_center_id": "distribution_center_2",
      "handling_cost": 0.3,
      "inventory": {
        "book": 10,
        "sneaker": 6,
        "hydrating gel": 9,
        "pressure cooker": 2,
        "mattress": 4
      }
    }
  ],
  "carrier_capacities": {
    "distribution_center_1": {
      "carrier1": 10.0,
      "carrier2": 25.0
    },
    "distribution_center_2": {
      "carrier1": 21.0,
      "carrier2": 18.0
    }
  },
  "carrier_delivery_costs": {
    "distribution_center_1": {
      "carrier1": {
        "weight_tiers": [
          2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30
        ],
        "weight_rates": [
          3.73, 3.76, 3.77, 3.77, 3.8, 3.88, 3.96, 4.05, 4.09, 4.11, 4.34, 4.58,
          4.62, 4.68, 4.69
        ]
      },
      "carrier2": {
        "weight_tiers": [
          2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30
        ],
        "weight_rates": [
          3.97, 3.97, 4.07, 4.11, 4.18, 4.32, 4.37, 4.4, 4.52, 4.92, 5.06, 5.11,
          5.12, 5.33, 5.75
        ]
      }
    },
    "distribution_center_2": {
      "carrier1": {
        "weight_tiers": [
          2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30
        ],
        "weight_rates": [
          3.73, 3.76, 3.77, 3.77, 3.8, 3.88, 3.96, 4.05, 4.09, 4.11, 4.34, 4.58,
          4.62, 4.68, 4.69
        ]
      },
      "carrier2": {
        "weight_tiers": [
          2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30
        ],
        "weight_rates": [
          3.97, 3.97, 4.07, 4.11, 4.18, 4.32, 4.37, 4.4, 4.52, 4.92, 5.06, 5.11,
          5.12, 5.33, 5.75
        ]
      }
    }
  },
  "carrier_dimensional_weight_factors": {
    "carrier1": 1.33,
    "carrier2": 1.43
  }
}
Copy

Output

The output schema defines the solution to the order fulfillment problem in JSON format. The output schema contains the following components.

Field nameAlways presentData typeSI UnitDescriptionExample
solutionsYesarray of solutionNASolutions to the order fulfillment problem.{"solutions": []}
statisticsYesstatisticsNASummary statistics of the solution.{"statistics": {"total_cost": 123}}
{
  "options": {
    "solve": {
      "control": {
        "bool": [],
        "float": [],
        "int": [],
        "string": []
      },
      "duration": 3000000000,
      "mip": {
        "gap": {
          "absolute": 0.000001,
          "relative": 0.0001
        }
      },
      "verbosity": "off"
    }
  },
  "solutions": [
    {
      "assignments": [
        {
          "carrier_id": "carrier1",
          "distribution_center_id": "distribution_center_2",
          "item_id": "book",
          "quantity": 3
        },
        {
          "carrier_id": "carrier2",
          "distribution_center_id": "distribution_center_2",
          "item_id": "book",
          "quantity": 2
        },
        {
          "carrier_id": "carrier2",
          "distribution_center_id": "distribution_center_1",
          "item_id": "sneaker",
          "quantity": 1
        },
        {
          "carrier_id": "carrier2",
          "distribution_center_id": "distribution_center_2",
          "item_id": "sneaker",
          "quantity": 1
        },
        {
          "carrier_id": "carrier2",
          "distribution_center_id": "distribution_center_1",
          "item_id": "hydrating gel",
          "quantity": 3
        },
        {
          "carrier_id": "carrier1",
          "distribution_center_id": "distribution_center_2",
          "item_id": "hydrating gel",
          "quantity": 2
        },
        {
          "carrier_id": "carrier1",
          "distribution_center_id": "distribution_center_2",
          "item_id": "hydrating gel",
          "quantity": 3
        },
        {
          "carrier_id": "carrier1",
          "distribution_center_id": "distribution_center_2",
          "item_id": "hydrating gel",
          "quantity": 4
        },
        {
          "carrier_id": "carrier1",
          "distribution_center_id": "distribution_center_2",
          "item_id": "pressure cooker",
          "quantity": 1
        },
        {
          "carrier_id": "carrier2",
          "distribution_center_id": "distribution_center_2",
          "item_id": "pressure cooker",
          "quantity": 1
        },
        {
          "carrier_id": "carrier1",
          "distribution_center_id": "distribution_center_2",
          "item_id": "mattress",
          "quantity": 1
        },
        {
          "carrier_id": "carrier2",
          "distribution_center_id": "distribution_center_2",
          "item_id": "mattress",
          "quantity": 1
        }
      ],
      "billable_weights": {
        "distribution_center_1-carrier1": 2,
        "distribution_center_1-carrier2": 4,
        "distribution_center_2-carrier1": 10,
        "distribution_center_2-carrier2": 10
      },
      "cartons": {
        "distribution_center_1-carrier1": 0,
        "distribution_center_1-carrier2": 0.25,
        "distribution_center_2-carrier1": 2.3000000000000003,
        "distribution_center_2-carrier2": 1.9000000000000001
      },
      "delivery_costs": {
        "distribution_center_1-carrier1": 3.73,
        "distribution_center_1-carrier2": 3.97,
        "distribution_center_2-carrier1": 3.8000000000000003,
        "distribution_center_2-carrier2": 4.18
      },
      "dimensional_weights": {
        "distribution_center_1-carrier1": 0,
        "distribution_center_1-carrier2": 0.715,
        "distribution_center_2-carrier1": 6.118,
        "distribution_center_2-carrier2": 5.433999999999999
      },
      "status": "optimal",
      "value": 17.19,
      "volumes": {
        "distribution_center_1-carrier1": 0,
        "distribution_center_1-carrier2": 0.5,
        "distribution_center_2-carrier1": 4.6000000000000005,
        "distribution_center_2-carrier2": 3.8000000000000003
      },
      "weight_tiers": {
        "distribution_center_1-carrier1": {
          "0": 1,
          "1": 0,
          "10": 0,
          "11": 0,
          "12": 0,
          "13": 0,
          "14": 0,
          "15": 0,
          "2": 0,
          "3": 0,
          "4": 0,
          "5": 0,
          "6": 0,
          "7": 0,
          "8": 0,
          "9": 0
        },
        "distribution_center_1-carrier2": {
          "0": 0,
          "1": 1,
          "10": 0,
          "11": 0,
          "12": 0,
          "13": 0,
          "14": 0,
          "15": 0,
          "2": 0,
          "3": 0,
          "4": 0,
          "5": 0,
          "6": 0,
          "7": 0,
          "8": 0,
          "9": 0
        },
        "distribution_center_2-carrier1": {
          "0": 0,
          "1": 0,
          "10": 0,
          "11": 0,
          "12": 0,
          "13": 0,
          "14": 0,
          "15": 0,
          "2": 0,
          "3": 0,
          "4": 1,
          "5": 0,
          "6": 0,
          "7": 0,
          "8": 0,
          "9": 0
        },
        "distribution_center_2-carrier2": {
          "0": 0,
          "1": 0,
          "10": 0,
          "11": 0,
          "12": 0,
          "13": 0,
          "14": 0,
          "15": 0,
          "2": 0,
          "3": 0,
          "4": 1,
          "5": 0,
          "6": 0,
          "7": 0,
          "8": 0,
          "9": 0
        }
      },
      "weights": {
        "distribution_center_1-carrier1": 0,
        "distribution_center_1-carrier2": 0.8300000000000001,
        "distribution_center_2-carrier1": 9.89,
        "distribution_center_2-carrier2": 10
      }
    }
  ],
  "statistics": {
    "result": {
      "custom": {
        "delivery_costs": 15.68,
        "handling_costs": 1.51
      },
      "duration": 0.123,
      "value": 17.19
    },
    "run": {
      "duration": 0.123
    },
    "schema": "v1"
  },
  "version": {
    "go-highs": "VERSION",
    "go-mip": "VERSION",
    "sdk": "VERSION"
  }
}
Copy

Solution

Field nameAlways presentData typeSI UnitDescriptionExample
assignmentsYesarray of assignmentNASolution to the order fulfillment problemSee assignment

Assignment

Field nameAlways presentData typeSI UnitDescriptionExample
item_idYesstringNAID of the item.{"item_id": "book"}
quantityYesintNAQuantity of the items in the assignment.{"quantity": 1}
distribution_center_idYesstringNAID of the distribution center.{"distribution_center_id": "distribution_center_2"}
carrier_idYesstringNAID of the carrier.{"carrier_id": "carrier1"}

Statistics

Field nameAlways presentData typeSI UnitDescriptionExample
resultNoresultNAFinal result of the solutions.See result
runYesrunNAInformation about the run.See run
schemaYesstringNASchema of the statistics.{"schema": "v1"}

Here you can find additional definitions used in the statistics schema:

  • result

    Field nameAlways presentData typeSI UnitDescriptionExample
    durationYesfloatsecondsTime duration to get to the final result.{"duration": 0.123}
    valueYesfloatNAValue of the final result.{"value": 0.123}
    customYesanyNACustom solver metrics.See custom
  • run

    Field nameAlways presentData typeSI UnitDescriptionExample
    durationYesfloatsecondsTime duration of the run.{"duration": 0.123}
  • custom

    Field nameAlways presentData typeSI UnitDescriptionExample
    constraintsYesintNANumber of constraints.{"constraints": 123}
    providerYesstringNASolver provider.{"provider": "highs"}
    statusYesstringNASolver status.{"status": "optimal"}
    variablesYesintNANumber of variables.{"variables": 123}

Run options

These are the default options that are available with routing without constraints.

Page last updated

Go to on-page nav menu