Algorithm to find the maximum acceptable values of the variables - java

I need an algorithm that gives me the maximum acceptable values of the variables under the equation system in Java. I could use Cramer's Algorithm but I thinks there are faster algorithms to solve this.
Edit:
It is not about maximizing a target function but simply looking under these restrictions what maximum value can any variable take.
Example:
x1 <= 4
x2 <= 4
x1 + x2 <= 6
-x1 + 2x3 <= 4
x1 >= 0
x2 >= 0
x3 >= 0
Solution:
x1 <= 4
x2 <= 4
x3 <= 4

Read through the input with any kind of Scanner or InputStreamReader class.
Using StringTokenizer, take the first variable name. Get the next token, the operator.
Using the number on the right (assuming the operator is < or <=) repeatedly find the max value of the given number.
If you have >= or > operators, you can also get a min value of the given number.

Related

Calculating the largest int less than the base 2 log of N

I have been reading Algorithms, 4th Edition, and it defines a question as follows:
Write a static method lg() that takes an int value N as an argument and returns the largest int not larger than the base-2 logarithm of N in Java. Do not use Math.
I discovered the following solution:
public static int lg(int N) {
int x = 0;
for (int n = N; n > 1; n/= 2) x++;
return x;
}
I am wondering why that solution works. Why does dividing by 2 continuously allow us to find the largest integer less than the base 2 logarithm of the argument? I do understand Java, just not how this particular algorithm works.
Thank you.
This has to do with properties of exponents and logarithms. The main observation you need is that
2lg n = n,
because logarithms are the inverses of exponentials. Rearranging that expression gives
1 = n / 2lg n.
In other words, the value of lg n is the number of times you have to divide n by two in order to drop it to 1. This, by the way, is a really great intuition to have when studying algorithms, since log terms show up all the time in contexts like these.
There are some other nuances here about how integer division works, but this is the basic idea behind why that code works.
Its follows trivially from the logarithmic identity log(a/b) = log(a) - log(b).
You are searching for the largest integer x so that:
x <= log2(n)
Using the identity above and taking in account that log2(2) = 1 we get:
x <= log2(n/2) + log2(2)
x <= log2(n/2) + 1
x <= log2(n/4) + 2
x <= log2(n/8) + 3
...
x <= log2(1) + k
x <= k (since log2(1) = 0)
So x is the number of times you divided n by 2 before reaching 1.
The answer is purely Mathmatics,
log₂(n) = ln(n)/ln(2) = x
By applying the rules of exponential:
ln(n) = ln(2)*(x)
n = 2^x
Therefore you have to divide by 2 until the value is smaller than 1 in order to get the closest int to it.
We are looking for the largest integer x such that x <= log_2(N) i.e. 2^x <= N
or equivalent 2^x <= N < 2^{x+1}
Let N_0=N
and for k > 0, N_k the quotient of the division of N_{k-1} by 2 and r_k in {0, 1} the remainder (N_{k-1} = 2.N_k + r_k)
We have:
2^{x-1} <= N_1 + (r_1 / 2) < 2^x
But 0 <= r_1 / 2 <= 1/2 and the others numbers are integers so that is equivalent to
2^{x-1} <= N_1 < 2^x
We have successively:
2^{x-1} <= N_1 < 2^x
2^{x-2} <= N_2 < 2^{x-1}
…
2^{x-x} <= N_x < 2^{x-x+1}
The last is also written 1 <= N_x < 2
But N_x is an integer so N_x = 1
Hence x is the number of division by 2 of N remaining greater or equal than 1.
Instead of starting from N_1, we can start from N_0 = N and stay greater than 1.

Can someone explain to me this code of multiplying two variables using shifts? [duplicate]

