GLPK Backend for access to GLPK graph functions¶
AUTHORS:
Christian Kuper (2012-11): Initial implementation
Methods index¶
Graph creation and modification operations:
Add an isolated vertex to the graph. |
|
Add vertices from an iterable container of vertices. |
|
Set the vertex parameters. |
|
Set the parameters of selected vertices. |
|
Return a specific vertex as a dictionary Object. |
|
Return a dictionary of the dictionaries associated to each vertex. |
|
Return a |
|
Remove a vertex from the graph. |
|
Remove vertices from the graph. |
|
Add an edge between vertices |
|
Add edges to the graph. |
|
Return an edge connecting two vertices. |
|
Return a |
|
Delete an edge from the graph. |
|
Delete edges from the graph. |
Graph writing operations:
Write the graph to a plain text file. |
|
Write the graph to a text file in DIMACS format. |
|
Write the mincost flow problem data to a text file in DIMACS format. |
|
Write the maximum flow problem data to a text file in DIMACS format. |
Network optimization operations:
Find solution to the mincost problem with the out-of-kilter algorithm. |
|
Find solution to the maxflow problem with Ford-Fulkerson algorithm. |
|
Solve the critical path problem of a project network. |
Classes and methods¶
- class sage.numerical.backends.glpk_graph_backend.GLPKGraphBackend[source]¶
Bases:
objectGLPK Backend for access to GLPK graph functions.
The constructor can either be called without arguments (which results in an empty graph) or with arguments to read graph data from a file.
INPUT:
data– a filename or aGraphobjectformat– whendatais a filename, specifies the format of the data read from a file. Theformatparameter is a string and can take values as described in the table below.
Format parameters:
plainRead data from a plain text file containing the following information:
nv nai[1] j[1]i[2] j[2]…i[na] j[na]where:
nv is the number of vertices (nodes);
na is the number of arcs;
i[k], k = 1, … , na, is the index of tail vertex of arc k;
j[k], k = 1, … , na, is the index of head vertex of arc k.
dimacsRead data from a plain ASCII text file in DIMACS format. A description of the DIMACS format can be found at http://dimacs.rutgers.edu/Challenges/.
mincostReads the mincost flow problem data from a text file in DIMACS format
maxflowReads the maximum flow problem data from a text file in DIMACS format
Note
When
datais aGraph, the following restrictions are applied.vertices – the value of the demand of each vertex (see
set_vertex_demand()) is obtained from the numerical value associated with the key “rhs” if it is a dictionary.edges – The edge values used in the algorithms are read from the edges labels (and left undefined if the edge labels are equal to
None). To be defined, the labels must be dictionary objects with keys “low”, “cap” and “cost”. Seeget_edge()for details.
EXAMPLES:
The following example creates an empty graph:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend()
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend()
The following example creates an empty graph, adds some data, saves the data to a file and loads it:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend() sage: gbe.add_vertices([None, None]) ['0', '1'] sage: a = gbe.add_edge('0', '1') sage: import tempfile sage: with tempfile.NamedTemporaryFile() as f: ....: _ = gbe.write_graph(f.name) ....: gbe1 = GLPKGraphBackend(f.name, "plain") Writing graph to ... 4 lines were written Reading graph from ... Graph has 2 vertices and 1 edge 3 lines were read
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend() >>> gbe.add_vertices([None, None]) ['0', '1'] >>> a = gbe.add_edge('0', '1') >>> import tempfile >>> with tempfile.NamedTemporaryFile() as f: ... _ = gbe.write_graph(f.name) ... gbe1 = GLPKGraphBackend(f.name, "plain") Writing graph to ... 4 lines were written Reading graph from ... Graph has 2 vertices and 1 edge 3 lines were read
The following example imports a Sage
Graphand then uses it to solve a maxflow problem:sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: g = graphs.PappusGraph() sage: for ed in g.edges(sort=False): ....: g.set_edge_label(ed[0], ed[1], {"cap":1}) sage: gbe = GLPKGraphBackend(g) sage: gbe.maxflow_ffalg('1', '2') 3.0
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> g = graphs.PappusGraph() >>> for ed in g.edges(sort=False): ... g.set_edge_label(ed[Integer(0)], ed[Integer(1)], {"cap":Integer(1)}) >>> gbe = GLPKGraphBackend(g) >>> gbe.maxflow_ffalg('1', '2') 3.0
- add_edge(u, v, params=None)[source]¶
Add an edge between vertices
uandv.Allows adding an edge and optionally providing parameters used by the algorithms. If a vertex does not exist it is created.
INPUT:
u– the name (as string) of the tail vertexv– the name (as string) of the head vertexparams– an optional dictionary containing the edge parameters used for the algorithms. The following keys are used:low– the minimum flow through the edgecap– the maximum capacity of the edgecost– the cost of transporting one unit through the edge
EXAMPLES:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend() sage: gbe.add_edge("A", "B", {"low":0.0, "cap":10.0, "cost":5}) sage: gbe.vertices() ['A', 'B'] sage: for ed in gbe.edges(): ....: print((ed[0], ed[1], ed[2]['cap'], ed[2]['cost'], ed[2]['low'])) ('A', 'B', 10.0, 5.0, 0.0) sage: gbe.add_edge("B", "C", {"low":0.0, "cap":10.0, "cost":'5'}) Traceback (most recent call last): ... TypeError: Invalid edge parameter.
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend() >>> gbe.add_edge("A", "B", {"low":RealNumber('0.0'), "cap":RealNumber('10.0'), "cost":Integer(5)}) >>> gbe.vertices() ['A', 'B'] >>> for ed in gbe.edges(): ... print((ed[Integer(0)], ed[Integer(1)], ed[Integer(2)]['cap'], ed[Integer(2)]['cost'], ed[Integer(2)]['low'])) ('A', 'B', 10.0, 5.0, 0.0) >>> gbe.add_edge("B", "C", {"low":RealNumber('0.0'), "cap":RealNumber('10.0'), "cost":'5'}) Traceback (most recent call last): ... TypeError: Invalid edge parameter.
- add_edges(edges)[source]¶
Add edges to the graph.
INPUT:
edges– an iterable container of pairs of the form(u, v), whereuis name (as string) of the tail vertex andvis the name (as string) of the head vertex or an iterable container of triples of the form(u, v, params)where params is a dictionary as described inadd_edge.
EXAMPLES:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend() sage: edges = [("A", "B", {"low":0.0, "cap":10.0, "cost":5})] sage: edges.append(("B", "C")) sage: gbe.add_edges(edges) sage: for ed in gbe.edges(): ....: print((ed[0], ed[1], ed[2]['cap'], ed[2]['cost'], ed[2]['low'])) ('A', 'B', 10.0, 5.0, 0.0) ('B', 'C', 0.0, 0.0, 0.0) sage: edges = [("C", "D", {"low":0.0, "cap":10.0, "cost":5})] sage: edges.append(("C", "E", 5)) sage: gbe.add_edges(edges) Traceback (most recent call last): ... TypeError: Argument 'params' has incorrect type ... sage: for ed in gbe.edges(): ....: print((ed[0], ed[1], ed[2]['cap'], ed[2]['cost'], ed[2]['low'])) ('A', 'B', 10.0, 5.0, 0.0) ('B', 'C', 0.0, 0.0, 0.0) ('C', 'D', 10.0, 5.0, 0.0)
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend() >>> edges = [("A", "B", {"low":RealNumber('0.0'), "cap":RealNumber('10.0'), "cost":Integer(5)})] >>> edges.append(("B", "C")) >>> gbe.add_edges(edges) >>> for ed in gbe.edges(): ... print((ed[Integer(0)], ed[Integer(1)], ed[Integer(2)]['cap'], ed[Integer(2)]['cost'], ed[Integer(2)]['low'])) ('A', 'B', 10.0, 5.0, 0.0) ('B', 'C', 0.0, 0.0, 0.0) >>> edges = [("C", "D", {"low":RealNumber('0.0'), "cap":RealNumber('10.0'), "cost":Integer(5)})] >>> edges.append(("C", "E", Integer(5))) >>> gbe.add_edges(edges) Traceback (most recent call last): ... TypeError: Argument 'params' has incorrect type ... >>> for ed in gbe.edges(): ... print((ed[Integer(0)], ed[Integer(1)], ed[Integer(2)]['cap'], ed[Integer(2)]['cost'], ed[Integer(2)]['low'])) ('A', 'B', 10.0, 5.0, 0.0) ('B', 'C', 0.0, 0.0, 0.0) ('C', 'D', 10.0, 5.0, 0.0)
- add_vertex(name=None)[source]¶
Add an isolated vertex to the graph.
If the vertex already exists, nothing is done.
INPUT:
name– string of max 255 chars length. If no name is specified, then the vertex will be represented by the string representation of the ID of the vertex or - if this already exists - a string representation of the least integer not already representing a vertex.
OUTPUT:
If no
nameis passed as an argument, the new vertex name is returned.Noneotherwise.EXAMPLES:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend() sage: gbe.add_vertex() '0' sage: gbe.add_vertex("2") sage: gbe.add_vertex() '1'
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend() >>> gbe.add_vertex() '0' >>> gbe.add_vertex("2") >>> gbe.add_vertex() '1'
- add_vertices(vertices)[source]¶
Add vertices from an iterable container of vertices.
Vertices that already exist in the graph will not be added again.
INPUT:
vertices– iterator of vertex labels (string); a label can beNone
OUTPUT:
Generated names of new vertices if there is at least one
Nonevalue present invertices.Noneotherwise.EXAMPLES:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend() sage: vertices = [None for i in range(3)] sage: gbe.add_vertices(vertices) ['0', '1', '2'] sage: gbe.add_vertices(['A', 'B', None]) ['5'] sage: gbe.add_vertices(['A', 'B', 'C']) sage: gbe.vertices() ['0', '1', '2', 'A', 'B', '5', 'C']
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend() >>> vertices = [None for i in range(Integer(3))] >>> gbe.add_vertices(vertices) ['0', '1', '2'] >>> gbe.add_vertices(['A', 'B', None]) ['5'] >>> gbe.add_vertices(['A', 'B', 'C']) >>> gbe.vertices() ['0', '1', '2', 'A', 'B', '5', 'C']
- cpp()[source]¶
Solve the critical path problem of a project network.
OUTPUT: the length of the critical path of the network
EXAMPLES:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend() sage: gbe.add_vertices([None for i in range(3)]) ['0', '1', '2'] sage: gbe.set_vertex_demand('0', 3) sage: gbe.set_vertex_demand('1', 1) sage: gbe.set_vertex_demand('2', 4) sage: a = gbe.add_edge('0', '2') sage: a = gbe.add_edge('1', '2') sage: gbe.cpp() 7.0 sage: v = gbe.get_vertex('1') sage: 1, v["rhs"], v["es"], v["ls"] # abs tol 1e-6 (1, 1.0, 0.0, 2.0)
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend() >>> gbe.add_vertices([None for i in range(Integer(3))]) ['0', '1', '2'] >>> gbe.set_vertex_demand('0', Integer(3)) >>> gbe.set_vertex_demand('1', Integer(1)) >>> gbe.set_vertex_demand('2', Integer(4)) >>> a = gbe.add_edge('0', '2') >>> a = gbe.add_edge('1', '2') >>> gbe.cpp() 7.0 >>> v = gbe.get_vertex('1') >>> Integer(1), v["rhs"], v["es"], v["ls"] # abs tol 1e-6 (1, 1.0, 0.0, 2.0)
- delete_edge(u, v, params=None)[source]¶
Delete an edge from the graph.
If an edge does not exist it is ignored.
INPUT:
u– the name (as string) of the tail vertex of the edgev– the name (as string) of the tail vertex of the edgeparams– an optional dictionary containing the edge parameters (seeadd_edge()). If this parameter is not provided, all edges connectinguandvare deleted. Otherwise only edges with matching parameters are deleted.
See also
EXAMPLES:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend() sage: edges = [("A", "B", {"low":0.0, "cap":10.0, "cost":5})] sage: edges.append(("A", "B", {"low":0.0, "cap":15.0, "cost":10})) sage: edges.append(("B", "C", {"low":0.0, "cap":20.0, "cost":1})) sage: edges.append(("B", "C", {"low":0.0, "cap":10.0, "cost":20})) sage: gbe.add_edges(edges) sage: gbe.delete_edge("A", "B") sage: gbe.delete_edge("B", "C", {"low":0.0, "cap":10.0, "cost":20}) sage: gbe.edges()[0][0], gbe.edges()[0][1], gbe.edges()[0][2]['cost'] ('B', 'C', 1.0)
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend() >>> edges = [("A", "B", {"low":RealNumber('0.0'), "cap":RealNumber('10.0'), "cost":Integer(5)})] >>> edges.append(("A", "B", {"low":RealNumber('0.0'), "cap":RealNumber('15.0'), "cost":Integer(10)})) >>> edges.append(("B", "C", {"low":RealNumber('0.0'), "cap":RealNumber('20.0'), "cost":Integer(1)})) >>> edges.append(("B", "C", {"low":RealNumber('0.0'), "cap":RealNumber('10.0'), "cost":Integer(20)})) >>> gbe.add_edges(edges) >>> gbe.delete_edge("A", "B") >>> gbe.delete_edge("B", "C", {"low":RealNumber('0.0'), "cap":RealNumber('10.0'), "cost":Integer(20)}) >>> gbe.edges()[Integer(0)][Integer(0)], gbe.edges()[Integer(0)][Integer(1)], gbe.edges()[Integer(0)][Integer(2)]['cost'] ('B', 'C', 1.0)
- delete_edges(edges)[source]¶
Delete edges from the graph.
Non existing edges are ignored.
INPUT:
edges– an iterable container of edges
See also
EXAMPLES:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend() sage: edges = [("A", "B", {"low":0.0, "cap":10.0, "cost":5})] sage: edges.append(("A", "B", {"low":0.0, "cap":15.0, "cost":10})) sage: edges.append(("B", "C", {"low":0.0, "cap":20.0, "cost":1})) sage: edges.append(("B", "C", {"low":0.0, "cap":10.0, "cost":20})) sage: gbe.add_edges(edges) sage: gbe.delete_edges(edges[1:]) sage: len(gbe.edges()) 1 sage: gbe.edges()[0][0], gbe.edges()[0][1], gbe.edges()[0][2]['cap'] ('A', 'B', 10.0)
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend() >>> edges = [("A", "B", {"low":RealNumber('0.0'), "cap":RealNumber('10.0'), "cost":Integer(5)})] >>> edges.append(("A", "B", {"low":RealNumber('0.0'), "cap":RealNumber('15.0'), "cost":Integer(10)})) >>> edges.append(("B", "C", {"low":RealNumber('0.0'), "cap":RealNumber('20.0'), "cost":Integer(1)})) >>> edges.append(("B", "C", {"low":RealNumber('0.0'), "cap":RealNumber('10.0'), "cost":Integer(20)})) >>> gbe.add_edges(edges) >>> gbe.delete_edges(edges[Integer(1):]) >>> len(gbe.edges()) 1 >>> gbe.edges()[Integer(0)][Integer(0)], gbe.edges()[Integer(0)][Integer(1)], gbe.edges()[Integer(0)][Integer(2)]['cap'] ('A', 'B', 10.0)
- delete_vertex(vert)[source]¶
Removes a vertex from the graph.
Trying to delete a non existing vertex will raise an exception.
INPUT:
vert– the name (as string) of the vertex to delete
EXAMPLES:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend() sage: verts = ["A", "D"] sage: gbe.add_vertices(verts) sage: gbe.delete_vertex("A") sage: gbe.vertices() ['D'] sage: gbe.delete_vertex("A") Traceback (most recent call last): ... RuntimeError: Vertex A does not exist.
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend() >>> verts = ["A", "D"] >>> gbe.add_vertices(verts) >>> gbe.delete_vertex("A") >>> gbe.vertices() ['D'] >>> gbe.delete_vertex("A") Traceback (most recent call last): ... RuntimeError: Vertex A does not exist.
- delete_vertices(verts)[source]¶
Removes vertices from the graph.
Trying to delete a non existing vertex will raise an exception.
INPUT:
verts– iterable container containing names (as string) of the vertices to delete
EXAMPLES:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend() sage: verts = ["A", "B", "C", "D"] sage: gbe.add_vertices(verts) sage: v_d = ["A", "B"] sage: gbe.delete_vertices(v_d) sage: gbe.vertices() ['C', 'D'] sage: gbe.delete_vertices(["C", "A"]) Traceback (most recent call last): ... RuntimeError: Vertex A does not exist. sage: gbe.vertices() ['C', 'D']
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend() >>> verts = ["A", "B", "C", "D"] >>> gbe.add_vertices(verts) >>> v_d = ["A", "B"] >>> gbe.delete_vertices(v_d) >>> gbe.vertices() ['C', 'D'] >>> gbe.delete_vertices(["C", "A"]) Traceback (most recent call last): ... RuntimeError: Vertex A does not exist. >>> gbe.vertices() ['C', 'D']
- edges()[source]¶
Return a
listof all edges in the graph.OUTPUT: a
listoftriplesrepresenting the edges of the graphEXAMPLES:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend() sage: edges = [("A", "B", {"low":0.0, "cap":10.0, "cost":5})] sage: edges.append(("B", "C")) sage: gbe.add_edges(edges) sage: for ed in gbe.edges(): ....: print((ed[0], ed[1], ed[2]['cost'])) ('A', 'B', 5.0) ('B', 'C', 0.0)
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend() >>> edges = [("A", "B", {"low":RealNumber('0.0'), "cap":RealNumber('10.0'), "cost":Integer(5)})] >>> edges.append(("B", "C")) >>> gbe.add_edges(edges) >>> for ed in gbe.edges(): ... print((ed[Integer(0)], ed[Integer(1)], ed[Integer(2)]['cost'])) ('A', 'B', 5.0) ('B', 'C', 0.0)
- get_edge(u, v)[source]¶
Return an edge connecting two vertices.
Note
If multiple edges connect the two vertices only the first edge found is returned.
INPUT:
u– name (as string) of the tail vertexv– name (as string) of the head vertex
OUTPUT:
A
tripledescribing if edge was found orNoneif not. The third value of the triple is a dictionary containing the following edge parameters:low– the minimum flow through the edgecap– the maximum capacity of the edgecost– the cost of transporting one unit through the edgex– the actual flow through the edge after solving
EXAMPLES:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend() sage: edges = [("A", "B"), ("A", "C"), ("B", "C")] sage: gbe.add_edges(edges) sage: ed = gbe.get_edge("A", "B") sage: ed[0], ed[1], ed[2]['x'] ('A', 'B', 0.0) sage: gbe.get_edge("A", "F") is None True
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend() >>> edges = [("A", "B"), ("A", "C"), ("B", "C")] >>> gbe.add_edges(edges) >>> ed = gbe.get_edge("A", "B") >>> ed[Integer(0)], ed[Integer(1)], ed[Integer(2)]['x'] ('A', 'B', 0.0) >>> gbe.get_edge("A", "F") is None True
- get_vertex(vertex)[source]¶
Return a specific vertex as a dictionary Object.
INPUT:
vertex– the vertex label as string
OUTPUT:
The vertex as a dictionary object or
Noneif the vertex does not exist. The dictionary contains the values used or created by the different algorithms. The values associated with the keys following keys contain:“rhs” – The supply / demand value the vertex (mincost alg)
“pi” – The node potential (mincost alg)
“cut” – The cut flag of the vertex (maxflow alg)
“es” – The earliest start of task (cpp alg)
“ls” – The latest start of task (cpp alg)
EXAMPLES:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend() sage: verts = ["A", "B", "C", "D"] sage: gbe.add_vertices(verts) sage: sorted(gbe.get_vertex("A").items()) [('cut', 0), ('es', 0.0), ('ls', 0.0), ('pi', 0.0), ('rhs', 0.0)] sage: gbe.get_vertex("F") is None True
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend() >>> verts = ["A", "B", "C", "D"] >>> gbe.add_vertices(verts) >>> sorted(gbe.get_vertex("A").items()) [('cut', 0), ('es', 0.0), ('ls', 0.0), ('pi', 0.0), ('rhs', 0.0)] >>> gbe.get_vertex("F") is None True
- get_vertices(verts)[source]¶
Return a dictionary of the dictionaries associated to each vertex.
INPUT:
verts– iterable container of vertices
OUTPUT:
A list of pairs
(vertex, properties)wherepropertiesis a dictionary containing the numerical values associated with a vertex. For more information, see the documentation ofGLPKGraphBackend.get_vertex().EXAMPLES:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend() sage: verts = ['A', 'B'] sage: gbe.add_vertices(verts) sage: sorted(gbe.get_vertices(verts)['B'].items()) [('cut', 0), ('es', 0.0), ('ls', 0.0), ('pi', 0.0), ('rhs', 0.0)] sage: gbe.get_vertices(["C", "D"]) {}
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend() >>> verts = ['A', 'B'] >>> gbe.add_vertices(verts) >>> sorted(gbe.get_vertices(verts)['B'].items()) [('cut', 0), ('es', 0.0), ('ls', 0.0), ('pi', 0.0), ('rhs', 0.0)] >>> gbe.get_vertices(["C", "D"]) {}
- maxflow_ffalg(u=None, v=None)[source]¶
Finds solution to the maxflow problem with Ford-Fulkerson algorithm.
INPUT:
u– name (as string) of the tail vertex; default isNonev– name (as string) of the head vertex; default isNone
If
uorvareNone, the currently stored values for the head or tail vertex are used. This behavior is useful when reading maxflow data from a file. When calling this function with values foruandv, the head and tail vertex are stored for later use.OUTPUT: the solution to the maxflow problem, i.e. the maximum flow
Note
If the source or sink vertex does not exist, an
IndexErroris raised.If the source and sink are identical, a
ValueErroris raised.This method raises
MIPSolverExceptionexceptions when the solution cannot be computed for any reason (none exists, or the LP solver was not able to find it, etc…)
EXAMPLES:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend() sage: v = gbe.add_vertices([None for i in range(5)]) sage: edges = ((0, 1, 2), (0, 2, 3), (1, 2, 3), (1, 3, 4), ....: (3, 4, 1), (2, 4, 2)) sage: for a in edges: ....: edge = gbe.add_edge(str(a[0]), str(a[1]), {"cap":a[2]}) sage: gbe.maxflow_ffalg('0', '4') 3.0 sage: gbe.maxflow_ffalg() 3.0 sage: gbe.maxflow_ffalg('0', '8') Traceback (most recent call last): ... IndexError: Source or sink vertex does not exist
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend() >>> v = gbe.add_vertices([None for i in range(Integer(5))]) >>> edges = ((Integer(0), Integer(1), Integer(2)), (Integer(0), Integer(2), Integer(3)), (Integer(1), Integer(2), Integer(3)), (Integer(1), Integer(3), Integer(4)), ... (Integer(3), Integer(4), Integer(1)), (Integer(2), Integer(4), Integer(2))) >>> for a in edges: ... edge = gbe.add_edge(str(a[Integer(0)]), str(a[Integer(1)]), {"cap":a[Integer(2)]}) >>> gbe.maxflow_ffalg('0', '4') 3.0 >>> gbe.maxflow_ffalg() 3.0 >>> gbe.maxflow_ffalg('0', '8') Traceback (most recent call last): ... IndexError: Source or sink vertex does not exist
- mincost_okalg()[source]¶
Finds solution to the mincost problem with the out-of-kilter algorithm.
The out-of-kilter algorithm requires all problem data to be integer valued.
OUTPUT:
The solution to the mincost problem, i.e. the total cost, if operation was successful.
Note
This method raises
MIPSolverExceptionexceptions when the solution cannot be computed for any reason (none exists, or the LP solver was not able to find it, etc…)EXAMPLES:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend() sage: vertices = (35, 50, 40, -45, -20, -30, -30) sage: vs = gbe.add_vertices([None for i in range(len(vertices))]) sage: v_dict = {} sage: for i, v in enumerate(vs): ....: v_dict[v] = vertices[i] sage: gbe.set_vertices_demand(list(v_dict.items())) sage: cost = ((8, 6, 10, 9), (9, 12, 13, 7), (14, 9, 16, 5)) sage: for i in range(len(cost)): ....: for j in range(len(cost[0])): ....: gbe.add_edge(str(i), str(j + len(cost)), {"cost":cost[i][j], "cap":100}) sage: gbe.mincost_okalg() 1020.0 sage: for ed in gbe.edges(): ....: print("{} -> {} {}".format(ed[0], ed[1], ed[2]["x"])) 0 -> 6 0.0 0 -> 5 25.0 0 -> 4 10.0 0 -> 3 0.0 1 -> 6 0.0 1 -> 5 5.0 1 -> 4 0.0 1 -> 3 45.0 2 -> 6 30.0 2 -> 5 0.0 2 -> 4 10.0 2 -> 3 0.0
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend() >>> vertices = (Integer(35), Integer(50), Integer(40), -Integer(45), -Integer(20), -Integer(30), -Integer(30)) >>> vs = gbe.add_vertices([None for i in range(len(vertices))]) >>> v_dict = {} >>> for i, v in enumerate(vs): ... v_dict[v] = vertices[i] >>> gbe.set_vertices_demand(list(v_dict.items())) >>> cost = ((Integer(8), Integer(6), Integer(10), Integer(9)), (Integer(9), Integer(12), Integer(13), Integer(7)), (Integer(14), Integer(9), Integer(16), Integer(5))) >>> for i in range(len(cost)): ... for j in range(len(cost[Integer(0)])): ... gbe.add_edge(str(i), str(j + len(cost)), {"cost":cost[i][j], "cap":Integer(100)}) >>> gbe.mincost_okalg() 1020.0 >>> for ed in gbe.edges(): ... print("{} -> {} {}".format(ed[Integer(0)], ed[Integer(1)], ed[Integer(2)]["x"])) 0 -> 6 0.0 0 -> 5 25.0 0 -> 4 10.0 0 -> 3 0.0 1 -> 6 0.0 1 -> 5 5.0 1 -> 4 0.0 1 -> 3 45.0 2 -> 6 30.0 2 -> 5 0.0 2 -> 4 10.0 2 -> 3 0.0
- set_vertex_demand(vertex, demand)[source]¶
Set the demand of the vertex in a mincost flow algorithm.
INPUT:
vertex– name of the vertexdemand– the numerical value representing demand of the vertex in a mincost flow algorithm (it could be for instance \(-1\) to represent a sink, or \(1\) to represent a source and \(0\) for a neutral vertex). This can either be anintorfloatvalue.
EXAMPLES:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend() sage: vertices = [None for i in range(3)] sage: gbe.add_vertices(vertices) ['0', '1', '2'] sage: gbe.set_vertex_demand('0', 2) sage: gbe.get_vertex('0')['rhs'] 2.0 sage: gbe.set_vertex_demand('3', 2) Traceback (most recent call last): ... KeyError: 'Vertex 3 does not exist.'
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend() >>> vertices = [None for i in range(Integer(3))] >>> gbe.add_vertices(vertices) ['0', '1', '2'] >>> gbe.set_vertex_demand('0', Integer(2)) >>> gbe.get_vertex('0')['rhs'] 2.0 >>> gbe.set_vertex_demand('3', Integer(2)) Traceback (most recent call last): ... KeyError: 'Vertex 3 does not exist.'
- set_vertices_demand(pairs)[source]¶
Set the parameters of selected vertices.
INPUT:
pairs– list of pairs(vertex, demand)associating a demand to each vertex. For more information, see the documentation ofset_vertex_demand().
EXAMPLES:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend() sage: vertices = [None for i in range(3)] sage: gbe.add_vertices(vertices) ['0', '1', '2'] sage: gbe.set_vertices_demand([('0', 2), ('1', 3), ('3', 4)]) sage: sorted(gbe.get_vertex('1').items()) [('cut', 0), ('es', 0.0), ('ls', 0.0), ('pi', 0.0), ('rhs', 3.0)]
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend() >>> vertices = [None for i in range(Integer(3))] >>> gbe.add_vertices(vertices) ['0', '1', '2'] >>> gbe.set_vertices_demand([('0', Integer(2)), ('1', Integer(3)), ('3', Integer(4))]) >>> sorted(gbe.get_vertex('1').items()) [('cut', 0), ('es', 0.0), ('ls', 0.0), ('pi', 0.0), ('rhs', 3.0)]
- vertices()[source]¶
Return the list of all vertices.
Note
Changing elements of the
listwill not change anything in the the graph.Note
If a vertex in the graph does not have a name / label it will appear as
Nonein the resultinglist.EXAMPLES:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend() sage: verts = ["A", "B", "C"] sage: gbe.add_vertices(verts) sage: a = gbe.vertices(); a ['A', 'B', 'C'] sage: a.pop(0) 'A' sage: gbe.vertices() ['A', 'B', 'C']
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend() >>> verts = ["A", "B", "C"] >>> gbe.add_vertices(verts) >>> a = gbe.vertices(); a ['A', 'B', 'C'] >>> a.pop(Integer(0)) 'A' >>> gbe.vertices() ['A', 'B', 'C']
- write_ccdata(fname)[source]¶
Writes the graph to a text file in DIMACS format.
Writes the data to plain ASCII text file in DIMACS format. A description of the DIMACS format can be found at http://dimacs.rutgers.edu/Challenges/.
INPUT:
fname– full name of the file
OUTPUT: zero if the operations was successful otherwise nonzero
EXAMPLES:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend() sage: a = gbe.add_edge("0", "1") sage: import tempfile sage: with tempfile.NamedTemporaryFile() as f: ....: gbe.write_ccdata(f.name) Writing graph to ... 6 lines were written 0
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend() >>> a = gbe.add_edge("0", "1") >>> import tempfile >>> with tempfile.NamedTemporaryFile() as f: ... gbe.write_ccdata(f.name) Writing graph to ... 6 lines were written 0
- write_graph(fname)[source]¶
Writes the graph to a plain text file
INPUT:
fname– full name of the file
OUTPUT: zero if the operations was successful otherwise nonzero
EXAMPLES:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend() sage: a = gbe.add_edge("0", "1") sage: import tempfile sage: with tempfile.NamedTemporaryFile() as f: ....: gbe.write_graph(f.name) Writing graph to ... 4 lines were written 0
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend() >>> a = gbe.add_edge("0", "1") >>> import tempfile >>> with tempfile.NamedTemporaryFile() as f: ... gbe.write_graph(f.name) Writing graph to ... 4 lines were written 0
- write_maxflow(fname)[source]¶
Writes the maximum flow problem data to a text file in DIMACS format.
INPUT:
fname– full name of file
OUTPUT:
Zeroif successful, otherwisenonzeroEXAMPLES:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend() sage: import tempfile sage: with tempfile.NamedTemporaryFile() as f: ....: gbe.write_maxflow(f.name) Traceback (most recent call last): ... OSError: Cannot write empty graph sage: gbe.add_vertices([None for i in range(2)]) ['0', '1'] sage: a = gbe.add_edge('0', '1') sage: gbe.maxflow_ffalg('0', '1') 0.0 sage: with tempfile.NamedTemporaryFile() as f: ....: gbe.write_maxflow(f.name) Writing maximum flow problem data to ... 6 lines were written 0
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend() >>> import tempfile >>> with tempfile.NamedTemporaryFile() as f: ... gbe.write_maxflow(f.name) Traceback (most recent call last): ... OSError: Cannot write empty graph >>> gbe.add_vertices([None for i in range(Integer(2))]) ['0', '1'] >>> a = gbe.add_edge('0', '1') >>> gbe.maxflow_ffalg('0', '1') 0.0 >>> with tempfile.NamedTemporaryFile() as f: ... gbe.write_maxflow(f.name) Writing maximum flow problem data to ... 6 lines were written 0
- write_mincost(fname)[source]¶
Writes the mincost flow problem data to a text file in DIMACS format
INPUT:
fname– full name of file
OUTPUT: zero if successful, otherwise nonzero
EXAMPLES:
sage: from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend sage: gbe = GLPKGraphBackend() sage: a = gbe.add_edge("0", "1") sage: import tempfile sage: with tempfile.NamedTemporaryFile() as f: ....: gbe.write_mincost(f.name) Writing min-cost flow problem data to ... 4 lines were written 0
>>> from sage.all import * >>> from sage.numerical.backends.glpk_graph_backend import GLPKGraphBackend >>> gbe = GLPKGraphBackend() >>> a = gbe.add_edge("0", "1") >>> import tempfile >>> with tempfile.NamedTemporaryFile() as f: ... gbe.write_mincost(f.name) Writing min-cost flow problem data to ... 4 lines were written 0