AMPL - Express summation with max function - ampl

I need to declare this image in my .mod as "subject to" but i don't know how to do it. Can someone explain it to me? My main problem is max{0,t-4}.
I tried:
set ANY_INICI:=1..10;
subject to constr{t in 1 .. 10}:
sum {j in max(0,t-4)+1 .. ANY_INICI, i in t-j+1 .. 4} decisio[i,j]>=restriccio[t];

The correct form is:
t iterates ANY_INICI and 1..10 is equal to ANY_INICI param
subject to constr{t in ANY_INICI }:
sum {j in max(0,t-4)+1..t, i in t-j+1..4} decisio[i,j] >= restriccio[t];

Related

Sum of variable changing over time (AMPL)

I have a time dependent variable that changes with some predefined timesteps. I would like get the sum of the variable over the course of several timesteps. How can I write the sum of the variable?
.mod file:
set Time default {}; #number of timesteps
param top{Time}; #number of hours in each timestep
var E{Time} >= 0.001; #the timedependent variable
subject to annualElectricity{t in Time}:
Ea = sum{E[t]*top[t]};
.dat file:
set Time := 1 2 3 4 5 6;
param top := #operating time (hours)
1 609
2 321
3 532
4 425
5 351
6 7
;
I'm guessing that the annualElectricity constraint collection that you have declared is your attempt to do what you want, but I'm not sure you want to use a constraint for that.
If you want to sum all variables in the collection E, the sum expression will be sum{t in Time} E[t]. If you want the sum of all products E[t]*top[t], the sum expression will be sum{t in Time} E[t]*top[t].
If you won't need this value to solve the problem, you can declare a param Esum and then, after you have solved the problem, you can call let Esum := sum{t in Time} E[t]. But if you need this value in your problem, I believe you can define a variable var Esum = sum{t in Time} E[t] and use it in your constraints/objective function.
I can see you are new to AMPL, so you may benefit from reading some basic AMPL introduction, such as this https://pifop.com/help/ampl_programs.html that I've written.

GAMS- manipulating expression within a loop

