How to write the following if-else condition in Linear Programming?
If YR1 == 1 , then 20 <= XR1 <= 80, else XR1 = 0
YR1 is a binary variable, XR1 is a continuous variable.
I tried
20 - XR1 <= 1000 * (1 - YR1)
80 - XR1 <= 1000 * (1 - YR1)
XR1 - 20 <= 1000 * YR1
Is it correct? If not, how can I convert the statement to linear programming conditions?
XR1 is called a semi-continuous variable. It can be modeled as:
20*YR1 <= XR1 <= 80*YR1
YR1 ∈ {0,1}
You need to split this into two inequalities.
Related
I am new to CPLEx and trying to set up my first problem. What I want to do set up a LP to minimise the sum of absolute deviations. I have set up the below as a start (based on googling possibilities). This is only a single deviation. I thought I would get this to work and then add to ti. It loads ok but won't solve. Can anyone shed some light on where I need to go next?
Minimize
obj: y1pos + y1neg
Subject To
c1: x0 + x1 + x2 + x3 = 1
c2: y1pos - y1neg + 451320 x0 + 500870 x1 + 483425 x2 + 447330 x3 = 58999
Bounds
0 <= x0 <= 1
0 <= x1 <= 1
0 <= x2 <= 1
0 <= x3 <= 1
y1pos >= 0
y1neg <= 0
End
As Erwin Kalvelagen suggested, changing y1neg <= 0 to y1neg >= 0 was the answer since our our error factor in our constraint is y1pos - y1neg which we want to minimise.
I have been reading some of the LibreOffice code, and there is code that converts from 100mm to twips.
Its basic formula is:
twips = (n>=0) ? (n*72+63) / 127 : (n*72-63) / 127;
Now I know that one twip is 1/20th of a point, and that one inch is 72 points, and 1 inch is 2.54cm, but I cannot work out how the above formula relates to these ratios!
Can anyone shed some light on this?
Putting together what OP provided:
n is the size in 100 mm.
1 inch is 2.54 cm is 25.4 mm.
inchs = n * 100 / 25.4
or inchs = n / (100 * 25.4)
or inchs = n / 2540
1 inch is 72 points.
points = inchs * 72
1 twip is 1/20th point.
twips = points / 20
Now, everything together:
twips = n / 2540 * 72 / 20
or twips = n * 72 / 2540 / 20
or twips = n * 72 / 127
If this is done in int arithmetic there will be truncation instead of mathematical rounding. This can be fixed by adding the half of 127 (127 / 2 = 63) to n * 72:
twips = (n * 72 + 63) / 127
This does not handle negative numbers correctly. For these, the 63 has to be subtracted instead:
twips = n >= 0 ? (n * 72 + 63) / 127) : (n * 72 - 63) / 127;
and here we are.
As already pointed out by Ron, the ?: operator is the ternary if-then-else operator.
An easier to read (but may be less optimized) replacement would be:
if (n >= 0) twips = (n * 72 + 63) / 127);
else twips = (n * 72 - 63) / 127;
Let's say I have 15 elements. I want to group them such a way that:
group1 = 1 - 5
group2 = 6 - 9
group3 = 10 - 12
group4 = 13 - 14
group5 = 15
This way I'll get elements in each group as below:
group1 = 5
group2 = 4
group3 = 3
group4 = 2
group5 = 1
As you can see loop interval is decreasing.
I took 15 just for an example. In actual programme it's user driven parameter which can be anything (hopefully few thousand).
Now what I'm looking for is:
Whatever is in group1 should have variable "loop" value 0, group2 should have 1, group3 should have 2 and so on... "loop" is an int variable which is being used to calculate some other stuff.
Let's put in other words too
I have an int variable called "loop". I want to assign value to it such a way that:
First n frames loop value 0 next (n -1) frames loop value 1 then next (n - 2) frames loop value 2 all the way to loop value (n - 1)
Let's say I have 15 frames on my timeline.
So n will be 5 ====>>>>> (5 + 4 + 3 + 2 + 1 = 15; as interval is decreasing by 1)
then
first 5 frames(1 - 5) loop is 0 then next 4 frames(6 - 9) loop is 1 then next 3 frames(10 - 12) loop is 2 then next 2 frames(13 - 14) loop is 3 and for last frame(15) loop is 4.
frames "loop" value
1 - 5 => 0
6 - 9 => 1
10 - 12 => 2
13 - 14 => 3
15 => 4
I've tried with modulo(%). But the issue is on frame 12 loop is 2 so (12 % (5 - 2)) remainder is 0 so it increments loop value.
The following lines are sample code which is running inside a solver. #loop is by default 0 and #Frame is current processing frame number.
int loopint = 5 - #loop;
if (#Frame % loopint == 0)
#loop += 1;
If I understand this correctly, then
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
for(int i = 1; i <= n; ++i) {
printf("%d: %f\n", i, ceil((sqrt(8 * (n - i + 1) + 1) - 1) / 2));
}
}
is an implementation in C.
The math behind this is as follows: The 1 + 2 + 3 + 4 + 5 you have there is a Gauß sum, which has a closed form S = n * (n + 1) / 2 for n terms. Solving this for n, we get
n = (sqrt(8 * S + 1) - 1) / 2
Rounding this upward would give us the solution if you wanted the short stretches at the beginning, that is to say 1, 2, 2, 3, 3, 3, ...
Since you want the stretches to become progressively shorter, we have to invert the order, so S becomes (n - S + 1). Therefore the formula up there.
EDIT: Note that unless the number of elements in your data set fits the n * (n+1) / 2 pattern precisely, you will have shorter stretches either at the beginning or in the end. This implementation places the irregular stretch at the beginning. If you want them at the end,
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char *argv[]) {
int n = atoi(argv[1]);
int n2 = (int) ceil((sqrt(8 * n + 1) - 1) / 2);
int upper = n2 * (n2 + 1) / 2;
for(int i = 1; i <= n; ++i) {
printf("%d: %f\n", i, n2 - ceil((sqrt(8 * (upper - i + 1) + 1) - 1) / 2));
}
}
does it. This calculates the next such number beyond your element count, then calculates the numbers you would have if you had that many elements.
How do I write such constraints in CPLEX (linear-programming) ?
forall(p in P, x in X, y in Y)
if ((remx[p,x] <= 0) OR (remy[p,y] <= 0)) then
pbl[p,x,y] == 0 // MUST be 0
else
pbl[p,x,y] == 1 OR == 0 // can be 0 or 1
where pbl is a decision variable (matrix), remx and remy is a normal matrix variable and p,x,y are indices.
I can not use if-then
Thanks,
I believe this cannot be done using (continuous) linear programming, but using mixed-integer programming we can use binary variables.
One way to attack this is using a bunch of inequalities, something like:
remx[p,x] <= 0 + bx[p,x]*M
remx[p,x] >= 0 - (1-bx[p,x])*M
remy[p,y] <= 0 + by[p,y]*M
remy[p,y] >= 0 - (1-by[p,y])*M
pbl[p,x,y] >= bx[p,x]+by[p,y]-1
pbl[p,x,y] <= bx[p,x]
pbl[p,x,y] <= bx[p,x]
bx[p,x],bx[p,x] in {0,1}
where M is indicating a sufficiently large number (they form a bound on remx and remy). Alternatively you can use the indicator constraints in Cplex to model implications:
bx[p,x]=0 => remx[p,x] <= 0
bx[p,x]=1 => remx[p,x] >= 0
by[p,y]=0 => remy[p,y] <= 0
by[p,y]=1 => remy[p,y] >= 0
pbl[p,x,y] = 1 => bx[p,x]+by[p,y] = 2
pbl[p,x,y] = 0 => bx[p,x]+by[p,y] <= 1
(Note: the question has changed, so these fragments are no longer 100% correct).
I am reading about shell sort in Algorithms in C++ by Robert Sedwick.
Here outer loop to change the increments leads to this compact shellsort implementation, which uses the increment sequence 1 4 13 40 121 364 1093 3280 9841 . . . .
template <class Item>
void shellsort(Item a[], int l, int r)
{
int h;
for (h = 1; h <= (r - l) / 9; h = 3 * h + 1);
for (; h > 0; h = h / 3)
{
for (int i = l + h; i <= r; i++)
{
int j = i; Item v = a[i];
while (j >= l + h && v < a[j - h])
{
a[j] = a[j - h]; j -= h;
}
a[j] = v;
}
}
}
My question under what basis author is checking for condition h <= (r-l)/9, and why author is dividing by 9.
The loop:
for (h = 1; h <= (r - l) / 9; h = 3 * h + 1);
calculates the initial value of h. This value must be smaller than the range it will be used in:
h <= (r - l)
Everytime this condition passes, h gets updated to 3 * h + 1, which means that even though h is smaller than (r-l), the updated value might be larger. To prevent this, we could check if the next value of h would surpass the largest index:
(h * 3) + 1 <= (r - l)
This will make sure h is smaller than range of the array.
For example: say we have an array of size 42, which means indices go from 0 to 41. Using the condition as described above:
h = 1, is (3 * 1 + 1) <= (41 - 0) ? yes! -> update h to 4
h = 4, is (3 * 4 + 1) <= (41 - 0) ? yes! -> update h to 13
h = 13, is (3 * 13 + 1) <= (41 - 0) ? yes! -> update h to 40
h = 40, is (3 * 40 + 1) <= (41 - 0) ? no! => h will begin at 40
This means our initial h is 40, because h is only marginally smaller than the range of the array, very little work will be done, the algorithm will only check the following:
Does array[40] needs to be swapped with array[0] ?
Does array[41] needs to be swapped with array[1] ?
This is a bit useless, the first iteration only performs two checks. A smaller initial value of h means more work will get done in the first iteration.
Using:
h <= (r - l) / 9
ensures the initial value of h to be sufficiently small to allow the first iteration to do useful work. As an extra advantage, it also looks cleaner than the previous condition.
You could replace 9 by any value greater than 3. Why greater than 3? To ensure (h * 3) + 1 <= (r - l) is still true!
But do remember to not make the initial h too small: Shell Sort is based on Insertion Sort, which only performs well on small or nearly sorted arrays. Personally, I would not exceed h <= (r - l) / 15.