05-29-2015 10:48 AM - edited 05-29-2015 10:50 AM
I am writing a function that will take an array of xy pairs and find the nearest point, but with two caveats. The two restrictions are:
1) Once a point is chosen, it can't be rechosen (duh or you'd keep going back and forth between two points).
2) The x direction is weighted more than the y direction (i.e. it should move in x before y).
I have implemented this and it works, but for ~15k elements it obviously takes a while -- about 8 seconds.
I can't find any way to optimize further. Any thoughts?
edit: woops, sorry, the y and x are going into real and imaginary, respectively. Forgot to realign those wires.

05-29-2015 11:10 AM
A VI would help.
Soyou're trying to find the nearest neighbour for each of the points in the array or are you traing to traverse the whole array taking each shortest step available. Like a simpler version of the travelling salesman problem?
Shane
05-29-2015 11:12 AM
Do you realise your XYGraph you are building is essentially the same as the shift register on the right-sideof your loop?
05-29-2015 11:34 AM - edited 05-29-2015 11:40 AM
I am sorry, I can't post the code otherwise I would. I can explain what it is doing -- it's actually pretty simple. It gets a starting point, swaps it with index 0, then starts search for the next nearest point, excluding index 0. Then, the second time around it swaps the point we just found with index 1, and starts searching at index 2. After it finds the next nearest point, i swaps i with the point in index 3, and starts searchin at index 3 and so on. That way, used points are placed at the top of the array and I only seach for the nearest point from my counter on down.
Good call about the repeated array. Before I was using delete from array, which I knew was inefficient but it was just to see if the concept would work. Then I started refacoring. That building of an array is left over from before but I ddn't even notice. Thanks for point that out.
Edit: didn't notice your traveling salesman reference. We are really looking more for neighbor, but trying to account for the case where they are not exactly on the same vertical plane. So, we can't just hold Y constant and look for all points with the same Y, then move on to the next Y. Traveling salesman assumes a constant rate of movement I assume, whereas we are limited by certain directions being faster than others.
Edit2: I'm not opposed to using a traveling salesman type solution and seeing where that gets us.
05-29-2015 12:19 PM - edited 05-29-2015 12:35 PM
Select your Point - subtract the remaining array of clusters from the deleted cluster, Convert to polar. find min Rho,rinse repeat til you run out of points
which is pretty much what I see you doing except for actually deleting the point of interest and wiring it to a indexing tunnel. at 15K points that IPE is eating your lunch with the 2010 compiler or later
05-29-2015 12:33 PM - edited 05-29-2015 12:33 PM
This code runs in 1 or 2 seconds with 15k points, I'm not sure if I perfectly understood what you need to do though.
What do you think?
05-29-2015 12:47 PM
Well I realize it doesn't make much sense to index the initial array. My code doesn't work for sure but I just hope one or two elements will give you ideas to improve your code.
05-29-2015 01:53 PM - edited 05-29-2015 03:08 PM
I'll try a few things....
05-29-2015 02:00 PM
If you can post a VI (in LabVIEW 2012 or earlier) with sample data and expected results, I'll try to find time to play with algorithms.
Here are some things I would play with, although I don't know without testing whether they'll help:
- move the subtract inside the case structure (inside the for loop) from outside the for loop, so that you only have to allocate one new cluster element rather than a new array as the result of the subtraction.
- instead of rearranging the existing array, allocate a new one of the correct size (you can probably do this with auto-indexing the output). Mark the used elements of the original array by changing their data (for example set the coordinates to NaN).
- If you stick with the current approach of rearranging elements, use "array subset" to skip all the already-processed points.
05-29-2015 03:24 PM
Thanks guys. We may also try "Binning" x and having some sort of buffer. At that point we can call X values that are sufficiently close on the same plane and sort, then go from there. Just a thought.