This question already has answers here:
Bitwise Multiply and Add in Java
(4 answers)
Closed 4 years ago.
So I have the following code to multiply two variables x and y using left and right shifts.
class Multiply {
public static long multiply(long x,long y) {
long sum = 0;
while(x != 0) {
if((x & 1) != 0) {
sum = sum+y;
}
x >>>= 1;
y <<= 1;
}
return sum;
}
public static void main(String args[]) {
long x = 7;
long y = 5;
long z = multiply(x,y);
}
}
But I dont understand the logic behind it, I understand that when you do
y<<=1
You are doubling y, but what does it mean that the number of iterations of the while loop depends on the number of bits x has?
while(x != 0)
Also why do I only sum if the rightmost bit of x is a 1?
if((x & 1) != 0) {
sum = sum+y;
}
I've really tried to understand the code but I haven't been able to get my head around the algorithm.
Those of us who remember from school how to multiply two numbers, each with two or more digits, will remember the algorithm:
23
x45
---
115
92x
----
1035
For every digit in the bottom factor, multiply it by the top factor and add the partial sums together. Note how we "shift" the partial sums (multiply them by 10) with each digit of the bottom factor.
This could apply to binary numbers as well. The thing to remember here is that no multiplication (by a factor's digit) is necessary, because it's either a 0 (don't add) or a 1 (add).
101
x110
-----
000
101
101
-----
11110
That's essentially what this algorithm does. Check the least significant bit; if it's a 1, add in the other factor (shifted), else don't add.
The line x >>>= 1; shifts right so that the next bit down becomes the least significant bit, so that the next bit can be tested during the next loop iteration. The number of loops depends on where the most significant bit 1 in x is. After the last 1 bit is shifted out of x, x is 0 and the loop terminates.
The line y <<= 1; shifts the other factor (multiplies by 2) in preparation for it be possibly added during the next loop iteration.
Overall, for every 1 bit in x at position n, it adds 2^n times y to the sum.
It does this without keeping track of n, but rather shuffling the bits x of 1 place right (dividing by 2) every iteration and shuffling the bits of y left (multiplying by 2).
Every time the 0 bit is set, which is tested by (x & 1) != 0, the amount to add is the current value of y.
Another reason this works are these equivalences:
(a + b) * y == a*y + b*y
x * y == (x/2) * (y*2)
which is the essence of what’s going on. The first equivalence allows bit-by-bit addition, and the second allows the opposite shuffling.
The >>> is an unsigned right shift which basically fills 0 irrespective of the sign of the number.
So for value x in the example 7 (in binary 111) the first time you do x >>>= 1; You are making the left most bit a zero so it changes from 111 to 011 giving you 3.
You do it again now you have 011 to 001 giving you 1
Once again and you have 001 to 000 giving you 0
So basically is giving you how many iterations before your number becomes zero. (Basically is diving your number in half and it is Integer division)
Now for the y value (5) you are adding it to your sum and then doubling the value of y
so you get:
y = 5 sum = 5
y = 10 sum = 15
y = 20 sum = 35
Only 3 iterations since x only needed to shift 3 times.
Now you have your result! 35

Modulus in Java

I want to get the value of an unknown number in equation containing modulus % in Java
For example:
x % 26 = y if I have the value of y how can I get x
The problem is that there are either zero solutions (if Math.abs(y) >= 26) or an infinite1 number of values of x that satisfy that equation for a given y. The general answer is:
x = 26 * k + y
for any integer value of k. You can pick whatever k you want.2
1 In practice, the range will be limited by the range of integer values you are using. If x and y are int values, then you are limited by Integer.MAX_VALUE and Integer.MIN_VALUE. On the other hand, if they are BigInteger values, you don't have much in the way of range constraints.
2 Actually, the signs of x and y must be the same in Java, so you only have half of infinity to pick from. :-)
You can't get the value of x, that's how modulus works. You just know x = 26 * k + y where k is an integer.

Java logical test questions

I've been solving a few problems about logic tests for AP Computer Science but I happened to get stuck on a few questions.
Here are the directions from the website: Translate each of the following English statements into logical tests that could be used in an if/else statement. Write the appropriate logical test for each statement below. Assume that three int variables, x, y, and z, have already been declared.
These are the 2 questions I have problems with:
Either x or y is even, and the other is odd.
x and z are of opposite signs.
I've been trying to find these answers out for a couple of hours and I still have no clue. I would appreciate it if someone could guide me in the right direction. I understand this is "homework" but some definitive help would be very helpful.
For the first question: x % 2 != y % 2
Second question: x * z < 0
You'll need to use and (&&) and or (||) to make a logic formula. I'm not going to do yours, but here's another one:
x is bigger than both y and z or x is less than both y and z.
Translates to:
((x > y) && (x > z)) || ((x < y) && (x < z))
You just need to figure out a formula for odd/even (hint - the low order bit) and for positive/negative (hint - compare with 0), and combine those with and/or.
For the first question, if x (or y)* is odd, y (or x) must be even, and vice versa. Checking for odd values implies that the modulo of x and 2 is 1 - from there, you would have to assert if y (or x) modulo 2 is 0 (to check for evenness).
For the second question, you would need to follow a chain of logic as such:
X is positive (or greater than 0), which implies Z must be negative (or less than 0).
Z is positive, which implies that X must be negative.
*: This is an exclusive or - I mean that you're either checking x or y, but not both at the same time.
First you have to fully understand the statement in order to put it into the language of a computer. For example,
x and y have the same sign
What this really means is:
( x is greater than or equal to 0 and y is greater than or equal to 0 ) or ( x is less than 0 and y is less than 0 )
Now it is easy to put this into Java:
(x >= 0 && y >= 0) || (x < 0 && y < 0)
Of course, your questions can be solved via a similar method.
Either x or y is even, and the other is odd.
The sum of an odd and even number is odd. The sum of two odd numbers is even and the sum of two even numbers are even.
So (x+y)%2!=0.
x and z are of opposite signs
This one is similar, you can do:
x*z<0
Since 0 is neither negative or positive and
neg * pos = neg
neg * neg = pos
pos * pos = pos
If you want to consider 0 and a negative number of opposite signs you can use (x >= 0) == (z < 0)
Putting it in plain english, for me anyhow.
If ((x is even AND y is odd) OR (x is odd AND y is even))
For the other
If ((x gt or eq 0 AND y lt 0) OR (y gt or eq 0 AND x lt 0))
Assuming 0 is positive.

How to find shortest path in both directions of a number with over wrapping?

Let's say I have to pick a number from 0-10.
The number I pick is 6.
The next number I want to pick is 0.
Now the rules are I have to keep incrementing the number by 1 or decrementing it by 1, the number can also wrap around the last number.
Now whats most important is to find which direction is shortest to take.
So
6-5-4-3-2-1-0 = 7 moves.
6-7-8-9-10-0 = 6 moves.
So incrementing wins in this case.
Well I came up with this code (probably broken)
int movesInc = 1;
int movesDec = 1;
int curNumber = 6;
int nextNumber = 0;
while((curNumber-- % 11) != nextNumber)
movesDec++;
while((curNumber++ % 11) != nextNumber)
movesInc++;
Now instead of using a while loop in both directions.. and finding out which takes less moves..
any way to do this without a while loop? just maybe some kind of mathematical equation?
Your code doesn't in fact work properly for two reasons:
You should be working modulo 11 instead of 10 (I see you've now fixed this per my earlier comment).
The % operator in Java and C++ doesn't deal with signs the way you think.
This does work, though it's not pretty, and it doesn't need loops.
It is tested for the start at 6 and end at 0, and I expect it works generally. For a different range, you'd of course need to change the number added when the result goes negative.
int curNumber = 6;
int nextNumber = 0;
int movesInc = (nextNumber - curNumber) + 1
+ ((nextNumber > curNumber)? 0: 11);
int movesDec = (curNumber - nextNumber) + 1
+ ((nextNumber < curNumber)? 0: 11);
The + 1 here is because you're counting both endpoints. The ternary expression is what handles going around 0.
int curNumber;
int nextNumber;
//calculate the modulo size by the highest number
int module = 10 + 1;
//calculate the direct distance to the nextNumber
int directDist = nextNumber - curNumber;
int nextNumberWrapped;
//calculate the wrapped distance, deciding the direction which wraps
if(directDist < 0)
//wrapping in positive direction: 10 -> 0
nextNumberWrapped = nextNumber + module;
else
//wrapping in negative direction 0 -> 10
nextNumberWrapped = nextNumber - module;
//calculating the wrapped distance
int wrappedDist = nextNumberWrapped - curNumber;
//assume the directDist to be shortest
int shortestDist = directDist;
//proof wrong if neccessary (compare the distances absolute values)
if(abs(wrappedDist) < abs(directDist))
//save the signed distance
shortestDist = wrappedDist;
The absolute value of shortestDist tells you the length of the shortest distance and the sign gives you the direction.
So when the sign is negative you have to decrement and when it is positive you must increment to go the shortest way.
http://ideone.com/0yCDw
Also your example seems wrong. Each - between the numbers is one step, leaving you with one step less than you counted:
6-5-4-3-2-1-0
^ ^ ^ ^ ^ ^
1 2 3 4 5 6 -> 6 moves
6-7-8-9-10-0
^ ^ ^ ^ ^
1 2 3 4 5 -> 5 moves

Categories