I'm considering using cvxopt to solve some nonlinear network flow optimisation problems. In order to understand the basics, I am trying it with a very simple test network with just 4 vertices and 5 edges.
My network looks like this. The blue and red nodes are a source and sink respectively.
The cost on each edge is:
alpha*x**2
where x is the vector containing the flow on each edge, and alpha is some coefficient. My optimisation problem is then:
min sum(alpha*x**2)
subject to:
E*x = b
x >= 0
where E is the edge-arc incidence matrix and b is the vector containing sources and sinks. The matrix-vector equation Ex = b should therefore just enforce Kirchoff's laws (i.e. conservation of flow at each node).
My python script to do this is:
from cvxopt import matrix, spdiag, solvers
#Four vertices, five edges
E = matrix(0.0, (4,5))
E[0,0] = 1.0
E[0,1] = 1.0
E[1,0] = -1.0
E[1,2] = 1.0
E[1,3] = 1.0
E[2,1] = -1.0
E[2,2] = -1.0
E[2,4] = 1.0
E[3,3] = -1.0
E[3,4] = -1.0
#Source-sink vector
b = matrix(0.0, (4,1))
b[0] = 0.5
b[3] = -0.5
#Coefficient in the quadtratic
alpha = 1.0
#Function to pass to cvxopt
def F(x=None, z=None):
if x is None:
return 0, matrix(0.05, (5,1))
if min(x) <= 0.0:
return None
f = sum(alpha*(x**2))
Df = (2.0*alpha*x).T
if z is None:
return f, Df
D2f = 2.0*alpha*matrix(1.0, (5,1))
H = spdiag(z[0]*D2f)
return f, Df, H
#Solve
x = solvers.cp(F, A=E, b=b)['x']
The error I get is:
pcost dcost gap pres dres
0: 0.0000e+00 1.2500e-02 1e+00 1e+00 2e-01
Traceback (most recent call last):
File "simple_network.py", line 45, in <module>
x = solvers.cp(F, A=E, b=b)['x']
File "/usr/local/lib/python2.7/dist-packages/cvxopt/cvxprog.py", line 1966, in cp
xdot_e, xaxpy_e, xscal_e, options = options)
File "/usr/local/lib/python2.7/dist-packages/cvxopt/cvxprog.py", line 782, in cpl
raise ValueError("Rank(A) < p or "\
ValueError: Rank(A) < p or Rank([H(x); A; Df(x); G]) < n
I am unsure how to proceed from here. I assumed this optimisation problem would be soluble with cvxopt, since it is simple enough to find the optimal flow by hand. I would appreciate it if somebody could tell me how to rectify this code, or else tell me why this type of problem is not suitable for this software.
Thanks in advance.