Using the sum function in GAMS to sum over a subset of variables - sum

I am working with maximazation problems in GAMS where I will choose
X=(x_1,x2,...,x_n) such that f(X)=c_1*x_1+...c_n*x_n is maximized. The c's are known scalars and I know n (10 in my case). I want my constraints to be such that the first (n-1)=9 x's should sum up to one and the last one should be less than 10. How do I use the sum to do so?
This is what I have tried:
SET C / c1 .... c2 /;
ALIAS(Assets,i)
Parameter Valuesforc(i) 'C values'/
*( here are my values typed in for all the C1)
POSITIVE VARIABLES
x(i);
EQUATIONS
Const1 First constraint
Const1 Second constraint
Obj The Object;
* here comes the trouble:
Const1 .. x(10) =l= 10
Const2 .. sum((i-1),x(i)) =e= 1
The code is not done all the way but I believe the essential setup is typed in. How do you make the summation to find x_1+x_1 + .... x_(n-1) and how do you refer to x_10?

Try this:
Const1 .. x('10') =l= 10;
Const2 .. sum(i$(ord(i)<card(i)),x(i)) =e= 1;
Edit: Here are some notes to explain what happens in Const2, especially in the "$(ord(i) < card(i))" part.
The "$" starts a condition, so it excludes certain elements of i from the sum (see: https://www.gams.com/latest/docs/UG_CondExpr.html#UG_CondExpr_TheDollarCondition)
The operator ord returns the relative position of a member in a set (see: https://www.gams.com/latest/docs/UG_OrderedSets.html#UG_OrderedSets_TheOrdOperator)
The operator card returns the number of elements in a set (see: https://www.gams.com/latest/docs/UG_OrderedSets.html#UG_OrderedSets_TheCardOperator)
So, all in all, there is a condition saying that all elements of i should be included in the sum except for the last one.

Related

Inline index addition in gams

I want to use an index equation to iterate over a tensors, whereas I always want to extract the value at index i and index i+1. An example:
Variable x; x.up = 10;
Parameter T /1=1,2=2,3=3,4=4,5=5/;
Set a /1,2,4/;
equation eq(a); eq(a).. x =g= T[a+1];
*x ist restricted by the values of T at the indices 2,3 and 5.
Model dummy /all/;
solve dummy min x use lp;
I am aware that gams sees the indices as string-keys rather than numerical ones, so the addition is not intended. Is this possible anyway? This e.g. can be solved by defining another tensor, unfortunaly my given conditions require the index operation inline (i.e. I am not allowed to define additional parameters or sets.
Does this work for you?
Variable x; x.up = 10;
Set aa /1*6/;
Parameter T(aa) /1=1,2=2,3=3,4=4,5=5/;
Set a(aa) /1,2,4/;
equation eq(a); eq(a(aa)).. x =g= T[aa+1];
*x ist restricted by the values of T at the indices 2,3 and 5.
Model dummy /all/;
solve dummy min x use lp;

GAMS modelation: how do i set an identifier as the last value of a set (index.last) on an equation

I'm modeling a VRP in GAMS language and one of my equations would ideally be:
SUM(i, x(i,n+1)) =e= 0;
with "n+1" being the last value of the set i /0*4/ (so it's 4)
I can't type x(i,"4") because this number (4) is just an example.
The software doesn't recognize this equation. the error says "unknown identifier set as index, which i understand is because "n" isn't a set.
so i put n as a set, just like i did with i, but then I'd have to give it a number (3, so that n+1 = 4) and i don't want that.
I just need a way to put "n+1" as a valid index for x(i,n+1)
Assuming that x is declared as x(i,i), you can do something like this:
Alias (i,i2);
Equation eq;
eq.. SUM((i,i2)$i2.last, x(i,i2)) =e= 0;

GAMS: Setting one variable to be equal to the second smallest of another vector variable

SET i /i1 * i10/ ;
VARIABLES
x(i)
y
;
I have an optimization (mip) problem where i need my control variable y to be equal to the second smallest number of x. How can I create an equation to do that?
EQUATIONS
myconstraint ;
myconstraint .. y =E= (second smallest element of x) ;

A loop in fortran code doesn't obey loop rules

First of all i am new at fortran. I tried to find the value of 1/e within tolerance of 0.0000005. I used the summation representation of 1/e which is (epsilon) n from zero goes to infinity ((-1)^n)/n!. I started from n=2 and when the value of 1/n! is smaller than my tolerance, the program will stop and print the total value that is calculated. But my program just goes to n=3 only and only prints the value of 1/3! which is 1.666666.
!program is edited. the edited form is calculates what i wanted.Before the condition of outer while was (num3<5e-8) and it didn't increase n. Now n increases problem is solved.
program Ecalculator
implicit none
integer :: mult,num1,n,num4,num5
real :: summ,num3,fact
mult=1
n=2.0
fact=1.0
summ=0.0
DO WHiLE(n<13)
fact=n
num1=n-1
DO WHiLE(num1>0)
fact=fact*num1;
num1=num1-1;
END DO
fact=fact*mult;
num3=1.0/fact;
mult=mult*(-1);
summ=summ+num3;
n=n+1;
END DO
print *, summ
read *, num5
end program Ecalculator
It looks like the factorial is not computed correctly: the line fact=num4*num1 is probably not doing what you want, because num4 is just assigned to be n and never changes throughout the inner loop. I don't think you need both variables num4 and fact; you could combine them into one variable.

Correct loop invariant?

I am trying to find the loop invariant in the following code:
Find Closest Pair Iter(A) :
# Precondition: A is a non-empty list of 2D points and len(A) > 1.
# Postcondition: Returns a pair of points which are the two closest points in A.
min = infinity
p = -1
q = -1
for i = 0,...,len(A) - 1:`=
for j = i + 1,...,len(A) - 1:
if Distance(A[i],A[j]) < min:
min = Distance(A[i],A[j])
p = i
q = j
return (A[p],A[q])
I think the loop invariant is min = Distance(A[i],A[j]) so closest point in A is A[p] and a[q] .
I'm trying to show program correctness. Here I want to prove the inner loop by letting i be some constant, then once I've proven the inner loop, replace it by it's loop invariant and prove the outer loop. By the way this is homework. Any help will be much appreciated.
I'm not sure I fully understand what you mean by replacing the inner loop by its loop invariant. A loop invariant is a condition that holds before the loop and after every iteration of the loop (including the last one).
That being said, I wouldn't like to spoil your homework, so I'll try my best to help you without giving too much of the answer away. Let me try:
There are three variables in your algorithm that hold very important values (min, p and q). You should ask yourself what is true about these values as the algorithm goes through each pair of points (A[i], A[j])?
In a simpler example: if you were designing an algorithm to sum values in a list, you would create a variable called sum before the loop and assign 0 to it. You would then sum the elements one by one through a loop, and then return the variable sum.
Since it is true that this variable holds the sum of every single element "seen" in the loop, and since after the main loop the algorithm will have "seen" every element in the list, the sum variable necessarily holds the sum of all values in the list. In this case the loop invariant would be: The sum variable holds the sum of every element "seen" so far.
Good luck with your homework!