I need to build a MILP (Mixed integer linear programming) constraint form this if-else statement:
with beta is a constant.
if (a > b) then c = beta else c = 0
How can I build the statement to MILP constraint. Are there any techniques for solving this problem. Thank you.
I am assuming that a, b, and c are all decision variables here. To build your constraint, you need to add a new binary variable -- let's call it x -- that will equal 1 if a > b and 0 otherwise. You also need a large constant M. Then add the following constraints:
Mx >= a - b
M(1-x) >= b - a
x in {0,1}
The logic is: If a > b, then x must equal 1 by the first constraint (and x may equal 1 by the second constraint). If b > a, then 1-x must equal 1 by the second constraint, i.e., x must equal 0 (and x may equal 0 by the first constraint).
Next, we need a constraint that says, if x = 1, then c = beta, otherwise, c = 0:
c = beta * x
Note: The logic above allows c to equal either 0 or beta if a = b; the solver will decide. Do you need c to equal 0 if a = b?
Another note: In "big-M"-type formulations like this one, it's always best to keep M as small as possible while maintaining the validity of the constraints. In this case, this means setting M to the largest possible (or plausible) difference between a and b. If your model is small, it won't matter much, but if you have lots of these decision variables, then it can matter a lot.
Related
Is it possible to simplify an expression in SymPy, if we know that variables satisfy certain equation?
For example in Mathematica we can write something like this:
Simplify[a+b-c, a+b==c]
Of course in this case it is possible to solve for a and make a substitution. However, for the long expressions making a global substitution might not make a sense. If the goal is to produce the shortest expression possible, one might need to apply substitution for the certain terms and leave the rest untouched or solve for b instead of a.
I think sympy.assumptions module cannot impose restrictions mutually on the several variables.
Is it possible to achieve the functionality of Mathematica's Simplify[expr, assum] in any other way in SymPy?
Or is there any other open-source project which can do something like this?
SymPy's current assumptions system can not handle relationships between variables although that is being worked on. There are a couple of ways that you can do this though.
The ratsimpmodprime function simplifies an expression that is polynomial in some symbols based on knowing that the symbols themselves satisfy polynomial equations. We can use this to make a function that simplifies the example you showed:
In [26]: a, b, c = symbols('a:c')
In [27]: polysimp = lambda expr, eqs: ratsimpmodprime(expr, groebner(eqs).exprs)
In [28]: polysimp(a + b - c, [a + b - c])
Out[28]: 0
In [29]: polysimp(a + b, [a + b - c])
Out[29]: c
In [31]: polysimp(a**4 + b - c, [a**2 - b, b - c])
Out[31]:
2
c
You can also introduce a new symbol and solve for that along with the other equations as a combined system:
In [33]: solve([z - (a + b - c), a + b - c])[z]
Out[33]: 0
This method has the advantage that you can choose which symbols you want to eliminate e.g.:
In [38]: solve([z - (a + b), a + b - c], [z, c])[z]
Out[38]: a + b
In [39]: solve([z - (a + b), a + b - c], [z, b])[z]
Out[39]: c
Either answer is valid since a + b == c so the expected output from "simplifying" is ambiguous.
If I let string w be a^mb^m then we know that y will consists of only a's because of the rule |xy| <= m.
And if I set i=0, then ww^R will have fewer a's on the left side than on the right side. Thus, it proves that this language is not regular.
However, my text book (An Introduction to Formal Languages and Automata pg. 118 by Linz) says if I were to choose w = a^2m and let y = aa, then I would fail.
But how so?
To my mind, no matter what x, y, z are, the first a^2m will have fewer a's or more depending on what i is than the second a^2m.
The reason why is you have an even scalar on m. Since the strings in L are just a string's reverse appended to itself, an even number of a's will always be in L.
For any m >= 1 you have aa[aa...]. So, when your opponent selects y = aa, they force you to inject a string that is in L into w(i). No matter how many times, if at all, it's pumped you end up with: (aa)^k : k = pumps, which is a string in L
I think it's a bad choice to only use a. Having two alphabet symbols usually makes it easier to win. As the book continues to say, you can't assume it should be easy to beat your opponent; any attempts are automatically invalid.
I have written the following code:
fun remove_element(nil, elem) = raise Empty
| remove_element(hd::tl, elem) = if(hd=elem) then tl else hd::remove_element(tl, elem);
but that function (which removed element elem from list) works for int. I need to make it work for real numbers, but I can't do it. I have tried a lot of ways of rewriting the function and also I used :real but these bring me errors.
Any suggestions?
Thank you
The accepted answer should have allowed you to finish your assignment, so I will show two other approaches for variations of your problem without worrying about doing your homework for you. As Kevin Johnson said, it isn't possible to directly compare two reals. It is possible to do so indirectly since a=b if and only if a<=b and b<=a. Often this is a bug, especially if the list in question is of numbers produced by numerical computations. But -- there are some situations where it makes sense to compare reals for equality so you should certainly be able to do so as long as you are clear that this is what you want. This leads to the following modification of your code:
fun remove_real([],x:real) = []
| remove_real(y::ys,x) =
if (y <= x andalso y >= x) then
remove_real(ys,x)
else
y::remove_real(ys,x);
A few points:
1) I changed it to remove all occurrences of the element from the list rather than just the first occurrence. This involved changing the basis case to returning the empty list since [] with y removed is just [] rather than an error situation. Also, rather than simply returning the tail if the element is found I return the recursive call applied to the tail to remove any additional occurrences later on. You could easily modify the code to make it closer to your original code.
2) I needed to put the explicit type annotation x:real so that SML could infer that the list was of type real list rather than type int list.
3) I replaced nil by [] for aesthetic reasons
4) I replaced your pattern hd::tl by y::ys. For one thing, hd and tl are built-in functions -- I see no reason to bind those identifiers to anything else, even if it is just local to a function definition. For another thing, the less visual clutter in a pattern the better.
5) I made more use of white space. Partially a matter of taste, but I think that fairly complicated clauses (like your second line) should be split across multiple lines.
If you want to go the route of including an error tolerance for comparing reals, I think that it makes most sense to include the tolerance as an explicit parameter. I find |x-y| < e to be more natural than two inequalities. Unfortunately, the built-in abs only applies to ints. If x - y is real then the expression
if x - y < 0.0 then y - x else x - y
returns the absolute value of x - y (it flips the sign in the case that it is neagative). As an added bonus -- the comparison with 0.0 rather than 0 is all that SML needs to infer the type. This leads to:
fun remove_elem([],x,tol) = []
| remove_elem(y::ys,x,tol) =
if (if x - y < 0.0 then y - x else x - y) < tol then
remove_elem(ys,x,tol)
else
y::remove_elem(ys,x,tol);
Typical output:
- remove_real([2.0, 3.1, 3.14, 3.145, 3.14], 3.14);
val it = [2.0,3.1,3.145] : real list
- remove_elem([2.0, 3.1, 3.14, 3.145, 3.14], 3.14,0.01);
val it = [2.0,3.1] : real list
- remove_elem([2.0, 3.1, 3.14, 3.145, 3.14], 3.14,0.001);
val it = [2.0,3.1,3.145] : real list
The issue is here: hd=elem
In languages like ML and Javascript, you cannot directly compare two reals as reals are bound to rounding errors.
You have to use a lambda range and define an interval instead. elem - lambda < hd andalso elem + lambda > hd
We all know that the DO loop is more powerful than the FORALL statement in Fortran. That is, you can always substitute a FORALL by a DO, but not vice versa.
What about the WHERE statement and block?
Can I always substitute the IF by a WHERE? Is it always possible to code the conditionals and bifurcations with a WHERE, thus avoiding the IF?
WHERE statements are reserved for arrays assignments and nothing else, e.g.:
INTEGER, DIMENSION(100,100) :: a, b
... define a ...
WHERE(a < 0)
b = 1
ELSEWHERE
b = 0
ENDWHERE
If you tried adding in something, say a WRITE statement, inside the WHERE block, you would see something like the following compiling error (compiler dependent):
Error: Unexpected WRITE statement in WHERE block at (1)
EDIT
Note that nested WHERE blocks are legal:
WHERE(a < 0)
WHERE( ABS(a) > 2)
b = 2
ELSEWHERE
b = 1
ENDWHERE
ELSEWHERE
b = 0
ENDWHERE
I have a universe of elements organized into n non-disjoint sets. I have m expressions built using these sets, using union/intersection/difference operators. So given an element, I need to evaluate these m expressions, to find out which of the "derived" sets contain the element. I do not want to compute the "derived" set because it will be very time and space inefficient. Is there a way to say whether an element will lie in one of the derived sets just by looking at its expression? For e.g. if the expression is C = A U B and the element lies in set A, then i can say that it will lie in set C. Are there any C libraries to perform computations of this nature?
if im not mistake,
let e = the element
replace each set A, B with true if e is in the set, false if its not. Then, convert the set operators to their logical equivalents, and evaluate the expression as boolean. It should all map well to boolean operators, even xor and stuff.
for example, if e is in both A B, but not D
C = (A U B) xor D
it would be in C because
C = (true or true) xor false
-> (true) xor false
-> true
That could be pretty fast if you can quickly find if an element is in a set