//Knn based public static LightWeightGraph GetKNNGraph(DistanceMatrix distances, int numNeighbors) { int numNodes = distances.Count; var nodes = new LightWeightNode[numNodes]; List <int>[] edgeLists = new List <int> [numNodes]; List <double>[] edgeWeights = new List <double> [numNodes]; for (int i = 0; i < numNodes; i++) { edgeLists[i] = new List <int>(); edgeWeights[i] = new List <double>(); } //prevent redundant edges HashSet <Tuple <int, int> > addedEdges = new HashSet <Tuple <int, int> >(); //Our comparator MinHeapPriorityQueue <Tuple <int, double> > .isGreaterThan comp = new MinHeapPriorityQueue <Tuple <int, double> > .isGreaterThan((x, y) => { return(x.Item2 > y.Item2); }); //Add Edges for (int i = 0; i < numNodes; i++) { //get list of edges List <Tuple <int, double> > edges = new List <Tuple <int, double> >(); for (int j = 0; j < numNodes; j++) { //Make sure we don't load our heap with repeated edges if (i != j) { edges.Add(new Tuple <int, double>(j, distances[i, j])); } } //Build the heap MinHeapPriorityQueue <Tuple <int, double> > heap = new MinHeapPriorityQueue <Tuple <int, double> >(comp); heap.addAll(edges); //Now add all of the neighbors for (int edgeNum = 0; edgeNum < numNeighbors; edgeNum++) { if (heap.isEmpty()) { break; } Tuple <int, double> e = heap.extractMin(); Tuple <int, int> edgeNodePair = (e.Item1 < i) ? new Tuple <int, int>(e.Item1, i) : new Tuple <int, int>(i, e.Item1); //if (!addedEdges.Contains(edgeNodePair)) if (!addedEdges.Contains(edgeNodePair)) { //make sure we don't add this edge again in the future //addedEdges.Add(edgeNodePair); addedEdges.Add(edgeNodePair); //Add the double edge now edgeLists[i].Add(e.Item1); edgeLists[e.Item1].Add(i); edgeWeights[i].Add((double)e.Item2); edgeWeights[e.Item1].Add((double)e.Item2); } } } for (int i = 0; i < numNodes; i++) { nodes[i] = new LightWeightNode(i, true, edgeLists[i], edgeWeights[i]); } return(new LightWeightGraph(nodes, true)); }
public LightWeightGraph GetLOOGraph(DistanceMatrix distances, int numNeighbors, bool[] exclusion = null, int numToLeaveOut = 0) { int numNodes = distances.Count; var nodes = new LightWeightGraph.LightWeightNode[numNodes]; List <int>[] edgeLists = new List <int> [numNodes]; List <double>[] edgeWeights = new List <double> [numNodes]; for (int i = 0; i < numNodes; i++) { edgeLists[i] = new List <int>(); edgeWeights[i] = new List <double>(); } //prevent redundant edges HashSet <Tuple <int, int> > addedEdges = new HashSet <Tuple <int, int> >(); //Our comparator MinHeapPriorityQueue <Tuple <int, double> > .isGreaterThan comp = ((x, y) => x.Item2 > y.Item2); //Deal with _skipLast Choice int lastNeighbor = (_skipLast) ? numNodes - 1 : numNodes; //Add Edges for (int i = 0; i < lastNeighbor; i++) { if (exclusion != null && exclusion[i]) { continue; } // Deal with the leave one out double probability = (double)numToLeaveOut / numNodes; double rollDie = rnd.NextDouble(); if (rollDie < probability) { //Console.WriteLine("Skipped Node " + i); _numLeftOut++; continue; } //get list of edges List <Tuple <int, double> > edges = new List <Tuple <int, double> >(); for (int j = 0; j < numNodes; j++) { //Make sure we don't load our heap with repeated edges if (i != j) { edges.Add(new Tuple <int, double>(j, distances[i, j])); } } //Build the heap MinHeapPriorityQueue <Tuple <int, double> > heap = new MinHeapPriorityQueue <Tuple <int, double> >(comp); heap.addAll(edges); //Now add all of the neighbors for (int edgeNum = 0; edgeNum < numNeighbors; edgeNum++) { if (heap.isEmpty()) { break; } Tuple <int, double> e = heap.extractMin(); Tuple <int, int> edgeNodePair = (e.Item1 < i) ? new Tuple <int, int>(e.Item1, i) : new Tuple <int, int>(i, e.Item1); //if (!addedEdges.Contains(edgeNodePair)) if (!addedEdges.Contains(edgeNodePair)) { //make sure we don't add this edge again in the future //addedEdges.Add(edgeNodePair); addedEdges.Add(edgeNodePair); //Add the double edge now edgeLists[i].Add(e.Item1); edgeLists[e.Item1].Add(i); edgeWeights[i].Add((double)e.Item2); edgeWeights[e.Item1].Add((double)e.Item2); } } } for (int i = 0; i < numNodes; i++) { nodes[i] = new LightWeightGraph.LightWeightNode(i, true, edgeLists[i], edgeWeights[i]); } return(new LightWeightGraph(nodes, true)); }