コード例 #1
0
ファイル: Subgraph.cs プロジェクト: allisterb/satsumagraph
        public int ArcCount(ArcFilter filter = ArcFilter.All)
        {
            if (nodeExceptions.Count == 0 && filter == ArcFilter.All)
            {
                return(defaultNodeEnabled ?
                       (defaultArcEnabled ? graph.ArcCount() - arcExceptions.Count : arcExceptions.Count)
                                        : 0);
            }

            return(Arcs(filter).Count());
        }
コード例 #2
0
ファイル: Isomorphism.cs プロジェクト: allisterb/satsumagraph
 public NodeHash(IGraph g)
 {
     graph     = g;
     minDegree = int.MaxValue;
     maxDegree = int.MinValue;
     coloring  = new Dictionary <Node, ulong>(graph.NodeCount());
     foreach (Node n in graph.Nodes())
     {
         int degree = graph.ArcCount(n);
         if (degree < minDegree)
         {
             minDegree = degree;
         }
         if (degree > maxDegree)
         {
             maxDegree = degree;
         }
         coloring[n] = (ulong)degree;
     }
     ComputeHash();
     buffer = new Dictionary <Node, ulong>(graph.NodeCount());
 }
コード例 #3
0
 public int ArcCount(ArcFilter filter = ArcFilter.All)
 {
     return(ArcsInternal(filter).Count + (graph == null ? 0 : graph.ArcCount(filter)));
 }
コード例 #4
0
 public int ArcCount(ArcFilter filter = ArcFilter.All)
 {
     return((filter != 0) ? Arcs(filter).Count() : graph.ArcCount(ArcFilter.All));
 }
コード例 #5
0
 public int ArcCount(ArcFilter filter = ArcFilter.All)
 {
     return(graph.ArcCount(ArcFilter.All));
 }
コード例 #6
0
 public int ArcCount(ArcFilter filter = ArcFilter.All)
 {
     return(ArcsInternal(filter).Count + ((graph != null) ? graph.ArcCount(filter) : 0));
 }
コード例 #7
0
        public Preflow(IGraph graph, Func <Arc, double> capacity, Node source, Node target)
        {
            Graph    = graph;
            Capacity = capacity;
            Source   = source;
            Target   = target;

            flow = new Dictionary <Arc, double>();

            // calculate bottleneck capacity to get an upper bound for the flow value
            Dijkstra dijkstra = new Dijkstra(Graph, a => - Capacity(a), DijkstraMode.Maximum);

            dijkstra.AddSource(Source);
            dijkstra.RunUntilFixed(Target);
            double bottleneckCapacity = -dijkstra.GetDistance(Target);

            if (double.IsPositiveInfinity(bottleneckCapacity))
            {
                // flow value is infinity
                FlowSize = double.PositiveInfinity;
                Error    = 0;
                for (Node n = Target, n2 = Node.Invalid; n != Source; n = n2)
                {
                    Arc arc = dijkstra.GetParentArc(n);
                    flow[arc] = double.PositiveInfinity;
                    n2        = Graph.Other(arc, n);
                }
            }
            else
            {
                // flow value is finite
                if (double.IsNegativeInfinity(bottleneckCapacity))
                {
                    bottleneckCapacity = 0;                     // Target is not accessible
                }
                U = Graph.ArcCount() * bottleneckCapacity;

                // calculate other upper bounds for the flow
                double USource = 0;
                foreach (var arc in Graph.Arcs(Source, ArcFilter.Forward))
                {
                    if (Graph.Other(arc, Source) != Source)
                    {
                        USource += Capacity(arc);
                        if (USource > U)
                        {
                            break;
                        }
                    }
                }
                U = Math.Min(U, USource);
                double UTarget = 0;
                foreach (var arc in Graph.Arcs(Target, ArcFilter.Backward))
                {
                    if (Graph.Other(arc, Target) != Target)
                    {
                        UTarget += Capacity(arc);
                        if (UTarget > U)
                        {
                            break;
                        }
                    }
                }
                U = Math.Min(U, UTarget);

                Supergraph sg        = new Supergraph(Graph);
                Node       newSource = sg.AddNode();
                artificialArc = sg.AddArc(newSource, Source, Directedness.Directed);

                CapacityMultiplier = Utils.LargestPowerOfTwo(long.MaxValue / U);
                if (CapacityMultiplier == 0)
                {
                    CapacityMultiplier = 1;
                }

                var p = new IntegerPreflow(sg, IntegralCapacity, newSource, Target);
                FlowSize = p.FlowSize / CapacityMultiplier;
                Error    = Graph.ArcCount() / CapacityMultiplier;
                foreach (var kv in p.NonzeroArcs)
                {
                    flow[kv.Key] = kv.Value / CapacityMultiplier;
                }
            }
        }