I have a matrix, of dimension, i rows and j columns, a specific element of which is called x(i,j), where say i are plants, and j are markets. In standard GAMS notation:
Sets
i canning plants / seattle, san-diego /
j markets / new-york, chicago, topeka / ;
Now, I also wish to create a loop, over time- for 5 periods. Essentially, say I define
Set t time period
/period1
period2
period3
period4
period5
/ ;
Parameters
time(t)
/ period1 1,
period2 2,
period3 3,
period4 4,
period5 5
/ ;
Basically, I want to re-run this loop, which contains a bunch of other commands, but I wish to re-define this matrix from period 2 onwards, to look like this:
x("seattle",j)=x("seattle",j)+s("new-york",j)
x("new-york",j)=0'
Essentially, within the loop, I want the matrix x(i,j) to look different after period 2, wherein the column x("seattle",j) is replaced with the erstwhile x("seattle",j)+s("new-york",j) and the column x("new-york",j) is set to 0.
The loop would start like :
loop
(t,
...
Option reslim = 20000 ;
option nlp = conopt3 ;
solve example using NLP maximizing VARIABLE ;
) ;
I am not sure how to keep redefining this matrix within the loop, for each period>2.
Please note: After period 2, the matrix looks the same. The change only happens once (i.e., the matrix elements do not keep looping from the previous period, but just switch once , at the end of period 2, and then stay constant thereafter.
Any help on this is much appreciated!
You can use a $ condition to make this change in the loop for period2 only, like this:
x("seattle",j)$sameAs(t,'period2')=x("seattle",j)+s("new-york",j);

Turning textual answers into dichotomous variables

I've done research using the google forms and now I need to prepare that data for the further analysis. The point is I don't really know how to go about that.
I have variables (questionnaire questions), each of this question have four answers. In my data those answers are just strings, so let's say:
Variable 1 (Here is a question)
Value = Answer (C. The answer)
Now I need to split every one of those variable into four different ones and the representation of that data should look like that:
Variable 1_1 where Value = 0
Variable 1_2 where Value = 0
Variable 1_3 where Value = 1 -> because as you seen above answer C was chosen.
Variable 1_4 where Value = 0
So here is the recoding part. It's not string anymore but 0 or 1.
Well I hope that this make sense. And thank you in advance.
If you want to do this one variable at a time, you can use:
IF (variable1="a") variable1_1=1 .
IF (variable1="b") variable1_2=1 .
IF (variable1="c") variable1_3=1 .
IF (variable1="d") variable1_4=1 .
RECODE variable1_1 TO variable1_4 (SYSMIS=0) .
EXE .
If all of your variables have the same response structure and you want to loop through all of them at once, you can use VECTOR to do that.
VECTOR variable = variable1 TO variable100 /* existing variables */ .
VECTOR response1_var = response1_var (100,F1) /* create new vars, response1_var1 TO response1_var100 */ .
VECTOR response2_var = response2_var (100,F1) /* create new vars, response2_var1 TO response2_var100 */ .
VECTOR response3_var = response3_var (100,F1) .
VECTOR response4_var = response4_var (100,F1) .
LOOP #i = 1 TO 100 .
IF (variable(#i)="a") response1_var(#i)=1 .
IF (variable(#i)="b") response2_var(#i)=1 .
IF (variable(#i)="c") response3_var(#i)=1 .
IF (variable(#i)="d") response4_var(#i)=1 .
END LOOP .
RECODE response1_var1 TO response4_var100 (SYSMIS=0) .
EXE .
Keep in mind that looping through this way would order your new variables by "response series" as oppose to questionnaire order. If you wanted to either re-order or rename your new variables that could be done separately.
There are many ways to do this, so here is one.
first to make some fake data to demonstrate on:
data list free/var1 to var4 (4a1).
begin data
"a" "b" "a" "c" "c" "b" "a" "c" "d" "d" "a" "b"
end data.
Now a separate recode command for each possible answer - each command taking care of all the relevant variables which have those possible answers:
recode var1 to var4 ("a"=1)(else=0) into varA1 to varA4.
recode var1 to var4 ("b"=1)(else=0) into varB1 to varB4.
recode var1 to var4 ("c"=1)(else=0) into varC1 to varC4.
recode var1 to var4 ("d"=1)(else=0) into varD1 to varD4.

How to split a series of number and compare it with another set of digit?

Say I have a no. 20101105, I need to compare it with a series of other nos. say 20110105 , 20090105 and find the nearest no. of it.
I don't want to compare it on the whole, I need to compare it each digit wise by parsing thru it and then see which is the closest.
Can someone suggest on how to do this in ABAP language?
In general You should mention some more information. For example, are the numbers really integers ? Then You can put them into an internal table and sorting all of them is the easiest solution to find any "nearest" number relating to an actual scanned. This is just like integers work in sort, they are sorted like numbers, my friend. But If You want it character-wise ( what really makes no sense, if the numbers are integers ) i give You some help with this character-comparison in a do-loop, taking smaller string-length as iterator-counter. I omitted the else, that's Your "homework". :-D
DATA:
lv_length1 TYPE i,
lv_length2 TYPE i,
lv_cnt TYPE i,
lv_teststr1 TYPE string VALUE '123456',
lv_teststr2 TYPE string VALUE '1235'.
lv_length1 = strlen( lv_teststr1 ).
lv_length2 = strlen( lv_teststr2 ).
IF lv_length1 GE lv_length2.
DO lv_length2 TIMES.
IF lv_teststr2+lv_cnt(1) NE lv_teststr1+lv_cnt(1).
BREAK-POINT.
ENDIF.
ADD 1 TO lv_cnt.
ENDDO.
ENDIF.
The counter variable is also the index of, in this case, the first not matching character. This gets the job done.
Coded and tested by me just right now.
I don't know if I understood but maybe this helps.
report znearest.
data lv_value(8) type n.
parameters p_value(8) type n. " ---------> The value
select-options s_values for lv_value. " -> The list
start-of-selection.
data: wa like line of s_values,
lv_dif(8) type n,
lv_nearest(8) type n,
lv_nearest_dif(8) type n,
lv_first type c.
loop at s_values into wa.
lv_dif = abs( p_value - wa-low ). " Calculate the difference
if lv_first is initial.
lv_nearest_dif = lv_dif.
lv_first = 'X'.
endif.
if lv_dif le lv_nearest_dif. " Compare the differences
lv_nearest = wa-low.
lv_nearest_dif = lv_dif.
endif.
endloop.
write: 'The nearest from', p_value, 'is', lv_nearest.
Hope it helps.

Increment an integer

Sometimes ABAP drives me crazy with really simple tasks such as incrementing an integer within a loop...
Here's my try:
METHOD test.
DATA lv_id TYPE integer.
lv_id = 1.
LOOP AT x ASSIGNING <y>.
lv_id = lv_id+1.
ENDLOOP.
ENDMETHOD.
This results in the error message Field type "I" does not permit subfield access.
You already answered the question yourself, but to make things a bit clearer:
variable + 1
is an arithmetic expression - add 1 to the value of the variable.
variable+1
is an offset operation on a character variable. For example, if variable contains ABC, variable+1 is BC.
This can be especially confusing when dealing with NUMCs. For example, with variable = '4711', variable + 1 is evaluated to 4712, whereas variable+1 is '711' (a character sequence).
The error you saw occurred because it's not possible to perform the index operation on a non-character-like variable.
You mean like:
ADD 1 to lv_id.
By the way, when you loop over an internal table, SY-TABIX has the loop counter.
Uh, I got it.
It's the f****** spaces...
lv_id = lv_id + 1
works...
Simple
DATA : gv_inc type I .
place this statement in loop
gv_inc = gv_inc + 1 .
from SAP NetWeaver Version 7.54 you can also use:
lv_id += 1.
Instead of
lv_id = lv_id + 1.
Happy coding!
If you are going to increment every loop cycle than you can directly get the table size.
describe table x lines data(lv_id). "Out side of the loop.