Exemplo n.º 1
0
        public static void Run(Graph graph, Action refresh, Size size)
        {
            if (!IsRun)
            {
                IsRun = true;

                ThreadPool.QueueUserWorkItem(state =>
                {
                    var avgEdgeLength             = graph.SelectMany(x => x.Edges.Select(e => e.GetLength())).Average();
                    Func <double> GetSolutionCost = () => CalcSolutionCost(graph, avgEdgeLength);

                    var rand            = new Random(DateTime.Now.Millisecond);
                    Temperature         = INITIAL_TEMPERATURE;
                    double solutionCost = GetSolutionCost();
                    for (int i = 0; i < COOLING_STEP; i++)
                    {
                        Temperature *= COOLING_FRACTION;

                        var startValue = solutionCost;
                        for (int j = 0; j < STEPS_PER_TEMP; j++)
                        {
                            var vertexIndex   = rand.Next(0, graph.Count);
                            var vertex        = graph[vertexIndex];
                            var moveDirection = (Direction)rand.Next(0, 7);
                            var moveDistance  = (float)rand.NextDouble() * avgEdgeLength;
                            var position      = vertex.Position;
                            Move(vertex, moveDirection, moveDistance, size);
                            refresh();
                            var flip = rand.NextDouble() * 1.1;
                            var currentSolutionCost = GetSolutionCost();
                            var delta    = solutionCost - currentSolutionCost;
                            var exponent = (-delta / solutionCost) / (K * Temperature);
                            var merit    = Math.Pow(Math.E, exponent);
                            if (delta < 0)                             //Принять удачный вариант
                            {
                                solutionCost = currentSolutionCost;
                                refresh();
                            }
                            else
                            {
                                if (merit > flip)                                 //Принять неудачный вариант
                                {
                                    solutionCost = currentSolutionCost;
                                    refresh();
                                }
                                else                                 //Отклонить
                                {
                                    vertex.Position = position;
                                }
                            }
                        }

                        if (solutionCost - startValue < 0)
                        {
                            Temperature = Temperature / COOLING_FRACTION;
                        }
                    }
                    IsRun = false;
                });
            }
        }
Exemplo n.º 2
0
        private static double CalcSolutionCost(Graph graph, float edgeLength)
        {
            var c = graph.SelectMany(x => x.Edges.Select(e => e.GetLength())).Where(x => Math.Abs(x / edgeLength) > 0.9 && Math.Abs(x / edgeLength) < 1.1).Count() / 2;

            return((((double)c * 2) / graph.SelectMany(x => x.Edges).Count()) * 100.0);
        }