コード例 #8
0
ファイル: Isomorphism.cs プロジェクト: allisterb/satsumagraph
        public Isomorphism(IGraph firstGraph, IGraph secondGraph, int maxIterations = 16)
        {
            FirstGraph    = firstGraph;
            SecondGraph   = secondGraph;
            FirstToSecond = null;

            if (firstGraph.NodeCount() != secondGraph.NodeCount() ||
                firstGraph.ArcCount() != secondGraph.ArcCount() ||
                firstGraph.ArcCount(ArcFilter.Edge) != secondGraph.ArcCount(ArcFilter.Edge))
            {
                Isomorphic = false;
            }
            else
            {
                ConnectedComponents firstCC  = new ConnectedComponents(firstGraph, ConnectedComponents.Flags.CreateComponents);
                ConnectedComponents secondCC = new ConnectedComponents(secondGraph, ConnectedComponents.Flags.CreateComponents);
                if (firstCC.Count != secondCC.Count ||
                    !firstCC.Components.Select(s => s.Count).OrderBy(x => x).SequenceEqual(
                        secondCC.Components.Select(s => s.Count).OrderBy(x => x)))
                {
                    Isomorphic = false;
                }
                else
                {
                    NodeHash firstHash  = new NodeHash(firstGraph);
                    NodeHash secondHash = new NodeHash(secondGraph);
                    if (firstHash.ColoringHash != secondHash.ColoringHash)
                    {
                        // degree distribution not equal
                        Isomorphic = false;
                    }
                    else if (firstHash.RegularGraph && secondHash.RegularGraph &&
                             firstHash.ColoringHash == secondHash.ColoringHash)
                    {
                        // TODO do something with regular graphs
                        // maybe spectral test
                        Isomorphic = null;
                    }
                    else
                    {
                        Isomorphic = null;
                        for (int i = 0; i < maxIterations; ++i)
                        {
                            firstHash.Iterate();
                            secondHash.Iterate();
                            if (firstHash.ColoringHash != secondHash.ColoringHash)
                            {
                                Isomorphic = false;
                                break;
                            }
                        }

                        if (Isomorphic == null)
                        {
                            // graphs are very probably isomorphic (or tricky), try to find the mapping
                            var firstColor  = firstHash.GetSortedColoring();
                            var secondColor = secondHash.GetSortedColoring();

                            // is the canonical coloring the same, and does it uniquely identify nodes?
                            Isomorphic = true;
                            for (int i = 0; i < firstColor.Count; ++i)
                            {
                                if (firstColor[i].Value != secondColor[i].Value)
                                {
                                    // unlikely because the hashes matched
                                    Isomorphic = false;
                                    break;
                                }
                                else if (i > 0 && firstColor[i].Value == firstColor[i - 1].Value)
                                {
                                    // two nodes colored the same way (this may happen)
                                    // TODO handle this case. Else we won't work for graphs with symmetries.
                                    Isomorphic = null;
                                    break;
                                }
                            }

                            if (Isomorphic == true)
                            {
                                FirstToSecond = new Dictionary <Node, Node>(firstColor.Count);
                                for (int i = 0; i < firstColor.Count; ++i)
                                {
                                    FirstToSecond[firstColor[i].Key] = secondColor[i].Key;
                                }
                            }
                        }
                    }
                }
            }
        }
コード例 #9
0
        public Preflow(IGraph graph, Func <Arc, double> capacity, Node source, Node target)
        {
            Graph    = graph;
            Capacity = capacity;
            Source   = source;
            Target   = target;
            flow     = new Dictionary <Arc, double>();
            Dijkstra dijkstra = new Dijkstra(Graph, (Arc a) => 0.0 - Capacity(a), DijkstraMode.Maximum);

            dijkstra.AddSource(Source);
            dijkstra.RunUntilFixed(Target);
            double num = 0.0 - dijkstra.GetDistance(Target);

            if (double.IsPositiveInfinity(num))
            {
                FlowSize = double.PositiveInfinity;
                Error    = 0.0;
                Node node    = Target;
                Node invalid = Node.Invalid;
                while (node != Source)
                {
                    Arc parentArc = dijkstra.GetParentArc(node);
                    flow[parentArc] = double.PositiveInfinity;
                    invalid         = Graph.Other(parentArc, node);
                    node            = invalid;
                }
            }
            else
            {
                if (double.IsNegativeInfinity(num))
                {
                    num = 0.0;
                }
                U = (double)Graph.ArcCount(ArcFilter.All) * num;
                double num2 = 0.0;
                foreach (Arc item in Graph.Arcs(Source, ArcFilter.Forward))
                {
                    if (Graph.Other(item, Source) != Source)
                    {
                        num2 += Capacity(item);
                        if (num2 > U)
                        {
                            break;
                        }
                    }
                }
                U = Math.Min(U, num2);
                double num3 = 0.0;
                foreach (Arc item2 in Graph.Arcs(Target, ArcFilter.Backward))
                {
                    if (Graph.Other(item2, Target) != Target)
                    {
                        num3 += Capacity(item2);
                        if (num3 > U)
                        {
                            break;
                        }
                    }
                }
                U = Math.Min(U, num3);
                Supergraph supergraph = new Supergraph(Graph);
                Node       node2      = supergraph.AddNode();
                artificialArc      = supergraph.AddArc(node2, Source, Directedness.Directed);
                CapacityMultiplier = Utils.LargestPowerOfTwo(9.2233720368547758E+18 / U);
                if (CapacityMultiplier == 0.0)
                {
                    CapacityMultiplier = 1.0;
                }
                IntegerPreflow integerPreflow = new IntegerPreflow(supergraph, IntegralCapacity, node2, Target);
                FlowSize = (double)integerPreflow.FlowSize / CapacityMultiplier;
                Error    = (double)Graph.ArcCount(ArcFilter.All) / CapacityMultiplier;
                foreach (KeyValuePair <Arc, long> nonzeroArc in integerPreflow.NonzeroArcs)
                {
                    flow[nonzeroArc.Key] = (double)nonzeroArc.Value / CapacityMultiplier;
                }
            }
        }
コード例 #10
0
 public int ArcCount(ArcFilter filter = ArcFilter.All)
 {
     return(filter == ArcFilter.All ? graph.ArcCount() : Arcs(filter).Count());
 }