linear programming in Lingo - lingo

I want to do a linear programming with Lingo, I have the solution but I want to improve the code.
Here is what I want to do:
SETS:
SEMANA/ 1..12/: D, X, I, Y, Z, R, n;
ENDSETS
X(1)>=D(1);
X(2)+I(1)>=D(2);
X(3)+I(2)>=D(3);
X(4)+I(3)>=D(4);
X(5)+I(4)>=D(5);
X(6)+I(5)>=D(6);
X(7)+I(6)>=D(7);
X(8)+I(7)>=D(8);
X(9)+I(8)>=D(9);
X(10)+I(9)>=D(10);
X(11)+I(10)>=D(11);
X(12)+I(11)>=D(12);
I have tried this option but there is a mistake that says: Subscript out of range on attribute I.
#FOR (SEMANA(j):
X(j)+ I(j-1)>= D(j)) ;
I(j-1) is out of range so I canĀ“t solve the problem.
Thank you

Notice that your code will try to get into I(0) when j=1. I(0) does not defined and that's why it's out of range problem.

You need a index filter
#FOR (SEMANA(j) | j#GT#1:
X(j)+ I(j-1)>= D(j)) ;
This would be equivalent to having I(0)=0, but only implicitly. If you have I(0)>0, e.g. you have positive initial inventory, then you will need to extend your index set to include '0' and put an additional constraint I(0)=INITIAL_VALUE
Consequently, your #for loop will have to be
#FOR (SEMANA(j) | j#GT#0:
X(j)+ I(j-1)>= D(j)) ;

Related

How to formulate the following constraint in OPL?

Suppose I have an array A of size n with two specific indices x and y of this array, where say x < y. How would I go about adding the constraint which ensures either an "increasing path" between array[x] and array[y] by increasing the indices (so array[x] < array[x+1] < ... < array[y]), or an increasing path by decreasing the indices (so array[x] < array[x-1] < ... array[0] < array[n-1] < ... < array[y]).
I've tried the following but I get at least two errors:
ctIncreasingX2Y:
(forall (i in x..y-1) A[i] < A[i+1])
|| (forall (i in x..-(n-y)+1) A[(i+n)%n] < A[(i-1+n)%n]);
The forall keyword doesn't like to be inside of the parantheses, but without the parantheses the || operator seems to get applied inside of the forall environment;
The second range goes from 0 to -1, and not the wanted x to (basically) y.
Maybe there's other problems as well, I'm pretty new to linear programming, but I'd like to solve these ones first.
After some searching around the web, the first problem seems to be me trying to formulate something inherently not LP-like, so maybe there is simply no fix.
Concerning the second problem, I could fix it by using an increasing range and modifying the constraint accordingly, but I find it astonishing that there seems to be no way to use a descending range, which is typically possible in any coding language.

Test a model with random data on GLPK

I'm new on GLPK, I want to test my simple model,
I use this comment to generate different random data:
param seed:=gmtime();
param u{(i,j) in E}:=(round(seed*Uniform01())) mod 40 ;
and I want to solve model for 100 times and obtain the average value of optimal value of objective function.
I don't know how to code iterated expression to repeat solving model in .mod file. Could you please help me?
This is my model:
### VARIABLES ###
var x{(i,j) in E} >= 0, <= u[i,j];
### OBJECTIVE ###
maximize Val: sum {(1,j) in E} x[1,j];
### CONSTRAINTS ###
subject to Balance {i in V diff {1,n}}:
sum {(j,i) in E} x[j,i] = sum {(i,k) in E} x[i,k];
solve;
I also asked this question in "https://lists.gnu.org/mailman/listinfo/help-glpk",
and I got this answer from Heinrich Schuchardt and it works.
"Dear Shaghayegh,
glpsol cannot iterate over multiple models or data sets by itself.
https://en.wikibooks.org/wiki/GLPK/Scripting_plus_MathProg
shows how to use a scripting language to call glpsol multiple times.
You can pass the seed value for the random number generator like this
glpsol --seed SEEDVALUE
In awk you can use function rand() to create random numbers."
To complete the model, the only thing we need is to add following comments:
param n >=1 integer; # Number of nodes
set V := 1..n; # Set of nodes
set E within (V cross V); # Set of arcs
This is a maximum flow problem.

How to specify custom order of values in variable's domain?

