Implementing Egyptian Algorithm in java - java

I want to find a multiplication of two numbers in Java recursively with using only Addition, Subtraction and Comparison. So, I googled and I found Egyptian Algorithm that meets the question requirement.
However, I'm not sure how to find the multiplication result after we reach the base case.
Example:
13 x 30
1 -- 30
2 -- 60
4 -- 120
8 -- 240 //we stop here because the double of 8 is larger than 13
To find the result we add the numbers from the left column that equals 13 which they are 1+4+8 and on the other hand we add its opposite numbers from the right column which they are 30+120+240 = 390 which is the result.
But now how to do last part programatically ? how to check which numbers to add? I hope you guys get my point. Hints only needed.

Here's pseudocode to solve the problem:
function egyptian(left, right)
prod := 0
while (left > 0)
if (left is odd)
prod := prod + right
left := halve(left)
right := double(right)
return prod
Basically, instead of waiting until the end, it is easier to check each row of the template as it is created and sum if it belongs in the output. I discuss this algorithm at my blog.

Do a loop through the created results in reverse order
Each time, if your multiplicant remainder (which starts equal to your multiplicant) is larger than the number in the left column, subtract the left column from your multiplicant and add the right column to your result (which starts at zero).

You might have found this Wikipedia article.
Have a look at the last part of the section called "decomposition". You'll find the sub-algorithm you have to implement.

Okay, I did it using Brute Force Algorithm. It's a BigO-(n) though. I'm sure there is more efficient way to implement it. For now. I'm settling with this.
Thanks guys!

Related

How to solve the closest subset sum problem in Java for 100+ element arrays?

I have came across a subset sum problem recently. I was able to solve it for smaller arrays using Java earlier, but in this case I have really no idea what should I do. Brute force and recurrence is probably not an option, as I came across out of memory problem.
So, let's say we have an array of {2500, 3200, 3300}. We are looking for the sum closest to the desired number K = 135000. The main difference is that we can use numbers from the array multiple times.
Ok, if we can use them multiple times, then we can change it to more "traditional" way - just divide K by each of these numbers - that is 54, 42 and 40 - and create a new array, which has those numbers the number of times received from dividing. It would be {2500, 2500, 2500, ... , ... 3300, 3300} and the new array would have the length of 136. Now this is much more than 3.
So - how to solve the closest subset sum problem, where we can pick more than 2 numbers from the array of 136 elements or more using Java?
The thing I want to get is not only the closest sum, but also a list of elements which gave that sum.
I heard and was reading about dynamic programing, approximation algorithms and genetic algorithms, but unfortunately I have no idea about those. I did genetic algorithm for a different case some time ago, but I am not sure how to use it in this case.
Any ideas? I will be really glad for help.
I am not going to solve it for you. but I'll give you the key ideas in pseudocode (aka Python).
We start with a state that represents the following statement: "I don't know how to arrive to any numbers. The best thing I can generate is 0. I have not yet processed the fact that I could get to 0."
In data:
can_generate = set()
todo = [0]
best = 0
K = 135000
What we will do is, while anything is in todo, take off a value, see if it is new to us. If it is, we might update best, and possibly add new values to todo. Like this:
while len(todo):
value = todo.pop()
if value not in can_generate:
can_generate.add(value)
if abs(K-value) < abs(K-best):
best = value
if value < K:
for term in [2500, 3200, 3300]:
todo.append(value + term)
Now that we know the values in can_generate, we search backwards to find how to get there.
answer = []
while 0 < best:
for term in [3300, 3200, 2500]:
if best - term in can_generate:
answer.append(term)
best -= term
break

Find the lowest sum path from 2d Array

Just thinking about the one algorithm below is the statement for that
Given a matrix, with each node having a value. You start from 0,0 and have to reach n,m. From i,j you can either go to i+1,j or i,j+1. When you step on each block, the value on that block gets added to your current score. What’s the minimum initial score you must carry so that you can always reach n,m(through any possible path) having positive score at the end.
Eg:
Matrix -> 2 3 4
-5 -6 7
8 3 1
Ans -> 6 – for path 2,-5,-6,3,1 we need initial score of 6 so that when we land on 1, we have a positive score of 1
So I can do this using brute force and Dynamic programming, but still thinking for approach which could be better then this, please share ur thoughts, just thoughts/idea I do not need implementation, as I can do this.
There's many search algorithm, i encourage you reading these Wikipedia pages :
https://en.wikipedia.org/wiki/Pathfinding
https://en.wikipedia.org/wiki/Tree_traversal
One possible solution, is to transform the array to graph and apply shortest paths algorithms to it, another solution is to use some IA algorithms such as A*.
Link to Wikipedia for A* (prounced A Star) :
https://en.wikipedia.org/wiki/A*_search_algorithm

Finding smallest delta available for permutations of a set of numbers

Presume we have a set of 12 objects, lets say {1,2,3,4,5,6,7,8,9,10,11,12}. We must break this set into 4 smaller ones composed of three objects, so that the largest sum and smallest sum of these four sets is minimized. We must find this difference. In our example, {1,7,12},(3,8,9},{4,5,10},{2,6,11}. These four sets satisfy the problem since their sums are 20 and 19, meaning a delta of 1, our answer.
How can one solve this problem for any arbitrary 12 values?
I've tried enumerating all partitions of said set into 4 sets of 3, and finding one with the optimal score. However, time is of the essence, and so I was wondering how one would approach this problem in Java
I don't have exact code on me right now, but what it essentially was was 9 nested for loops, where the first three that nest are one set, the next three are the next set, the last three are another set, and the three left overs are another set. I used a 2D array so that values would be in score[i][0] and score[i][1] would act as an indicator to let me know if that value in score[i][0] had already been placed into a set.
This of course gets tedious and inefficient.
You could easily simplify the problem by finding the values that the sums must approach for a better optimisation :
For instance, in your simple case (1,2...12), then the total sum of every terms is 78. Thus, Each groups must have a sum very close to 78/4=19.
So, let's try a very simple algorithm :
- compute TOTAL_SUM = SUM(terms)
- compute TARGET_SUM = TOTAL_SUM / number(terms)
- set DELTA=0
- loop {
- Try to split terms in groups where TARGET_SUM - DELTA <= SUM <= TARGET_SUM + DELTA
- if a solution is found, exit
- DELTA = DELTA + 1
- }
Ok, I did not helped you much with this "Try to split..." step. But it should look like you own solution, except that you have additional constraints which can help you to speed up the process.
Hope this helps.

