正確な結果を得る最も簡単な方法は、現在のセットを無効にしないランダムな色を段階的に追加することで、できるだけ大きな色のセットを構成しようとするラスベガス アルゴリズムを使用することだと思います。そのような色が利用できない場合 (たとえば、そのような色を見つけるための最後の 100 回の試行が失敗したため)、現在のセットが結果を形成します。
スタックした場合、間違った追加の可能性を「元に戻す」ことはせず、終了するだけであることに注意してください。これにより、アルゴリズムは多くの最適でないセットを報告しますが、非常に迅速です。したがって、このアルゴリズムを数回 (数千回?) 実行して、構成できるセットのサイズを確認する必要があります。
これは、比較的少ないプログラミングや分析の労力でまともな結果を得る迅速な方法の 1 つだと思います。
編集:いくつかのクイックランを行いました:私が見つけた競合しない色で構成される最大セットサイズは273でした。
編集 2要求に応じて、対応する (関連する) ソースコード:
public class Colour
{
public int Red;
public int Green;
public int Blue;
public int Primality
{
get { return Math.Abs(Red - Green) + Math.Abs(Green - Blue) + Math.Abs(Blue - Red); }
}
public int Difference(Colour other)
{
return Math.Abs(this.Red - other.Red) + Math.Abs(this.Green - other.Green) + Math.Abs(this.Blue - other.Blue);
}
public Colour(int red, int green, int blue)
{
Red = red;
Green = green;
Blue = blue;
}
public static Colour Generate(Random rnd)
{
return new Colour(rnd.Next(256), rnd.Next(256), rnd.Next(256));
}
public static Colour GeneratePrimal(Random rnd)
{
Colour candidate = null;
do
{
candidate = Generate(rnd);
} while (candidate.Primality <= 250);
return candidate;
}
}
このクラスを使用すると、説明したアルゴリズムを 1 回実行すると、次のようになります。
private Random _rnd = new Random();
public List<Colour> Run()
{
List<Colour> resultSet = new List<Colour>();
//Shouldn't find a set larger than 1000 Colours.
for (int colourCount = 0; colourCount < 1000; colourCount++)
{
Colour candidate = null;
bool found = false;
//100000 means: Try *very* hard to find a next candidate
for (int index = 0; index < 100000; index++)
{
candidate = Colour.GeneratePrimal(_rnd);
if (resultSet.Any(col => candidate.Difference(col) < 50) == false)
{
resultSet.Add(candidate);
found = true;
break;
}
}
if (found == false)
return resultSet;
}
return resultSet;
}