Created
March 18, 2017 15:13
-
-
Save kacpak/5b21d023b9f64d5718993057ccf3c02c to your computer and use it in GitHub Desktop.
Algorytm ewolucyjny funkcji G2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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