2

私たちのプロジェクトでは、フィギュアごとに異なる色を使用するようにします。これらの色は、次の条件を満たす必要があります。

  1. すべての色が満たされている必要があります:abs(AR-AG)+ abs(AG-AB)+ abs(AB-AR)> 250
  2. すべての色は十分に異なっている必要があります。色AとBが一致する場合:abs(AR-BR)+ abs(AG-BG)+ abs(AB-BB)> = 50の場合、それらは十分に異なります。問題は、最大で何色を取得できるかということです。すべての組み合わせを列挙せずに色を取得するための迅速な方法はありますか?
4

2 に答える 2

2

色が必要な場所 (ウェブサイト、写真など) によって異なります。私はかつて非常によく似た問題に遭遇しました。以下は私が見つけたものです。最後に、HSV 色空間を使用しました (これは私のアプリケーションでは簡単でした)。これにより、色相範囲を同じサイズの間隔に分割し、毎回異なる色を得ることができます。

これは私が便利だと思ったものです:

グラフで明確に異なる RGB カラーを生成する

N個の「異なる」色を自動的に生成する方法は?

ユニークな色を生成する

于 2012-11-12T10:15:27.920 に答える
2

正確な結果を得る最も簡単な方法は、現在のセットを無効にしないランダムな色を段階的に追加することで、できるだけ大きな色のセットを構成しようとするラスベガス アルゴリズムを使用することだと思います。そのような色が利用できない場合 (たとえば、そのような色を見つけるための最後の 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;
}
于 2012-11-12T12:02:49.393 に答える