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
I'm new to Theoretical Computer Science, and I would like to calculate the time complexity of the following algorithm that evaluates the binomial coefficient defined as
nf = 1;
for i = 2 to n do nf = nf * i;
kf = 1;
for i = 2 to k do kf = kf * i;
nkf = 1;
for i = 2 to n-k do nkf = nkf * i;
c = nf / (kf * nkf);
My textbook suggests to use Stirling's approximation
However, I can get the same result by considering that for i = 2 to n do nf = nf * i; have complexity O(n-2)=O(n), that is predominant.
Stirling's approximation seems a little bit overkill. Is my approach wrong?
In your first approach you calculate n!, k! and (n-k)! separately and then calculate the binomial coefficient. Therefore since all of those terms can be calculated with at most operations you have O(n) time complexity.
However, you are wrong about the time complexity of calculating the Stirling's formula. You only need log(n) in base 2 operations to calculate it. This is because when trying to calculate p'th power of some real number, instead of multiplicating it p times, you can instead keep squaring the number to calculate it quickly. For example:
If you want to calculate 2^17, instead of doing 17 operations like this:
return 2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2*2
you can do this:
a = 2*2
b = a*a
c = b*b
d = c*c
return d * 2
which is only 5 operations.
Note: However keep in mind that the Stirling's formula is not equal to the factorial. It is only an approximation but a good one.
Edit: Also you can consider a^n as e^(log(a)*n) and then calculate it by the quickly converging series expansion
1 + (log(a)n) + ((log(a)n)^2)/2! + ((log(a)n)^3)/3! + ...
Since the series converges very quickly you can get really close approximations in no time.
I have a constraint of the type(in zmpl)
sum (i,j) in S1 : x[i,j]*c[i,j]<=100
where, x is a binary variable of two dimension and c[i,j] is a parameter.
I would like to change this to
sum (i,j) in S1 : x[i,j]*c[i,sum (i) x[i,j]]<=100
Essentially the parameter in the second index depends on the number of selected variables in the ith row. Any effective way to do this ?
First: It is not possible to index parameters with variable expressions, because this essentially makes them variables, too.
Instead, I suggest to use additional variables to model the desired constraint and I try to be as zimpl as possible:
set S2 := { 0..card(S1) }; # new set to model all possible outcomes of the sum operation
var y[S1] >= 0; # y models nonnegative coefficients c[i,j]
var z[S2] binary; # models the value of the x-sum
subto binlink: sum <i,j> in S1: x[i,j] - sum <s> in S2: s * z[s] == 0;
# binlink expresses the outcome of the x-sum in z
subto partition: sum <s> in S2: z[s] == 1;
# maybe redundant because of binlink, but easy to write
subto coeflink: forall <i,j> in S1: y[i,j] == sum <s> in S2: c[i,s] * z[i,s]
#links continous coefficient variable to coefficient parameter
subto yourcons: sum <i,j> in S1: x[i,j] * y[i,j] <= 100;
# finally...
Note that this formulation is nonlinear, but I think it is worth a try. Its effectiveness pretty much depends on the number of "dynamic coefficients" in your formulation and the size of the set S2 defined in my answer.
Let's say we have a set : {1, 2, ..., n}.
How many subsets of order R exist S = {a_i1, a_i2, ...a_iR} that sum up to a certain number S?. What is the recursion for this problem?
Just define method to solve original problem. Parameters it receives are:
max number to use (n),
subset size (R),
subset sum (S),
and returns number of combinations.
To implement this method, first we have to check is it possible to make this request. It is not possible to fulfill task if:
subset size is larger than number of possible elements (R > n)
maximal possible sum is smaller than S. n + (n-1) + ... + (n-R+1) < S => R*((n-R) + (R+1)/2) < S
After that it is enough to try all possibilities for larger element that will go in subset. In python style it should be implemented like:
def combinations(n, R, S):
if R > n or R*((n-R) + (R+1)/2) < S:
return 0
c = 0
for i in xrange(R, n+1): # try i as maximal element in subset. It can go from R to n
# recursion n is i-1, since i is already used
# recursion R is R-1, since we put i in a set
# recursion S is S-i, since i is added to a set and we are looking for sum without it
c += combinations(i-1, R-1, S-i)
return c
I know the modulus (%) operator calculates the remainder of a division. How can I identify a situation where I would need to use the modulus operator?
I know I can use the modulus operator to see whether a number is even or odd and prime or composite, but that's about it. I don't often think in terms of remainders. I'm sure the modulus operator is useful, and I would like to learn to take advantage of it.
I just have problems identifying where the modulus operator is applicable. In various programming situations, it is difficult for me to see a problem and realize "Hey! The remainder of division would work here!".
Imagine that you have an elapsed time in seconds and you want to convert this to hours, minutes, and seconds:
h = s / 3600;
m = (s / 60) % 60;
s = s % 60;
0 % 3 = 0;
1 % 3 = 1;
2 % 3 = 2;
3 % 3 = 0;
Did you see what it did? At the last step it went back to zero. This could be used in situations like:
To check if N is divisible by M (for example, odd or even)
or
N is a multiple of M.
To put a cap of a particular value. In this case 3.
To get the last M digits of a number -> N % (10^M).
I use it for progress bars and the like that mark progress through a big loop. The progress is only reported every nth time through the loop, or when count%n == 0.
I've used it when restricting a number to a certain multiple:
temp = x - (x % 10); //Restrict x to being a multiple of 10
Wrapping values (like a clock).
Provide finite fields to symmetric key algorithms.
Bitwise operations.
And so on.
One use case I saw recently was when you need to reverse a number. So that 123456 becomes 654321 for example.
int number = 123456;
int reversed = 0;
while ( number > 0 ) {
# The modulus here retrieves the last digit in the specified number
# In the first iteration of this loop it's going to be 6, then 5, ...
# We are multiplying reversed by 10 first, to move the number one decimal place to the left.
# For example, if we are at the second iteration of this loop,
# reversed gonna be 6, so 6 * 10 + 12345 % 10 => 60 + 5
reversed = reversed * 10 + number % 10;
number = number / 10;
}
Example. You have message of X bytes, but in your protocol maximum size is Y and Y < X. Try to write small app that splits message into packets and you will run into mod :)
There are many instances where it is useful.
If you need to restrict a number to be within a certain range you can use mod. For example, to generate a random number between 0 and 99 you might say:
num = MyRandFunction() % 100;
Any time you have division and want to express the remainder other than in decimal, the mod operator is appropriate. Things that come to mind are generally when you want to do something human-readable with the remainder. Listing how many items you could put into buckets and saying "5 left over" is good.
Also, if you're ever in a situation where you may be accruing rounding errors, modulo division is good. If you're dividing by 3 quite often, for example, you don't want to be passing .33333 around as the remainder. Passing the remainder and divisor (i.e. the fraction) is appropriate.
As #jweyrich says, wrapping values. I've found mod very handy when I have a finite list and I want to iterate over it in a loop - like a fixed list of colors for some UI elements, like chart series, where I want all the series to be different, to the extent possible, but when I've run out of colors, just to start over at the beginning. This can also be used with, say, patterns, so that the second time red comes around, it's dashed; the third time, dotted, etc. - but mod is just used to get red, green, blue, red, green, blue, forever.
Calculation of prime numbers
The modulo can be useful to convert and split total minutes to "hours and minutes":
hours = minutes / 60
minutes_left = minutes % 60
In the hours bit we need to strip the decimal portion and that will depend on the language you are using.
We can then rearrange the output accordingly.
Converting linear data structure to matrix structure:
where a is index of linear data, and b is number of items per row:
row = a/b
column = a mod b
Note above is simplified logic: a must be offset -1 before dividing & the result must be normalized +1.
Example: (3 rows of 4)
1 2 3 4
5 6 7 8
9 10 11 12
(7 - 1)/4 + 1 = 2
7 is in row 2
(7 - 1) mod 4 + 1 = 3
7 is in column 3
Another common use of modulus: hashing a number by place. Suppose you wanted to store year & month in a six digit number 195810. month = 195810 mod 100 all digits 3rd from right are divisible by 100 so the remainder is the 2 rightmost digits in this case the month is 10. To extract the year 195810 / 100 yields 1958.
Modulus is also very useful if for some crazy reason you need to do integer division and get a decimal out, and you can't convert the integer into a number that supports decimal division, or if you need to return a fraction instead of a decimal.
I'll be using % as the modulus operator
For example
2/4 = 0
where doing this
2/4 = 0 and 2 % 4 = 2
So you can be really crazy and let's say that you want to allow the user to input a numerator and a divisor, and then show them the result as a whole number, and then a fractional number.
whole Number = numerator/divisor
fractionNumerator = numerator % divisor
fractionDenominator = divisor
Another case where modulus division is useful is if you are increasing or decreasing a number and you want to contain the number to a certain range of number, but when you get to the top or bottom you don't want to just stop. You want to loop up to the bottom or top of the list respectively.
Imagine a function where you are looping through an array.
Function increase Or Decrease(variable As Integer) As Void
n = (n + variable) % (listString.maxIndex + 1)
Print listString[n]
End Function
The reason that it is n = (n + variable) % (listString.maxIndex + 1) is to allow for the max index to be accounted.
Those are just a few of the things that I have had to use modulus for in my programming of not just desktop applications, but in robotics and simulation environments.
Computing the greatest common divisor
Determining if a number is a palindrome
Determining if a number consists of only ...
Determining how many ... a number consists of...
My favorite use is for iteration.
Say you have a counter you are incrementing and want to then grab from a known list a corresponding items, but you only have n items to choose from and you want to repeat a cycle.
var indexFromB = (counter-1)%n+1;
Results (counter=indexFromB) given n=3:
`1=1`
`2=2`
`3=3`
`4=1`
`5=2`
`6=3`
...
Best use of modulus operator I have seen so for is to check if the Array we have is a rotated version of original array.
A = [1,2,3,4,5,6]
B = [5,6,1,2,3,4]
Now how to check if B is rotated version of A ?
Step 1: If A's length is not same as B's length then for sure its not a rotated version.
Step 2: Check the index of first element of A in B. Here first element of A is 1. And its index in B is 2(assuming your programming language has zero based index).
lets store that index in variable "Key"
Step 3: Now how to check that if B is rotated version of A how ??
This is where modulus function rocks :
for (int i = 0; i< A.length; i++)
{
// here modulus function would check the proper order. Key here is 2 which we recieved from Step 2
int j = [Key+i]%A.length;
if (A[i] != B[j])
{
return false;
}
}
return true;
It's an easy way to tell if a number is even or odd. Just do # mod 2, if it is 0 it is even, 1 it is odd.
Often, in a loop, you want to do something every k'th iteration, where k is 0 < k < n, assuming 0 is the start index and n is the length of the loop.
So, you'd do something like:
int k = 5;
int n = 50;
for(int i = 0;i < n;++i)
{
if(i % k == 0) // true at 0, 5, 10, 15..
{
// do something
}
}
Or, you want to keep something whitin a certain bound. Remember, when you take an arbitrary number mod something, it must produce a value between 0 and that number - 1.