これは最適化の仕事であり、最適なソリューションを探しているならかなり複雑な仕事です。幸いなことに、私はそれが十分に役立つケースの一つであると信じています。
最初に行うことは、数学的な品質基準を確立することです。これは、リストの順列が与えられると、その順列の程度を表す単一の数値を返す式です。
単純な数式の提案、考慮したい各基準に重みを付け、重要な基準に高い重みを付け、多くの歌が同じ特性を共有する基準に低い重みを与えて、それらが支配しないようにする必要があります:
For each song on the list
For each other song on the list
For each criteria
If the two songs share that criteria
Add to the quality value: square root( [criteria weight]/[distance between the two songs] )
このプロシージャが生成する値が小さいほど、リストの並べ替えは良くなります。
順列を作る
これで、この式をmath.stackexchangeに渡して、些細な数の曲以外の最適なソリューションを見つけるのが非常に困難であり、実際には不可能であるかを教えてもらうか、クロックサイクルを投げて取得することができます良い解決策。
これを行うには多くの方法がありますが、ここにその1つがあります。
Start with a random permutation of the list.
Several million times do the following:
Select two entries at random
For each of those two entries calculate their contribution to the quality value
Swap the positions of the two entries
Calculate the contribution to the quality value of the two entries at their new position
If the sum of the calculations in the new positions is greater than the sum in the old positions
Swap back
これはやや無駄なアルゴリズムですが、実装が簡単で、必要なだけ多くの基準に対処できます。
最適化
さまざまな調整と最適化の負荷を適用できます。以下にいくつかを示します。
品質値の計算では、リストにある他のすべての曲と照合するのではなく、100曲ほど近い曲と照合するだけです。一般的な値の場合、この速度の最適化は結果の品質に実質的に影響しません。
特定のプロパティのまれな値の場合、それらの値を検索するよりも、その値の既存のインスタンスを追跡する方が効率的です。
インスタンスがほとんどない値は、間隔を空けるのではなく、均等に近づけることが重要であると考える場合、その基準の他の値ではなく、それらの特定の値の重みを大きくする必要があります。
リストからすべての可能なペアを等しい分布で選択する擬似ランダム関数は、通常のランダムピックよりもピックごとの効率がわずかに優れている場合があります。