Combine models: solve a model with the solution of another


I want to combine 2 models. I want to solve a model and with the results, insert them as parameters of another model.

What I was doing was solving the first model, and then typing manually that solution as parameters of the second model and run the optimization of the second model. However, this is too time consuming and I can make typo mistakes.

How can I do this ? I tried by reading chapter 14 “named problems”, but to be honest, I didn’t understand how to do it.

Thanks !

To combine two models the way you are describing, you can define a variable in the first model, and a corresponding parameter in the second model. Then after solving the first model, use an AMPL “let” (assignment) statement to assign the values from the first model’s variable to the second model’s parameter. As a simple example, if the first model contains

var X {S} >= 0;

then in the second model you can define

param xval {S};

and after the first model is solved, you can execute

let {j in S} xval[j] := X[j];

before solving the second model.

To use named problems, first read a model file that contains all the definitions for the first model and for the second model. Then execute commands of this form:

problem pr1: ...
problem pr2: ...

where the first ... is replaced by a list of the variables, objective, and constraints of the first model, and the second ... is replaced by a list of the variables, objective, and constraints of the second model. After this, you can use the simple commands

problem pr1;
let {j in S} xval[j] := X[j];
problem pr2;

to solve the first model, copy the values of the variables, and solve the second model. (Of course this idea can be extended to copying more than one variable.)


Maybe I didn’t explain it correctly, but the values in the second model aren’t parameter, they’re variable too.

Do you mean that there are some variables in the first model that are also variables in the second model? Then you do not have to define any extra parameters or assignments. Just list those variables in both of your problem statements.

In the example I gave, if the X variables are in both of the models, then you would include X in the list of the variables for problem pr1 and also in the list of the variables for problem pr2.

If you are trying to do something else, then I suggest that you give an example. Your example should show the AMPL statements in your models and should explain what trouble you are having to get them to work. It is often easier to explain an example than to give a general description of what you are trying to do.

You can see that in model1, I solve the values for a variable x[1…40,1…10,1…4]. Then in order to solve model2, I must insert the values of variable x[1…40,1…10,1…4, 1] as restrictions of the model. X is binary.

The models are really similar, the big difference is that in model1, the x variable has 3 indices while in model2 the x variable has 4 indices. I was solving model1 and typing the results as restrictions in model2, but it too time consuming. I want to automatize this.

For example, imagine that in model1 the solution is that x[4,1,4]=1. Then in model2, I must insert a new restriction:
s.t x[4,1,4,1]=1

Attached both models and data for them.

data.dat (560 Bytes)
ronda1.mod (5.1 KB)
ronda2.mod (7.6 KB)

To use problem statements here, you would have to rename the variable x and all of the constraints in the second model. But since you just want to assign values from one variable in the first model to some of the variables in the second model, there is an easier way. It uses the fact that the output of AMPL’s display statement is in the same format as an AMPL data file.

After you solve the first model,

model ronda1.mod;
data data.dat;

assign the values of the x-variables to a param xval1, and write the output of “display xval1” to a file:

param xval1 {A,D,T};
let {i in A, d in D, t in T} xval1[i,d,t] := x[i,d,t]; 
display xval1 >xval1.out;

Now reset and read the second model:

model ronda2.mod;
data data.dat;

At this point, you can read the values from the file back into param xval1, with the following statements:

param xval1 {A,D,T};
param include xval1.out;

An finally, you can fix the variables x[i,d,t,1] to equal xval1[i,d,t], and solve again:

fix {i in A, d in D, t in T} x[i,d,t,1] := xval1[i,d,t];