Forum Discussion
FICO
7 years agoCommunity Manager
Dynamic array type in Xpress Python interface
Hello,
I query is there any functionality or method in Xpress Python Interface that can be used to resemble the dynamic array type (e.g., "dynamic array(set of range) of mpvar/linctr)") available in Xpress IVE?
Thanks in advance
4 Replies
- FICOCommunity Manager
Hello,
the distinction between array and dynamic array in Mosel disappears when one uses Python, because the array of variables or constraints is created on the spot, based on a set of indices. If your question is about how to create an array with a sparse index set, I would suggest using dictionaries like in the following example:
import xpress as xp S = set(['NY', 'AK', 'WA', 'ME']) cost = {'NY': 4, 'AK': 3, 'WA': 7, 'ME': 11} x = {i: xp.var() for i in S} con1 = xp.Sum(x) <= 1 obj = xp.Sum(cost[i] * x[i] for i in S) p = xp.problem() p.addVariable(x) p.addConstraint(con1) p.setObjective(obj)The python interface allows for declaring a dictionary of variables with multiple indices, and provides the shortcut xpress.vars function:
import xpress as xp S1 = set(['a', 'b', 'c', 'd']) S2 = set(['y', 'z', 't', 'w']) A = [2,2,4,5] x = {(i,j): xp.var(ub=A[i]) for i in range(len(A)) for j in S} x2 = xp.vars(S1, S2, ub=1)I hope this helps.
- FICOCommunity Manager
Hello Pietro,
Thank you for your reply and please have a look of the example I gave in this post which I thought will be helpful to clarify my question.
In my case, I am iterating the optimization and dynamically adding a set of variable X into the objective function as well as adding a set of constraints Constr1. The question is the dimension of variable X and constriant Constr1 is unknown.
In Xpress IVE, the code snippet looks as follows:
declaration prob:mmproblem I=1..NI # Set of index for X iter:integer X:dynamic array (range,range) of mpvar sol_X:dynamic array(range,range) of real Constr1:dynamic array(set of mpproblem,range,range) of linctr Obj:array(set of mpproblem) of linctr end-declaration [#############] # Define Optimization ... [#############] iter:=0 repeat [#############] # Solve Optimization with prob do minimize( Obj(prob) ) end-do # Get Output... if iter>=1 then forall(i in I) create( sol_X(i,iter) ) forall(i in I, j in 1..iter) sol_X(i,j):=getsol( X(i,j) ) end-if [#############] iter+=1 forall(i in I) create( X(i,iter) ) # Create a new set of variable with prob do Obj(prob)+=sum(i in I)( X(i,iter) ) # Add the new set of variable into Obj if iter>=2 then # Create and define a new set of constraint based on the X which is just solved forall(i in I) create( Constr1(prob,i,iter-1) ) forall(i in I, j in 1..iter-1) Constr1(prob,i,j):= X(i,j)<=sol_X(i,j) end-if end-do until condition - FICOCommunity Manager
Hello Yijun,
I translated the script you provided to Python, I hope this helps clarify. As you can see in Python you can amend an item to a dictionary at any time as (i,j) in this point is just a key to a dictionary, but we can use it as our index set.
import xpress as xp X = {} sol_X = {} # Define optimization problem here iter = 0 condition = True objective = 0 # Initially, the objective function is null while condition: prob.solve() # Optimization sense has been specified in the # definition of prob if iter >= 1: for i in I: for j in range(1, iter + 1): sol_X[i,j] = prob.getSolution(X[i, j]) iter += 1 # Create new variables for i in I: X[i,iter] = xp.var() prob.addVariable(X[i, iter]) # Update objective function objective += xp.Sum(X[i,iter] for i in I) prob.setObjective(objective) if iter >= 2: prob.addConstraint(X[i, j] <= sol_X[i, j] for i in I for j in range(1, iter)) condition = ... # update exit condition hereUsing dictionaries for both X and sol_X, while ensuring both have the same set of keys (which you can get with X.keys() and sol_X.keys()).
I hope this helps. Regards,
Pietro
- FICOCommunity Manager
Many thanks Pietro, very helpful indeed!
Best wishes,
Yijun