Exclusive or between N bit sets

I am implementing a program in Java using BitSets and I am stuck in the following operation:
Given N BitSets return a BitSet with 0 if there is more than 1 one in all the BitSets, and 1 otherwise
As an example, suppose we have this 3 sets:
10010
01011
00111
11100 expected result
For the following sets :
10010
01011
00111
10100
00101
01000 expected result
I am trying to do this exclusive with bit wise operations, and I have realized that what I need is literally the exclusive or between all the sets, but not in an iterative fashion,
so I am quite stumped with what to do. Is this even possible?
I wanted to avoid the costly solution of having to check each bit in each set, and keep a counter for each position...
Thanks for any help
Edit : as some people asked, this is part of a project I'm working on. I am building a time table generator and basically one of the soft constraints is that no student should have only 1 class in 1 day, so those Sets represent the attending students in each hour, and I want to filter the ones who have only 1 class.
You can do what you want with two values. One has the bits set at least once, the second has those set more than once. The combination can be used to determine those set once and no more.
int[] ints = {0b10010, 0b01011, 0b00111, 0b10100, 0b00101};
int setOnce = 0, setMore = 0;
for (int i : ints) {
setMore |= setOnce & i;
setOnce |= i;
}
int result = setOnce & ~setMore;
System.out.println(String.format("%5s", Integer.toBinaryString(result)).replace(' ', '0'));
prints
01000
Well first of all, you can't do this without checking every bit in each set. If you could solve this question without checking some arbitrary bit, then that would imply that there exist two solutions (i.e. two different ones for each of the two values that bit can be).
If you want a more efficient way of computing the XOR of multiple bit sets, I'd consider representing your sets as integers rather than with sets of individual bits. Then simply XOR the integers together to arrive at your answer. Otherwise, it seems to me that you would have to iterate through each bit, check its value, and compute the solution on your own (as you described in your question).

Normalized Iteration Count does not work. What am I doing wrong?

As you can see from the title, I'm busy programming a little programm for visualizing fractals in Java. Anybody who deals with fractals will come to the point where he/she searches for a solution to get these stupid "bands" away, when you just colour a pixel by the number of iterations it took to escape.
So I searched for a more advanced colouring algorithm, finding the "normalized iteration count". The formula I'm using is:
float loc = (float) 1 - Math.log(Math.log(c.abs())) / Math.log(2);
Everybody on the Internet is so happy about this algorithm, everybody uses it, everbody gets great results. Except me. I thought, this algorithm should provide a float between 0 and 1. But that doesn't happen. I did some calculations and came to the conclusion, that this algorithm only works for c.abs() >= Math.E && c.abs() <= Math.exp(2) (that is Math.E * Math.E).
In numbers this means, my input into this equation has to be between about 2.718 and 7.389.
But a complex number c is considerd to tend towards infinity when its magnitude gets greater than 2. But for any Input smaller than Math.E, I get a value greater than one. And for any number greater than Math.exp(2), it gets negative. That is the case if a complex number escapes really fast.
So please tell me: what am I doing wrong. I'm desperate.
Thanks.
EDIT:
I was wrong: the code I posted is correct, I just
1. used it the wrong way and so it didn't provide the right output.
2. had to set the bailout value of the mandelbrot/julia algorithm to 10, otherwise I would've got stupid bands again.
Problem solved!
As you've already discovered, you need to increase the bailout radius before smoothing will look right.
Two is the minimum length that a coordinate can have such that when you square it and add the initial value, it cannot result in a smaller length. If the previous length was 2.0, and you squared it, you'd have a length of 4.0 (pointing in whichever direction), and the most that any value of c could reduce that by is 2.0 (by pointing in precisely the opposite direction). If c were larger than that then it would start to escape right away.
Now, to estimate the fractional part of the number of iterations we look at the final |z|. If z had simply been squared and c not added to it, then it would have a length between 2.0 and 4.0 (the new value must be larger than 2.0 to bail out, and the old value must have been less than 2.0 to have not bailed out earlier).
Without c, taking |z|'s proportional position between 2 and 4 gives us a fractional part of the number of iterations. If |z| is close to 4 then the previous length must have been close to 2, so it was already close to bailing out in the previous iteration and the smoothed result should be close to the previous iteration count to represent that. If it's close to 2, then the previous iteration was further from bailing out, and so the smoothed result should be closer to the new iteration count.
Unfortunately c messes that up. The larger c is, the larger the potential error is in that simple relationship. Even if the old length was nearly at 2.0, it might have landed such that c's influence made it look like it must have been smaller.
Increasing the bailout mitigates the effect of adding c. If the bailout is 64 then the resulting length will be between 64 and 4096, and c's maximum offset of 2 has a proportionally smaller very impact on the result.
You have left out the iteration value, try this:
float loc = <iteration_value> + (float) 1 - Math.log(Math.log(c.abs())) / Math.log(2);
The iteration_value is the number of iterations which yielded c in the formula.

Categories