pywr / pywr

Pywr is a generalised network resource allocation model written in Python.
GNU General Public License v3.0
157 stars 60 forks source link

NLP solver #111

Open snorfalorpagus opened 8 years ago

snorfalorpagus commented 8 years ago

Investigate writing a network linear programme based solver using GLPK.

See glpk/docs/graphs.pdf.

netlp_is_easy

snorfalorpagus commented 8 years ago

NetworkX has a function for returning the "line graph" (what we were calling the dual) from an existing directional graph: https://networkx.github.io/documentation/latest/reference/generated/networkx.generators.line.line_graph.html

>>> import networkx as nx
>>> G = nx.DiGraph()
>>> G.add_edge('a', 'b') #  implicitly adds nodes
>>> G.add_edge('b', 'c')
>>> G.nodes()
['a', 'b', 'c']
>>> G.edges()
[('a', 'b'), ('b', 'c')]
>>> L = nx.line_graph(G)
>>> L.nodes()
[('a', 'b'), ('b', 'c')]
>>> L.edges()
[(('a', 'b'), ('b', 'c'))]

That's the hard bit done. Need to add the inputs+outputs onto the graph, then all the hidden arcs.

jetuk commented 8 years ago

There are some properties of the constraint matrix A that determine whether a problem is a NLP. I'll dig out the references but it something like each column containing only two entries (1 and -1). Essentially it is the network connectivity matrix.

I wonder if it is possible to transform the existing A matrix in to a NLP. This may be easier than building it from scratch? The pycllp solver constructs the A matrix directly. It ends up looking like this,

[[A1 I],
 [A2 0]]

in block form.

snorfalorpagus commented 8 years ago

Initial attempt is here: https://github.com/pywr/pywr/commit/a5e4f368f828f55f9723bbba9cf6946b7e305439

I did this a while back (200 commits ago!). I think this is workable although no idea what state the commited code is in. I've worked out the basics.

I think there might be some limitations, e.g. I don't think cross-domain conversion factors != 1 are possible.

snorfalorpagus commented 7 years ago

Another limitation of this is that there is no way to implement the aggegate nodes that limit flow over a group of nodes.

jetuk commented 7 years ago

We could have a mechanism for the solver to bail out if it detects something in a Model that it can't handle?

snorfalorpagus commented 7 years ago

We could have a mechanism for the solver to bail out if it detects something in a Model that it can't handle?

Yes. I thought about adding some sort of "capabilities" object to parameters/nodes, which the solver would check at the start. If it finds a capability it isn't aware of it would croak.

jetuk commented 4 years ago

Related to #702.