difficulty with element method constraint programming - optimization

I'm having hard time regarding how to model a constraint. I'm trying to solve a transportation problem and one of the constraints is as follows:
t[s[i]] >= t[i] + travelTime (i, s[i])
which t is the time at which node i is visited and s is the successor variable of node i ( t and s are variables).
I also have a travel time matrix :
int time = travelTime(int origin, int destination)
which defines the travel time between pair of nodes.
I have defined the constraint as below:
for (int i : set){
IloIntExpr expr = model.linearIntExpr();
expr = model.sum(model.element(t, s[i]), model.prod(t[i], -1));
IloIntExpr next = model.element(range(0, nbNodes), s[i]);
model.addGe(expr, travelTime(i, next));
}
***range function generates [0,1, ... ,nbNodes] and [size(s) = size(t) = nbNodes]
now the problem is that next is returning IloIntExpr and I want it to be int to pass it to travelTime(int, int), and also IloIntExpr is not castable to int.
What can be the possible solution for my problem.
I really appreciate any help in this regard.

Related

How do I run a simulation experiment (iterative procedure) in CPLEX?

I am a beginner of programming. I'm trying to practice run a simulation with CPLEX.
Since I want to be a person who wants to work in an area in optimization.
Therefore, I am trying to study some journals from different areas by myself.
The attached image is the objective function and constraints.
I made up the code written below. I am not sure I made it right or wrong.
enter image description here
//Data
{string} product = ...;
{string} interval = ...;
// Limit
float low[interval] = ...;
float upper[interval] = ...;
// Maximum demand
float A[product] = ...;
// Slope of demand function
float varphi[product][interval] = ...;
// Price
float p[product] = ...;
// Setup cost
float f[product] = ...;
// Inventory holding cost rate
float h[product][interval] = ...;
// Variable cost rate
float v[product][interval] = ...;
// Variables
dvar float+ X[product][interval]; enter code here
dvar float+ D[product][interval];
dvar float+ a[interval];
dvar float+ beta[product][interval];
// Objective
maximize sum(i in product, j in interval) p[i]*X[i][j]-f[i]*beta[i][j]-v[i][j]*X[i][j]-0.5*h[i][j]*X[i][j] - F;
// Constraint
subject to{
forall(j in interval) sum(j in interval) a[j] == 1;
forall(i in product, j in interval) beta[i][j] <= a[j];
forall(i in product, j in interval) sum(i in product, j in interval) X[i][j] <= C;
forall(i in product, j in interval) X[j][i] <= D[i][j]*beta[i][j];
forall(j in interval) sum(i in product) beta[i][j] <= upper[j]*a[j];
forall(j in interval) sum(i in product) beta[i][j] >= low[j]*a[j];
forall(i in product, j in interval) D[i][j] = (A[i]-varphi[i][j]*p[i])*a[j];
}
I want to demonstrate how an iterative procedure may be applied to progressively narrow the interval of search to precisely determine the optimal number of products to produce in order to maximize profit.
The journal explains as "The cost and revenue data for these smaller intervals are provided as new inputs to the model which then identifies one of these new intervals as best in the subsequent iteration. The procedure is repeated in successive iterations until the last interval has only one or two levels (i.e., numbers of products) from which the model is able to make a final choice of product variety. In order to save time when the marginal benefit from successive iterations is very small, we also terminate the process if the difference between the objective function values (profit) of successive iterations is below a small predetermined convergence parameter. The model determines which of the levels of the final interval is optimal and also identifies which particular products to produce and in what quantities.
The first stage of this process begins with 100 products (as before) and a configuration involving price structure 3 and cost structure 3 (please see Tables 2–5). The product variety range is divided into four intervals with interval boundaries shown in Table 1. The result from this stage is that the third interval is selected as optimal, with 75 products and their corresponding optimal production quantities identified. The data are shown in Table 9 and the results are provided in Table 12, Table 13 (which also provide results from subsequent stages)."
Tables are attached below.
enter image description here
enter image description here
enter image description here
enter image description here
Product is total 100.
I have not decided the values of other parameters.
What I want to know is how to run the following iterative procedure?
When I run CPLEX, the objective function in the code keeps telling there is an error?
Thank you for your kind answers and you are the bests.
Regards,
forall(j in interval) sum(j in interval) a[j] == 1;
Looks bad since you used j twice !
For errors you should share dat file so that Other users could try

Get the most occuring number amongst several integers without using arrays

