0

I am trying to implement this but I can't find a good paper or description of how to do it, could you guys point me in the right direction please? I do have an implementation of it in C# but I don't know enough to just convert the code to Java.

As per a comment I'm adding some of the C# Code I haven't been able to convert to Java:

//T with the smallest func(t)
      static T MinBy<T, TComparable>(this IEnumerable<T> xs, Func<T, TComparable> func) where TComparable : IComparable<TComparable>{
        return xs.DefaultIfEmpty().Aggregate((maxSoFar, elem) => func(elem).CompareTo(func(maxSoFar)) > 0 ? maxSoFar : elem);
      }

      //returns an ordered set of nearest neighbors
      static IEnumerable<Stop> NearestNeighbors(this IEnumerable<Stop> stops){
        var stopsLeft = stops.ToList();
        for (var stop = stopsLeft.First(); stop != null; stop = stopsLeft.MinBy(s => Stop.Distance(stop, s))){
            stopsLeft.Remove(stop);
            yield return stop;
        }
      }
Tsundoku
  • 9,104
  • 29
  • 93
  • 127
  • Why don't you post the parts you can't convert and we'll see how we can help? :) – Vitaliy Sep 05 '12 at 20:07
  • Also, please add the code that constructs the input into NearestNeighbours. I am adding a partial answer for now, so you will better understand what is written. – Vitaliy Sep 06 '12 at 05:54

1 Answers1

0

I assume you are not familiar with C#. So I will try to explain some of the things in short.

  1. IEnumerable<T> is C#'s equivalent of java's Iterable<T>

  2. Func<T, V> is an abstraction of a method who's input is T and return value is V. C#, unlike Java, supports closures, but they are effectively like java anonymous classes, without all the syntactic fuss around. So basically, the second argument of MinBy is a means to extract the property from T is relevant for comparison. You could easily implement the very same abstraction with an anonymous class, but it will not be as concise.

  3. The strange this modifier that comes before the first argument is saying that this is an extension method. It solely serves a syntactic sugar purpose. When a method is define like this, it means that it can be called on the instance of the first argument (that has the this modifier before it). This allowes you to write code like:

    IEnumerable<String> seq = getS();
    seq.MinBy(/*bla*/);

instead of explicitly specifying the Utility class the static method is defined in:

   MyUtility.MinBy(s, /*bla*/);

You probably do not need this high level of abstraction (and lets face it, java is simply not built for it today) so what you want to do is to define a method instead of MinBy that inputs an Iterable leftStops and another Stop currentStop and finds the closest stop to currentStop from leftStops.

Something like:

Stop findClosest(Stop currentStop, Iterable<Stop> left stops) {/*implement me*/}

That done, lets turn to NearestNeighbors itself. What is that yield return? it is a very powerful way to implelent iterators in .Net. I feel that a full explanation on its workings is beyond the scope of our discussion, so I have rewritten the method not to use this feature in a way that conserves its functionality (and removed the this qualifier of its first argument):

 static IEnumerable<Stop> NearestNeighbors(IEnumerable<Stop> stops){

        IEnumerable<Stop> result = new List<stop>();

        var stopsLeft = stops.ToList();

        for (var stop = stopsLeft.First(); stop != null; stop = stopsLeft.MinBy(s => Stop.Distance(stop, s))){
            stopsLeft.Remove(stop);
            result.Add(stop);
        }
        return result;
      }

So we are left with the following algorithm:

  1. Input a list of Stops
  2. next-stop = first-stop
  3. Remove next-stop from the Stop list
  4. Find the closest stop to next-stop and set next-stop=closest
  5. if there are more stops, go to 3
  6. Return the stops in the order they were visited.

Hopefully it is clearer now.

Vitaliy
  • 8,044
  • 7
  • 38
  • 66