Beispiel #1
0
        private static void CollectAdjacentVerticesRecursive <TVertex, TEdge>(IBidirectionalGraph <TVertex, TEdge> graph,
                                                                              TVertex vertex, EdgeDirection direction, ICollection <TVertex> collectedVertices,
                                                                              EdgePredicate <TVertex, TEdge> edgePredicate = null, bool recursive = false)
            where TEdge : IEdge <TVertex>
        {
            var adjacentEdges = direction == EdgeDirection.In
                ? graph.InEdges(vertex)
                : graph.OutEdges(vertex);

            var adjacentVertices = adjacentEdges
                                   .Where(edge => edgePredicate == null || edgePredicate(edge))
                                   .Select(edge => edge.GetOtherEnd(vertex))
                                   .Distinct();

            foreach (var adjacentVertex in adjacentVertices)
            {
                // Loop detection
                if (collectedVertices.Contains(adjacentVertex))
                {
                    continue;
                }

                collectedVertices.Add(adjacentVertex);

                if (recursive)
                {
                    CollectAdjacentVerticesRecursive(graph, adjacentVertex, direction, collectedVertices, edgePredicate, recursive: true);
                }
            }
        }
        protected static IMutableBidirectionalGraph <T, IEdge <T> > GetSubGraphFrom(IBidirectionalGraph <T, IEdge <T> > graph, T source)
        {
            var result = new BidirectionalGraph <T, IEdge <T> >();

            var visited = new HashSet <T>(new IdentityComparer <T>());
            var toVisit = new Queue <T>();

            toVisit.Enqueue(source);

            while (toVisit.Count > 0)
            {
                var node = toVisit.Dequeue();

                var outEdges = graph.OutEdges(node);
                visited.Add(node);
                result.AddVertex(node);

                foreach (var outEdge in outEdges)
                {
                    if (!visited.Contains(outEdge.Target))
                    {
                        toVisit.Enqueue(outEdge.Target);
                    }
                    result.AddVerticesAndEdge(outEdge);
                }
            }

            return(result);
        }
Beispiel #3
0
 /// <summary>
 /// Returns with the adjacent vertices of the <code>vertex</code>.
 /// </summary>
 /// <param name="g">The graph.</param>
 /// <param name="vertex">The vertex which neighbours' we want to get.</param>
 /// <returns>List of the adjacent vertices of the <code>vertex</code>.</returns>
 public static IEnumerable <TVertex> GetNeighbours <TVertex, TEdge>(this IBidirectionalGraph <TVertex, TEdge> g, TVertex vertex)
     where TEdge : IEdge <TVertex>
 {
     return(((from e in g.InEdges(vertex) select e.Source)
             .Concat(
                 (from e in g.OutEdges(vertex) select e.Target))).Distinct());
 }
Beispiel #4
0
 public IEnumerable <IAction> GetNextActions(IAction action)
 {
     if (action == null)
     {
         throw new ArgumentNullException("action");
     }
     return(_graph.OutEdges(action).Select(x => x.Target));
 }
 public static IEnumerable <T> GetAllDataObjects <T>(this IBidirectionalGraph <Cluster <T>, ClusterEdge <T> > tree, Cluster <T> cluster)
 {
     if (tree.IsOutEdgesEmpty(cluster))
     {
         return(cluster.DataObjects);
     }
     return(tree.OutEdges(cluster).Aggregate((IEnumerable <T>)cluster.DataObjects, (res, edge) => res.Concat(tree.GetAllDataObjects(edge.Target))));
 }
Beispiel #6
0
 public static IEnumerable <TEdge> GetEdges <TVertex, TEdge>(
     this IBidirectionalGraph <TVertex, TEdge> graph, TVertex vertex, EdgeDirection edgeDirection)
     where TEdge : IEdge <TVertex>
 {
     return(edgeDirection == EdgeDirection.In
         ? graph.InEdges(vertex)
         : graph.OutEdges(vertex));
 }
Beispiel #7
0
 private IEnumerable <IVertex3D> getConnectedVertices(IVertex3D vertex3D)
 {
     return(graph.OutEdges((TVertex)vertex3D).Select(e => e.Target).Cast <IVertex3D>()
            .Union(
                graph.InEdges((TVertex)vertex3D).Select(e => e.Source).Cast <IVertex3D>()
                )
            );
 }
