0

I recently started to code the benders decomposition algorithm into python. For the math.formulations numpy is used.

My question/problem is that I need to calculate a lambda value (which can be seen below), however the bad part about it that I use a while loop for the calculation. Which causes long run times, and/or crashes.

Any Ideas to calculate lambdas in more efficient way?


Math:

L = -Obj -sum(mü_i * const_i) - lambda * variable

grad(L) = 0


Code for calculating lambdas with making the grad function equals to 0:

x,y = np.mgrid[-100:100, -100:100]  #Grid for gradient

d1 = s.dual[s.const1]           #mü
d2 = s.dual[s.const2]           #mü
d3 = s.dual[s.const3]           #mü
d4 = s.dual[s.const4]           #mü

L = -y-(d1*(y-x-5.0))-(d2*(y-x/2.0-15.0/2.0))\
    -(d3*(y+x/2.0-35.0/2.0))-(d4*(-y+x-10.0))


Lambda = -2.0               #Lambda_0 starts -2.0

while Lambda <= 2.0:

    Ex,Ey = np.gradient(L - Lambda*x)

    if np.allclose(Ex,0.0) == True and np.allclose(Ey,0.0) == True:  #works better for now 0.001 worked.
        break
    else:
        Lambda += 0.001

1st run is wrong answer. 2nd one is right.

oakca
  • 1,408
  • 1
  • 18
  • 40
  • Most of the value of `L` appears to be independent of `Lambda`; you can precompute that *once* before the loop starts, and just call `np.gradient(L - Lambda * x)`. – chepner Dec 06 '16 at 15:33
  • `Ex.all() == 0.0` does not do what you seem to think it does. What that really means is `Ex.astype(np.bool).all() == bool(0.0)`. That says _"convert every element to a boolean, check that all of them are true, and then check if the result of that comparison is false"_. You've essentially written `np.any(Ex == 0.0)` when you meant `np.all(Ex == 0.0)` – Eric Dec 06 '16 at 15:33
  • No, you need to write `np.all(Ex == 0.0)` instead of `Ex.all() == 0.0`. That second one doesn't make any sense at all, but just happens to have a valid interpretation equivalent to `np.any(Ex == 0.0)` – Eric Dec 06 '16 at 15:39
  • Then you have other problems. There's no way in hell you intended to write`np.all(Ex) == 0.0`. `np.all()` returns a boolean. Comparing that to 0.0 makes no sense at all. Try `np.array([0, 1, 2, 3, 4]).all() == 0.0` if you still don't believe me – Eric Dec 06 '16 at 15:48
  • I just wanna check the x derivative of L is equal to 0 and y derivative of L is equal to 0. – oakca Dec 06 '16 at 15:56
  • 1
    Since you are dealing with floats and fixed increments for ```Lambda``` you may want to use [numpy.allclose](https://docs.scipy.org/doc/numpy/reference/generated/numpy.allclose.html) – wwii Dec 06 '16 at 17:01
  • _"I just wanna check the x derivative of L is equal to 0"_ - for what values of x? All of them or one of them? – Eric Dec 06 '16 at 17:02
  • @wwii done better ty, Eric which is irrelevant it is a liniar func actually. I though mgrid produces an array of x values when I code np.mgrid[-100:100] – oakca Dec 06 '16 at 17:30
  • Is `grad(L)` the mathematical derivative of the function `L` or the spatial partial derivatives of the `L` grid? – Imanol Luengo Dec 07 '16 at 00:53
  • grad(L) = (dL/dx , dL/dy) and this needs to be equal to 0 – oakca Dec 07 '16 at 13:05

0 Answers0