public FlagColor[] SelectColors(Culture Culture, FlagColorMap Colors, Random Random, int Iterations = 30) { FlagColor[] Chosen = Colors.Closest(Culture, _Parts.Length); Pair <double, int> P = ColoringScore(Culture, Chosen); for (int j = 0; j < Iterations; ++j) { P = ColoringScore(Culture, Chosen); int C = Random.NextDouble() > .5 ? P.Second : Random.Next(0, _Parts.Length); double Score = P.First; FlagColor Original = Chosen[C]; // Find best new assignment FlagColor Best = Chosen[C]; for (int i = 0; i < Colors.Colors.Length; ++i) { Chosen[C] = Colors.Colors[i]; double thisScore = ColoringScore(Culture, Chosen).First; if (thisScore > Score) { Score = thisScore; Best = Colors.Colors[i]; } } Chosen[C] = Best; } return(Chosen); }
private Pair <double, int> ColoringScore(Culture Culture, FlagColor[] Colors) { double Score = 0; double WorstPartScore = double.MaxValue; int WorstPart = -1; for (int i = 0; i < _Parts.Length; ++i) { GraphNode <Vector2f[]> part = _Parts[i]; FlagColor Color = Colors[i]; double Distance = 1 - Color.DistanceTo(Culture) / 2.2360679775; Distance *= Distance * Distance; double PartScore = Distance; foreach (var edge in part.Edges) { double M = 1 - Color.DistanceTo(Colors[Array.IndexOf(_Parts, edge.Second)]) / 1.73205080757; M = M * M * M * M; PartScore -= Distance * M * edge.First; } Score += PartScore; if (PartScore < WorstPartScore) { WorstPart = i; WorstPartScore = PartScore; } } return(new Pair <double, int>(Score, WorstPart)); }
public float DistanceTo(FlagColor Color) { float R = (float)(_Color.R - Color.Color.R) / 255; float G = (float)(_Color.G - Color.Color.G) / 255; float B = (float)(_Color.B - Color.Color.B) / 255; return((float)Math.Sqrt(R * R + G * G + B * B)); }
public FlagColor[] Closest(Culture Culture, int Number) { float[] Keys = new float[_Colors.Length]; for (int i = 0; i < _Colors.Length; ++i) { Keys[i] = _Colors[i].DistanceTo(Culture); } Array.Sort(Keys, _Colors); FlagColor[] R = new FlagColor[Number]; Array.Copy(_Colors, R, Number); return(R); }