Beispiel #1
0
        public DirectedGraph Sample(DirectedGraph graph, int sampledVertexCount, double burningProbability, Random random)
        {
            var result = new DirectedGraph();
            var index2index = new Dictionary<int, int>();
            var visit = new bool[graph.Vertices.Count];

            while (result.Vertices.Count < sampledVertexCount) {
                // 開始点を決める
                int start;
                do { start = random.Next(graph.Vertices.Count); } while (visit[start]);

                var stack = new Stack<int>();
                stack.Push(start);
                AddVertexToResultGraph(start, graph, result, index2index);
                visit[start] = true;

                while (stack.Count > 0 && result.Vertices.Count < sampledVertexCount) {
                    int v = stack.Pop();
                    var outEdges = graph.OutEdges[v];
                    for (int i = 0; i < outEdges.Count; ++i) {
                        if (random.NextDouble() >= burningProbability) { break; }

                        // i番目以降の辺を一つ選んでi番目と入れ替える
                        int j = random.Next(i, outEdges.Count);
                        Edge t = outEdges[i];
                        outEdges[i] = outEdges[j];
                        outEdges[j] = t;

                        // 結果に追加
                        int dst = outEdges[i].Dst;
                        if (!visit[dst]) { AddVertexToResultGraph(dst, graph, result, index2index); }
                        result.AddEdge(new Edge(index2index[v], index2index[dst]));

                        // 再帰的に探索
                        if (!visit[dst]) {
                            visit[dst] = true;
                            stack.Push(dst);
                        }
                    }
                }
            }

            return result;
        }
        /// <summary>
        /// Cools system until it reaches minimal, targeted temperature.
        /// </summary>
        /// <param name="algorithm">Simulated annealing algorithm being cooled.</param>
        /// <param name="coolingAction">Delegate of action to cool system by one step of cooling ratio.</param>
        /// <returns>Processor time cost</returns>
        //TODO: Possibly a more narrow dependency to something like ISimulatedAnnealing to not force cast for CurrentTemperature access?
        public IEnumerable<IAlgorithmProgressReport> Cool(IAlgorithm algorithm, Action coolingAction)
        {
            if (algorithm == null) throw new ArgumentException(nameof(algorithm));
            if (coolingAction == null) throw new ArgumentException(nameof(coolingAction));

            var startTime = DateTime.Now.Ticks;
            while (algorithm.CanContinueSearching())
            {
                //Pick random node from graph and keep on adding them to solution until correctness criteria is met
                HashSet<Node> proposedSolution = new HashSet<Node>();
                List<Node> nodesCopy = algorithm.Graph.Nodes;
                Stack<int> randomIndexes = new Stack<int>(Enumerable.Range(0, nodesCopy.Count).OrderBy(r => _random.Next()));
                while (!algorithm.Problem.IsSolutionCorrect(proposedSolution))
                {
                    proposedSolution.Add(nodesCopy[randomIndexes.Pop()]);
                }

                bool wasAccepted = false;

                //Accept the answer if algorithm allows
                if (algorithm.CanAcceptAnswer(proposedSolution))
                {
                    algorithm.Problem.SetNewSolution(proposedSolution);
                    wasAccepted = true;
                }

                var casted = algorithm as SimulatedAnnealing;
                var currentTemp = casted == null ? 0 : casted.CurrentTemperature;

                yield return new SimulatedAnnealingProgressReport(DateTime.Now.Ticks - startTime, algorithm.Problem.CurrentSolution, (uint)(algorithm.Graph.TotalNodes - algorithm.Problem.CurrentSolution.Count + 1), currentTemp, wasAccepted);

                //Cool system
                coolingAction.Invoke();
            }
            
        }