2017-08-16 3 views
-1

にソート半ランダム配列を維持するために私はこのようなたびに数字の配列を生成し、自分のコードでforループを持っている:C++ - どのようにループ

1,2,3,4-

for次のラウンドに:あなたは、各要素が前の要素に近いですが、それは順序が変更されている見ることができるように

2.001、4.008、1.002、2.099

。このループは何千もの時間を実行し、これらの値がどのように変化するかを知る必要がありますが、順序を変更することは不可能です。

どのように並べ替えるのですか?

私の試み:

の1-私はBubbleSortで最大数から最小に彼らにするたびに並べ替えてみました。要素がすべて増加または減少している場合、これは正常に機能します。しかし、それらのいくつかが増加し、いくらか減少するときはない。

私はループの最初のラウンドの要素を保存し、次のラウンドと比較して要素の順序を変更して、最初のラウンドに比べて最小限の変更を行う方法を考えました次のラウンドで。しかし、私はそれを行うための実用的なコードを書くことができませんでした。

編集: 私のコードは非常に大きく複雑なものですが、私はそれをコピーしても混乱を招いてしまいます。しかし、ここで、それがどのように見えるかのサンプルコードです:

for(x=50;x=65;x+=0.01){ 
    for(i=0;i<100;i++) w[i] = SomeCalculations(i); 
    output<<x<<" "<<w[1]<<endl; 
    output<<x<<" "<<w[2]<<endl; 
    ... 
} 
+5

あなたのコードは何に見えますか?なぜ彼らは秩序を変え続けるのだろうか? –

+1

次の反復で '1.6 1.7 4 3'を得たとします。それが' 1.6 1.7'か '1.7 1.6'であるべきかどうかをどのように知っていますか? – user463035818

+0

@MateenUlhaq実際には、変化する行列の固有値を計算しますが、複雑にしたくありませんでした。それらを計算するために使用されるルーチンは、それらを最大から最小まで並べ替えますが、それらの最初の位置を維持して、その動作を監視することができます。 – Alireza

答えて

2

あなたはおそらく、各固有値のための違い(一次誘導体)を監視することができます。次に、固有値が交差していても、最も近い派生物があるかどうかを知ることによって固有値を「追跡」し続けることができます。

このためには、距離関数(またはコスト関数)が必要です。その一例:このすべてが動作するために、もちろん

void track_evals(std::vector<Eigenvalues>& evals, 
       const std::vector<Eigenvalues>& old_evals) { 
    // Loop through new eigenvalues (evals) and match with 
    // old eigenvalues (old_evals) 
    for (auto& e : evals) { 
     // Find closest match 
     auto old = std::min_element(old_evals.begin(), old_evals.end(), 
      [e](const Eigenvalue& a, const Eigenvalue& b) { 
       return dist(a, e) < dist(b, e); }); 

     // Match by copying identifier 
     // You can use a dictionary or some other data structure, 
     // if you prefer 
     e.id = (*old).id; 
    } 
} 

、あなたが正しいを維持する必要があります。私たちは今、互いの間少なくとも距離を持つ固有値のペアを一致させる

double dist(Eigenvalue e1, Eigenvalue e2) { 
    x_dist = abs(e1.x - e2.x); 
    dx_dist = abs(e1.dx - e2.dx); 

    return x_dist + dx_dist; // example distance function 
} 

struct Eigenvalue { 
    int id;  // unique identifier for eigenvalue 
    double x; // actual value 
    double dx; // first order derivative 
} 

Eigenvalueの値:

std::vector<Eigenvalue> evals; 
std::vector<Eigenvalue> old_evals; 

// Precompute eigenvalues 
evals = SomeCalculations(0); 

// Assign unique identifiers 
int id = 0; 
for (auto& e : evals) { 
    e.id = id++; 
} 

// Your for loop 
for (int i = 1; i < 100; i++) { 
    // Save old eigenvalues 
    std::swap(old_evals, evals); 

    // Perform SomeCalculations() and update evals 
    evals = SomeCalculations(i); 

    // Also update derivatives (dx) for each of the evals! 
    auto old = old_evals.begin(); 
    for (auto& e : evals) { 
     e.dx = e.x - (*old++).x; 
    } 

    // Track 
    track_evals(evals, old_evals); 

    // Sort evals into same order (if desired) 
    std::sort(evals.begin(), evals.end(), 
     [](Eigenvalue& a, Eigenvalue& b) { return a.id < b.id; }); 
} 

この方法は絶対的なものではありません。衝突が発生する可能性があります。その場合は、より多くのデリバティブの注文を試したり、固有値が変化する速度を遅くしたりすることができます。

0

使用std::sort

std::sort(std::begin(w), std::end(w)); 

for (auto a : w) { 
    output << x << " "<< a << endl; 
}