Skip to content

Instantly share code, notes, and snippets.

@kacpak
Created March 18, 2017 15:13
Show Gist options
  • Save kacpak/5b21d023b9f64d5718993057ccf3c02c to your computer and use it in GitHub Desktop.
Save kacpak/5b21d023b9f64d5718993057ccf3c02c to your computer and use it in GitHub Desktop.
Algorytm ewolucyjny funkcji G2
using System;
using System.Collections.Generic;
using System.Linq;
using static G2.Problem;
namespace G2
{
internal static class Algorytm
{
private const int WielkośćPopulacji = 50;
private const int LiczbaPokoleń = 50;
private static readonly Random Random = new Random();
public static Osobnik Run()
{
Osobnik najlepszyOsobnik = null;
Osobnik najlepszyDozwolonyOsobnik = null;
var populacja = GenerujPopulacjęStartową();
//Print(populacja);
for (var i = 0; i < LiczbaPokoleń; i++)
{
var najlepszyWPopulacji = Najlepszy(populacja);
var najlepszyWPopulacjiDozwolony = Najlepszy(populacja, true);
if (najlepszyOsobnik == null || Funkcja(najlepszyOsobnik.Fenotyp) < Funkcja(najlepszyWPopulacji.Fenotyp))
najlepszyOsobnik = najlepszyWPopulacji;
if (najlepszyDozwolonyOsobnik == null
|| najlepszyWPopulacjiDozwolony != null && Funkcja(najlepszyDozwolonyOsobnik.Fenotyp) < Funkcja(najlepszyWPopulacjiDozwolony.Fenotyp))
najlepszyDozwolonyOsobnik = najlepszyWPopulacjiDozwolony;
populacja = GenerujNowąPopulację(populacja);
//Print(populacja);
}
var losowaPopulacja = GenerujPopulacjęStartową(WielkośćPopulacji * LiczbaPokoleń);
Console.WriteLine("Najlepszy w losowej populacji:\n\tx='{0}'\n\tf(x)='{1}'", Najlepszy(losowaPopulacja), Funkcja(Najlepszy(losowaPopulacja).Fenotyp));
Console.WriteLine("Najlepszy w poprzednich populacjach:\n\tx='{0}'\n\tf(x)='{1}'", najlepszyOsobnik, Funkcja(najlepszyOsobnik.Fenotyp));
Console.WriteLine("Najlepszy dozwolony w poprzednich populacjach:\n\tx='{0}'\n\tf(x)='{1}'", najlepszyDozwolonyOsobnik, Funkcja(najlepszyDozwolonyOsobnik.Fenotyp));
Console.WriteLine("Najlepszy w ostatniej populacji:\n\tx='{0}'\n\tf(x)='{1}'", Najlepszy(populacja), Funkcja(Najlepszy(populacja).Fenotyp));
return Najlepszy(populacja);
}
private static ICollection<Osobnik> GenerujPopulacjęStartową(int wielkośćPopulacji = WielkośćPopulacji)
{
return Enumerable.Range(0, wielkośćPopulacji)
.Select(o => new Osobnik())
.ToArray();
}
private static ICollection<Osobnik> GenerujNowąPopulację(ICollection<Osobnik> populacja)
{
var nowaPopulacja = new Osobnik[populacja.Count];
for (var i = 0; i < nowaPopulacja.Length; i++)
{
var mama = Selekcja(populacja);
var tata = Selekcja(populacja);
nowaPopulacja[i] = new Osobnik(mama, tata);
}
return nowaPopulacja;
}
private static Osobnik Selekcja(ICollection<Osobnik> populacja)
{
var i = Random.Next(populacja.Count);
var j = Random.Next(populacja.Count);
var rywal1 = populacja.ElementAt(i);
var rywal2 = populacja.ElementAt(j);
//Console.WriteLine(rywal1 > rywal2 ? "r1* [{2}]: {0}; r2 [{3}]: {1}" : "r1 [{2}]: {0}; r2* [{3}]: {1}", rywal1, rywal2, i, j);
return rywal1 > rywal2 ? rywal1 : rywal2;
}
private static void Print(IEnumerable<Osobnik> populacja)
{
Console.WriteLine(string.Join(";\n", populacja));
Console.WriteLine();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
namespace G2
{
internal static class Problem
{
/// <summary>
/// Funkcja G2
/// </summary>
internal static double Funkcja(double[] x)
{
double s1 = 0, s2 = 1, s3 = 0;
for (var i = 0; i < x.Length; i++)
{
s1 += Math.Pow(Math.Cos(x[i]), 4);
s2 *= Math.Pow(Math.Cos(x[i]), 2);
s3 += (i + 1) * Math.Pow(x[i], 2);
}
return Math.Abs((s1 - 2 * s2) / Math.Sqrt(s3));
}
/// <summary>
/// Najlepszy <see cref="Osobnik"/> z populacji
/// </summary>
internal static Osobnik Najlepszy(ICollection<Osobnik> populacja, bool allowedOrNull = false)
{
var sorted = populacja
.OrderByDescending(o => Funkcja(o.Fenotyp));
var bestAllowed = sorted
.FirstOrDefault(o => o.IsAllowed);
if (!allowedOrNull && bestAllowed == null)
return sorted
.First();
return bestAllowed;
}
internal class Osobnik
{
private const int LiczbaWymiarów = 4;
private const int Dokładność = 8;
private static readonly Random Random = new Random();
private readonly double[] _wartości;
public Osobnik()
{
_wartości = new double[LiczbaWymiarów];
for (var i = 0; i < _wartości.Length; i++)
_wartości[i] = Random.NextDouble() * 10; //0 <= x[i] <= 10
}
public Osobnik(Osobnik matka, Osobnik ojciec)
{
_wartości = new double[LiczbaWymiarów];
for (int i = 0; i < _wartości.Length; i++)
{
int maska = 0;
maska = ~maska;
maska <<= Random.Next(1, 24); // max: ile bitów zajmuje maksymalna wartość w int'cie
int dziecko = matka.Genotyp[i] & maska | ojciec.Genotyp[i] & ~maska;
//Console.WriteLine("matka: {0} [{1}]\n" +
// "ojciec: {2} [{3}]\n" +
// "\tmaska: {4}; część matki: {5}; część ojca: {6}\n" +
// "\tdziecko: {7} [{8}]\n",
// matka.Genotyp[i], Convert.ToString(matka.Genotyp[i], 2),
// ojciec.Genotyp[i], Convert.ToString(ojciec.Genotyp[i], 2),
// Convert.ToString(maska, 2), Convert.ToString(matka.Genotyp[i] & maska, 2), Convert.ToString(ojciec.Genotyp[i] & ~maska, 2),
// dziecko, Convert.ToString(dziecko, 2)
//);
if (Random.NextDouble() < 0.1)
{
int bit_zmiana = 1;
bit_zmiana <<= Random.Next(0, 24);
dziecko ^= bit_zmiana;
}
//Console.WriteLine("m: {0}; t: {1}; d: {2} [{3}]", matka.Genotyp[i], ojciec.Genotyp[i], dziecko, dziecko / Math.Pow(10, Dokładność));
_wartości[i] = dziecko / Math.Pow(10, Dokładność);
}
}
public int[] Genotyp
{
get
{
var geny = new int[_wartości.Length];
for (var i = 0; i < _wartości.Length; i++)
geny[i] = (int)(_wartości[i] * Math.Pow(10, Dokładność));
return geny;
}
}
public double[] Fenotyp => _wartości;
public bool IsAllowed => Fenotyp.All(f => f > 0 && f < 10);
public static bool operator >(Osobnik o1, Osobnik o2)
{
if (o1 == null && o2 != null)
return false;
if (o2 == null)
return true;
if (o1.IsAllowed && !o2.IsAllowed)
return true;
if (!o1.IsAllowed && o2.IsAllowed)
return false;
return Funkcja(o1.Fenotyp) > Funkcja(o2.Fenotyp);
}
public static bool operator <(Osobnik o1, Osobnik o2) => o2 > o1;
public override string ToString() => String.Join(", ", _wartości);
}
}
}
using System;
namespace G2
{
class Program
{
public static void Main(string[] args)
{
Algorytm.Run();
Console.ReadKey();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment