0

I am new to mystic and working on an optimization problem.My mystic code looks like this:

def find_loss(e,lmd,q,k):  
    edge_pmf=find_final_dist(e,lmd,q) 
    l_e=sum(edge_pmf[k+1:])
    return l_e   

def objective(x):
    s=0
    for i in range(len(x)):
        s+=find_loss(edge_enum[i],lamd,q,x[i]) 
    return s 

added=lambda x: [i for i in x]        
cons=lambda x: my.constraints.impose_sum(total_cap,added(x)) 

@integers() 
def round(x): 
    return x 

bounds=[(0,None)]*a    
if __name__=='_main_':
   result=diffev2(objective,x0=bounds,bounds=bounds,constraints=round,npop=20,gtol=50,disp=True,full_output=True) 
   print(result[0])

I assure my objective() is defined right(it contains a few dictionaries and functions not mentioned in this code). But does my constraint cons work only with x only as integer values, or I need to add some constraints like @integers()above my.constraints for that,as done below? Also,my optimization result shows nothing.Where's my fault?

Mike McKerns
  • 33,715
  • 8
  • 119
  • 139
  • can you modify your example so it's a self-contained example, with all variables and functions defined? Also, posting any results or tracebacks you get is also helpful. If you do both, people can try to run it themselves and more easily can see what the issues are. – Mike McKerns Apr 02 '20 at 12:56
  • @MikeMcKerns my present issue is that, my constraint `cons` should be working only with x as integers(`x` is a vector of the variables, so, all elements of `x` are to integers). How to resolve that? – Divyayan Dey May 02 '20 at 12:32
  • Looks like you are building `cons` and `round` correctly, but only using `round`. Is that the issue? You want to know how to apply both constraints at once? If that's the case, you need a constraints coupler. If so, let me know and I'll post an example. – Mike McKerns May 02 '20 at 13:25
  • Yes thats what I need. `round` will round off all my values in`x` to integers and `cons` will restrict the sum of those integers to a given value. – Divyayan Dey May 02 '20 at 13:53
  • Could you modify your example so it's a self-contained example, with all variables and functions defined? Also, posting any results or tracebacks you get is also helpful – Mike McKerns May 10 '20 at 12:22

1 Answers1

1

If you want to apply both constraints at once, mystic has couplers to help do that. If you apply two constraints decorators to a single function, it will be a constraints "OR", and people generally want an "AND". So, within mystic.constraints, there's "AND", "OR", and "NOT", to build compound constraints, as well as mystic.coupler for other types of function coupling.

Here's an example of using "AND":

>>> import mystic as my
>>> total_cap = 10
>>> added=lambda x: [i for i in x] 
>>> cons=lambda x: my.constraints.impose_sum(total_cap,added(x))
>>> import numpy as np
>>> round = np.round
>>> c = my.constraints.and_(cons, round)
>>> c([1.1, 2.3, 4.5, 6.7])
[1.0, 1.0, 3.0, 5.0]
>>> 

A full example of using a coupler with integer constraints can be found here: https://github.com/uqfoundation/mystic/blob/master/examples2/eq10.py

Update: Following up on the email you sent me with your full code in it. One issue is that this line requires k to be an integer:

 l_e=sum(edge_pmf[k+1:])

however, np.round merely rounds a float to the integers, so that's where you have an error. If you use int(k), then that resolves the error.

With regard to the code you've posted above, cons is not used, you are only using round. By using and_, as in my example above, it will attempt to solve both cons and round simultaneously. I've checked, and round(result[0]) will round to integers, as well as cons(result[0]) imposes a sum constraint. However, it seems that both of the constraints may be mutually exclusive, as I mentioned in the comments below... which is why you'd see inf for the "score" (cost) of the optimization.

