Пример #1
0
 internal static PropertyGraphModel SortGraph(PropertyGraphModel graph)
 {
     graph.CreateLinks();
     if (graph.Vertices != null)
     {
         graph.Vertices = graph.Vertices.OrderBy(v => v.Id).ToList();
     }
     if (graph.Edges != null)
     {
         graph.Edges = graph.Edges.OrderBy(e => new Tuple <Guid, Guid, string>(e.SourceVertex.Id, e.TargetVertex.Id, e.Name)).ToList();
     }
     if (graph.Vertices != null)
     {
         foreach (var vertex in graph.Vertices)
         {
             vertex.Props = vertex.Props != null ? new SortedDictionary <string, object>(vertex.Props) : new SortedDictionary <string, object>();
             vertex.Edges = new List <PropertyEdgeModel>();
         }
     }
     if (graph.Edges != null && graph.Vertices != null)
     {
         foreach (var edge in graph.Edges)
         {
             edge.Source = graph.Vertices.IndexOf(edge.SourceVertex);
             edge.Target = graph.Vertices.IndexOf(edge.TargetVertex);
             edge.SourceVertex.Edges.Add(edge);
             edge.SourceVertex.Edges.Add(edge);
             edge.Props = edge.Props != null ? new SortedDictionary <string, object>(edge.Props) : new SortedDictionary <string, object>();
         }
     }
     return(graph);
 }
Пример #2
0
        public PropertyGraphModel Calculate(PropertyGraphModel graph)
        {
            if (graph?.Vertices == null)
            {
                return(graph);
            }

            var counter = new int[graph.Vertices.Count];

            if (graph.Edges != null)
            {
                foreach (var edge in graph.Edges)
                {
                    if (Expression == null || Expression.Evaluate(null, edge))
                    {
                        counter[edge.Source]++;
                    }
                }
            }

            for (int i = 0; i < graph.Vertices.Count; i++)
            {
                graph.Vertices[i].Props["out_degree"] = counter[i];
            }
            return(graph);
        }
Пример #3
0
        public async Task ShouldReturnVerticesWithPropsAndIgnoreRedundantSchema()
        {
            _repo.Db.VertexProperties.Add(new VertexProperty()
            {
                VertexId  = _fake.AdminVertex.Id,
                Created   = _fake.Clock.TimeStamp,
                Id        = Guid.NewGuid(),
                JsonValue = "\"Jan\"",
                SchemaUri = "first_name"
            });

            _repo.Db.SaveChanges();

            _graphSchema.VertexSchema.Add(new GraphProfileSectionModel()
            {
                Name        = "Wizytowka",
                Uri         = "wizytowka",
                PropsSchema = new List <GraphPropertySchemaModel>()
                {
                    new GraphPropertySchemaModel()
                    {
                        Name = "First name",
                        Uri  = "first_name"
                    },
                    new GraphPropertySchemaModel()
                    {
                        Name = "Last name",
                        Uri  = "last_name"
                    }
                }
            });

            var query = new InternalGraphQuery()
            {
                NetworkId = _fake.Network.Id,
            };
            var result = await _handler.Execute(query);

            var expected = new PropertyGraphModel()
            {
                Vertices = new List <PropertyVertexModel>()
                {
                    new PropertyVertexModel()
                    {
                        Id    = _fake.AdminVertex.Id,
                        Props = new Dictionary <string, object>()
                        {
                            { "First name", "Jan" }
                        }
                    },
                    new PropertyVertexModel()
                    {
                        Id = _fake.OtherVertex.Id
                    },
                },
                Edges = new List <PropertyEdgeModel>()
            };

            PropertyGraphAssertions.AssertGraphsEqual(expected, result.Snapshot());
        }
Пример #4
0
        public PropertyGraphModel Transform(PropertyGraphModel graph)
        {
            var result = graph;

            if (WhereClause != null)
            {
                result = WhereClause.Transform(result);
            }

            if (CalculateClause != null)
            {
                result = CalculateClause.Transform(result);
            }

            if (SelectPropsClause != null)
            {
                result = SelectPropsClause.Transform(result);
            }

            if (GroupByClause != null)
            {
                result = GroupByClause.Transform(result);
            }

            if (LayoutClause != null)
            {
                result = LayoutClause.Transform(result);
            }

            result.ClearIfEmpty();

            return(result);
        }
