-
Notifications
You must be signed in to change notification settings - Fork 11
mincost() return dual variables #20
Comments
hi, sorry for the delay, it is indeed an interesting piece of information when solving flows. Regarding network simplex this is correct, but I'm not sure you can pass this info without being solver-specific. If you look at Clp FAQ: https://www.coin-or.org/Clp/faq.html |
In general, it may not be possible to do in a solver-agnostic manner. But if the solver provides more than the primal solution, could |
ah sorry, I miswrote it: |
I think you all are talking about roughly the same thing I want. I'm not a mathematician, nor have I ever played one on TV. But I am really interested in getting flow paths, rather then just flows. For example: if I wanted to implement Earth Mover Distance using mincost_flow it might look something like the following: a = [3,2,1]
a = a ./ sum(a)
b = [1,2,3]
b = b ./ sum(b)
len = length(a)
g = LightGraphs.DiGraph(len)
cost,demand,capacity = zeros(len,len), zeros(len,len), ones(len,len)
for i in 1:len
for j in 1:len
LightGraphs.add_edge!(g, i, j)
cost[i,j] = abs(j - i)
end
demand[i,i] = b[i]
end
flow = mincost_flow(g, capacity, demand, cost, ClpSolver())
#new api?
flow = mincost_flow(g, path,
capacity, cost, ClpSolver(),
edge_demand=demand)
but the Flow does not return the path/cost of the flow. It just gives ... b, which is pretty uninteresting. Granted I may have goofed in my implementation as well. I hope the idea is clear. If what i'm thinking is different should I file a different issue? |
Your problem is not the same as above, I think you misunderstand the entries of the algorithm. To give you an example, to model the problem linked here: const lg = LightGraphs
g = lg.DiGraph(6) # Create a flow-graph
w = zeros(6,6)
lg.add_edge!(g, 1, 4)
w[1,4] = 3
lg.add_edge!(g, 1, 5)
w[1,5] = 1
lg.add_edge!(g, 2, 4)
w[2,4] = 4
lg.add_edge!(g, 2, 5)
w[2,5] = 2
lg.add_edge!(g, 2, 6)
w[2,6] = 4
lg.add_edge!(g, 3, 5)
w[3,5] = 3
lg.add_edge!(g, 3, 6)
w[3,6] = 3
demand = zeros(6)
demand[1] = 5
demand[2] = 7
demand[3] = 3
demand[4] = -7
demand[5] = -3
demand[6] = -5
capacity = fill(10, (6,6))
flow = mincost_flow(g, demand, capacity, w, ClpSolver()) The output will be: 6×6 SparseArrays.SparseMatrixCSC{Float64,Int64} with 7 stored entries:
[1, 4] = 2.0
[2, 4] = 5.0
[1, 5] = 3.0
[2, 5] = 0.0
[3, 5] = 0.0
[2, 6] = 2.0
[3, 6] = 3.0 Which is a sparse matrix with the desired flow values. |
Thank you for your help! think I got a simple earth movers distance worked out using light graph flows now! a = [3,2,1]
b = [1,2,3]
len = length(a)
g = LightGraphs.DiGraph(len)
cost, capacity = zeros(len,len), ones(len,len)
demand = b .- a
for i in 1:len, j in 1:len
if i != j
LightGraphs.add_edge!(g, i, j)
cost[i,j] = abs(j - i)# +1
end
end
flow = mincost_flow(g, demand, capacity, cost, ClpSolver())
result = Matrix(flow)
cost
EMD = sum( flow .* cost ) Maybe this should be an example? I think there are packages dedicated to solving this type of problem. |
Just a code optimization: it might be faster to create a |
Is there a way to have
mincost()
return not just the solution variables, but also the dual variables? In the example posted,mincost()
is passedClpsolver()
, which produces the dual variables already. For anyone unfamiliar with LP duality, these represent the subgradients of the min cost problem with respect to the arc constraints.Since I need both the primal and dual variables, I'm currently converting the min cost problem to an LP and calling
Clpsolver()
directly. However, I'm not sure ifmincost()
, as written, takes advantage of reformatting the problem as a network simplex problem before passing it toClpsolver()
. I'd be missing out on that boost in speed with my current code.Wikipedia says that network simplex "works very well in practice, typically 200 to 300 times faster than the simplex method applied to general linear program of same dimensions." (Although it does have a "citation needed" annotation)
The text was updated successfully, but these errors were encountered: