//Threshold based public static LightWeightGraph GetGeometricGraph(DistanceMatrix distances, double threshold) { //construct the geo graph int numNodes = distances.Count; var nodes = new LightWeightNode[numNodes]; List <int>[] edges = new List <int> [numNodes]; List <double>[] weights = new List <double> [numNodes]; for (int i = 0; i < numNodes; i++) { edges[i] = new List <int>(); } //Add Edges for (int i = 0; i < numNodes - 1; i++) { for (int j = i + 1; j < numNodes; j++) { if (distances[i, j] <= threshold) { edges[i].Add(j); edges[j].Add(i); } } } for (int i = 0; i < numNodes; i++) { nodes[i] = new LightWeightNode(i, true, edges[i], weights[i]); } return(new LightWeightGraph(nodes, true)); }
public LightWeightGraph() { Nodes = new LightWeightNode[1]; NumNodes = 1; Nodes[0] = new LightWeightNode(0, false, new List <int>()); IsWeighted = false; }
/// <summary> /// Copy Constructor /// </summary> /// <param name="n">LightWeightNode to copy</param> public LightWeightNode(LightWeightNode n) { Id = n.Id; Label = n.Label; Edge = (int[])n.Edge.Clone(); EdgeWeights = (double[])n.EdgeWeights.Clone(); //NodeWeight = n.NodeWeight; Count = n.Count; }
public static LWGWithNodeDescriptors GetGraphFromNetFile(String file) { using (StreamReader sr = new StreamReader(file)) { String vertCountPattern = "[*]Vertices\\s+(?<vert>\\d+)"; String firstLine = sr.ReadLine(); var match = Regex.Match(firstLine, vertCountPattern, RegexOptions.IgnoreCase); int numVert = int.Parse(match.Groups["vert"].Value); String vertPattern = "\\s+(?<vertid>\\d+)\\s+\"(?<vertName>[^\"]+)\"\\s+(?<x>\\d[.]\\d+)\\s+(?<y>\\d+[.]\\d+)"; NetVertDesciption[] verts = new NetVertDesciption[numVert]; for (int i = 0; i < numVert; i++) { String line = sr.ReadLine(); match = Regex.Match(line, vertPattern, RegexOptions.IgnoreCase); String vertID = match.Groups["vertid"].Value; String vertName = match.Groups["vertName"].Value; String x = match.Groups["x"].Value; String y = match.Groups["y"].Value; verts[i] = (new NetVertDesciption(int.Parse(vertID) - 1, vertName, double.Parse(x), double.Parse(y))); } while (!sr.ReadLine().Contains("*Edges")) { } List <int>[] edges = new List <int> [numVert]; List <double>[] edgeWeights = new List <double> [numVert]; for (int i = 0; i < numVert; i++) { edges[i] = new List <int>(); edgeWeights[i] = new List <double>(); } String edgePattern = "\\s+(?<fIndex>\\d+)\\s+(?<tIndex>\\d+)\\s+(?<dist>\\d[.]\\d+)"; while (!sr.EndOfStream) { String line = sr.ReadLine(); match = Regex.Match(line, edgePattern, RegexOptions.IgnoreCase); int from = int.Parse(match.Groups["fIndex"].Value) - 1; int to = int.Parse(match.Groups["tIndex"].Value) - 1; double dist = double.Parse(match.Groups["dist"].Value); edges[from].Add(to); edgeWeights[from].Add(dist); edges[to].Add(from); edgeWeights[to].Add(dist); } LightWeightNode[] nodes = new LightWeightNode[numVert]; for (int i = 0; i < numVert; i++) { nodes[i] = (new LightWeightNode(i, true, edges[i], edgeWeights[i])); } return(new LWGWithNodeDescriptors(verts, new LightWeightGraph(nodes, true))); } }
/// <summary> /// Make a deep Copy of a Graph /// </summary> /// <param name="g">LightWeightGraph to copy</param> public LightWeightGraph(LightWeightGraph g) : base(DataType.Graph) { NumNodes = g.NumNodes; Nodes = new LightWeightNode[NumNodes]; for (int i = 0; i < NumNodes; i++) { Nodes[i] = new LightWeightNode(g[i]); } IsWeighted = g.IsWeighted; }
//override for the sake of dictionary public override bool Equals(Object obj) { LightWeightNode n = obj as LightWeightNode; if (n == null) { return(false); } return(n.Id == Id); }
public static LightWeightGraph GetGraphFromFile(String file) { DelimitedFile parsedFile = new DelimitedFile(file, false, true); int parsedFileRowCount = parsedFile.Data.Count; //Ensure it has atleast 1 point and lists if it is weighted if (parsedFileRowCount < 2) { throw new InvalidDataException("file"); } String weightString = parsedFile.Data[0][0]; bool isWeighted = true; if (weightString == "unweighted") { isWeighted = false; } else if (weightString != "weighted") { throw new InvalidDataException("Invalid Weight Type"); } //Start parsing the file List <List <NodeWeightPair> > nodes = new List <List <NodeWeightPair> >(); for (int i = 1; i < parsedFileRowCount; i++) { var row = parsedFile.Data[i]; List <NodeWeightPair> nList = new List <NodeWeightPair>(); nodes.Add(nList); int edgeSize = (isWeighted) ? 2 : 1; for (int j = 1; j < row.Length; j += edgeSize) { int from = int.Parse(row[j]); double weight = (isWeighted) ? double.Parse(row[j + 1]) : 1.0f; nList.Add(new NodeWeightPair { Node = from, Weight = weight }); } } //Construct the graph var lwn = new LightWeightNode[nodes.Count]; List <int>[] edges = new List <int> [nodes.Count]; List <double>[] edgeWeights = new List <double> [nodes.Count]; for (int i = 0; i < nodes.Count; i++) { edges[i] = new List <int>(); edgeWeights[i] = new List <double>(); } for (int i = 0; i < lwn.Length; i++) { int count = nodes[i].Count; for (int j = 0; j < count; j++) { var a = nodes[i][j]; edges[i].Add(a.Node); edgeWeights[i].Add(a.Weight); } } for (int i = 0; i < lwn.Length; i++) { lwn[i] = new LightWeightNode(i, true, edges[i], edgeWeights[i]); } return(new LightWeightGraph(lwn, isWeighted)); }
//construct a subgraph using some exclusion rules public LightWeightGraph(LightWeightGraph lwg, bool[] S) : base(DataType.Graph) { int sSize = S.Count(c => c); //Setup our node array to be filled Nodes = new LightWeightNode[lwg.NumNodes - sSize]; NumNodes = Nodes.Length; IsWeighted = lwg.IsWeighted; int nodeID = 0; int[] oldIDToNewID = new int[lwg.NumNodes]; int[] oldLabel = new int[NumNodes]; //Now we need to itterate over each node in lwg for (int v = 0; v < lwg.NumNodes; v++) { if (!S[v]) { oldIDToNewID[v] = nodeID; oldLabel[nodeID] = lwg.Nodes[v].Label; nodeID++; } } List <int>[] edgesList = new List <int> [NumNodes]; List <double>[] edgeWeightList = new List <double> [NumNodes]; for (int i = 0; i < lwg.NumNodes - sSize; i++) { edgesList[i] = new List <int>(); edgeWeightList[i] = new List <double>(); } //now we should add our edges nodeID = 0; for (int v = 0; v < lwg.NumNodes; v++) { if (!S[v]) //if this is not a removed node we should add the edges { var edges = lwg.Nodes[v].Edge; var edgeWeights = lwg.Nodes[v].EdgeWeights; //Go through all of the edges and only add those not removed for (int u = 0; u < lwg.Nodes[v].Count; u++) { int edgeTo = edges[u]; if (!S[edgeTo]) //this edge is still valid so we should add it { edgesList[nodeID].Add(oldIDToNewID[edgeTo]); if (lwg.IsWeighted) { edgeWeightList[nodeID].Add(edgeWeights[u]); } } } nodeID++; } } for (int i = 0; i < NumNodes; i++) { Nodes[i] = new LightWeightNode(i, oldLabel[i], lwg.IsWeighted, edgesList[i], (IsWeighted) ? edgeWeightList[i] : null); } }
//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)); }