public List <GraphNode> GetNearestNeighbours(List <float[]> input) { // Assign each point in the input data to the nearest node in // the graph. Return the list of the nearest node instances, and // the list of distances. List <GraphNode> nodes = new List <GraphNode>(); List <double> distances = new List <double>(); foreach (float[] pos in input) { NNResult nnresult = this.g.GetNearestNodes(pos); nodes.Add(nnresult.nearestNeighbour0); distances.Add(nnresult.distance0); } return(nodes); }
public NNResult GetNearestNodes(float[] sample) { DataTable dt = GetDataTable(); double[,] results = NearestNeighbour.GetTwoNearestNeighbours(metric, numThreads, this.insertNodeCount, dt.NumDimensions, sample, dt.GetData()); int first_index = (int)results[0, 1]; int second_index = (int)results[1, 1]; NNResult nnresult = new NNResult(); nnresult.nearestNeighbour0 = (GraphNode)dt.GetDataObject(first_index); nnresult.distance0 = results[0, 0]; nnresult.index0 = first_index; nnresult.nearestNeightbour1 = (GraphNode)dt.GetDataObject(second_index); nnresult.distance1 = results[1, 0]; nnresult.index1 = second_index; return(nnresult); }
public void train(List <float[]> input) { checkInput(input); if (this.graph.GetNodeCount() == 0) { // if missing, generate two initial nodes at random // assuming that the input data has zero mean and unit variance, // choose the random position according to a gaussian distribution // with zero mean and unit variance //InitialiseGraph(); GraphNode g1 = graph.AddNode(input[0], tlen); GraphNode g2 = graph.AddNode(input[1], tlen); //graph.addEdge(g1, g2); } foreach (float[] sample in input) { this.tlen++; // step 2 - find the nearest nodes // dists are the squared distances of sample from the 2 nn NNResult nnresult = this.graph.GetNearestNodes(sample); GraphNode n0 = nnresult.nearestNeighbour0; GraphNode n1 = nnresult.nearestNeightbour1; // step 3 increase age of the emanating edges foreach (GraphEdge e in n0.getEdges()) { e.incAge(); } double n0CumError = getCumError(n0); if (this.metric == 1) { n0CumError += Math.Sqrt(nnresult.distance0); // do the sqrt here instead of the nn call } //n0CumError += nnresult.distance0; // Fritzke says add the SQUARED distance ......do the sqrt here instead of the nn call else { n0CumError += Math.Abs(nnresult.distance0); // cosine } setCumError(n0, n0CumError); // step 5 - move nearest node and neighbours this.moveNode(n0, sample, this.eps_b); List <GraphNode> neighbours = n0.getNeighbours(); foreach (GraphNode n in neighbours) { moveNode(n, sample, this.eps_n); } // step 6 update n0<->n1 edge if (neighbours.Contains(n1)) { // should only be one edge List <GraphEdge> edges = n0.getEdges(n1); edges[0].Age = 0; } else { "Adding edge {0} id0: {1} id1: {2} ".Cout(this.tlen, nnresult.index0, nnresult.index1); this.graph.addEdge(n0, n1); } // step 7 this.removeOldEdges(n0.getEdges()); // step 8 - add a new node each lambda steps if (this.tlen % this.lambda == 0 && graph.GetNodeCount() < this.max_nodes) { foreach (GraphNode zn in this.graph.getNodes()) { float[] pos = this.graph.GetNodePosition(zn); double cumError = zn.getCumError(tlen, this.d); //Console.WriteLine("{4} [{0},{1},{2}] {3}", pos[0], pos[1], pos[2], cumError, tlen); } //if (tlen > 2000) // Console.WriteLine("stop"); this.insertNewNode(); } if (this.tlen % 10000 == 1) { Console.WriteLine("Number of Nodes: {0}, Number of edges: {1}", this.graph.GetNodeCount(), this.graph.GetEdgeCount()); } // step 9 - no step 9 } "tlen:{0} insert_node_count: {1} removed_node_count: {2}".Cout(this.tlen, this.graph.InsertNodeCount, this.graph.RemovedNodeCount); Console.WriteLine("Number of Nodes: {0}, Number of edges: {1}", this.graph.GetNodeCount(), this.graph.GetEdgeCount()); }