I want to know if it is possible to optimize a problem in OpenMDAO in such a way that the objective approaches a specified value rather than minimizing or maximizing the objective?
For example:
prob.model.add_objective("objective1", equals=10)
as in specifying constraints is not possible.
You can not specify an equality for the objective like that. You could specify a given objective, then secondarily add an equality constraint for that same value. This is technically valid, but it would be a very strange way to pose an optimization problem.
If you have a specific design variable you hope to vary to satisfy the equality constraint, then you probably don't want to do an optimization at all. Instead, you likely want to use a solver. You can use solvers to vary just one variable, or potentially more than one (as long as you have one equality constraint per variable). An generic example of using a solver can be found here, setting up a basic nonlinear circit analysis.
However, in your case you more likely want to use a BalanceComp. You can set a specific fixed value into the right hand side of the balance, using an init argument like this:
bal = BalanceComp()
bal.add_balance('x', val=1.0, rhs_val=3.0)
Then you can connect the variable you want to hold fixed to that value to the left hand side of the balance.
Related
I am writing a mathematical program and want to let the solver choose the optimal time to switch between two simulation phases. At that specific time, I am writing a constraint for the states of one model instance to be equal the states of a second model instance.
I am trying to achieve something like:
t_switch = prog.NewContinuousVariables(1, name="t_switch")
prog.AddConstraint(eq(q_A[t_switch[0],0], q_B[t_switch[0],0]))
but this returns an IndexError since t_switch is of pydrake type symbolic.Variable, but I need to use an integer as an index.
Any thoughts on how to use a symbolic variable as an index in another constraint, or of an alternate way to solve this problem?
I wouldn't suggest to treat the time index as a decision variable; instead you can always fix the trajectory to switch at a specific time index, but set the time duration as decision variable. This allows you to change the total timing of each phase.
I am working on a complex model in pyomo. Unfortunately, i have to change the formula of the objective function, based on how is the previous value.
In particular my objective function is composed of two terms ,call them A and B, that have different order of magnitude (A is usually 2 or 3 order of magnitude higher than B, but this may vary)
In order to guarantee that A and B have the same weight of the formula, i need to write my objective function as below:
objective= A + B*K`
Where K is the value which bring the second term at the same scale/magnitude of A
example:
A=4e10
B=2e3
K=1e(10-3)=1e7
The problem is that, in order to know K, i must know the values of A and B, but pyomo doesn't give value, it just pass an expression to the solver.
I have read that thanks to a smart use of binary variables is possible to overcome this issue, anyone could suggest a useful methodology?
Kind regards
It seems like you are dealing with a multi-objective optimization problem. Since the values of variables involved in A and B are not known before solving the model, you can't define the value of K based on A and B.
There are different ways to solve multi-objective optimization problems which you can consider for your specific problem (e.g., ε-constraints method). In these problems, usually you are not interested in finding a single solution, but finding a set of Pareto optimal solutions which are not dominated by any other solution in the feasible region.
Ist it possible to formulate a min-max-optimization problem of the following form in pyomo:
min(max(g_m(x)) s.t. L
where g_m are nonlinear functions (actually constrains of another model) and L is a set of linear constrains?
How would I create the expression for the objective function of the model?
The problem is that using max() on a list of constraint-objects returns only the constraint possessesing the maximum value at a given point.
I think yes, but unless you find a clever way to reformulate your model, it might not be very efficent.
You could solve all possiblity of max(g_m(x)), then select the solution with the lowest objective function value.
I fear that the max operation is not something you can add to a minimization model, since it is not a mathematical operation, but a solver operation. This operation is on the problems level. Keep in mind that when solving a model, Pyomo requires as argument only one sense of optimization (min or max), thus making it unable to understand min-max sense. Even if it did, how could it knows what to maximize or minimize? This is why I suggest you to break your problem in two, unless you work on its formulation.
I've a MIP to solve with Pyomo and I want to set an initial solution for cplex.
So googling I find that I can set some variable of instance to some value and then execute this:
solver.solve(instance,warmstart=True,tee=True)
But when I run cplex it seem that it doesn't use the warm start, because for example i pass a solution with value 16, but in 5 seconds it return a solution with value 60.
So I don't know there is some error or other stuff that doesn't work.
P.S.
I don't know if is a problem but my warm start solution set only some variale to a value, but not all. Could be a problem?
Make sure that the solution you give to CPLEX is feasible. Otherwise, CPLEX will reject it and start from scratch.
If your solution is feasible, it is possible that CPLEX simply found a better solution than yours, since, after all, it is CPLEX's job, and in my own experience, CPLEX is very good at it. Is this a maximization problem? If so, in your example, CPLEX found a better solution (objective=60) than yours (objective=16), which is the expected behavior.
Sadly, CPLEX is often greedy in term of verbose, so it is hard to know from the solver log if warmstart was used or not (unlike its competitor GUROBI where it is clearly written in the log). However, it seems like you started the warmstart correctly, using the warmstart=True parameter.
If, however, your problem isn't a maximization problem, it is possible that CPLEX will not make a differenciation between the variables that you gave a value and the variable that still holds a solution from last solve. Plus, giving values to only a fraction of your variables might make the problem infeasible, considering that all values not manually specified are the values previously found by CPLEX. ex: contraint x<=2y. The solver found x=2, y=1 as a feasible solution. You define x:=3, then your constraint is not respected (y is still =1 for CPLEX, so the constraint x<=2y is 3<=2, which is false). CPLEX will see it as infeasible and will reject your solution.
One alternative that I can give you, if you absolutely want to use your own values in the final solution, is instead of defining values for your variables, create a constraint that explicitly defines your variable value. This constraint can afterward be "deactivated" if needed. But be careful, as this does not necessarily yield the optimal solution, but the "optimal solution when some variables have the specific value".
I want to run an optimisation problem repeatedly to further refine the end result.
Essentially, the objective is to minimise the maximum of a set of variables (subject to inequality and equality constraints), and then minimise the maximum of the set excluding the maximum, and then minimise the maximum of the set excluding the two largest numbers and so on...
The algorithm I have in mind is:
Run scipy.linprog(..., bounds=[(-numpy.inf, numpy.inf), (-numpy.inf, numpy.inf), (-numpy.inf, numpy.inf), ...]) with all variables unbounded, to minimise the maximum of the set of numbers.
Assuming optimisation problem is feasible and successfully solved, fix the maximum to opt_val by setting bounds=[..., (opt_val, opt_val), ...], where all other variables have the bounds (-numpy.inf, numpy.inf).
Make inequality constraints corresponding to that variable ineffective, by changing the coefficient of b_ub to numpy.inf.
Rerun simulation with modified bounds and inequality vector.
This can run without error, but it seems like scipy/numpy explicitly ignore the bounds I place on the variables - I get results for the variables that I have 'fixed' that are not the corresponding opt_val.
Can scipy handle bounds that restrict a variable to a single floating point number?
Is this the best way to be solving my problem?
The code I have developed is really quite extensive, which is why I have not posted it here, so of course I don't expect a code-based solution. What I am looking for here is a yes/no answer as to whether scipy can handle bounding intervals restricted to a single float, and, on a higher level, whether I have the correct approach.
The documentation at https://docs.scipy.org/doc/scipy-0.15.1/reference/generated/scipy.optimize.linprog.html does not explicitly say whether or not it is possible to specify fixed-point bounds.
It turns out it was a problem with relaxing the inequality constraints. I had mistakenly relaxed all constraints regarding the fixed variables, when instead I needed to have relaxed some of the constraints.
#ErwinKalvelagen's comment is still worth noting however.