Are the segments combined into another structure or are they operated on as is? Also, abstraction might do wonders, I'm not sure if you can drop all these loops, but you could hide them for sure.
–
BobbyJan 15 '14 at 11:15

Segments are not used in any other structure. it is operated on as it is.
–
anand mahuliJan 15 '14 at 11:19

Your code generates occasional superimposed points, e.g. the first time thrugh the loop all the points are at Point(0,0). Is this intentional?
–
rolfl♦Jan 15 '14 at 12:12

@rolfl : yes..i have kept it intentionally..i want all combinations of points even if they are overlapping.
–
anand mahuliJan 15 '14 at 12:23

thanks for the reply. but it will take too much space to store (12345+1) * (6789+1) points and then segments from those points. it directly goes out of memory. thats why i have not created points and segments seprately outside this loop.
–
anand mahuliJan 15 '14 at 10:44

3

@anandmahuli: There is a note in the javadoc which could help: Performance notes: while the cartesian product of sets of size m, n, p is a set of size m x n x p, its actual memory consumption is much smaller. When the cartesian set is constructed, the input sets are merely copied. Only as the resulting set is iterated are the individual lists created, and these are not retained after iteration.
–
palacsintJan 15 '14 at 11:15

Given the large size of the potential result set, the previously suggested iteration mechanism seems appropriate.

I looked at this and thought 'nice challenge', and I looked at your code, and figured there were too many loops. The way I see you doing the work inside the loops also looks cumbersome...

I figured it would be 'neat' to have a generator that created all the segments on an as-needed basis, and did not do the actual work.... then I played with it, and found there were some potential optimizations.

So, the parts of your code that are potential performance problems:

you re-create Point instances much more than you need to... I can reduce by at least 24 times the amount of point creation you do.

your problem space is two separate things, you have a combination problem, and also a permutation problem. If you solve them separately, you can pre-calculate the permutations and not have to do them multiple times, then you can just reuse the same points in each permutation.

So, with that in mind, I 'played' with your code. This is not a review of your code, but, rather, it is the result of me solving your problem in a different way. There are pro's and con's to my solution... so, use it with appropriate care. The goal of my 'refactoring' was to hit a usage-model something like:

for (Segment[] sides : new SegmentGenerator(m, n)) {
// do something with this set of segments.
}

One note to consider first.... it is a 'common' model when doing matrix-operations in high-performance computing, to 'flatten' the matrix in to a single dimension. For example, a 3x3 matrix will be flattened in to a single-dimension of 9. The (row,column) indices in the flattened matrix are calculated as follows (row = matrix-row, col = matrix-column, and flat = one-D index)

flat = row * width + col;
row = flat / width;
col = flat % width;

By doing this flattening of the data you can halve the number of loops you need (you only need one loop to access the entire matrix), and you reduce the number of physical arrays (and the memory-separation) of those arrays.

I have employed this type of logic in the solution....

Pro's:

it precomputes all the Permutations for the number of segments in each result.

you can easily adjust it to do any number of 'sides', not just 4.

it exposes things neatly in an Iterable engine, which allows you to do some neat code when using it.

you can probably use this to 'feed' a parallel process where each thread processes chunks of results.

it reuses Point instances a lot.... in fact, a huge amount less duplication than your code (I am guessing it is something approximately like m*(X!) times fewer Point instances where m is the width of the matrix, and X is the number of sides. So, for example a 100-wide matrix with 4-sided segments will create (100 * 24), or 2400 times fewer Point instances.... put another way, it will reuse Points 2400 times.

Con's

the logic is always a bit more complicated when you add the flexibility of an Iterator

because of the Point re-use, you may have conditions where Point a == Point b whereas in your code no two points are ever identity-equals(==).

Note that you get a lot of duplication of values because you allow overlapping points. This appears to be a requirement of yours. Still, for example, by design, you will get 24 identical results each with the segments: [P(0,0), P(0,0), P(0,0), P(0,0)] If you want to reduce the results to unique solutions only, then it is a relatively trivial adjustment to the way the cursors array is managed.... (relatively).

Initialize objects as soon as you have the arguments. Reuse them through the inner loop. Create the first point as soon as you have x1 and y1.

Make this multi-threaded. This seems like an obvious candidate for a Hadoop map-reduce approach, depending on the inner loop calculations you are doing.

Depending on the context, use mathematics instead. Recall the story about Gauss summing 1+2+3+4+...+100 in a matter of seconds. There may be a far better solution to your problem.

Use a language that is more expressive, and which allows the compiler to optimize your problem. Scala has a Stream concept that would be very useful here, only generating the possibilities when they are used (and dynamically managing memory in the process). Haskell could also help you solve this problem better. If you must write imperative code, try Fortran for efficient management of arrays and memory.

thanks for reply but i didnt get point 1. how will initializing objects soon will be beneficial?
–
anand mahuliJan 15 '14 at 11:22

3

Your inner loop is executed (m*n)ˆ4 times. Once you choose x1 and y1, you should already be able to create object p1=new Point(x1, y1), and keep reusing the same object in the for-loops below. This reduces the number of Points created from (m*n)ˆ4 to m*n.
–
parasietjeJan 15 '14 at 11:35

1

Concerning point 4., I would just like to point out that Java 8 (released after this post), does have Streams now. Its members are also "lazily" evaluated.
–
toto2Jun 5 '14 at 14:18