AMPL Variables in subscripts are not yet allowed - ampl

I really hope someone can help with this...
This is what i have in the .mod file
set I := 1..10;
set J := 1..10;
set K := 1..2;
set W := 1..20;
param v{K, W};
param d{I, J};
var x1, integer;
var y1, integer;
var x2, integer;
var y2, integer;
var assist{W}, binary;
and this is the code generating error:
minimize nome: sum{w in W} (if (assist[w] == 0) then
(if (x1 >= v[1,w]) then
(if (y1 >= v[2,w]) then
(d[x1 - v[1,w],y1 - v[2,w]])....
where the error regards the last line and says:
Variables in subscripts are not yet allowed.
context: (d[x1 - v[1,w],y1 - >>> v[2,w]] <<< )
this is one of constraints (others are just the same):
subject to rangex1:
x1 > 0 && x1 <= 10;

As the error message says, you can't use decision variables within a subscript in AMPL. In this case x1 and y1 are decision variables, so d[x1 - v[1,w],y1 - v[2,w]] is not allowed. You'll need to reformulate the problem in a way that avoids this issue.

Related

AMPL error "is not a set" "is not a param (or var or constraint or objective)""No variables declared"

I'm super new to AMPL and now struggling to solve the error.
I created both dat.file and mod.file separately, and wrote codes as exactly as the same as my teacher mentioned but it keeps showing below errors. I asked the teacher but seems it's properly shown on his PC, but not on mine (I'm Mac user).
Dat file:
`set PRODUCTION := P1 P2;
set RESOURCES := C W; # C W
param max_res := C 3000 W 1440;
param profit := P1 3.5 P2 1.5;
param param_res : C W :=
P1 1.5 5
P2 2 4.5;`
Mod file:
`reset;
option solver cplex;
set PRODUCTION;
set RESOURCES;
param profit {PRODUCTION};
param max_res {RESOURCES};
param param_res {PRODUCTION, RESOURCES};
var x {PRODUCTION} >= 0;
maximize profit: sum {i in PRODUCTION} profit[i] * x[i];
s.t. c_res {j in RESOURCES}: sum {i in production} param_res[i,j]*x[i] <= max_res[j];
s.t. c_minp2 {i in PRODUCTION]: sum {i in production} P2[i] >=30;
data PRODUCTION_REV.dat;`
Error:
ampl: data '/Users/XXX/Desktop/PRODUCTION_REV.dat';
/Users/XXX/Desktop/PRODUCTION_REV.dat, line 4 (offset 37):
PRODUCTION is not a set
context: set >>> PRODUCTION <<< := P1 P2;
/Users/XXX/Desktop/PRODUCTION_REV.dat, line 5 (offset 62):
RESOURCES is not a set
context: set >>> RESOURCES <<< := C W; # C W
/Users/XXX/Desktop/PRODUCTION_REV.dat, line 8 (offset 120):
max_res is not a param (or var or constraint or objective)
context: param >>> max_res <<< := C 3000 W 1440;
/Users/XXX/Desktop/PRODUCTION_REV.dat, line 9 (offset 152):
profit is not a param (or var or constraint or objective)
context: param >>> profit <<< := P1 3.5 P2 1.5;
/Users/XXX/Desktop/PRODUCTION_REV.dat, line 12 (offset 209):
param_res is not a param (or var or constraint or objective)
context: param >>> param_res <<< : C W :=
ampl: solve;
No variables declared.
ampl:
Anyone has a clue for this? The teacher's reply is slow and my assignment due is tomorrow night, can't wait for another reply from him...

Two warnings "This local variable has the same name as a global variable" and "ELSE with no matching IF"

I'm getting two weird warnings.
One is "This local variable has the same name as a global variable",
referring to the wx, wy, ww, wh.
Another is "ELSE with no matching IF", referring to the two if-else statements.
Here's the whole script.
#NoEnv
#Warn
SendMode Input
SetWorkingDir %A_ScriptDir%
screen_scaling_factor := A_ScreenDPI/96
^p::mouse_move_win(200,300)
mouse_move_win(x,y,horizontal:="left",vertical:="top",mouse_click:=""){
wingetpos,wx,wy,ww,wh,a
global screen_scaling_factor
if horizontal="left"{
x1 := wx + x * screen_scaling_factor
}else{
x1 := wx + ww - x * screen_scaling_factor
}
if vertical="top"{
y1 := wy + y * screen_scaling_factor
}else{
y1 := wy + wh - y * screen_scaling_factor
}
DllCall("SetCursorPos", int, x1, int, y1)
}
When I add local as the first line of the function to enable the "force-local mode", however, the first warning disappears.
When I add a parentheses to the if condition or remove the curly braces following it, as shown below, the second warning disappears.
if (horizontal="left"){
x1 := wx + x * screen_scaling_factor
}else{
x1 := wx + ww - x * screen_scaling_factor
}
or
if horizontal="left"
x1 := wx + x * screen_scaling_factor
else
x1 := wx + ww - x * screen_scaling_factor
Any idea why this is happening?
If you want to use the legacy style if statement (please don't) you can't start your braces from the same line as the if statement. You'd have to drop the starting brace { down one line.
But please just use the modern expression style if-statement like so:
mouse_move_win(x,y,horizontal:="left",vertical:="top",mouse_click:=""){
wingetpos,wx,wy,ww,wh,a
global screen_scaling_factor
if (horizontal="left"){
x1 := wx + x * screen_scaling_factor
}else{
x1 := wx + ww - x * screen_scaling_factor
}
if (vertical="top"){
y1 := wy + y * screen_scaling_factor
}else{
y1 := wy + wh - y * screen_scaling_factor
}
DllCall("SetCursorPos", int, x1, int, y1)
}
Also, personally I'd call that brace style disgusting, but of course it's just personal preference haha.
But just in case you didn't know, you can omit braces from one liner if/else statements:
mouse_move_win(x,y,horizontal:="left",vertical:="top",mouse_click:="")
{
wingetpos,wx,wy,ww,wh,a
global screen_scaling_factor
if (horizontal="left")
x1 := wx + x * screen_scaling_factor
else
x1 := wx + ww - x * screen_scaling_factor
if (vertical="top")
y1 := wy + y * screen_scaling_factor
else
y1 := wy + wh - y * screen_scaling_factor
DllCall("SetCursorPos", int, x1, int, y1)
}
EDIT: oh seems you edited your post. I started typing this before you edited it, but then I had to go do something.
Anyway, my answer should answer your questions.
Use mouse_move_win(200, 300) instead of mouse_move(200,300)
When you define horizontal:="left", it means Left is its default value, meaning if no value is supplied it assumes it's left. So
if horizontal=left
is unnecessary.
So I guess your code should be other way around with the if and else combos.
^p::mouse_move_win(200, 300)
mouse_move_win(x, y, horizontal:="left", vertical:="top", mouse_click:="") {
wingetpos,wx,wy,ww,wh,a
global screen_scaling_factor
if horizontal=right
x1 := wx + ww - x * screen_scaling_factor
else
x1 := wx + x * screen_scaling_factor
if vertical=bottom
y1 := wy + wh - y * screen_scaling_factor
else
y1 := wy + y * screen_scaling_factor
DllCall("SetCursorPos", int, x1, int, y1)
}
This worked perfectly for me

Is there a way to make a specific variable from a set an integer in Ampl?

set P;
set K;
set I:= {i in K};
set J:={j in P};
param C {P} >=0;
param A {K,P} >=0;
param B {K} >=0;
var X{j in P} >=0;
P consists of 4 set values, namely sweatshirt-f, sweatshirtB/F, tshirtf and tshirtBF, but I would like sweatshirt-f only to return an integer:
maximize f: sum{j in P} C[j]*X[j];
s.t. Constraint {i in K}:
sum{j in P} A[i,j]*X[j]<=B[i];
Option 1: declare all of them as integer, then relax integer constraints for the others:
var X{j in P} >=0 integer;
let {i in P: i <> "sweatshirt-f"} X[i].relax := 1;
Option 2: declare a dummy variable as integer, then constrain relevant value to match it:
var X{j in P} >=0;
var int_dummy integer;
s.t. force_integer: X["sweatshirt-f"] = int_dummy;
I'm not able to test those right now, so you may have to do a little debugging, but that should get you in the neighbourhood of a solution.

declare default value for variables in ampl

Now I have variable set x in my ampl model, and I want to define a default value for each x.
set N := 1..10;
var x {i in N} default 0;
If I build the model like this, the initial value of all x would be set as 0. How can I set different value for each x, like [0,0,0,0,0,1,1,1,1,1]?
If you just want to change some parts of x to a non-default value, this is easy to do. For example:
var x{i in N} default 0;
let{i in 6..10} x[i] := 1;
I'm not aware of any way to have more than one default value for different elements of a var.

GLPK: set expression following default must have dimension 2 rather than 1

I have an AMPL model file that I'm working to convert to GLPK. It begins:
param n; # The number of nodes in the graph
set V := {1 .. n}; # The set of vertices in the graph
set E within V cross V; # The set of edges in the graph
set NE within V cross V := {i in V, j in V: i < j} diff E;
set FIXED within V cross V default {}; # The set of demand pairs with fixed flow
When running this, I get the following error:
_test.mod:5: set expression following default must have dimension 2 rather than 1
Context: : i < j } diff E ; set FIXED within V cross V default { } ;
MathProg model processing error
This must be a syntactic difference between MathProg and its superset, AMPL—running the code in AMPL works perfectly. How does one express a 2D empty set in MathProg?
Alright, the hack of a solution is this:
set FIXED within V cross V default {i in V, j in V: 1 < 0};
Put an obviously false condition. It'll have the dimensionality you want and still be empty.