Cost Flow

Cost flow

A how-to guide for specifying the input and output schemas in cost-flow.

The cost flow app is available in one modeling language as a network flow problem. You can also choose to make customizations to the model by instantiating the app first.

nextmv community clone -a cost-flow-ortools
Copy

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 nodes of the network with their supply (negative supply equals a demand) as well as the edges between nodes. 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
projectsYesarray of projectNAThe list of available projects.See project
workersYesarray of workerNAA list of all available workers to fulfill the projects.See worker

Project

Field nameRequiredData typeSI UnitDescriptionExample
idYesstringNAThe ID of the project.{"id": "project_1"}
required_skillsYesarray of stringNAA list of skills required for this project.{"required_skills": ["programming"]}
valueYesfloatNAThe value of the project.{"value": 100}
required_timeYesfloatNAThe required time to fulfill this project.{"required_time": 2}

Worker

Field nameRequiredData typeSI UnitDescriptionExample
idYesstringNAThe ID of the worker.{"id": "worker_1"}
skillsYesfloatNAA list of skills the worker can offer.{"skills": ["programming"]}
available_timeYesmapNAThe number of time units this worker is available.{"available_time": 3

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

{
  "projects": [
    {
      "id": "project-1",
      "required_skills": ["programming"],
      "value": 3000,
      "required_time": 2
    },
    {
      "id": "project-2",
      "required_skills": ["programming", "design"],
      "value": 4500,
      "required_time": 4
    },
    {
      "id": "project-3",
      "required_skills": ["design"],
      "value": 3500,
      "required_time": 3
    },
    {
      "id": "project-4",
      "required_skills": ["design"],
      "value": 2450,
      "required_time": 2
    },
    {
      "id": "project-5",
      "required_skills": ["programming"],
      "value": 4000,
      "required_time": 5
    }
  ],
  "workers": [
    {
      "id": "worker-1",
      "skills": ["programming"],
      "available_time": 3
    },
    {
      "id": "worker-2",
      "skills": ["programming", "design"],
      "available_time": 9
    },
    {
      "id": "worker-3",
      "skills": ["design"],
      "available_time": 4
    }
  ]
}
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
solutionYesarray of solutionNASolutions to the order fulfillment problem.See solution
statisticsYesstatisticsNASummary statistics of the solution.{"statistics": {"total_cost": 123}}
{
  "solution": {
    "assignments": [
      {
        "project": "project-1",
        "time_units": 2,
        "value": 3000,
        "worker": "worker-1"
      },
      {
        "project": "project-5",
        "time_units": 1,
        "value": 4000,
        "worker": "worker-1"
      },
      {
        "project": "project-2",
        "time_units": 4,
        "value": 4500,
        "worker": "worker-2"
      },
      {
        "project": "project-4",
        "time_units": 1,
        "value": 2450,
        "worker": "worker-2"
      },
      {
        "project": "project-5",
        "time_units": 4,
        "value": 4000,
        "worker": "worker-2"
      },
      {
        "project": "project-3",
        "time_units": 3,
        "value": 3500,
        "worker": "worker-3"
      },
      {
        "project": "project-4",
        "time_units": 1,
        "value": 2450,
        "worker": "worker-3"
      }
    ],
    "flows": [
      {
        "capacity": 3,
        "flow": 3,
        "from": 0,
        "to": 4,
        "value": 0
      },
      {
        "capacity": 9,
        "flow": 9,
        "from": 0,
        "to": 5,
        "value": 0
      },
      {
        "capacity": 4,
        "flow": 4,
        "from": 0,
        "to": 6,
        "value": 0
      },
      {
        "capacity": 3,
        "flow": 2,
        "from": 4,
        "to": 7,
        "value": 3000
      },
      {
        "capacity": 3,
        "flow": 1,
        "from": 4,
        "to": 11,
        "value": 800
      },
      {
        "capacity": 9,
        "flow": 0,
        "from": 5,
        "to": 7,
        "value": 0
      },
      {
        "capacity": 9,
        "flow": 4,
        "from": 5,
        "to": 8,
        "value": 4500
      },
      {
        "capacity": 9,
        "flow": 0,
        "from": 5,
        "to": 9,
        "value": 0
      },
      {
        "capacity": 9,
        "flow": 1,
        "from": 5,
        "to": 10,
        "value": 1225
      },
      {
        "capacity": 9,
        "flow": 4,
        "from": 5,
        "to": 11,
        "value": 3200
      },
      {
        "capacity": 4,
        "flow": 3,
        "from": 6,
        "to": 9,
        "value": 3500
      },
      {
        "capacity": 4,
        "flow": 1,
        "from": 6,
        "to": 10,
        "value": 1225
      },
      {
        "capacity": 2,
        "flow": 2,
        "from": 7,
        "to": 1,
        "value": 0
      },
      {
        "capacity": 4,
        "flow": 4,
        "from": 8,
        "to": 1,
        "value": 0
      },
      {
        "capacity": 3,
        "flow": 3,
        "from": 9,
        "to": 1,
        "value": 0
      },
      {
        "capacity": 2,
        "flow": 2,
        "from": 10,
        "to": 1,
        "value": 0
      },
      {
        "capacity": 5,
        "flow": 5,
        "from": 11,
        "to": 1,
        "value": 0
      },
      {
        "capacity": 3,
        "flow": 0,
        "from": 4,
        "to": 3,
        "value": 0
      },
      {
        "capacity": 9,
        "flow": 0,
        "from": 5,
        "to": 3,
        "value": 0
      },
      {
        "capacity": 4,
        "flow": 0,
        "from": 6,
        "to": 3,
        "value": 0
      },
      {
        "capacity": 0,
        "flow": 0,
        "from": 2,
        "to": 7,
        "value": 0
      },
      {
        "capacity": 0,
        "flow": 0,
        "from": 2,
        "to": 8,
        "value": 0
      },
      {
        "capacity": 0,
        "flow": 0,
        "from": 2,
        "to": 9,
        "value": 0
      },
      {
        "capacity": 0,
        "flow": 0,
        "from": 2,
        "to": 10,
        "value": 0
      },
      {
        "capacity": 0,
        "flow": 0,
        "from": 2,
        "to": 11,
        "value": 0
      }
    ],
    "status": "optimal",
    "total_value_of_fulfilled_projects": 17450
  },
  "statistics": {
    "result": {
      "custom": {
        "available_time_units": 16,
        "excess_time_units": 0,
        "number_of_edges": 25,
        "number_of_fulfilled_projects": 5,
        "number_of_nodes": 12,
        "number_of_projects": 5,
        "number_of_unfilled_projects": 0,
        "number_of_unfulfilled_projects": 0,
        "number_of_workers": 3,
        "required_time_units": 16,
        "unmet_time_units": 0
      },
      "duration": 0.015,
      "value": -17448
    },
    "run": {
      "duration": 0.015
    },
    "schema": "v1"
  }
}
Copy

Solution

Field nameAlways presentData typeSI UnitDescriptionExample
flowsNoarray of flowNAA list of all the flows in the solution, including flows to and from the dummy source and
the dummy sink nodes.See flow
assignmentsNoarray of assignmentNAA list of actual assignments between workers and projects; translates the flows
into the context of the use case.See assignment
statusNostringNAThe status of the solution{"status": "optimal"}
total_value_of_fulfilled_projectsNointNAThe total value of all the projects that could be fully staffed by workers.{"value": 123}

Flow

Field nameAlways presentData typeSI UnitDescriptionExample
fromNointNAIndex of start node of the flow.{"from": 123}
toNointNAIndex of the end node of the flow.{"to": 1}
flowNointNANumber of time units in this flow.{"flow": 123}
capacityNointNAOriginal capacity between the start and the end node.{"capacity": 123}
valueNointNAProject value that is realized with this flow.{"value": 123}

Assignment

Field nameAlways presentData typeSI UnitDescriptionExample
projectNostringNAThe project id of the project in this assignment.{"project": "project_1"}
workerNostringNAThe worker id of the worker in this assignment.{"worker": "worker_1"}
valueNointNAThe the realized project value of this assignment.{"value": 123}
time_unitsNointNAThe utilized time units of the worker to fulfill the indicated project.{"capacity": 123}

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
    number_of_edgesYesintNANumber of edges in the network that is constructed based on the input.{"number_of_edges": 123}
    number_of_nodesYesintNANumber of nodes in the network that is constructed based on the input.{"number_of_nodes": 123}
    number_of_workersYesintNANumber of workers in the input.{"number_of_workers": "optimal"}
    number_of_projectsYesintNANumber of projects in the input.{"number_of_projects": 123}
    available_time_unitsYesintNANumber of time units offered by the workers.{"available_time_units": 123}
    required_time_unitsYesintNANumber of time units required by the projects.{"required_time_units": 123}
    excess_time_unitsYesintNANumber of time units in excess of the demand.{"excess_time_units": 123}
    unmet_time_unitsYesintNANumber of time units that can't be fulfilled by the workers.{"unmet_time_units": 123}
    number_of_fulfilled_projectsYesintNANumber of projects that could be completely fulfilled by the workers.{"number_of_fulfilled_projects": 123}
    number_of_unfulfilled_projectsYesintNANumber of projects that could not be completely fulfilled by the workers.{"number_of_unfulfilled_projects": 123}

Run options

These are the default options that are available with cost flow model.

usage: main.py [-h] [-input INPUT] [-output OUTPUT] [-penalty PENALTY]

Solve cost-flow with OR-Tools.

options:
  -h, --help        show this help message and exit
  -input INPUT      Path to input file. Default is stdin.
  -output OUTPUT    Path to output file. Default is stdout.
  -penalty PENALTY  A penalty added to the edges from dummy source to
                    projects. Default is 3000.
Copy

Page last updated

Go to on-page nav menu