I am struggling with a seemingly simple model in MathProg. The model is as follows:
set W;
set V;
param b {W, V} binary;
param p;
var w {j in W} <= 0, >= 1;
minimize obj: 0;
subject to within_radius_of {i in V}:
sum {j in W} b[i,j] * w[j] >= 1;
subject to p_limit:
sum {j in W} w[j] <= p;
end;
When I run it, it gives me the error feasibility.glp:11: b[v1,w1] out of domain. I have no idea what is going wrong. Even more strange to me, if I change the relevant line to b[j,i] it keeps giving the exact same error (not b[w1,v1] as I expected).
I inspected the AMPL Diet Example carefully, and despite me seeing no difference in the relevant part of my model it still doesn't work. What is wrong?
Parameter b is declared as binary so it can only take values 0 or 1. You haven't provided a data file, but the error message suggests that the data for b is out of domain (not 0 or 1), for example:
data;
set W := w1;
set V := v1;
param b := w1 v1 0.5;
AMPL gives a more detailed error message in this case:
error processing param b['w1','v1']:
failed check: param b['w1','v1'] = 0.5
is not binary (0 or 1);
The reason why the order of indices doesn't matter in this case is that the data for b is checked completely before the model is actually instantiated. So it seems that w1 and v1 may be swapped in the data file.
Related
I'm brand new to AMPL and can't seem to get past this issue.
The code I've written is very basic (again, just starting out) but I keep getting this error message "AMPLPrac.mod, line 2 (offset 6):
x1 is already defined
context: var >>> x1> <<< =0;"
Here is the code:
var x1>=0; var x2>=0;
maximize z: 2*x1 + 3*x2;
subject to c1: 2*x1 + x2 <=4; c2: x1 + 2*x2 <=5;
solve;
Any help would be appreciated. Thanks!
I think the problem may be that you are defining to variables on the same line i AMPL. I tried to run this code (who is the same as yours, only with one argument at every line:
var x1 >= 0;
var x2 >= 0;
maximize z: 2*x1 + 3*x2;
subject to c1: 2 * x1 + x2 <= 4;
subject to c2: x1 + 2 * x2 <= 5;
And I got no errors, and the following output:
x1 = 1
x2 = 2
So I think the problem must be that you have defines mulitply variables on the same line. So to next time, just one variables in every line.
The solution proposed by eriksen1110 is correct, but the problem with your model is that you omited the multiplication operator * from your math expressions, which is not possible in AMPL. It should be:
maximize z: 2*x1 + 3*x2;
# ^ ^
subject to c1: 2*x1 + x2 <= 4;
# ^
subject to c2: x1 + 2*x2 <= 5;
# ^
See it on PIFOP
However, you said that AMPL reports that x1 is already defined, which makes me suspect that you are reading the model file twice, and thus declaring the variable twice, which cannot be done.
Try reseting all declarations by putting this at the beggining of your model file:
reset;
Thanks for all your help! It turns out that the other issues I was having was that I had downloaded not the full version of AMPL and didn't have the correct solvers installed too so I was also getting error messages about not having Minos installed etc but it seems to be resolved now.
I'm trying to set up a ampl model which clusters given points in a 2-dimensional space according to the model of Saglam et al(2005). For testing purposes I want to generate randomly some datapoints and then calculate the euclidian distance matrix for them (since I need this one). I'm aware that I could only make the distance matrix without the data points but in a later step the data points will be given and then I need to calculate the distances between each the points.
Below you'll find the code I've written so far. While loading the model I keep getting the error message "i is not defined". Since i is a subscript that should run over x1 and x1 is a parameter which is defined over the set D and have one subscript, I cannot figure out why this code should be invalid. As far as I understand, I don't have to define variables if I use them only as subscripts?
reset;
# parameters to define clustered
param m; # numbers of data points
param n; # numbers of clusters
# sets
set D := 1..m; #points to be clustered
set L := 1..n; #clusters
# randomly generate datapoints
param x1 {D} = Uniform(1,m);
param x2 {D} = Uniform(1,m);
param d {D,D} = sqrt((x1[i]-x1[j])^2 + (x2[i]-x2[j])^2);
# variables
var x {D, L} binary;
var D_l {L} >=0;
var D_max >= 0;
#minimization funcion
minimize max_clus_dis: D_max;
# constraints
subject to C1 {i in D, j in D, l in L}: D_l[l] >= d[i,j] * (x[i,l] + x[j,l] - 1);
subject to C2 {i in D}: sum{l in L} x[i,l] = 1;
subject to C3 {l in L}: D_max >= D_l[l];
So far I tried to change the line form param x1 to
param x1 {i in D, j in D} = ...
as well as
param d {x1, x2} = ...
Alas, nothing of this helped. So, any help someone can offer is deeply appreciated. I searched the web but I found nothing useful for my task.
I found eventually what was missing. The line in which I calculated the parameter d should be
param d {i in D, j in D} = sqrt((x1[i]-x1[j])^2 + (x2[i]-x2[j])^2);
Retrospectively it's clear that the subscripts i and j should have been mentioned on the line, I don't know how I could miss that.
I’m using MathProg (a language specific to the GLPK library, resembling a subset of AMPL) to find topological ranking of vertices of a graph. It’s an assignment for my linear programming class. It’s an introductory exercise to make sure we can formulate a simple linear program and solve it using GLPK.
I’ve written a Perl script that generates the linear program in MathProg for a given graph. It prints values of the variables (ranks of vertices) via printf. If it’s feasible, that’s exactly what I want; otherwise it prints all zeros, but I want to print just Infeasible, has cycles or loops..
I managed to do it in a hacky way (see below). How to do it more elegantly, without repeating the condition for feasibility? Is there a way to detect infeasibility that does not depend on the problem being solved?
param Vsize := 3;
set V "Vertices" := (0..Vsize-1);
set E "Edges" within V cross V := {(0, 1), (1, 2), (2, 0)};
var v{i in V} >= 0;
minimize rank_total: sum{i in V} v[i];
edge{(i, j) in E}: v[j] - v[i] >= 1;
solve;
printf "#OUTPUT:\n";
printf (if ((exists{i in V} v[i] >= 1) or card(E) = 0) then "" else "Infeasible, has cycles or loops.\n");
printf{i in V} (if ((exists{j in V} v[j] >= 1) or card(E) = 0) then "v_%d: %d\n" else ""), i, v[i];
printf "#OUTPUT END\n";
end;
I tried to declare param Feasible binary := (exists{i in V} v[i] >= 1) or card(E) = 0; but GLPK refused it with Model processing error. When I declared it before solve, it said operand preceding >= has invalid type, when after, it said expression following := has invalid type. I was seeking something like a variable in common programming languages.
In AMPL you can check the built-in parameter solve_result to see if the problem is infeasible:
if solve_result = 'infeasible' then
print 'Infeasible, has cycles or loops.';
However, I'm not sure if GLPK supports this parameter in which case you might need to check for feasibility manually.
As for the error, since exists is a logical expression you can't use it as a numeric one. The fix is to simply put logical expression in if:
param Feasible binary :=
if (exists{i in V} v[i].val >= 1) or card(E) = 0 then 1;
I have a variable called Rest defined as:
var Rest{I,J,T} >= 0;
where T is the set of time periods and I and J the arcs. I need to define that every value for I and J where T = 0 must be 0. I is the set of supply nodes, and J the set of demand nodes.
I've tried:
let Rest[*,*,0] default 0;
but it got me syntax error. I tried this in both the .dat and .mod file using both := and :
I also tried to put this in the .dat file
var Rest default 0:=
[*,*,0] 1 City1 0;
but it gave me the error
Error at _cmdno 3 executing "solve" command
(file amplin, line 286, offset 11443):
error processing constraint Constraint1[1,'Leveaniemi',1]:
invalid subscript Rest[1,'City1',0]
Thanks in advance!
EDIT:
I now use:
var Rest default 0 :=
[*,*,0] 1 Leveaniemi 0;
which give me the error
Error at _cmdno 3 executing "solve" command
(file amplin, line 286, offset 11438):
error processing constraint Constprocessing commands.
Executing on neos-3.neos-server.org
Error (2) in /opt/ampl/ampl -R amplin
(I am using NEOS server, Gurobi solver). What does this even mean? Also if I declare a Variable Rest like that will it cause every Rest solution to become 0? Or does the compiler interpret it as a start value?
EDIT:
I've tried to implement the solution provided by vitaut. It did not work however, as expressed in the comments below that reply. I figured that since I've defined T as:
set T := 1 2 3 ... 15;
and since I wanted to do a let statement at t = 0, I have to account for that and define Rest as:
var Rest{I,J,TimeT};
where TimeU is T union a set with only a 0 element, i.e. TimeU is interpreted as:
TimeU := 0 1 2 3 ... 15;
With these fixed however, the compiler complains that all my variables and parameters are already defined.
The correct syntax of a let command is
let {i in I, j in J} Rest[i, j, 0] := 0;
However, it will assign starting values to the variables which can change during the optimization process. If you want to make Rest[i, j, 0] always equal to zero, then you should use a constraint instead:
s.t. c{i in I, j in J} Rest[i, j, 0] = 0;
Hello fellow optimizers!
I'm having some issues with the following constraint:
#The supply at node i equals what was present at the last time period + any new supply and subtracted by what has been extracted from the node.
subject to Constraint1 {i in I, t in T, c in C}:
l[i,t-1,c] + splus[i,t] - sum{j in J, v in V, a in A} x[i,j,v,t,c,a]= l[i,t,c];
which naturally causes this constraint to provide errors the first time it loops, as the t-1 is not defined (for me, l[i,0,c] is not defined. Where
var l{I,T,C} >= 0; # Supply at supply node I in time period T for company C.
param splus{I,T}; # Additional supply at i.
var x{N,N,V,T,C,A} integer >= 0; #Flow from some origin within N to a destination within N using vehicle V, in time T, for company C and product A.
and set T; (in the .mod) is a set defined as:
set T := 1 2 3 4 5 6 7; in the .dat file
I've tried to do:
subject to Constraint1 {i in I, t in T: t >= 2, c in C}:
all else same
which got me a syntax error. I've also tried to include "let l[1,0,1] := 0" for all possible combinations, which got me the error
error processing var l[...]:
no data for set I
I've also tried
subject to Constraint1 {i in I, t in T, p in TT: p>t, c in C}:
l[i,t,c] + splus[i,p] - sum{j in J, v in V, a in A} x[i,j,v,p,c,a]= l[i,p,c];
where
set TT := 2 3 4 5 6;
in the .dat file (and merely set TT; in the .mod) which also gave errors. Does someone have any idea of how to do this?
One way to fix this is to specify the condition t >= 2 at the end of the indexing expression:
subject to Constraint1 {i in I, t in T, c in C: t >= 2}:
...
See also Section A.3 Indexing expressions and subscripts for more details on syntax of indexing expressions.