A few good things to always check is (1) try applying the constraints without the optimizer, and confirm that it works (and you get a valid solution), if not, you may have constraints with no solution; (2) if you appear to have invalid solutions, then you may want to use a mystic.penalty to provide soft constraints; (3) run the optimizer with a mystic.monitor.VerboseMonitor(1,1) to see what's going on for each step.

Mike McKerns
  • 33,715
  • 8
  • 119
  • 139
  • Thanks a lot for answering my question. But as I found out after coupling my constraints, my objective function gave a value of infinity after optimization and the input optimizing array gave absurd results without following any of the constraints. Neither are my values in`x` integers ,nor do they sum up to `total_cap`. What could be a possible reason for this? – Divyayan Dey May 05 '20 at 09:01
  • Is there anything wrong with this code ? `result=diffev2(objective,x0=bounds,bounds=bounds,constraints=constr,npop=20,gtol=50,disp=True,full_output=True)` . `bounds` has been specified as a list of non-zero tuples and `constr` is the coupled constraint as shown in your answer. – Divyayan Dey May 05 '20 at 09:21
  • That sounds ok. – Mike McKerns May 05 '20 at 12:39
  • But what about this - my constraints are not at all followed and the objective function returns infinity? Is it that the diffev2 solver cannot handle my problem ,or I need to nudge the npop and gtol values ? – Divyayan Dey May 05 '20 at 18:51
  • If you are getting `inf` as the return value, that means that the optimizer did not yet find a valid solution. That can happen if you have tight constraints with very few solutions. You might get 'inf' many times... then a solution will kick in and the optimizer will start working to improve it. Or, if you always get `inf`, it can indicate that there are no solutions to the constraints. I'd suggest trying another solver, like `lattice` or `buckshot` to see if it finds a non-`inf` solution... and if you have a valid starting point, you can start from there with `diffev` or increase `npts`. – Mike McKerns May 06 '20 at 12:39
  • The problem with both `buckshot` and `lattice` is that they cannot handle any constraints to the problem,which is quite necessary in my case. Would you suggest any improvisation to my `diffev2` method , or why it isn't satisfying my constraints at all? (I tried with the best initialisation , but the optimized vector came out to be exactly same as the initial guess) – Divyayan Dey May 06 '20 at 18:25
  • Why do you say `buckshot` etc can't handle constraints? They take a constraints and penalty keywords, like the other solvers. – Mike McKerns May 07 '20 at 12:17
  • You might also try to increase the number of points in `diffev`, or the mutation settings. Or you could try the `fmin_powell` solver for that matter. The point is, you want to see whether you can find something that gives you a result other than `inf`. If you can't, then it may be that there's no valid solution. – Mike McKerns May 07 '20 at 12:21
  • After I couple the constraints with `my.constraints.and_(cons,round)` , do I need to write anything like `generate_constraint(...)` before using the coupled constraint in the `diffev2` function ? – Divyayan Dey May 09 '20 at 08:45
  • It seems quite absurd that a optimizer cannot find any minima when the function is surely not a constant function. Increasing the number of iterations doesn't do any help. – Divyayan Dey May 09 '20 at 08:48
  • No, you don't -- `generate_constraint` is just for symbolic constraints. I could help you diagnose better if I had a fully encapsulated code sample from you. – Mike McKerns May 09 '20 at 11:59
  • Running the `fmin_powell()` solver with my objective and constraints gives this -`RuntimeWarning: invalid value encountered in subtract if (fx2 - fval) > delta:` . Is my integer constraint hampering the optimization process ? – Divyayan Dey May 09 '20 at 12:16
  • Here is my code with the miniaturised problem statement - https://stackoverflow.com/questions/61696799/absurd-results-with-mystic-for-handling-constrained-optimization – Divyayan Dey May 09 '20 at 12:38
  • Typically `invalid value ... in subtract` means that you have a `nan` in a subtraction, or something similar. See: http://numpy-discussion.10968.n7.nabble.com/Warning-invalid-value-encountered-in-subtract-td13426.html – Mike McKerns May 10 '20 at 12:14