Let's assume I have a variable V and value of V can be any number from the range 0..5. However, some values are more preferred than other others therefore it would help me to specify the domain of V as an ordered sequence.
Can I do it in SICStus Prolog?
Example:
% PSEUDOCODE
%
% 3 is more preferred than 4; 4 is more preferred than 2; and so on..
% So I would write something like this:
V in {3,4,2,5,1,0},
getDomainAsList(V, List), % the predicate do not exist
% and the List would be: [3,4,2,5,1,0] and not [1,2,3,4,5]
I read the manual and I did not find anything that would help. I can solve the problem by custom labeling (i.e., convert the domain of V to a list, sort it and assign a value to V) but I expect worse performance.
There is a manual page describing this.
See the value(Enum) option to labeling/2, here:
You can have an array or list of all the values in the preferred order.
Then you work with array indexes in your program, and at the very end you return values corresponding to the indexes.

Do programming languages have consistent interpretations of {1,...,n} when n = 0?

On math.SE, a question about math notation enerated a discussion of how programming languages interpret the set {1,...,n} when n=0
The question asked for a mathematical notation to represent the R code 1:n
According to the comments, the mathematical interpretation of {1,...,n} when n=0 is that this is an empty set. A subsequent comment suggested that C is consistent with this interpretation, because for (int i = 1; i < n; i++) returns a empty set because it iterates 0 times.
It is not clear to me what the equivalent statement in R is, but 1:0 returns the vector [1,0]
Thus, for (i in 1:0) print(i) iterates over 1 and 0 (I interpret as analogous to the C code above)
Is this because {1,...,n} is not the correct notation for 1:n?
Does this mean R violates a universal rule?
Is there a consistent interpretation for this set among programming languages?
Each mathematical formalism has its own notation. To suggest that there is a "universal notation" is very "un-mathematical". Look at the notation associated with tensors or groups if you want examples of mathematical domains where multiple notational systems exist.
In R the code x <- 1:0 returns the ordered vector c(1,0). Just as the code x <- 2:-2 returns c(2,1,0,-1,-2). The code x <- seq(1, length=0) returns a sequence of length 0 which is printed in console sessions as integer(0). R is not really designed to mimic set notation but it does have some set functions and it also has packages that more fully implement set notation.
C has no concept of a set that a for loop runs over. A for loop for(a;b;c) d; is simply syntactic sugar for:
a;
loop: if (!b) goto done;
d;
c;
goto loop;
done: ;
See also my response at: Sequence construction that creates an empty sequence if lower is greater than upper bound - in R, seq_len(n) should be used in preference to 1:n for exactly this reason (the latter fails misbehaves when n=0).
some languages support the concept of ranges, in C it is arbitary what you make a for loop do, you could make it mean 0 or you could make it count backwards. In other languages a range that has the second number less that the first often produces a number sequence that is decreasing. But its arbitrary, and there is no universal rule.

Barebones sort algorithm

I have been asked to make a simple sort aglorithm to sort a random series of 6 numbers into numerical order. However, I have been asked to do this using Barebones-a theoretical language put forward in the book Computer Science, an Overview.
Some information on the language can be found here.
Just to clarify, I am a student teacher and have been doing anaysis on "mini-programing languages" and their uses in a teaching environment. I suggested to my tutor that I look at barebones (the language) and asked what sort of exmaple program I should write. He suggested a simple sort algorithm. Now since looking at the language I can't understand how I can do this without using arrays and if statements.
The code to swap the value of variables would be
while a not 0 do;
incr Aux1;
decr a;
end;
while b not 0 do;
incr Aux2
decr b
end;
while Aux1 not 0 do;
incr a;
decr Aux1;
end;
while Aux2 not 0 do;
incr b;
decr Aux2;
end;
However, the language does not provide < or > operators. What could I use as a workaround?
Oh, come on, start thinking about the problem!
What's an array? A list of variables.
So Barebones doesn't have an if statement? It's got while loops.
Get on with your homework.
Interesting exercise.
I would suggest you try to first implement the following:
Swap values of two variables
Set a variable (say z) to zero if value of variable x >= value of variable y.
Since the program is supposed to sort exactly 6 integers, I suppose you can assume they are in the variables x1, x2, .., x6.
In the end we need: x1 <= x2 <= ... <= x6.

Resources