DISCLAIMER: Rather theoretical question here, not looking for a correct answere, just asking for some inspiration!
Consider this:
A function is called repetitively and returns integers based on seeds (the same seed returns the same integer). Your task is to find out which integer is returned most often. Easy enough, right?
But: You are not allowed to use arrays or fields to store return values of said function!
Example:
int mostFrequentNumber = 0;
int occurencesOfMostFrequentNumber = 0;
int iterations = 10000000;
for(int i = 0; i < iterations; i++)
{
int result = getNumberFromSeed(i);
int occurencesOfResult = magic();
if(occurencesOfResult > occurencesOfMostFrequentNumber)
{
mostFrequentNumber = result;
occurencesOfMostFrequentNumber = occurencesOfResult;
}
}
If getNumberFromSeed() returns 2,1,5,18,5,6 and 5 then mostFrequentNumber should be 5 and occurencesOfMostFrequentNumber should be 3 because 5 is returned 3 times.
I know this could easily be solved using a two-dimentional list to store results and occurences. But imagine for a minute that you can not use any kind of arrays, lists, dictionaries etc. (Maybe because the system that is running the code has such a limited memory, that you cannot store enough integers at once or because your prehistoric programming language has no concept of collections).
How would you find mostFrequentNumber and occurencesOfMostFrequentNumber? What does magic() do?? (Of cause you do not have to stick to the example code. Any ideas are welcome!)
EDIT: I should add that the integers returned by getNumber() should be calculated using a seed, so the same seed returns the same integer (i.e. int result = getNumber(5); this would always assign the same value to result)
Make an hypothesis: Assume that the distribution of integers is, e.g., Normal.
Start simple. Have two variables
. N the number of elements read so far
. M1 the average of said elements.
Initialize both variables to 0.
Every time you read a new value x update N to be N + 1 and M1 to be M1 + (x - M1)/N.
At the end M1 will equal the average of all values. If the distribution was Normal this value will have a high frequency.
Now improve the above. Add a third variable:
M2 the average of all (x - M1)^2 for all values of xread so far.
Initialize M2 to 0. Now get a small memory of say 10 elements or so. For every new value x that you read update N and M1 as above and M2 as:
M2 := M2 + (x - M1)^2 * (N - 1) / N
At every step M2 is the variance of the distribution and sqrt(M2) its standard deviation.
As you proceed remember the frequencies of only the values read so far whose distances to M1 are less than sqrt(M2). This requires the use of some additional array, however, the array will be very short compared to the high number of iterations you will run. This modification will allow you to guess better the most frequent value instead of simply answering the mean (or average) as above.
UPDATE
Given that this is about insights for inspiration there is plenty of room for considering and adapting the approach I've proposed to any particular situation. Here are some thoughts
When I say assume that the distribution is Normal you should think of it as: Given that the problem has no solution, let's see if there is some qualitative information I can use to decide what kind of distribution would the data have. Given that the algorithm is intended to find the most frequent number, it should be fine to assume that the distribution is not uniform. Let's try with Normal, LogNormal, etc. to see what can be found out (more on this below.)
If the game completely disallows the use of any array, then fine, keep track of only, say 10 numbers. This would allow you to count the occurrences of the 10 best candidates, which will give more confidence to your answer. In doing this choose your candidates around the theoretical most likely value according to the distribution of your hypothesis.
You cannot use arrays but perhaps you can read the sequence of numbers two or three times, not just once. In that case you can read it once to check whether you hypothesis about its distribution is good nor bad. For instance, if you compute not just the variance but the skewness and the kurtosis you will have more elements to check your hypothesis. For instance, if the first reading indicates that there is some bias, you could use a LogNormal distribution instead, etc.
Finally, in addition to providing the approximate answer you would be able to use the information collected during the reading to estimate an interval of confidence around your answer.
Alright, I found a decent solution myself:
int mostFrequentNumber = 0;
int occurencesOfMostFrequentNumber = 0;
int iterations = 10000000;
int maxNumber = -2147483647;
int minNumber = 2147483647;
//Step 1: Find the largest and smallest number that _can_ occur
for(int i = 0; i < iterations; i++)
{
int result = getNumberFromSeed(i);
if(result > maxNumber)
{
maxNumber = result;
}
if(result < minNumber)
{
minNumber = result;
}
}
//Step 2: for each possible number between minNumber and maxNumber, count occurences
for(int thisNumber = minNumber; thisNumber <= maxNumber; thisNumber++)
{
int occurenceOfThisNumber = 0;
for(int i = 0; i < iterations; i++)
{
int result = getNumberFromSeed(i);
if(result == thisNumber)
{
occurenceOfThisNumber++;
}
}
if(occurenceOfThisNumber > occurencesOfMostFrequentNumber)
{
occurencesOfMostFrequentNumber = occurenceOfThisNumber;
mostFrequentNumber = thisNumber;
}
}
I must admit, this may take a long time, depending on the smallest and largest possible. But it will work without using arrays.

Find all pairs of consecutive numbers in BST

