一意の整数のリストがあり、それらを並べ替えて、次の整数が常に残りの整数からできるだけ離れているようにしたいと考えています。
たとえば、{1,2,3,4,5,6,7,8,9} => {1,9,6,2,8,3,7,4,5}
そして、私はそれを本当に速くする必要があります。
現在、私は次のようにしています:
static double GetDistanceIndex(int value, List<int> others)
{
double result=0;
foreach (var other in others)
{
result += Math.Sqrt(Math.Abs(other - value));
}
return result;
}
static List<int> Sort(List<int> items, int initialValue)
{
items = items.ToList();
List<int> result=new List<int>();
lock (rnd)
{
while (true)
{
result.Add(initialValue);
items.Remove(initialValue);
if (items.Count == 0)
{
break;
}
Dictionary<double, List<int>> distances = new Dictionary<double, List<int>>();
foreach (var item in items)
{
var d = GetDistanceIndex(item, result);
if (!distances.ContainsKey(d))
{
distances[d] = new List<int>();
}
distances[d].Add(item);
}
var max = distances.Keys.Max();
var l = distances[max];
//if (l.Count == 1)
//{
// initialValue = l[0];
//}
//else
//{
initialValue = l[rnd.Next(l.Count)];
//}
}
}
return result;
}
しかし問題は、このように実装されたアルゴリズムは、大きな配列に対して非常に遅く動作することです。
誰かが私にそれを行うためのより良い方法を提案できますか?
アップデート
何が行われたかについてのより良い説明は次のとおりです。
{1,2,3,4,5,6,7,8,9}=>
- 初期シード : 1. 実際には、任意の数にすることができます。5 を選択して、{5,9,1,2,8,3,7,6,4} のようなものを取得できます。
- 提供された配列から、9 は距離によって 1 から最も離れています
- リストでは、すべての数字が 1 と 9 から等距離にあるため、任意の数字を選択できます。rand を使用して 6 を選択しました。
- ここで、{1,9,6} から最も離れた数を探しています。and がor or or or orより大きい
abs(2-1)+abs(2-9)+abs(2-6)=12
ため、2 が選択されます。abs(3-1)+abs(3-9)+abs(3-6)=11
abs(4-1)+abs(4-9)+abs(4-6)=10
abs(8-1)+abs(8-9)+abs(8-6)=10
abs(7-1)+abs(7-9)+abs(7-6)=9
abs(5-1)+abs(5-9)+abs(5-6)=9
- 等
更新 1
このアルゴリズムを使用して、固定数の選択肢から可能な限り互いに異なる数を選択しています
更新 2
Dukeling は答えの中で、{1,9,2,8,3,7,4,6,5} も私の要件に準拠していると指摘しました。これは本当でした、そしてそれは私の間違いです。数字をできるだけ離したいのですが、最初の数字に非常に近い3次元の数字は意図したものではありません。だから私はこれを反映するために距離関数を更新しています