SCIP: How to find if a current value of a variable in the incumbent solution is integer or not? - scip

I am trying to go over over some variables during some branching and I want to know if the current solution has any variables that are integers.
I am doing this:
SCIPgetSolVal(scip, sol, (*transport_vars)[i][j])) > 0.999
But I want to know if there exists a method that can tell me that (*transport_vars)[i][j] is achieving its upper limit (binary 1.0) instead of comparing it to > 0.999.
In case it matters, I am comparing it with 0.999 in a constraint handler. I think I am facing numerical issues if I use 0.999

You can just call SCIPisIntegral(SCIP* scip, SCIP_Real val) if you just want to know if your value is integer (within tolerances).
If you really want to know if it is 1 or not, you can use either SCIPisEq or SCIPisFeasEq. Both check equality with a tolerance. In the first case the tolerance is scips num_epsilon parameter and in the second it is the feasibility tolerance.

Related

X and Y inputs in LabVIEW

I am new to LabVIEW and I am trying to read a code written in LabVIEW. The block diagram is this:
This is the program to input x and y functions into the voltage input. It is meant to give an input voltage in different forms (sine, heartshape , etc.) into the fast-steering mirror or galvano mirror x and y axises.
x and y function controls are for inputting a formula for a function, and then we use "evaluation single value" function to input into a daq assistant.
I understand that { 2*(|-Mpi|)/N }*i + -Mpi*pi goes into the x value. However, I dont understand why we use this kind of formula. Why we need to assign a negative value and then do the absolute value of -M*pi. Also, I don`t understand why we need to divide to N and then multiply by i. And finally, why need to add -Mpi again? If you provide any hints about this I would really appreciate it.
This is just a complicated way to write the code/formula. Given what the code looks like (unnecessary wire bends, duplicate loop-input-tunnels, hidden wires, unnecessary coercion dots, failure to use appropriate built-in 'negate' function) not much care has been given in writing it. So while it probably yields the correct results you should not expect it to do so in the most readable way.
To answer you specific questions:
Why we need to assign a negative value and then do the absolute value
We don't. We can just move the negation immediately before the last addition or change that to a subtraction:
{ 2*(|Mpi|)/N }*i - Mpi*pi
And as #yair pointed out: We are not assigning a value here, we are basically flipping the sign of whatever value the user entered.
Why we need to divide to N and then multiply by i
This gives you a fraction between 0 and 1, no matter how many steps you do in your for-loop. Think of N as a sampling rate. I.e. your mirrors will always do the same movement, but a larger N just produces more steps in between.
Why need to add -Mpi again
I would strongly assume this is some kind of quick-and-dirty workaround for a bug that has not been fixed properly. Looking at the code it seems this +Mpi*pi has been added later on in the development process. And while I don't know what the expected values are I would believe that multiplying only one of the summands by Pi is probably wrong.

Minimize a differece that has to be positive

I have the following optimization:
mnimize: obj(x) = f(x) - constant
sbj.to: lb < x < hb
sbj.to: f(x) - constant >= 0
I have the feeling that this is not the most convenient way to put the optimization problem. Is there another way which might be more convenient computationally?
Till now I tried to modify the objective for example using obj(x) = (f(x) - constant)^2, which permit me to avoid the second constraint. But it gives me some convergence problems depending on the value of the constant. Some ideas?
I can think of two other possible approaches - not sure whether they are any better, but that is:
If [f(x) - constant]^2 gives you convergence issues (not sure why?), try and replace it with abs(f(x) - constant). Warning: the abs() function is not always the best behaved, sometimes it confuses some optimization algorithms
In your objective function, if (f(x) - constant) becomes negative, return a big value - proportional to how much it becomes negative. Otherwise return the normal difference.

Summation iterated over a variable length

I have written an optimization problem in pyomo and need a constraint, which contains a summation that has a variable length:
u_i_t[i, t]*T_min_run - sum (tnewnew in (t-T_min_run+1)..t-1) u_i_t[i,tnewnew] <= sum (tnew in t..(t+T_min_run-1)) u_i_t[i,tnew]
T is my actual timeline and N my machines
usually I iterate over t, but I need to guarantee the machines are turned on for certain amount of time.
def HP_on_rule(model, i, t):
return model.u_i_t[i, t]*T_min_run - sum(model.u_i_t[i, tnewnew] for tnewnew in range((t-T_min_run+1), (t-1))) <= sum(model.u_i_t[i, tnew] for tnew in range(t, (t+T_min_run-1)))
model.HP_on_rule = Constraint(N, rule=HP_on_rule)
I hope you can provide me with the correct formulation in pyomo/python.
The problem is that t is a running variable and I do not know how to implement this in Python. tnew is only a help variable. E.g. t=6 (variable), T_min_run=3 (constant) and u_i_t is binary [00001111100000...] then I get:
1*3 - 1 <= 3
As I said, I do not know how to implement this in my code and the current version is not running.
TypeError: HP_on_rule() missing 1 required positional argument: 't'
It seems like you didn't provide all your arguments to the function rule.
Since t is a parameter of your function, I assume that it corresponds to an element of set T (your timeline).
Then, your last line of your code example should include not only the set N, but also the set T. Try this:
model.HP_on_rule = Constraint(N, T, rule=HP_on_rule)
Please note: Building a Constraint with a "for each" part, you must provide the Pyomo Sets that you want to iterate over at the begining of the call for Constraint construction. As a rule of thumb, your constraint rule function should have 1 more argument than the number of Pyomo Sets specified in the Constraint initilization line.

Using Subtraction in a Conditional Statement in Verilog

I'm relatively new to Verilog and I've been working on a project in which I would, in an ideal world, like to have an assignment statement like:
assign isinbufferzone = a > (packetlength-16384) ? 1:0;
The file with this type of line in it will compile, but isinbufferzone doesn't go high when it should. I'm assuming it's not happy with having subtraction in the conditional. I'm able to make the module work by moving stuff around, but the result is more complicated than I think it should need to be and the latency really starts to add up. Does anyone have any thoughts on what the most concise way to do this is? Thank you in advance for your help.
You probably expect isinbufferzone to go high if packetlength is 16384 or less regardless of a, however this is not what happens.
If packetlength is less than 16384, the value packetlength - 16384 is not a negative number −X, but some very large positive number (maybe 232 − X, or 217 − X, I'm not quite sure which, but it doesn't matter), because Verilog does unsigned arithmetic by default. This is called integer overflow.
You could maybe try to solve this by declaring some signals as signed, but in my opinion the safest way is to explicitly handle the overflow case and making sure the subtraction result is only evaluated for packetlength values of 16384 or greater:
assign isinbufferzone = (packetlength < 16384) ? 1 : (a > packetlength - 16384);

Redefining a variable

I am using AMPL for the optimization of my model, and just have started with that project.
I have two variables, say A and B that I utilize in my objective function:
A[d,t]*costA-B[d,t]*costB
Later on I have the following constraint:
G[d,t]-U[d,t]-R[d,t]=A[d,t]
Here I realized that I can use just A, but the problem is, depending on whether or not this variable will be positive or negative I should use costA or costB.
My question is, can I redefine A[d,t] as B[d,t] if A[d,t] is less than 0? And if I can, how can I do it? Or is there any other way?
I think what you are after is something like (in some math-like notation):
min sum((d,t), APlus[d,t]*CostA + AMin[d,t]*CostB)
s.t. A[d,t] = APlus[d,t]-AMin[d,t]
positive variables APlus,AMin
This is called "variable splitting".