bwerf's Blog

It's plukalicious
posts - 14, comments - 12, trackbacks - 0, articles - 0
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Imager
{
    public class Optimizer
    {
        List<Parameter> parameters = new List<Parameter>();
        HashSet<Parameter> active = new HashSet<Parameter>();
        int index;
        public void RegisterParameter(double initial, double increment, bool optimize)
        {
            parameters.Add(new Parameter(initial, increment, optimize));
        }
        public void Run(Func<double[], double> lambda, Action<double[], double, int> bestSoFar)
        {
            int activeIndex;
            {
                Parameter p;
                while (true)
                {
                    if (index >= parameters.Count)
                        return; // no active parameters
                    p = parameters[index];
                    activeIndex = index;
                    if (p.Optimize) break;
                    index++;
                }
                active.Add(p);
            }
            var best = lambda(parameters.Select(x => x.Original).ToArray());
            if (double.IsNaN(best))
                return;
            while (true)
            {
                var r = lambda(parameters.Select(x => active.Contains(x) ? x.Value : x.Original).ToArray());
                if (double.IsNaN(r))
                    return;
                var d = best - r;
                foreach (var p in active)
                    p.ProcessResult(d);
                if (d >= 0)
                    best = r;
                if (d > 0)
                    bestSoFar(parameters.Select(x => x.Original).ToArray(), best, activeIndex);
                else
                {
                    active.Clear();
                    Parameter p;
                    while (true)
                    {
                        if (index == 0)
                        {
                            if (parameters.All(x=>x.Stagnated))
                                return; // no effect in optimizer
                        }
                        p = parameters[index];
                        activeIndex = index;
                        index++;
                        if (index >= parameters.Count)
                            index = 0;
                        if (p.Optimize) break;
                    }
                    active.Add(p);
                }
            }
        }
        private class Parameter
        {
            public double Value { get; private set; }
            public double Increment { get; private set; }
            public bool Optimize { get; private set; }
            public double Original { get; private set; }
            public bool Stagnated { get { return (!Optimize) || (reversals > 2); } }
            private double magnitude;
            private bool direction;
            private int reversals = 0;
            public Parameter(double value, double increment, bool optimize)
            {
                Increment = increment;
                Optimize = optimize;
                magnitude = Increment;
                direction = true;
                Original = value;
                Value = value + magnitude;
            }
            public void ProcessResult(double delta)
            {
                if (!Optimize) return;
                if (delta < 0.0d)
                {
                    magnitude *= 0.5d;
                    if (direction ? (magnitude < Increment) : (magnitude > -Increment))
                    {
                        direction = !direction;
                        magnitude = direction ? Increment : -Increment;
                        reversals++;
                    }
                    Value = Original + magnitude;
                }
                else
                {
                    if (delta > 0)
                        reversals = 0;
                    magnitude *= 2.0d;
                    Original = Value;
                    Value += magnitude;
                }
            }
        }
    }
}

Feedback

# re: Simple Hillclimber that can handle alot of dimensions and can be pretty fast.

10/27/2009 9:36 PM by film izle
http://filmizlenir.blogspot.com">http://filmizlenir.blogspot.com
http://filmizlenir.blogspot.com">http://filmizlenir.blogspot.com

Post Comment

Title  
Name  
Url
Comment   

ATTENTION: the code you need to copy is CaSe SeNsItIvE and is required to prevent spam.
Enter the code you see: