C++ - 如何保持半随机数组在循环中排序

C++ - How to keep a semi-random array sorted in a loop

本文关键字:循环 排序 数组 随机 何保持 C++      更新时间:2023-10-16

我的代码中有一个for循环,每次都会生成一个数字数组,如下所示:

1,2,3,4

在下一轮for

:2.001, 4.008, 1.002, 2.099

如您所见,每个元素都接近前一个元素,但它的顺序发生了变化。这个循环运行数千次,我需要看看这些值是如何变化的,但随着它们改变顺序,这是不可能的。

如何保持它们的排序?

我的尝试:

1-我尝试每次使用BubbleSort从最大数字到最小数字对它们进行排序。如果元素都在增加或减少,这将正常工作。但当其中一些增加和一些减少时,情况并非如此。

2-我想到了一种方法来存储循环第一轮的元素,并将它们与下一轮进行比较并更改元素的顺序,以便与第一轮相比,它们的变化最小,依此类推。但是我无法编写工作代码来做到这一点。

编辑:我的代码是一个非常大和复杂的代码,我确信复制它只会增加混乱。但下面是它的外观示例代码:

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;
...
}

您也许可以监视每个特征值的差异(一阶导数(。然后,您可以继续"跟踪"特征值,即使它相交,方法是对具有最接近导数的导数进行有根据的猜测。

为此,我们需要一个距离函数(或成本函数(。一个这样的例子:

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
}

现在,我们匹配彼此之间距离最小的特征值对:

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;
}
}

当然,要使所有这些工作正常工作,您需要保持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; }); 
}

这种方法并非万无一失。可能存在冲突,在这种情况下,您可能希望尝试更多导数阶数或尝试降低特征值变化的速度。

使用 std::sort

std::sort(std::begin(w), std::end(w));
for (auto a : w) {
output << x << "    "<< a << endl;
}