Пример #5
0
        public async Task ShouldReturnEmptyVertices()
        {
            var query = new InternalGraphQuery()
            {
                NetworkId = _fake.Network.Id,
            };
            var result = await _handler.Execute(query);

            var expected = new PropertyGraphModel()
            {
                Vertices = new List <PropertyVertexModel>()
                {
                    new PropertyVertexModel()
                    {
                        Id = _fake.AdminVertex.Id
                    },
                    new PropertyVertexModel()
                    {
                        Id = _fake.OtherVertex.Id
                    },
                },
                Edges = new List <PropertyEdgeModel>()
            };

            PropertyGraphAssertions.AssertGraphsEqual(expected, result.Snapshot());
        }
Пример #6
0
 public PropertyGraphModel Transform(PropertyGraphModel graph)
 {
     foreach (var metric in Metrics)
     {
         graph = metric.Calculate(graph);
     }
     return(graph);
 }
Пример #7
0
        internal static void AssertGraphsEqual(PropertyGraphModel expected, PropertyGraphModel actual)
        {
            var left  = (JObject)JsonConvert.DeserializeObject(JsonConvention.SerializeObject(SortGraph(expected)));
            var right = (JObject)JsonConvert.DeserializeObject(JsonConvention.SerializeObject(SortGraph(actual)));

            Sort(left); Sort(right);
            Assert.AreEqual(left.ToString(Formatting.None), right.ToString(Formatting.None));
            //Assert.AreEqual(JsonConvention.SerializeObject(SortGraph(expected)), JsonConvention.SerializeObject(SortGraph(actual)));
        }
Пример #8
0
 public PropertyGraphModel Calculate(PropertyGraphModel graph)
 {
     using (var engine = new V8ScriptEngine())
     {
         engine.AddHostObject("graph", graph);
         engine.Execute(Script);
         return(engine.Script.graph);
     }
 }
Пример #9
0
        public async Task ShouldSkipEdgesOutsideSchema()
        {
            var edge = new Edge()
            {
                Id             = Guid.NewGuid(),
                SourceVertexId = _fake.AdminVertex.Id,
                TargetVertexId = _fake.OtherVertex.Id,
                Created        = DateTime.Now,
                SchemaUri      = "wiedza"
            };

            _repo.Db.Edges.Add(edge);

            _repo.Db.SaveChanges();

            _graphSchema.EdgeSchema.Add(new GraphRelationshipSchemaModel()
            {
                Name        = "Współpraca",
                Uri         = "wspolpraca",
                PropsSchema = new List <GraphPropertySchemaModel>()
                {
                    new GraphPropertySchemaModel()
                    {
                        Name = "Value",
                        Uri  = "wspolpraca/value"
                    }
                }
            });
            var query = new InternalGraphQuery()
            {
                NetworkId = _fake.Network.Id,
            };
            var result = await _handler.Execute(query);

            var expected = new PropertyGraphModel()
            {
                Vertices = new List <PropertyVertexModel>()
                {
                    new PropertyVertexModel()
                    {
                        Id = _fake.AdminVertex.Id
                    },
                    new PropertyVertexModel()
                    {
                        Id = _fake.OtherVertex.Id
                    },
                },
                Edges = new List <PropertyEdgeModel>()
            };

            PropertyGraphAssertions.AssertGraphsEqual(expected, result.Snapshot());
        }
Пример #10
0
        public PropertyGraphModel Calculate(PropertyGraphModel graph)
        {
            if (graph?.Vertices == null)
            {
                return(graph);
            }

            var counter = new int[graph.Vertices.Count];

            if (graph.Edges != null)
            {
                foreach (var edge in graph.Edges)
                {
                    if (Expression == null || Expression.Evaluate(null, edge))
                    {
                        counter[edge.Target]++;
                    }
                }
            }

            if (Normalized)
            {
                var max = counter.Max();
                for (int i = 0; i < graph.Vertices.Count; i++)
                {
                    graph.Vertices[i].Props["in_degree"] = (double)counter[i] / (double)max;
                }
            }
            else
            {
                for (int i = 0; i < graph.Vertices.Count; i++)
                {
                    graph.Vertices[i].Props["in_degree"] = counter[i];
                }
            }
            return(graph);
        }