Beispiel #8
0
 public static IEnumerable <TVertex> GetNeighbors <TVertex, TEdge>(
     [NotNull] this IBidirectionalGraph <TVertex, TEdge> graph,
     [NotNull] TVertex vertex)
     where TEdge : IEdge <TVertex>
 {
     return(graph.InEdges(vertex).Select(e => e.Source)
            .Concat(graph.OutEdges(vertex).Select(e => e.Target))
            .Distinct());
 }
Beispiel #9
0
 private static void GenerateHierarchicalVertices(BidirectionalGraph <HierarchicalGraphVertex, HierarchicalGraphEdge> graph, HierarchicalGraphVertex vertex,
                                                  IBidirectionalGraph <Cluster <Variety>, ClusterEdge <Variety> > tree, Cluster <Variety> cluster)
 {
     foreach (ClusterEdge <Variety> edge in tree.OutEdges(cluster))
     {
         double depth     = vertex.Depth + edge.Length;
         var    newVertex = edge.Target.DataObjects.Count == 1 ? new HierarchicalGraphVertex(edge.Target.DataObjects.First(), depth) : new HierarchicalGraphVertex(depth);
         graph.AddVertex(newVertex);
         graph.AddEdge(new HierarchicalGraphEdge(vertex, newVertex, edge.Length));
         GenerateHierarchicalVertices(graph, newVertex, tree, edge.Target);
     }
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="ArrayBidirectionalGraph{TVertex,TEdge}"/> class.
        /// </summary>
        /// <param name="baseGraph">Wrapped graph.</param>
        /// <exception cref="T:System.ArgumentNullException"><paramref name="baseGraph"/> is <see langword="null"/>.</exception>
        public ArrayBidirectionalGraph([NotNull] IBidirectionalGraph<TVertex, TEdge> baseGraph)
        {
            if (baseGraph is null)
                throw new ArgumentNullException(nameof(baseGraph));

            AllowParallelEdges = baseGraph.AllowParallelEdges;
            _vertexEdges = new Dictionary<TVertex, InOutEdges>(baseGraph.VertexCount);
            EdgeCount = baseGraph.EdgeCount;
            foreach (TVertex vertex in baseGraph.Vertices)
            {
                TEdge[] outEdges = baseGraph.OutEdges(vertex).ToArray();
                TEdge[] inEdges = baseGraph.InEdges(vertex).ToArray();
                _vertexEdges.Add(vertex, new InOutEdges(outEdges, inEdges));
            }
        }
        /// <summary>
        /// Constructs a new ArrayBidirectionalGraph instance from a
        /// IBidirectionalGraph instance
        /// </summary>
        /// <param name="visitedGraph"></param>
        public ArrayBidirectionalGraph(
            IBidirectionalGraph <TVertex, TEdge> visitedGraph
            )
        {
            Contract.Requires(visitedGraph != null);

            this.vertexEdges = new Dictionary <TVertex, InOutEdges>(visitedGraph.VertexCount);
            this.edgeCount   = visitedGraph.EdgeCount;
            foreach (var vertex in visitedGraph.Vertices)
            {
                var outEdges = Enumerable.ToArray(visitedGraph.OutEdges(vertex));
                var inEdges  = Enumerable.ToArray(visitedGraph.InEdges(vertex));
                this.vertexEdges.Add(vertex, new InOutEdges(outEdges, inEdges));
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ArrayBidirectionalGraph{TVertex,TEdge}"/> class.
        /// </summary>
        /// <param name="visitedGraph">Graph to visit.</param>
        public ArrayBidirectionalGraph([NotNull] IBidirectionalGraph <TVertex, TEdge> visitedGraph)
        {
            if (visitedGraph is null)
            {
                throw new ArgumentNullException(nameof(visitedGraph));
            }

            _vertexEdges = new Dictionary <TVertex, InOutEdges>(visitedGraph.VertexCount);
            EdgeCount    = visitedGraph.EdgeCount;
            foreach (var vertex in visitedGraph.Vertices)
            {
                var outEdges = visitedGraph.OutEdges(vertex).ToArray();
                var inEdges  = visitedGraph.InEdges(vertex).ToArray();
                _vertexEdges.Add(vertex, new InOutEdges(outEdges, inEdges));
            }
        }
        private static void AssertSameProperties <TVertex, TEdge>(IBidirectionalGraph <TVertex, TEdge> graph)
            where TEdge : IEdge <TVertex>
        {
            ArrayBidirectionalGraph <TVertex, TEdge> bidirectionalGraph = graph.ToArrayBidirectionalGraph();

            Assert.AreEqual(graph.VertexCount, bidirectionalGraph.VertexCount);
            CollectionAssert.AreEqual(graph.Vertices, bidirectionalGraph.Vertices);

            Assert.AreEqual(graph.EdgeCount, bidirectionalGraph.EdgeCount);
            CollectionAssert.AreEqual(graph.Edges, bidirectionalGraph.Edges);

            foreach (TVertex vertex in graph.Vertices)
            {
                CollectionAssert.AreEqual(graph.OutEdges(vertex), bidirectionalGraph.OutEdges(vertex));
            }
        }
Beispiel #14
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="g"></param>
        /// <param name="assg"></param>
        public void Transform(IBidirectionalGraph g, IMutableVertexAndEdgeListGraph assg)
        {
            VertexCollection avs = new VertexCollection();

            // adding vertices
            foreach (IEdge e in g.Edges)
            {
                // xi_-(L) = g(xi_-(0), xi_+(L))
                CharacteristicVertex avm = (CharacteristicVertex)assg.AddVertex();
                avm.IncomingEdge = e;
                avm.Vertex       = e.Target;
                avs.Add(avm);

                // xi_+(0) = g(xi_-(0), xi_+(L))
                CharacteristicVertex avp = (CharacteristicVertex)assg.AddVertex();
                avp.IncomingEdge = e;
                avp.Vertex       = e.Source;
                avs.Add(avp);
            }

            // adding out edges
            foreach (CharacteristicVertex av in avs)
            {
                foreach (IEdge e in g.OutEdges(av.Vertex))
                {
                    // find target vertex:
                    CharacteristicVertex avtarget = FindTargetVertex(e);
                    // add xi_-
                    CharacteristicEdge aem = (CharacteristicEdge)assg.AddEdge(av, avtarget);
                    aem.Positive = false;
                    aem.Edge     = e;
                }
                foreach (IEdge e in g.InEdges(av.Vertex))
                {
                    // find target vertex:
                    CharacteristicVertex avtarget = FindTargetVertex(e);
                    // add xi_-
                    CharacteristicEdge aem = (CharacteristicEdge)assg.AddEdge(av, avtarget);
                    aem.Positive = true;
                    aem.Edge     = e;
                }
            }
        }
        public static void BidirectionalContainsEdgeAssertions(
            [NotNull] IBidirectionalGraph <int, IEdge <int> > graph,
            [NotNull] IEdge <int> e12,
            [NotNull] IEdge <int> f12,
            [CanBeNull] IEdge <int> e21,
            [CanBeNull] IEdge <int> f21)
        {
            Assert.AreEqual(0, graph.InDegree(1));
            Assert.AreEqual(1, graph.OutDegree(1));
            Assert.AreEqual(1, graph.InDegree(2));
            Assert.AreEqual(0, graph.OutDegree(2));
            Assert.AreEqual(1, graph.OutEdges(1).Count());
            Assert.AreEqual(1, graph.InEdges(2).Count());

            // e12 must be present in u, because we added it.
            Assert.IsTrue(graph.ContainsEdge(e12));

            // f12 is also in u, because e12 == f12.
            Assert.IsTrue(graph.ContainsEdge(f12));

            // e21 and f21 are not in u, because it's a directed graph.
            if (e21 != null)
            {
                Assert.IsFalse(graph.ContainsEdge(e21));
            }
            if (f21 != null)
            {
                Assert.IsFalse(graph.ContainsEdge(f21));
            }

            // There must be an edge between vertices 1, 2.
            Assert.IsTrue(graph.ContainsEdge(1, 2));

            // No edge between vertices 2, 1, because the graph is directed.
            Assert.IsFalse(graph.ContainsEdge(2, 1));

            // ContainsEdge(1, 3) raises contracts violation in IncidenceGraphContract, because 3 is not in the graph.
            // obviously no edge between vertices 1, 3, as vertex 3 is not even present in the graph.
            // Assert.IsFalse(g.ContainsEdge(1, 3));
        }
Beispiel #16
0
        private double CalcSequenceWeights(IBidirectionalGraph <Cluster <TSeq>, ClusterEdge <TSeq> > tree, ClusterEdge <TSeq> edge, double curWeight,
                                           Stack <Cluster <TSeq> > nodeStack, Dictionary <Cluster <TSeq>, Profile <TSeq, TItem> > profiles)
        {
            double length = edge.Length;

            if (tree.IsOutEdgesEmpty(edge.Target))
            {
                TSeq   seq    = edge.Target.DataObjects.First();
                double weight = curWeight + length;
                profiles[edge.Target] = CreateProfile(seq, weight);
                return(weight);
            }

            nodeStack.Push(edge.Target);
            double lengthPart = length / tree.OutDegree(edge.Target);
            double maxWeight  = double.MinValue;

            foreach (ClusterEdge <TSeq> childEdge in tree.OutEdges(edge.Target))
            {
                maxWeight = Math.Max(maxWeight, CalcSequenceWeights(tree, childEdge, curWeight + lengthPart, nodeStack, profiles));
            }
            return(maxWeight);
        }
Beispiel #17
0
        private void WorklistTraversal2(IBidirectionalGraph <CFGBlock, TaggedEdge <CFGBlock, EdgeTag> > graph)
        {
            while (_workList.Any())
            {
                var block = _workList.GetNext();

                var didChange = _analysis.Analyze2(block, graph);

                var successors = graph.OutEdges(block)
                                 .OrderBy(e => e.Tag.EdgeType)
                                 .Select(e => e.Target);

                foreach (var successor in successors)
                {
                    if (didChange || !_visited.Contains(successor))
                    {
                        _workList.Add(successor);
                    }
                }

                _visited.Add(block);
            }
        }
Beispiel #18
0
        public static IEnumerable <CFGBlock> ReachableBlocks(this IBidirectionalGraph <CFGBlock, TaggedEdge <CFGBlock, EdgeTag> > graph, CFGBlock root)
        {
            Preconditions.NotNull(graph, "graph");
            Preconditions.NotNull(root, "root");

            var reachableBlocks = new HashSet <CFGBlock> {
                root
            };
            var toVisitQueue = new Queue <CFGBlock>(reachableBlocks);

            while (toVisitQueue.Any())
            {
                var current = toVisitQueue.Dequeue();
                foreach (var block in graph.OutEdges(current).Select(e => e.Target))
                {
                    if (reachableBlocks.Add(block))
                    {
                        toVisitQueue.Enqueue(block);
                    }
                }
            }

            return(reachableBlocks);
        }
        public static void ContainsEdgeAssertions(IBidirectionalGraph<int, IEdge<int>> g,
            IEdge<int> e12,
            IEdge<int> f12,
            IEdge<int> e21,
            IEdge<int> f21)
        {
            Assert.AreEqual(0, g.InDegree(1));
            Assert.AreEqual(1, g.OutDegree(1));
            Assert.AreEqual(1, g.InDegree(2));
            Assert.AreEqual(0, g.OutDegree(2));
            Assert.AreEqual(1, g.OutEdges(1).Count());
            Assert.AreEqual(1, g.InEdges(2).Count());

            // e12 must be present in u, because we added it.
            Assert.IsTrue(g.ContainsEdge(e12));

            // f12 is also in u, because e12 == f12.
            Assert.IsTrue(g.ContainsEdge(f12));

            // e21 and f21 are not in u, because it's a directed graph.
            if (e21 != null) Assert.IsFalse(g.ContainsEdge(e21));
            if (f21 != null) Assert.IsFalse(g.ContainsEdge(f21));

            // there must be an edge between vertices 1, 2.
            Assert.IsTrue(g.ContainsEdge(1, 2));

            // no edge between vertices 2, 1, because the graph is directed.
            Assert.IsFalse(g.ContainsEdge(2, 1));

            // ContainsEdge(1, 3) raises contracts violation in IIncidenceGraphContract, because 3 is not in the graph.
            // obviously no edge between vertices 1, 3, as vertex 3 is not even present in the graph.
            // Assert.IsFalse(g.ContainsEdge(1, 3));
        }
Beispiel #20
0
        public void Compute()
        {
            var clusterer = new NeighborJoiningClusterer <TSeq>((seq1, seq2) =>
            {
                var pairwiseAligner = new PairwiseAlignmentAlgorithm <TSeq, TItem>(_scorer, seq1, seq2, _itemsSelector);
                pairwiseAligner.Compute();
                return(1.0 - pairwiseAligner.GetAlignments().First().NormalizedScore);
            });
            IUndirectedGraph <Cluster <TSeq>, ClusterEdge <TSeq> >    unrootedTree = clusterer.GenerateClusters(_sequences);
            IBidirectionalGraph <Cluster <TSeq>, ClusterEdge <TSeq> > rootedTree   = unrootedTree.ToRootedTree();

            var            profiles  = new Dictionary <Cluster <TSeq>, Profile <TSeq, TItem> >();
            var            nodeStack = new Stack <Cluster <TSeq> >();
            Cluster <TSeq> root      = rootedTree.Roots().First();
            double         maxWeight = double.MinValue;

            if (root.DataObjects.Count == 1)
            {
                profiles[root] = CreateProfile(root.DataObjects.First(), 0);
                maxWeight      = 0;
            }
            nodeStack.Push(root);
            foreach (ClusterEdge <TSeq> edge in rootedTree.OutEdges(root))
            {
                maxWeight = Math.Max(maxWeight, CalcSequenceWeights(rootedTree, edge, 0, nodeStack, profiles));
            }

            foreach (Profile <TSeq, TItem> profile in profiles.Values)
            {
                profile.Weights[0] += 1.0 - maxWeight;
            }

            var scorer = new ProfileScorer <TSeq, TItem>(_scorer);

            while (nodeStack.Count > 0)
            {
                Cluster <TSeq> node = nodeStack.Pop();

                var curProfiles = new Stack <Profile <TSeq, TItem> >();
                foreach (ClusterEdge <TSeq> childEdge in rootedTree.OutEdges(node))
                {
                    curProfiles.Push(profiles[childEdge.Target]);
                    profiles.Remove(childEdge.Target);
                }
                if (node.DataObjects.Count == 1)
                {
                    curProfiles.Push(profiles[node]);
                    profiles.Remove(node);
                }
                while (curProfiles.Count > 1)
                {
                    Profile <TSeq, TItem> profile1 = curProfiles.Pop();
                    Profile <TSeq, TItem> profile2 = curProfiles.Pop();
                    var profileAligner             = new PairwiseAlignmentAlgorithm <Profile <TSeq, TItem>, AlignmentCell <TItem>[]>(scorer, profile1, profile2, GetProfileItems);
                    profileAligner.Compute();
                    Alignment <Profile <TSeq, TItem>, AlignmentCell <TItem>[]> profileAlignment = profileAligner.GetAlignments().First();
                    var sequences = new List <Tuple <TSeq, AlignmentCell <TItem>, IEnumerable <AlignmentCell <TItem> >, AlignmentCell <TItem> > >();
                    for (int i = 0; i < profile1.Alignment.SequenceCount; i++)
                    {
                        int seq = i;
                        sequences.Add(Tuple.Create(profile1.Alignment.Sequences[i], profile1.Alignment.Prefixes[i], Enumerable.Range(0, profileAlignment.ColumnCount)
                                                   .Select(col => profileAlignment[0, col].IsNull ? new AlignmentCell <TItem>() : profileAlignment[0, col][0][seq]), profile1.Alignment.Suffixes[i]));
                    }
                    for (int j = 0; j < profile2.Alignment.SequenceCount; j++)
                    {
                        int seq = j;
                        sequences.Add(Tuple.Create(profile2.Alignment.Sequences[j], profile2.Alignment.Prefixes[j], Enumerable.Range(0, profileAlignment.ColumnCount)
                                                   .Select(col => profileAlignment[1, col].IsNull ? new AlignmentCell <TItem>() : profileAlignment[1, col][0][seq]), profile2.Alignment.Suffixes[j]));
                    }
                    var newAlignment = new Alignment <TSeq, TItem>(profileAlignment.RawScore, profileAlignment.NormalizedScore, sequences);
                    curProfiles.Push(new Profile <TSeq, TItem>(newAlignment, profile1.Weights.Concat(profile2.Weights)));
                }
                profiles[node] = curProfiles.Pop();
            }

            Alignment <TSeq, TItem> alignment = profiles[root].Alignment;

            if (UseInputOrder)
            {
                var reorderedSequences = new List <Tuple <TSeq, AlignmentCell <TItem>, IEnumerable <AlignmentCell <TItem> >, AlignmentCell <TItem> > >();
                foreach (TSeq sequence in _sequences)
                {
                    for (int i = 0; i < alignment.SequenceCount; i++)
                    {
                        int seq = i;
                        if (sequence.Equals(alignment.Sequences[seq]))
                        {
                            reorderedSequences.Add(Tuple.Create(sequence, alignment.Prefixes[seq], Enumerable.Range(0, alignment.ColumnCount).Select(col => alignment[seq, col]), alignment.Suffixes[seq]));
                            break;
                        }
                    }
                }

                _result = new Alignment <TSeq, TItem>(alignment.RawScore, alignment.NormalizedScore, reorderedSequences);
            }
            else
            {
                _result = alignment;
            }
        }
Beispiel #21
0
 public IEnumerable <TaggedEdge <CFGBlock, EdgeTag> > NextEdges(IBidirectionalGraph <CFGBlock, TaggedEdge <CFGBlock, EdgeTag> > graph, CFGBlock block)
 {
     return(graph.OutEdges(block));
 }
Beispiel #22
0
 public static IEnumerable <TEdge> GetAllEdges <TVertex, TEdge>(this IBidirectionalGraph <TVertex, TEdge> graph,
                                                                TVertex vertex)
     where TEdge : IEdge <TVertex>
 {
     return(graph.InEdges(vertex).Union(graph.OutEdges(vertex)));
 }
Beispiel #23
0
        private void WorklistTraversal2(IBidirectionalGraph<CFGBlock, TaggedEdge<CFGBlock, EdgeTag>> graph)
        {
            while (_workList.Any())
            {
                var block = _workList.GetNext();

                var didChange = _analysis.Analyze2(block, graph);

                var successors = graph.OutEdges(block)
                                      .OrderBy(e => e.Tag.EdgeType)
                                      .Select(e => e.Target);

                foreach (var successor in successors)
                {
                    if (didChange || !_visited.Contains(successor))
                    {
                        _workList.Add(successor);
                    }
                }

                _visited.Add(block);
            }
        }
Beispiel #24
0
 public IEnumerable<TaggedEdge<CFGBlock, EdgeTag>> NextEdges(IBidirectionalGraph<CFGBlock, TaggedEdge<CFGBlock, EdgeTag>> graph, CFGBlock block)
 {
     return graph.OutEdges(block);
 }
Beispiel #25
0
        private static void GenerateHierarchicalVertices(BidirectionalGraph<HierarchicalGraphVertex, HierarchicalGraphEdge> graph, HierarchicalGraphVertex vertex,
			IBidirectionalGraph<Cluster<Variety>, ClusterEdge<Variety>> tree, Cluster<Variety> cluster)
        {
            foreach (ClusterEdge<Variety> edge in tree.OutEdges(cluster))
            {
                double depth = vertex.Depth + edge.Length;
                var newVertex = edge.Target.DataObjects.Count == 1 ? new HierarchicalGraphVertex(edge.Target.DataObjects.First(), depth) : new HierarchicalGraphVertex(depth);
                graph.AddVertex(newVertex);
                graph.AddEdge(new HierarchicalGraphEdge(vertex, newVertex, edge.Length));
                GenerateHierarchicalVertices(graph, newVertex, tree, edge.Target);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="g"></param>
        /// <param name="assg"></param>
        public void Transform(IBidirectionalGraph g, IMutableVertexAndEdgeListGraph assg)
        {
            VertexCollection avs = new VertexCollection();
            // adding vertices
            foreach(IEdge e in g.Edges)
            {
                // xi_-(L) = g(xi_-(0), xi_+(L))
                CharacteristicVertex avm = (CharacteristicVertex)assg.AddVertex();
                avm.IncomingEdge = e;
                avm.Vertex = e.Target;
                avs.Add(avm);

                // xi_+(0) = g(xi_-(0), xi_+(L))
                CharacteristicVertex avp = (CharacteristicVertex)assg.AddVertex();
                avp.IncomingEdge = e;
                avp.Vertex = e.Source;
                avs.Add(avp);
            }

            // adding out edges
            foreach(CharacteristicVertex av in avs)
            {
                foreach(IEdge e in g.OutEdges(av.Vertex))
                {
                    // find target vertex:
                    CharacteristicVertex avtarget = FindTargetVertex(e);
                    // add xi_-
                    CharacteristicEdge aem = (CharacteristicEdge)assg.AddEdge(av,avtarget);
                    aem.Positive = false;
                    aem.Edge = e;
                }
                foreach(IEdge e in g.InEdges(av.Vertex))
                {
                    // find target vertex:
                    CharacteristicVertex avtarget = FindTargetVertex(e);
                    // add xi_-
                    CharacteristicEdge aem = (CharacteristicEdge)assg.AddEdge(av,avtarget);
                    aem.Positive = true;
                    aem.Edge = e;
                }
            }
        }