{
  "__type": "IngestedDoc",
  "__tag": 4010,
  "_content": {
    "Notes": {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "This solves the maximum flow problem on a given directed weighted graph: A flow associates to every edge a value, also called a flow, less than the capacity of the edge, so that for every vertex (apart from the source and the sink vertices), the total incoming flow is equal to the total outgoing flow. The value of a flow is the sum of the flow of all edges leaving the source vertex, and the maximum flow problem consists of finding a flow whose value is maximal."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "By the max-flow min-cut theorem, the maximal value of the flow is also the total weight of the edges in a minimum cut."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "To solve the problem, we provide Edmonds--Karp "
            },
            {
              "__type": "FootnoteReference",
              "__tag": 4066,
              "label": "1"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " and Dinic's algorithm "
            },
            {
              "__type": "FootnoteReference",
              "__tag": 4066,
              "label": "4"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ". The implementation of both algorithms strive to exploit sparsity. The time complexity of the former "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "O(|V|\\,|E|^2)"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " and its space complexity is "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "O(|E|)"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ". The latter achieves its performance by building level graphs and finding blocking flows in them. Its time complexity is "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "O(|V|^2\\,|E|)"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " and its space complexity is "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "O(|E|)"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "The maximum flow problem is usually defined with real valued capacities, but we require that all capacities are integral to ensure convergence. When dealing with rational capacities, or capacities belonging to "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "x\\mathbb{Q}"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " for some fixed "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "x \\in \\mathbb{R}"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", it is possible to reduce the problem to the integral case by scaling all capacities accordingly."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Solving a maximum-flow problem can be used for example for graph cuts optimization in computer vision "
            },
            {
              "__type": "FootnoteReference",
              "__tag": 4066,
              "label": "3"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "."
            }
          ]
        }
      ],
      "title": [],
      "level": 0,
      "target": null
    },
    "Warns": {
      "__type": "Section",
      "__tag": 4015,
      "children": [],
      "title": [],
      "level": 0,
      "target": null
    },
    "Raises": {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Parameters",
          "__tag": 4026,
          "children": [
            {
              "__type": "DocParam",
              "__tag": 4016,
              "name": "",
              "annotation": "TypeError:",
              "desc": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "if the input graph is not in CSR format."
                    }
                  ]
                }
              ]
            },
            {
              "__type": "DocParam",
              "__tag": 4016,
              "name": "",
              "annotation": "ValueError:",
              "desc": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "if the capacity values are not integers, or the source or sink are out of bounds."
                    }
                  ]
                }
              ]
            }
          ]
        }
      ],
      "title": [],
      "level": 0,
      "target": null
    },
    "Yields": {
      "__type": "Section",
      "__tag": 4015,
      "children": [],
      "title": [],
      "level": 0,
      "target": null
    },
    "Methods": {
      "__type": "Section",
      "__tag": 4015,
      "children": [],
      "title": [],
      "level": 0,
      "target": null
    },
    "Returns": {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Parameters",
          "__tag": 4026,
          "children": [
            {
              "__type": "DocParam",
              "__tag": 4016,
              "name": "res",
              "annotation": "MaximumFlowResult",
              "desc": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "A maximum flow represented by a "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "MaximumFlowResult"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": " which includes the value of the flow in "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "flow_value"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": ", and the flow graph in "
                    },
                    {
                      "__type": "InlineCode",
                      "__tag": 4051,
                      "value": "flow"
                    },
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "."
                    }
                  ]
                }
              ]
            }
          ]
        }
      ],
      "title": [],
      "level": 0,
      "target": null
    },
    "Summary": {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Maximize the flow between two vertices in a graph."
            }
          ]
        }
      ],
      "title": [],
      "level": 0,
      "target": null
    },
    "Receives": {
      "__type": "Section",
      "__tag": 4015,
      "children": [],
      "title": [],
      "level": 0,
      "target": null
    },
    "Warnings": {
      "__type": "Section",
      "__tag": 4015,
      "children": [],
      "title": [],
      "level": 0,
      "target": null
    },
    "Attributes": {
      "__type": "Section",
      "__tag": 4015,
      "children": [],
      "title": [],
      "level": 0,
      "target": null
    },
    "Parameters": {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Parameters",
          "__tag": 4026,
          "children": [
            {
              "__type": "DocParam",
              "__tag": 4016,
              "name": "csgraph",
              "annotation": "csr_array",
              "desc": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "The square matrix representing a directed graph whose (i, j)'th entry is an integer representing the capacity of the edge between vertices i and j."
                    }
                  ]
                }
              ]
            },
            {
              "__type": "DocParam",
              "__tag": 4016,
              "name": "source",
              "annotation": "int",
              "desc": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "The source vertex from which the flow flows."
                    }
                  ]
                }
              ]
            },
            {
              "__type": "DocParam",
              "__tag": 4016,
              "name": "sink",
              "annotation": "int",
              "desc": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "The sink vertex to which the flow flows."
                    }
                  ]
                }
              ]
            },
            {
              "__type": "DocParam",
              "__tag": 4016,
              "name": "method: {'edmonds_karp', 'dinic'}, optional",
              "annotation": "",
              "desc": [
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "The method/algorithm to be used for computing the maximum flow. Following methods are supported,"
                    }
                  ]
                },
                {
                  "__type": "Blockquote",
                  "__tag": 4059,
                  "children": [
                    {
                      "__type": "BulletList",
                      "__tag": 4053,
                      "ordered": false,
                      "start": 1,
                      "children": [
                        {
                          "__type": "ListItem",
                          "__tag": 4054,
                          "children": [
                            {
                              "__type": "Paragraph",
                              "__tag": 4045,
                              "children": [
                                {
                                  "__type": "Text",
                                  "__tag": 4046,
                                  "value": "'edmonds_karp': Edmonds Karp algorithm in "
                                },
                                {
                                  "__type": "FootnoteReference",
                                  "__tag": 4066,
                                  "label": "1"
                                },
                                {
                                  "__type": "Text",
                                  "__tag": 4046,
                                  "value": "."
                                }
                              ]
                            }
                          ]
                        },
                        {
                          "__type": "ListItem",
                          "__tag": 4054,
                          "children": [
                            {
                              "__type": "Paragraph",
                              "__tag": 4045,
                              "children": [
                                {
                                  "__type": "Text",
                                  "__tag": 4046,
                                  "value": "'dinic': Dinic's algorithm in "
                                },
                                {
                                  "__type": "FootnoteReference",
                                  "__tag": 4066,
                                  "label": "4"
                                },
                                {
                                  "__type": "Text",
                                  "__tag": 4046,
                                  "value": "."
                                }
                              ]
                            }
                          ]
                        }
                      ]
                    }
                  ]
                },
                {
                  "__type": "Paragraph",
                  "__tag": 4045,
                  "children": [
                    {
                      "__type": "Text",
                      "__tag": 4046,
                      "value": "Default is 'dinic'."
                    }
                  ]
                },
                {
                  "__type": "Admonition",
                  "__tag": 4056,
                  "kind": "versionadded",
                  "base_type": "neutral",
                  "children": [
                    {
                      "__type": "AdmonitionTitle",
                      "__tag": 4055,
                      "children": [
                        {
                          "__type": "Text",
                          "__tag": 4046,
                          "value": "versionadded 1.8.0"
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          ]
        }
      ],
      "title": [],
      "level": 0,
      "target": null
    },
    "Extended Summary": {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Admonition",
          "__tag": 4056,
          "kind": "versionadded",
          "base_type": "neutral",
          "children": [
            {
              "__type": "AdmonitionTitle",
              "__tag": 4055,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "versionadded 1.4.0"
                }
              ]
            }
          ]
        }
      ],
      "title": [],
      "level": 0,
      "target": null
    },
    "Other Parameters": {
      "__type": "Section",
      "__tag": 4015,
      "children": [],
      "title": [],
      "level": 0,
      "target": null
    }
  },
  "_ordered_sections": [
    "Summary",
    "Extended Summary",
    "Parameters",
    "Attributes",
    "Methods",
    "Returns",
    "Yields",
    "Receives",
    "Other Parameters",
    "Raises",
    "Warns",
    "Warnings",
    "Notes"
  ],
  "item_file": null,
  "item_line": null,
  "item_type": "cython_function_or_method",
  "aliases": [
    "scipy.sparse.csgraph.maximum_flow"
  ],
  "example_section_data": {
    "__type": "Section",
    "__tag": 4015,
    "children": [
      {
        "__type": "Text",
        "__tag": 4046,
        "value": "Perhaps the simplest flow problem is that of a graph of only two vertices\nwith an edge from source (0) to sink (1)::\n\n    (0) --5--> (1)\n\nHere, the maximum flow is simply the capacity of the edge:\n\n"
      },
      {
        "__type": "Code",
        "__tag": 4050,
        "value": "import numpy as np\nfrom scipy.sparse import csr_array\nfrom scipy.sparse.csgraph import maximum_flow\ngraph = csr_array([[0, 5], [0, 0]])\n",
        "execution_status": "success"
      },
      {
        "__type": "Code",
        "__tag": 4050,
        "value": "maximum_flow(graph, 0, 1).flow_value\nmaximum_flow(graph, 0, 1, method='edmonds_karp').flow_value\n",
        "execution_status": "failure"
      },
      {
        "__type": "Text",
        "__tag": 4046,
        "value": "\nIf, on the other hand, there is a bottleneck between source and sink, that\ncan reduce the maximum flow::\n\n    (0) --5--> (1) --3--> (2)\n\n"
      },
      {
        "__type": "Code",
        "__tag": 4050,
        "value": "graph = csr_array([[0, 5, 0], [0, 0, 3], [0, 0, 0]])\n",
        "execution_status": "success"
      },
      {
        "__type": "Code",
        "__tag": 4050,
        "value": "maximum_flow(graph, 0, 2).flow_value\n",
        "execution_status": "failure"
      },
      {
        "__type": "Text",
        "__tag": 4046,
        "value": "\nA less trivial example is given in [2]_, Chapter 26.1:\n\n"
      },
      {
        "__type": "Code",
        "__tag": 4050,
        "value": "graph = csr_array([[0, 16, 13,  0,  0,  0],\n                   [0,  0, 10, 12,  0,  0],\n                   [0,  4,  0,  0, 14,  0],\n                   [0,  0,  9,  0,  0, 20],\n                   [0,  0,  0,  7,  0,  4],\n                   [0,  0,  0,  0,  0,  0]])\n",
        "execution_status": "success"
      },
      {
        "__type": "Code",
        "__tag": 4050,
        "value": "maximum_flow(graph, 0, 5).flow_value\n",
        "execution_status": "failure"
      },
      {
        "__type": "Text",
        "__tag": 4046,
        "value": "\nIt is possible to reduce the problem of finding a maximum matching in a\nbipartite graph to a maximum flow problem: Let :math:`G = ((U, V), E)` be a\nbipartite graph. Then, add to the graph a source vertex with edges to every\nvertex in :math:`U` and a sink vertex with edges from every vertex in\n:math:`V`. Finally, give every edge in the resulting graph a capacity of 1.\nThen, a maximum flow in the new graph gives a maximum matching in the\noriginal graph consisting of the edges in :math:`E` whose flow is positive.\n\nAssume that the edges are represented by a\n:math:`\\lvert U \\rvert \\times \\lvert V \\rvert` matrix in CSR format whose\n:math:`(i, j)`'th entry is 1 if there is an edge from :math:`i \\in U` to\n:math:`j \\in V` and 0 otherwise; that is, the input is of the form required\nby :func:`maximum_bipartite_matching`. Then the CSR representation of the\ngraph constructed above contains this matrix as a block. Here's an example:\n\n"
      },
      {
        "__type": "Code",
        "__tag": 4050,
        "value": "graph = csr_array([[0, 1, 0, 1], [1, 0, 1, 0], [0, 1, 1, 0]])\nprint(graph.toarray())\ni, j = graph.shape\nn = graph.nnz\nindptr = np.concatenate([[0],\n                         graph.indptr + i,\n                         np.arange(n + i + 1, n + i + j + 1),\n                         [n + i + j]])\nindices = np.concatenate([np.arange(1, i + 1),\n                          graph.indices + i + 1,\n                          np.repeat(i + j + 1, j)])\ndata = np.ones(n + i + j, dtype=int)\ngraph_flow = csr_array((data, indices, indptr))\nprint(graph_flow.toarray())\n",
        "execution_status": "success"
      },
      {
        "__type": "Text",
        "__tag": 4046,
        "value": "\nAt this point, we can find the maximum flow between the added sink and the\nadded source and the desired matching can be obtained by restricting the\nflow function to the block corresponding to the original graph:\n\n"
      },
      {
        "__type": "Code",
        "__tag": 4050,
        "value": "result = maximum_flow(graph_flow, 0, i+j+1, method='dinic')\nmatching = result.flow[1:i+1, i+1:i+j+1]\nprint(matching.toarray())\n",
        "execution_status": "success"
      },
      {
        "__type": "Text",
        "__tag": 4046,
        "value": "\nThis tells us that the first, second, and third vertex in :math:`U` are\nmatched with the second, first, and third vertex in :math:`V` respectively.\n\nWhile this solves the maximum bipartite matching problem in general, note\nthat algorithms specialized to that problem, such as\n:func:`maximum_bipartite_matching`, will generally perform better.\n\nThis approach can also be used to solve various common generalizations of\nthe maximum bipartite matching problem. If, for instance, some vertices can\nbe matched with more than one other vertex, this may be handled by\nmodifying the capacities of the new graph appropriately."
      }
    ],
    "title": [],
    "level": 0,
    "target": null
  },
  "see_also": [],
  "signature": {
    "__type": "SignatureNode",
    "__tag": 4029,
    "kind": "function",
    "parameters": [
      {
        "__type": "SigParam",
        "__tag": 4030,
        "name": "csgraph",
        "annotation": {
          "__type": "Empty",
          "__tag": 4031
        },
        "kind": "POSITIONAL_OR_KEYWORD",
        "default": {
          "__type": "Empty",
          "__tag": 4031
        }
      },
      {
        "__type": "SigParam",
        "__tag": 4030,
        "name": "source",
        "annotation": {
          "__type": "Empty",
          "__tag": 4031
        },
        "kind": "POSITIONAL_OR_KEYWORD",
        "default": {
          "__type": "Empty",
          "__tag": 4031
        }
      },
      {
        "__type": "SigParam",
        "__tag": 4030,
        "name": "sink",
        "annotation": {
          "__type": "Empty",
          "__tag": 4031
        },
        "kind": "POSITIONAL_OR_KEYWORD",
        "default": {
          "__type": "Empty",
          "__tag": 4031
        }
      }
    ],
    "return_annotation": {
      "__type": "Empty",
      "__tag": 4031
    },
    "target_name": "maximum_flow"
  },
  "references": [
    ".. [1] Edmonds, J. and Karp, R. M.",
    "       Theoretical improvements in algorithmic efficiency for network flow",
    "       problems. 1972. Journal of the ACM. 19 (2): pp. 248-264",
    ".. [2] Cormen, T. H. and Leiserson, C. E. and Rivest, R. L. and Stein C.",
    "       Introduction to Algorithms. Second Edition. 2001. MIT Press.",
    ".. [3] https://en.wikipedia.org/wiki/Graph_cuts_in_computer_vision",
    ".. [4] Dinic, Efim A.",
    "       Algorithm for solution of a problem of maximum flow in networks with",
    "       power estimation. In Soviet Math. Doklady, vol. 11, pp. 1277-1280.",
    "       1970."
  ],
  "qa": "scipy.sparse.csgraph._flow:maximum_flow",
  "arbitrary": [],
  "local_refs": [
    "'dinic'}",
    "csgraph",
    "method: {'edmonds_karp'",
    "optional",
    "res",
    "sink",
    "source"
  ]
}