public void TestEmptyPQ() { var emptyHeap = new MinHeapPriorityQueue <int>(); int[] values = new int[] { 0, 1, 2, -10, 100 }; foreach (int n in values) { bool result = emptyHeap.Contains(n); Console.WriteLine($"Check if pq = {emptyHeap.ToString()} Contains {n}?: {result}"); Assert.False(result); } }
public void TestIntMinPQ() { var heap = new MinHeapPriorityQueue <int>(); int[] values = new int[] { 9, 33, 8, -3, 49, 72, 24, 15, 0, 1, 10, 40 }; foreach (int n in values) { heap.Add(n); Console.WriteLine($"After adding {n}: pq = {heap.ToString()}, size = {heap.Count}"); } Assert.Equal("[-3, 0, 9, 8, 1, 40, 24, 33, 15, 49, 10, 72]", heap.ToString()); Assert.Equal(12, heap.Count); foreach (int n in values) { bool result = heap.Contains(n); Console.WriteLine($"Check if pq = {heap.ToString()} Contains {n} ?: {result}"); Assert.True(result); } for (int i = 0; i < 5; i++) { int removed = heap.Remove(); bool result = heap.Contains(removed); Console.WriteLine($"After removing min element {removed}: pq = {heap.ToString()}, Contains {removed}?: {result}"); Assert.False(result); } Assert.Equal("[10, 15, 24, 33, 49, 40, 72]", heap.ToString()); int[] needToRemove = new int[] { 15, 0, 15, -3, 40 }; foreach (int n in needToRemove) { bool result = heap.Remove(n); Console.WriteLine($"After removing element {n}: pq = {heap.ToString()}, successfully ?: {result}"); } heap.Clear(); Console.WriteLine($"After Clear pq = {heap.ToString()}"); Assert.Equal("[]", heap.ToString()); Assert.True(heap.IsEmpty()); }
//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)); }
//Stacked MST public static LightWeightGraph GetStackedMST(DistanceMatrix distances, int numMSTs) { int numNodes = distances.Count; //in a complete graph, there are n*(n-1)/2 edges //an MST contains n-1 edges //number of msts is n/2 if (numMSTs > numNodes / 2) { numMSTs = numNodes / 2; } LightWeightNode[] nodes = new LightWeightNode[numNodes]; List <int>[] edges = new List <int> [numNodes]; List <double>[] weights = new List <double> [numNodes]; //List<double>[] edgeWeights = new List<double>[numNodes]; for (int i = 0; i < numNodes; i++) { edges[i] = new List <int>(); weights[i] = new List <double>(); } //Add all of the distances to the Heap List <distXY> points = new List <distXY>(); for (int x = 0; x < numNodes - 1; x++) { for (int y = x + 1; y < numNodes; y++) { points.Add(new distXY(x, y, distances[x, y])); } } //Now we need to start making our MST for (int n = 0; n < numMSTs; n++) { MinHeapPriorityQueue <distXY> minheap = new MinHeapPriorityQueue <distXY>(((x, y) => x.Dist > y.Dist)); minheap.addAll(points); DisjointSet ds = new DisjointSet(numNodes); int k = 0; while (k < numNodes - 1) { distXY e = minheap.extractMin(); if (ds.diff(e.X, e.Y)) //different { ds.union(e.X, e.Y); //change the dist e.Dist = double.MaxValue; //Add it edges[e.X].Add(e.Y); edges[e.Y].Add(e.X); weights[e.X].Add(distances[e.X, e.Y]); weights[e.Y].Add(distances[e.X, e.Y]); k++; } } } for (int i = 0; i < numNodes; i++) { nodes[i] = new LightWeightNode(i, true, edges[i], weights[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)); }