Calculating index in a subdivided interval? - c++

Consider an interval of values [x, y] equally subdivided in n samples in the following way:
y can be greater, equal or less than x.
Now, we pick up a value z between x and y.
Question: what is the formula to compute the index i of z ? (if x = y, then the formula should return 0 or n-1) (I repeat: y can be greater, equal or less than x.)
For example: if x = - 5, y = -10 and n = 5, then for z = -7.5, i = 2 (if z = -7, i = 2 but if z = -8, i = 3).

You can compute the length of the interval as:
len = y - x
Then you can compute the increase per a single element
increase = len / n;
And now you have i = (z - x) / increase. In short you compute how much does the value increase per a single element and than you compute how many times this increase is needed to get from x to z.
EDIT: if you really require the solution in C++ take care to do all the calculations in double. Also please note the value of i should be an integer rounded down.

Answer logic(IN java):
i = Math.abs(Math.ceil(z - Math.min(x,y)));

if(x>y) high = x low = y
else high = y low = x
if(y>=x)
i = ceil((z-low+1)/(high-low+1)*n)-1
else i = ceil((high-z+1)/(high-low+1)*n)-1

Related

Converting conditional constraints to linear constraints in Linear Programming

I have two variables: x>= 0 and y binary (either 0 or 1), and I have a constant z >= 0. How can I use linear constraints to describe the following condition:
If x = z then y = 1 else y = 0.
I tried to solve this problem by defining another binary variable i and a large-enough positive constant U and adding constraints
y - U * i = 0;
x - U * (1 - i) = z;
Is this correct?
Really there are two classes of constraints that you are asking about:
If y=1, then x=z. For some large constant M, you could add the following two constraints to achieve this:
x-z <= M*(1-y)
z-x <= M*(1-y)
If y=1 then these constraints are equivalent to x-z <= 0 and z-x <= 0, meaning x=z, and if y=0, then these constraints are x-z <= M and z-x <= M, which should not be binding if we selected a sufficiently large M value.
If y=0 then x != z. Technically you could enforce this constraint by adding another binary variable q that controls whether x > z (q=1) or x < z (q=0). Then you could add the following constraints, where m is some small positive value and M is some large positive value:
x-z >= mq - M(1-q)
x-z <= Mq - m(1-q)
If q=1 then these constraints bound x-z to the range [m, M], and if q=0 then these constraints bound x-z to the range [-M, -m].
In practice when using a solver this usually will not actually ensure x != z, because small bounds violations are typically allowed. Therefore, instead of using these constraints I would suggest not adding any constraints to your model to enforce this rule. Then, if you get a final solution with y=0 and x=z, you could adjust x to take value x+epsilon or x-epsilon for some infinitesimally small value of epsilon.
So I change the conditional constraints to
if x = z then y = 0 else y = 1
Then the answer will be
x - z <= M * y;
x - z >= m * y;
where M is a large enough positive number, m is a small enough positive number.

Getting the nearest multiple of x of an integer thats equal or greater than the original value

Lets say I have x = 25 and y = 4. I want the nearest value to x that is a) multiple of y and b) equal or greater than x, for these numbers it would be 28. Usually I would do this:
result = ceil((float)x / (float)y) * y
however, this time I'm dealing with uint64's and rather large numbers that would probably get chewed up by the conversion to a double and back so currently I'm doing this:
if (x % y) result = (x / y + 1) * y
else result = x
but I'm wondering if theres a better way since this has to come up a lot when dealing with files (i know it does for me)
I'd do it this way:
z = x%y;
result = x + (z? y-z: 0);
No multiplication or division, and no danger of overflow (if the correct result can fit in the type).

Need clarification about this loop performing multiplication

