private static List <NamedResultValue> ParseResultList(EdgeCondition begin, EdgeCondition end, string input, out string rest) { rest = string.Empty; List <NamedResultValue> list = new List <NamedResultValue>(); int i = 0; if (!begin(input, ref i)) { ParseError("Unexpected opening character", input); return(null); } if (end(input, ref i)) // tuple is empty { rest = input.Substring(i); // eat through the closing brace return(list); } input = input.Substring(i); var item = ParseResult(input, out rest); if (item == null) { ParseError("Result expected", input); return(null); } list.Add(item); input = rest; while (!string.IsNullOrEmpty(input) && input[0] == ',') { item = ParseResult(input.Substring(1), out rest); if (item == null) { ParseError("Result expected", input); return(null); } list.Add(item); input = rest; } i = 0; if (!end(input, ref i)) // tuple is not closed { ParseError("Unexpected list termination", input); rest = string.Empty; return(null); } rest = input.Substring(i); return(list); }
private List <NamedResultValue> ParseResultList(EdgeCondition begin, EdgeCondition end, Span input, out Span rest) { rest = Span.Empty; List <NamedResultValue> list = new List <NamedResultValue>(); int i = input.Start; if (!begin(input, ref i)) { ParseError("Unexpected opening character", input); return(null); } if (end(input, ref i)) // tuple is empty { rest = input.AdvanceTo(i); // eat through the closing brace return(list); } input = input.AdvanceTo(i); var item = ParseResult(input, out rest); if (item == null) { ParseError("Result expected", input); return(null); } list.Add(item); input = rest; while (!input.IsEmpty && _resultString[input.Start] == ',') { item = ParseResult(input.Advance(1), out rest); if (item == null) { ParseError("Result expected", input); return(null); } list.Add(item); input = rest; } i = input.Start; if (!end(input, ref i)) // tuple is not closed { ParseError("Unexpected list termination", input); rest = Span.Empty; return(null); } rest = input.AdvanceTo(i); return(list); }
public PropertyGraphModel Calculate(PropertyGraphModel graph) { if (graph?.Vertices == null || graph.Vertices.Count == 0 || graph?.Edges == null || graph.Edges.Count == 0) { return(graph); } var nodes = graph.Vertices.Count; var stack = new Stack <int>(); var paths = new List <int> [nodes]; for (var v = 0; v < nodes; v++) { paths[v] = new List <int>(); } var distances = new Dictionary <int, double>(); var seen = new Dictionary <int, double>(); var queue = new SimplePriorityQueue <Path, double>(); // start nodes for (var start = 0; start < nodes; start++) { if (StartCondition.Evaluate(graph.Vertices[start], null)) { queue.Enqueue(new Path() { Dist = 0, Start = start, End = start }, 0); seen.Add(start, 0); } } while (queue.Count > 0) { var path = queue.Dequeue(); var dist = path.Dist; var vertex = path.End; if (distances.ContainsKey(vertex)) { continue; // already searched this node } stack.Push(vertex); distances[vertex] = dist; foreach (var edge in graph.Vertices[vertex].Edges) { var target = edge.Target; if (edge.Target == vertex) { if (DirectedGraph) { continue; } else { target = edge.Source; } } if (EdgeCondition != null && !EdgeCondition.Evaluate(null, edge)) { continue; } double weight = 1.0; if (LengthPropIdentifier != null) { weight = Convert.ToDouble(LengthPropIdentifier.Evaluate(null, edge) ?? 1.0); } var edgeDist = distances[vertex] + weight; if (!(distances.ContainsKey(target)) && (!(seen.ContainsKey(target)) || edgeDist < seen[target])) { seen[target] = edgeDist; queue.Enqueue(new Path() { Dist = edgeDist, Start = vertex, End = target }, edgeDist); paths[target] = new List <int>() { vertex }; } else if (Math.Abs(edgeDist - seen[target]) < 0.001) { // handle equal paths paths[target].Add(vertex); } } } for (int i = 0; i < nodes; i++) { double dist; if (distances.TryGetValue(i, out dist)) { if (graph.Vertices[i].Props == null) { graph.Vertices[i].Props = new Dictionary <string, object>(); } graph.Vertices[i].Props["pathLength"] = dist; if (paths[i].Count > 0) { graph.Vertices[i].Props["pathNext"] = paths[i]; } } } return(graph); }
public PropertyGraphModel Calculate(PropertyGraphModel graph) { if (graph?.Vertices == null || graph.Vertices.Count == 0 || graph?.Edges == null || graph.Edges.Count == 0) { return(graph); } var config = new { iterations = 100, tolerance = 0.0001 }; var nodesCount = graph.Vertices.Count; double start = 1.0 / (double)nodesCount; var metric = new double[nodesCount]; for (var n = 0; n < nodesCount; n++) { metric[n] = start; } normalize(metric); for (var iter = 0; iter < config.iterations; iter++) { var v0 = metric; metric = new double[nodesCount]; for (var source = 0; source < metric.Length; source++) { foreach (var edge in graph.Vertices[source].Edges) { if (edge.Target == source) { continue; } if (EdgeCondition != null && !EdgeCondition.Evaluate(null, edge)) { continue; } double weight = 1.0; if (LengthPropIdentifier != null) { weight = Convert.ToDouble(LengthPropIdentifier.Evaluate(null, edge) ?? 1.0); } metric[source] += v0[edge.Target] * weight; } } normalize(metric); double energy = metric.Select((t, n) => Math.Abs(t - v0[n])).Sum(); if (energy < nodesCount * config.tolerance) { // Normalize between 0.0 and 1.0. var max = metric.Max(); for (var id = 0; id < metric.Length; id++) { graph.Vertices[id].Props["eigenvector"] = metric[id] / max; } return(graph); } } // did not converge return(graph); }
public PropertyGraphModel Calculate(PropertyGraphModel graph) { if (graph?.Vertices == null || graph.Vertices.Count == 0 || graph?.Edges == null || graph.Edges.Count == 0) { return(graph); } var config = new { samples = 100 }; var nodes = graph.Vertices.Count; var metric = new double[nodes]; var moduloSample = Convert.ToInt32(Math.Round((double)(graph.Vertices.Count / (double)config.samples))); for (var n = 0; n < nodes; n++) { if (graph.Vertices.Count > config.samples && n % moduloSample != 0) { continue; // sampling: skip some nodes } var start = n; var stack = new Stack <int>(); var paths = new HashSet <int> [nodes]; var sigma = new double[nodes]; for (var v = 0; v < nodes; v++) { paths[v] = new HashSet <int>(); sigma[v] = 0; } var distances = new Dictionary <int, double>(); sigma[start] = 1; var seen = new Dictionary <int, double>() { { start, 0 } }; var queue = new SimplePriorityQueue <Path, double>(); queue.Enqueue(new Path() { Dist = 0, Start = start, End = start }, 0); while (queue.Count > 0) { var path = queue.Dequeue(); var dist = path.Dist; var pred = path.Start; var vertex = path.End; if (distances.ContainsKey(vertex)) { continue; // already searched this node } sigma[vertex] = sigma[vertex] + sigma[pred]; // count paths stack.Push(vertex); distances[vertex] = dist; foreach (var edge in graph.Vertices[vertex].Edges) { if (edge.Target == vertex) { continue; } if (EdgeCondition != null && !EdgeCondition.Evaluate(null, edge)) { continue; } double weight = 1.0; if (LengthPropIdentifier != null) { weight = Convert.ToDouble(LengthPropIdentifier.Evaluate(null, edge) ?? 1.0); } var target = edge.Target; var edgeDist = distances[vertex] + weight; if (!(distances.ContainsKey(target)) && (!(seen.ContainsKey(target)) || edgeDist < seen[target])) { seen[target] = edgeDist; queue.Enqueue(new Path() { Dist = edgeDist, Start = vertex, End = target }, edgeDist); sigma[target] = 0; paths[target] = new HashSet <int>() { vertex }; } else if (Math.Abs(edgeDist - seen[target]) < 0.001) { // handle equal paths sigma[target] += sigma[vertex]; paths[target].Add(vertex); } } } var delta = new double[nodes]; while (stack.Count > 0) { var vertex = stack.Pop(); foreach (var v in paths[vertex]) { delta[v] = delta[v] + (sigma[v] / sigma[vertex]) * (1.0 + delta[vertex]); } if (vertex != start) { metric[vertex] = metric[vertex] + delta[vertex]; } } } var max = metric.Max(); for (int i = 0; i < nodes; i++) { graph.Vertices[i].Props["betweenness"] = metric[i] / max; } return(graph); }
public static T[,] GetCenteredContext <T>(this T[,] input, int size, int sourceX, int sourceY, EdgeCondition edgeCondition, T fillValue) { if (size % 2 == 0) { throw new System.ArgumentException("Size must be odd"); } int offset = (size - 1) / 2; T[,] context = new T[size, size]; int xMin = sourceX - offset; int xMax = xMin + size; int yMin = sourceY - offset; int yMax = yMin + size; int width = input.GetLength(0); int height = input.GetLength(1); for (int x = xMin, x2 = 0; x < xMax; x++, x2++) { for (int y = yMin, y2 = 0; y < yMax; y++, y2++) { if (x < 0 || y < 0 || x >= width || y >= height) { switch (edgeCondition) { case EdgeCondition.Constant: context[x2, y2] = fillValue; break; default: throw new NotImplementedException("Condition " + edgeCondition + " not supported yet"); } } else { context[x2, y2] = input[x, y]; } } } return(context); }
public static T[,] GenericFilter <T>(this bool[,] input, int size, Func <int, int, bool[, ], T> function, EdgeCondition edgeCondition, bool fillValue) { int w = input.GetLength(0); int h = input.GetLength(1); T[,] result; bool centeredContext = true; switch (edgeCondition) { case EdgeCondition.Constant: result = new T[w, h]; break; case EdgeCondition.Valid: w -= (size - 1); h -= (size - 1); result = new T[w, h]; centeredContext = false; break; default: throw new NotImplementedException("Condition " + edgeCondition + " not supported yet"); } for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { result[x, y] = function(x, y, centeredContext ? input.GetCenteredContext(size, x, y, edgeCondition, fillValue) : input.GetNonCenteredContext(size, x, y, edgeCondition)); } } return(result); }
public static bool[,] Dilate(this bool[,] input, Neighbourhood neighbourhood, EdgeCondition edgeCondition) { switch (neighbourhood) { case Neighbourhood.Cross: return(input.GenericFilter(3, CrossDilate, edgeCondition, false)); case Neighbourhood.Eight: return(input.GenericFilter(3, EightDilate, edgeCondition, false)); default: throw new NotImplementedException("Neighbourhood " + neighbourhood + " not implemented as dilation"); } }
public static T[,] GetNonCenteredContext <T>(this T[,] input, int size, int sourceX, int sourceY, EdgeCondition edgeCondition = EdgeCondition.Valid) { T[,] context = new T[size, size]; int xMax = sourceX + size; int yMax = sourceY + size; for (int x = sourceX, x2 = 0; x < xMax; x++, x2++) { for (int y = sourceY, y2 = 0; y < yMax; y++, y2++) { context[x2, y2] = input[x, y]; } } return(context); }