Пример #11
0
        public PropertyGraphModel Transform(PropertyGraphModel graph)
        {
            // no vertices to filter
            if (graph.Vertices == null)
            {
                return(graph);
            }

            var edges = new List <PropertyEdgeModel>();

            // evaluate each vertex
            var vertices = graph.Vertices
                           .Where(vertex => Expression.Evaluate(vertex, null))
                           .ToList();

            // index new set of vertices
            var vertexIndexer = new Dictionary <Guid, int>();

            for (var i = 0; i < vertices.Count; i++)
            {
                vertexIndexer.Add(vertices[i].Id, i);
            }

            // add all edges that have both ends in vertices list
            foreach (var vertex in vertices)
            {
                if (vertex.Edges == null)
                {
                    continue;
                }

                var newVertexEdges = new List <PropertyEdgeModel>();
                foreach (var edge in vertex.Edges)
                {
                    if (edge.SourceVertex.Id != vertex.Id)
                    {
                        continue;
                    }

                    int sourceIndex;
                    int targetIndex;
                    if (vertexIndexer.TryGetValue(edge.SourceVertex.Id, out sourceIndex) &&
                        vertexIndexer.TryGetValue(edge.TargetVertex.Id, out targetIndex))
                    {
                        var newEdge = new PropertyEdgeModel()
                        {
                            SourceVertex = edge.SourceVertex,
                            TargetVertex = edge.TargetVertex,
                            Source       = sourceIndex,
                            Target       = targetIndex,
                            Name         = edge.Name,
                            Props        = edge.Props
                        };
                        edges.Add(newEdge);
                        newVertexEdges.Add(newEdge);
                    }
                }
                vertex.Edges = newVertexEdges;
            }

            var result = new PropertyGraphModel()
            {
                Vertices = vertices,
                Edges    = edges,
                Data     = graph.Data
            };

            result.CreateLinks();
            return(result);
        }
Пример #12
0
        public PropertyGraphModel Transform(PropertyGraphModel graph)
        {
            // calculate groups and memberships
            var groupKeyToIndexSet = new Dictionary <object, HashSet <int> >();  // groupKey to vertex index set
            var lpToGroupKeySet    = new Dictionary <int, HashSet <object> >();

            for (int index = 0; index < graph.Vertices.Count; index++)
            {
                var vertex        = graph.Vertices[index];
                var groupKeyArray = GroupKeyArray(vertex);
                if (groupKeyArray == null)
                {
                    continue;
                }

                foreach (var key in groupKeyArray)
                {
                    if (key == null)
                    {
                        continue;
                    }
                    if (!groupKeyToIndexSet.ContainsKey(key))
                    {
                        groupKeyToIndexSet[key] = new HashSet <int>();
                    }
                    groupKeyToIndexSet[key].Add(index);
                    if (!lpToGroupKeySet.ContainsKey(index))
                    {
                        lpToGroupKeySet[index] = new HashSet <object>();
                    }
                    lpToGroupKeySet[index].Add(key);
                }
            }

            // transform groups to vertices
            var groupVertices        = new List <PropertyVertexModel>();
            var groupKeyToGroupIndex = new Dictionary <object, int>();
            var i = 0;

            foreach (var group in groupKeyToIndexSet)
            {
                groupVertices.Add(new PropertyVertexModel()
                {
                    Id    = new Guid(i, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
                    Props = new Dictionary <string, object>()
                    {
                        { "label", group.Key },
                        { "size", group.Value.Count },
                        { "members", group.Value }
                    }
                });
                groupKeyToGroupIndex[group.Key] = i;
                i++;
            }

            // transform edges
            List <PropertyEdgeModel> groupEdgesList = null;

            if (graph.Edges != null)
            {
                var groupEdges = new Dictionary <Tuple <int, int, string>, PropertyEdgeModel>();
                foreach (var edge in graph.Edges)
                {
                    if (!lpToGroupKeySet.ContainsKey(edge.Source))
                    {
                        continue;
                    }
                    if (!lpToGroupKeySet.ContainsKey(edge.Target))
                    {
                        continue;
                    }

                    var sourceGroupSet = lpToGroupKeySet[edge.Source];
                    var targetGroupSet = lpToGroupKeySet[edge.Target];

                    foreach (var sourceGroup in sourceGroupSet)
                    {
                        var source = groupKeyToGroupIndex[sourceGroup];
                        foreach (var targetGroup in targetGroupSet)
                        {
                            var target = groupKeyToGroupIndex[targetGroup];

                            var name = edge.Name;
                            var key  = new Tuple <int, int, string>(source, target, name);
                            if (!groupEdges.ContainsKey(key))
                            {
                                groupEdges[key] = new PropertyEdgeModel()
                                {
                                    Name         = name,
                                    Source       = source,
                                    Target       = target,
                                    SourceVertex = groupVertices[source],
                                    TargetVertex = groupVertices[target],
                                    Props        = new Dictionary <string, object>()
                                    {
                                        { "size", 0 },
                                        { "connectors", new Dictionary <int, HashSet <int> >() } // member index => other members set
                                    }
                                };
                            }
                            groupEdges[key].Props["size"] = (int)groupEdges[key].Props["size"] + 1;
                            var connectors = groupEdges[key].Props["connectors"] as Dictionary <int, HashSet <int> >;
                            if (!connectors.ContainsKey(edge.Source))
                            {
                                connectors[edge.Source] = new HashSet <int>()
                                {
                                    edge.Target
                                }
                            }
                            ;
                            else
                            {
                                connectors[edge.Source].Add(edge.Target);
                            }
                        }
                    }
                }

                groupEdgesList = groupEdges.Select(kv => kv.Value).ToList();
            }

            var result = new PropertyGraphModel()
            {
                Vertices = groupVertices,
                Edges    = groupEdgesList
            };

            result.CreateLinks();

            result.Data["grouped_vertices"] = graph.Vertices;

            return(result);
        }
Пример #13
0
        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);
        }
