Putting integer constraints in mystic

删除回忆录丶 提交于 2020-06-09 05:32:06

问题


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?


回答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.



来源:https://stackoverflow.com/questions/60978086/putting-integer-constraints-in-mystic

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!