int x, y; // x is a non-negative integer
p = 0;
while (x > 0)
{
if ( x % 2 == 1 )
p = p + y;
y = y*2;
x = x/2;
}
// p == a*b here
I understand that this loop finds the product of 'a' and 'b' using the algebra:
a * b = (1/2)a * 2b
but I don't understand the code:
if ( x % 2 == 1 )
p = p + y;
I was hoping someone could explain why 'p' is assigned 'p + y' on odd values of x.
while (x > 0) {
if (x % 2 == 1)
p = p + y;
y = y*2;
x = x/2;
}
imagine x = 4, y = 5
iterations:
x is even, y = 10, x = 2 (i.e. x can be divided, y should be doubled)
x is even, y = 20, x = 1
x is odd, p = 20, y = 40, x = 0 (i.e. x can not be divided anymore, y should be added to p)
x > 0 is false, loop ends
p = 4 * y
now imagine x is odd at the beginning, let's say x = 5, y = 2:
x is odd, p = 2, y = 4, x = 2
(5/2 = 2.5, new value of x will be rounded down, y should be added BEFORE it is doubled)
x is even, y = 8, x = 1
x is odd, p = 10, y = 16, x = 0
p = y + 4*y
that first y is the reason, adding it to the result before it is doubled (1 * y) is in this case equivalent to 0.5 * (2 * y)
Because these are integers, a / 2 will be an integer. If a is odd, that integer has been rounded down, and you’re missing one-half b in the next iteration of the loop, i.e. one whole b in the current iteration of the loop (since b [y] is doubled each time).
If x is odd, x = x/2 will set x to 0.5 less than x/2 (because integer division rounds it down). p needs to be adjusted to allow for that.
Think of multiplication as repeated addition, x*y is adding y together x times. It is also the same as adding 2*y together x/2 times. Conceptually it is somewhat unclear what it means if x is odd. For example, if x=5 and y=3, what does it mean to add 2.5 times? The code notices when x is odd, adds y in, then does the y=y*2 and x=x/2. When x is odd, this throws away the .5 part. So in this example, you add y one time, then x becomes 2 (not 2.5) because integer division throws away the fraction.
At the end of each loop, you will see that the product of the original x and y is equal to p + x*y for the current values of p, x, and y. The loop iterates until x is 0, and the result is entirely in p.
It also helps to see what is going on if you make a table and update it each time through the loop. These are the values at the start of each iteration:
x | y | p
----------
5 | 3 | 0
2 | 6 | 3
1 | 12 | 3
0 | 24 | 15
This works by observing that (for example) y * 10 = y * 8 + y * 2.
It's pretty much like doing multiplication on paper in school. For example, to multiply 14 x 21, we multiply one digit at a time (and shift left a place where needed) so we add 1x14 + 2 x 14 (shifted left one digit).
14
x 21
----
14
280
Here, we're doing pretty much the same thing, but working in binary instead of decimal. The right shifting has nothing to do with the numbers being odd, and everything to do with simply finding which bits in the number are set.
As we shift one operand right to find whether a bit is set, we also shift the other operand left, just like we add zeros to shift numbers left when doing arithmetic on paper in decimal.
So, viewing things in binary, we end up with something like:
101101
x 11010
--------
1011010
+ 101101000
+ 1011010000
If we wanted to, instead of shifting the operand right, we could just shift the mask left so instead of repeatedly anding with 1, we'd and with 1, then with 2, then with 4, and so on (in fact, it would probably make a lot more sense that way). For better or worse, however, in assembly language (where this sort of thing is normally done) it's usually a little easier to shift the operand and use a constant for the mask than load the mask in a register and shift it when needed.
You should rewrite x as 2*b+1 (assuming x is odd). Then
x*y = (2*b+1)*y = (2*b)*y + y = b*(2*y) + y = (x/2)*(2*y) + y
where (x/2) is meant to be the integer division. With the operation rewritten this way, you see the x/2, the 2y and the +y appear.

Finding solution set of a Linear equation?

