/// <summary> /// Оптимизация методом пчелиной колонии /// </summary> /// <param name="f">Оптимизируемая функция</param> /// <param name="min">Нижняя граница области решений</param> /// <param name="max">Верхняя граница области решений</param> /// <param name="n">Размерность области решений</param> /// <param name="s">Общее число пчёл</param> /// <param name="p">Число пчёл, выбранных для последующего исследования (p меньше s)</param> /// <param name="e">Число особо исследуемых пчёл (e меньше p)</param> /// <param name="sp">Число вспомогательных пчёл для пчёл из p</param> /// <param name="se">Число вспомогательных пчёл для пчёл из e</param> /// <param name="delta">Радиус окрестности</param> /// <param name="eps">Допустимая погрешность</param> /// <param name="maxcount">Максимальное число итераций</param> /// <returns></returns> public static Tuple <Vectors, double> GetGlobalMin(Func <Vectors, double> f, Vectors min, Vectors max, int n = 1, int s = 1000, int p = 300, int e = 100, int sp = 50, int se = 100, double delta = 1.0, double eps = 1e-10, int maxcount = 10) { SBee[] mas = SBee.Create(f, min, max, s); int k = 0; while (SBee.GetBest(mas).v > eps && maxcount > 0 && k < 3) { double old = SBee.GetBest(mas).v; SBee.MakeStep(ref mas, f, min, max, n, p, e, sp, se, delta); double now = SBee.GetBest(mas).v; if (now < old) { Debug.WriteLine($"\tColony: {old} ---> {now}"); k = 0; } else { k++; } maxcount--; } SBee res = SBee.GetBest(mas); return(new Tuple <Vectors, double>(res.x, res.v)); }
/// <summary> /// Получить случайный массив упрощённых пчёл /// </summary> /// <param name="f"></param> /// <param name="min"></param> /// <param name="max"></param> /// <param name="count">Число пчёл</param> /// <returns></returns> public static SBee[] Create(Func <Vectors, double> f, Vectors min, Vectors max, int count = 100, bool withaverage = true) { SBee[] res = new SBee[count]; Vectors[] tmp = new Vectors[count]; Parallel.For(0, count, (int i) => { tmp[i] = Vectors.Create(min, max); }); for (int i = 0; i < count; i++) { res[i] = new SBee(tmp[i], f(tmp[i])); } if (withaverage) { res[res.Length - 1] = new SBee((max + min) / 2, f); } return(res); }
/// <summary> /// Сделать шаг по алгоритму пчелиной колонии /// </summary> /// <param name="mas"></param> /// <param name="f"></param> /// <param name="min"></param> /// <param name="max"></param> /// <param name="n"></param> /// <param name="p"></param> /// <param name="e"></param> /// <param name="sp"></param> /// <param name="se"></param> /// <param name="delta"></param> public static void MakeStep(ref SBee[] mas, Func <Vectors, double> f, Vectors min, Vectors max, int n = 1, int p = 300, int e = 100, int sp = 50, int se = 100, double delta = 1.0) { Array.Sort(mas); Vectors[] t = new Vectors[se]; for (int i = 0; i < e; i++) { SBee it = new SBee(mas[i]), tmp; Vectors cent = it.x.dup; Parallel.For(0, t.Length, (int u) => { t[u] = Vectors.Create(cent, delta); }); for (int j = 0; j < se; j++) { tmp = new SBee(t[j], f); if (tmp.v < it.v) { it = new SBee(tmp); } } mas[i] = new SBee(it); } t = new Vectors[sp]; for (int i = e; i < p; i++) { SBee it = new SBee(mas[i]), tmp; Vectors cent = it.x.dup; Parallel.For(0, t.Length, (int u) => { t[u] = Vectors.Create(cent, delta); }); for (int j = 0; j < sp; j++) { tmp = new SBee(t[j], f); if (tmp.v < it.v) { it = new SBee(tmp); } } mas[i] = new SBee(it); } t = new Vectors[mas.Length - p]; Parallel.For(0, t.Length, (int i) => { t[i] = Vectors.Create(min, max); }); for (int i = p; i < mas.Length; i++) { mas[i] = new SBee(t[i - p], f); } }
public int CompareTo(SBee obj) { return(v.CompareTo(obj.v)); }
public SBee(SBee be) : this(be.x, be.v) { }