Пример #14
0
        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);
        }
Пример #15
0
        public async Task ShouldExtractNameFromVertexPropsOutsideSchema()
        {
            _repo.Db.VertexProperties.Add(new VertexProperty()
            {
                VertexId  = _fake.AdminVertex.Id,
                Created   = _fake.Clock.TimeStamp,
                Id        = Guid.NewGuid(),
                JsonValue = "\"Jan\"",
                SchemaUri = "first_name"
            });

            _repo.Db.VertexProperties.Add(new VertexProperty()
            {
                VertexId  = _fake.AdminVertex.Id,
                Created   = _fake.Clock.TimeStamp,
                Id        = Guid.NewGuid(),
                JsonValue = "\"Kowalski\"",
                SchemaUri = "Last name"
            });

            _repo.Db.VertexProperties.Add(new VertexProperty()
            {
                VertexId  = _fake.AdminVertex.Id,
                Created   = _fake.Clock.TimeStamp,
                Id        = Guid.NewGuid(),
                JsonValue = "\"Marketing\"",
                SchemaUri = "e8fc9157-c17e-49d8-b62b-1a0c6000955d/Dział"
            });

            _repo.Db.SaveChanges();

            _graphSchema.VertexSchema.Add(new GraphProfileSectionModel()
            {
                Name        = "Wizytowka",
                Uri         = "wizytowka",
                PropsSchema = new List <GraphPropertySchemaModel>()
                {
                    new GraphPropertySchemaModel()
                    {
                        Name = "First name",
                        Uri  = "first_name"
                    }
                }
            });

            var query = new InternalGraphQuery()
            {
                NetworkId = _fake.Network.Id,
            };
            var result = await _handler.Execute(query);

            var expected = new PropertyGraphModel()
            {
                Vertices = new List <PropertyVertexModel>()
                {
                    new PropertyVertexModel()
                    {
                        Id    = _fake.AdminVertex.Id,
                        Props = new Dictionary <string, object>()
                        {
                            { "First name", "Jan" },
                            { "Last name", "Kowalski" },
                            { "Dział", "Marketing" }
                        }
                    },
                    new PropertyVertexModel()
                    {
                        Id = _fake.OtherVertex.Id
                    },
                },
                Edges = new List <PropertyEdgeModel>()
            };

            PropertyGraphAssertions.AssertGraphsEqual(expected, result.Snapshot());
        }
Пример #16
0
 public PropertyGraphModel Transform(PropertyGraphModel result)
 {
     result.Data["layout"] = this;
     return(result);
 }
