问题
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