I need to write a code that will find all pairs of consecutive numbers in BST.
For example: let's take the BST T with key 9, T.left.key = 8, T.right.key = 19. There is only one pair - (8, 9).
The naive solution that I thought about is to do any traversal (pre, in, post) on the BST and for each node to find its successor and predecessor, and if one or two of them are consecutive to the node - we'll print them. But the problem is that it'll will the O(n^2), because we have n nodes and for each one of them we use function that takes O(h), that in the worst case h ~ n.
Second solution is to copy all the elements to an array, and to find the consecutive numbers in the array. Here we use O(n) additional space, but the runtime is better - O(n).
Can you help me to find an efficient algorithm to do it? I'm trying to think about algorithm that don't use additional space, and its runtime is better than O(n^2)
*The required output is the number of those pairs (No need to print the pairs).
*any 2 consecutive integers in the BST is a pair.
*The BST containts only integers.
Thank you!
Why don't you just do an inorder traversal and count pairs on the fly? You'll need a global variable to keep track of the last number, and you'll need to initialize it to something which is not one less than the first number (e.g. the root of the tree). I mean:
// Last item
int last;
// Recursive function for in-order traversal
int countPairs (whichever_type treeRoot)
{
int r = 0; // Return value
if (treeRoot.leftChild != null)
r = r + countPairs (treeRoot.leftChild);
if (treeRoot.value == last + 1)
r = r + 1;
last = treeRoot.value;
if (treeRoot.rightChild != null)
r = r + countPairs (treeRoot.rightChild);
return r; // Edit 2016-03-02: This line was missing
}
// Main function
main (whichever_type treeRoot)
{
int r;
if (treeRoot == null)
r = 0;
else
{
last = treeRoot.value; // to make sure this is not one less than the lowest element
r = countPairs (treeRoot);
}
// Done. Now the variable r contains the result
}

Variable indexes outside of defined range in AMPL

Not too familiar with AMPL, but running into some issues with indexes...
Basically, I have some variables defined as such:
var array{i in set};
And I need to do some amount of checking the elements around a given i in some of the constraints:
subject to Constraint{i in set}:
array[i] + array[i-1] + array[i+1] <= 12;
But obviously array[0] or array[card(set) + 1] don't exist. To add a further issue, I'm trying to model a sort of problem in which array[0] or array[card(set) + 1] just shouldn't be factored into our computation at all (e.g. it shouldn't constrain the other variables). Any help appreciated :) Thanks.
In AMPL, you can create or define your own "sets" for valid indices and use them in your constraints.
So, in your case, to avoid invalid indices, you can define a set of permissible indices: param inner_i {2..(N-1)} and loop over those when creating the constraints.
The price we pay is that we have to explicitly take care of the corner cases.
Here's one way to do it: (Note, I don't have AMPL loaded, so the code is untested.)
param N > 0; #number of elements
set ELEM; # Elements
set inner_i {2..(N-1)} > 0; #valid indices
var array {ELEM} >= 0;
subject to LimitSum{i in inner_i}:
array[i-1] + array[i] + array[i+1] <= 12;
#Take care of the boundary conditions explicitly, if needed
subject to LimitSum_start:
array[1] + array[2] <= 12;
#only two elements since array[0] doesn't exist.
subject to LimitSum_last:
array[N-1] + array[N] <= 12;
#only two elements since array[N+1] doesn't exist.
Hope this helps you move forward.
You can use an if-then-else expression to conditionally include some terms:
subject to Constraint{i in set}:
array[i] + (if i != 0 then array[i-1]) + (if i != N then array[i+1]) <= 12;
where N is the last element of the set.

Syntax errors in sml: Inserting LOCAL

The following method determines how many numbers can be added up starting from the beginning of the list without adding up to 4:
number_before_Reaching_sum (4, [1,2,3,4,6]);
should return : val it = 2 : int
fun number_before_reaching_sum (sum : int * int list) =
let val len_orig_list = length (#2 sum)
in fun num_bef_reach_sum (sum) =
if #1 sum <= 0
then len_orig_list - (length (#2 sum)) - 1
else num_bef_reach_sum (#1 sum - hd (#2 sum), tl (#2 sum))
end
syntax error: inserting LOCAL
syntax error found at EOF
I can't seem to find the errors in this code. I have some experience with Python, but just starting to learn sml. I'm loving it, but I don't understand all the error messages. I have really spent hours on this, but I think I don't know enough to solve my problem. I tried exchanging let with local, but i still got a syntax error (equalop). I think that the function between in and end is an expression and not a declaration. But I would appreciate any comments on this. If you come up with alternative code, it would be great if you did it without using more advanced features, since I'm just trying to get the basics down :-)
You probably meant this:
fun number_before_reaching_sum (sum : int * int list) =
let
val len_orig_list = length (#2 sum)
fun num_bef_reach_sum (sum) =
if #1 sum <= 0
then len_orig_list - (length (#2 sum)) - 1
else num_bef_reach_sum (#1 sum - hd (#2 sum), tl (#2 sum))
in
num_bef_reach_sum (sum)
end
With let … in … end, the part between let and in is for the local definitions; the part between in and end is for the expression which will be the evaluation of the let … in … end expression (this construct is indeed an expression).
Think of let … in … end as a possibly complex expression. You hoist parts of the expression as definitions, then rewrite the complex expression using references to these definitions. This help write shorter expressions by folding some of its sub‑expressions. This construct is also required when recursion is needed (a recursion requires a defining name).
Another way to understand it, is as the application of an anonymous function whose arguments bindings are these definitions.
Ex.
let
val x = 1
val y = 2
in
x + y
end
is the same as writing
(fn (x, y) => x + y) (1, 2)
which is the same as writing
1 + 2
You erroneously put a definition at the place of the expression the whole evaluates to.
(note I did not check the function's logic, as the question was about syntax)