I need to find all possible solutions for this equation:
x+2y = N, x<100000 and y<100000.
given N=10, say.
I'm doing it like this in python:
for x in range(1,100000):
for y in range(1,100000):
if x + 2*y == 10:
print x, y
How should I optimize this for speed? What should I do?
Essentially this is a Language-Agnostic question. A C/C++ answer would also help.
if x+2y = N, then y = (N-x)/2 (supposing N-x is even). You don't need to iterate all over range(1,100000)
like this (for a given N)
if (N % 2): x0 = 1
else: x0 = 0
for x in range(x0, min(x,100000), 2):
print x, (N-x)/2
EDIT:
you have to take care that N-x does not turn negative. That's what min is supposed to do
The answer of Leftris is actually better than mine because these special cases are taken care of in an elegant way
we can iterate over the domain of y and calculate x. Also taking into account that x also has a limited range, we further limit the domain of y as [1, N/2] (as anything over N/2 for y will give negative value for x)
x=N;
for y in range(1,N/2-1):
x = x-2
print x, y
This just loops N/2 times (instead of 50000)
It doesn't even do those expensive multiplications and divisions
This runs in quadratic time. You can reduce it to linear time by rearranging your equation to the form y = .... This allows you to loop over x only, calculate y, and check whether it's an integer.
Lefteris E 's answer is the way to go,
but I do feel y should be in the range [1,N/2] instead of [1,2*N]
Explanation:
x+2*y = N
//replace x with N-2*y
N-2*(y) + 2*y = N
N-2*(N/2) + 2*y = N
2*y = N
//therefore, when x=0, y is maximum, and y = N/2
y = N/2
So now you can do:
for y in range(1,int(N/2)):
x = N - (y<<1)
print x, y
You may try to only examine even numbers for x given N =10;
the reason is that: 2y must be even, therefore, x must be even. This should reduce the total running time to half of examining all x.
If you also require that the answer is natural number, so negative numbers are ruled out. you can then only need to examine numbers that are even between [0,10] for x, since both x and 2y must be not larger than 10 alone.

Find two integers such that their product is close to a given real

I'm looking for an algorithm to find two integer values x,y such that their product is as close as possible to a given double k while their difference is low.
Example: The area of a rectangle is k=21.5 and I want to find the edges length of that rectangle with the constraint that they must be integer, in this case some of the possible solutions are (excluding permutations) (x=4,y=5),(x=3,y=7) and the stupid solution (x=21,y=1)
In fact for the (3,7) couple we have the same difference as for the (21,1) couple
21.5-3*7=0.5 = 21.5-21*1
while for the (4,5) couple
21.5-4*5=1.5
but the couple (4,5) is preferable because their difference is 1, so the rectangle is "more squared".
Is there a method to extract those x,y values for which the difference is minimal and the difference of their product to k is also minimal?
You have to look around square root of the number in question. For 21.5 sqrt(21.5) = 4.6368 and indeed the numbers you found are just around this value.
You want to minimize
the difference of the factors X and Y
the difference of the product X × Y and P.
You have provided an example where these objectives contradict each other. 3 × 7 is closer to 21 than 4 × 5, but the latter factors are more square. Thus, there cannot be any algorithm which minimizes both at the same time.
You can weight the two objectives and transform them into one, and then solve the problem via non-linear integer programming:
min c × |X × Y - P| + d × |X – Y|
subject to X, Y ∈ ℤ
X, Y ≥ 0
where c, d are non-negative numbers that define which objective you value how much.
Take the square root, floor one integer, ceil the other.
#include <iostream>
#include <cmath>
int main(){
double real_value = 21.5;
int sign = real_value > 0 ? 1 : -1;
int x = std::floor(std::sqrt(std::abs(real_value)));
int y = std::ceil(std::sqrt(std::abs(real_value)));
x *= sign;
std::cout << x << "*" << y << "=" << (x*y) << " ~~ " << real_value << "\n";
return 0;
}
Note that this approach only gives you a good distance between x and y, for example if real_value = 10 then x=3 and y=4, but the product is 12. If you want to achieve a better distance between the product and the real value you have to adjust the integers and increase their difference.
double best = DBL_MAX;
int a, b;
for (int i = 1; i <= sqrt(k); i++)
{
int j = round(k/i);
double d = abs(k - i*j);
if (d < best)
{
best = d;
a = i;
b = j;
}
}
Let given double be K.
Take floor of K, let it be F.
Take 2 integer arrays of size F*F. Let they be Ar1, Ar2.
Run loop like this
int z = 0 ;
for ( int i = 1 ; i <= F ; ++i )
{
for ( int j = 1 ; j <= F ; ++j )
{
Ar1[z] = i * j ;
Ar2[z] = i - j ;
++ z ;
}
}
You got the difference/product pairs for all the possible numbers now. Now assign some 'Priority value' for product being close to value K and some other to the smaller difference. Now traverse these arrays from 0 to F*F and find the pair you required by checking your condition.
For eg. Let being closer to K has priority 1 and being smaller in difference has priority .5. Consider another Array Ar3 of size F*F. Then,
for ( int i = 0 ; i <= F*F ; ++i )
{
Ar3[i] = (Ar1[i] - K)* 1 + (Ar2[i] * .5) ;
}
Traverse Ar3 to find the greatest value, that will be the pair you are looking for.