Пример #17
0
        public async Task ShouldReturnEdgePropsFirstFoundInSchema()
        {
            var edge = new Edge()
            {
                Id             = Guid.NewGuid(),
                SourceVertexId = _fake.AdminVertex.Id,
                TargetVertexId = _fake.OtherVertex.Id,
                Created        = DateTime.Now,
                SchemaUri      = "wspolpraca"
            };

            _repo.Db.Edges.Add(edge);

            _repo.Db.EdgeProperties.Add(new EdgeProperty()
            {
                Id        = Guid.NewGuid(),
                EdgeId    = edge.Id,
                SchemaUri = "survey/wspolpraca/value",
                JsonValue = "5",
                Created   = DateTime.Now,
                Deleted   = null
            });

            _repo.Db.EdgeProperties.Add(new EdgeProperty()
            {
                Id        = Guid.NewGuid(),
                EdgeId    = edge.Id,
                SchemaUri = "connector/wspolpraca/value",
                JsonValue = "0",
                Created   = DateTime.Now,
                Deleted   = null
            });

            _repo.Db.SaveChanges();

            _graphSchema.EdgeSchema.Add(new GraphRelationshipSchemaModel()
            {
                Name        = "Współpraca",
                Uri         = "wspolpraca",
                PropsSchema = new List <GraphPropertySchemaModel>()
                {
                    new GraphPropertySchemaModel()
                    {
                        Name = "Value",
                        Uri  = "survey/wspolpraca/value"
                    },
                    new GraphPropertySchemaModel()
                    {
                        Name = "Value",
                        Uri  = "connector/wspolpraca/value"
                    }
                }
            });
            var query = new InternalGraphQuery()
            {
                NetworkId = _fake.Network.Id,
            };
            var result = await _handler.Execute(query);

            var expected = new PropertyGraphModel()
            {
                Vertices = new List <PropertyVertexModel>()
                {
                    new PropertyVertexModel()
                    {
                        Id = _fake.AdminVertex.Id
                    },
                    new PropertyVertexModel()
                    {
                        Id = _fake.OtherVertex.Id
                    },
                },
                Edges = new List <PropertyEdgeModel>()
                {
                    new PropertyEdgeModel()
                    {
                        Name   = "Współpraca",
                        Source = 0,
                        Target = 1,
                        Props  = new Dictionary <string, object>()
                        {
                            { "Value", 5 }
                        }
                    }
                }
            };

            PropertyGraphAssertions.AssertGraphsEqual(expected, result.Snapshot());

            _graphSchema.EdgeSchema[0].PropsSchema = new List <GraphPropertySchemaModel>()
            {
                new GraphPropertySchemaModel()
                {
                    Name = "Value",
                    Uri  = "connector/wspolpraca/value"
                },
                new GraphPropertySchemaModel()
                {
                    Name = "Value",
                    Uri  = "survey/wspolpraca/value"
                }
            };

            expected.Edges.First().Props = new Dictionary <string, object>()
            {
                { "Value", 0 }
            };
        }
Пример #18
0
        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);
        }
Пример #19
0
        public PropertyGraphModel Transform(PropertyGraphModel graph)
        {
            if (VertexProps.Any(p => p is WildcardProp))
            {
                return(graph);
            }

            if (VertexProps != null && graph.Vertices != null)
            {
                foreach (var vertex in graph.Vertices)
                {
                    var newProps = new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase);
                    foreach (var prop in VertexProps)
                    {
                        newProps[prop.Alias] = prop.Evaluate(vertex);
                    }
                    vertex.Props = newProps;
                }
            }
            var filteredEdges          = new List <PropertyEdgeModel>();
            var wildcardEdgePropFilter = Edges.ContainsKey("*");

            if (graph.Edges != null)
            {
                foreach (var edge in graph.Edges)
                {
                    List <Prop> edgePropsFilter = null;

                    if (!Edges.TryGetValue(edge.Name, out edgePropsFilter))
                    {
                        if (!wildcardEdgePropFilter)
                        {
                            edge.SourceVertex.Edges.Remove(edge);
                            edge.TargetVertex.Edges.Remove(edge);
                            continue;
                        }
                    }

                    if (edgePropsFilter != null)
                    {
                        var newProps = new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase);
                        foreach (var prop in edgePropsFilter)
                        {
                            object value;
                            if (edge.Props.TryGetValue(prop.Name, out value))
                            {
                                newProps.Add(prop.Alias ?? prop.Name, value);
                            }
                            if (prop.Name == "name")
                            {
                                edge.Name = prop.Alias;
                            }
                        }
                        edge.Props = newProps.Count > 0 ? newProps : null;
                    }
                    else if (!wildcardEdgePropFilter)
                    {
                        edge.Props = null;
                    }
                    filteredEdges.Add(edge);
                }
                graph.Edges = filteredEdges;
            }

            return(graph);
        }