【问题标题】:C++ STL Vector Sorting - corrupting & zeroing outC++ STL 向量排序 - 破坏和归零
【发布时间】:2011-02-03 19:06:19
【问题描述】:

我正在开发的程序旨在处理大量数据并生成至少 2^34 个布尔数据。这些数据在整个程序运行过程中静态生成和清除(每个实例仅对一部分进行排序),最后将至少 2^21 行统计数据的向量传递到最后阶段进行进一步处理。

但是,对于某些输入数据,STL 排序失败。在排序完成其过程后,一些向量行将被清零或损坏。看来我唯一的选择是尝试硬编码混合快速排序/插入排序算法。

如果您能表达自己的想法,我将不胜感激。干杯。


最后阶段数据的数据结构:

struct statisticalValues{
    unsigned long long id;      //index id
    unsigned int col_Sum;       //Sum: total number of 1s for each combination
    unsigned int col_Relevancy; //Relevancy = total number of 1s produced by (Comb AND Rel)
    float col_Sensitivity;      //Sensitivity= Relevancy / X
    float col_Precision;        //Precision= Relevancy / Sum
};
extern vector<statisticalValues> statistics;

调用 STL 排序:

sort(statistics.begin(), statistics.end(), BySensitivity());

比较标准:

#define EPSILON 0.0001 // user-defined tolerance for equality of floating-point numbers
struct BySensitivity {
    bool operator()(statisticalValues const &a, statisticalValues const &b) const {
        float sensitivityDif = b.col_Sensitivity - a.col_Sensitivity;

        if((sensitivityDif < EPSILON) && (sensitivityDif > -EPSILON)){
            return ((b.col_Precision - a.col_Precision) < EPSILON);
        }else{
            return (sensitivityDif < -EPSILON);
        }
    }
};

将被破坏的样本数据行(不分先后):

id,col_Sum,col_Relevancy,col_Sensitivity,col_Precision
1568676,5353,3696,94.166,69.045
1770228,5353,3696,94.166,69.045
2040533,5353,3696,94.166,69.045
2053376,5353,3696,94.166,69.045
1231712,4668,3425,87.261,73.372
1946656,4668,3425,87.261,73.372
1948021,4668,3425,87.261,73.372

在通过 STL 排序进行破坏和归零后:

id,col_Sensitivity,col_Precision
10540996614775448722,5.8399e-34,5.8399e-34
8589934369,0.0000,0.0000
0,0.0000,0.0000
0,0.0000,0.0000
0,0.0000,0.0000
0,0.0000,0.0000
0,0.0000,0.0000


实施建议的修改后:

比较标准:

struct BySensitivity {
    bool operator()(statisticalValues const &a, statisticalValues const &b) const {
        float sensitivityDif = b.col_Sensitivity - a.col_Sensitivity;

        if((sensitivityDif <= EPSILON) && (sensitivityDif >= -EPSILON)){
            return ((b.col_Precision - a.col_Precision) < -EPSILON);
        }else{
            return (sensitivityDif < -EPSILON);
        }
    }
};

感谢@Mark-B、@btilly、@David-Thornley、@sth 和 @Daniel-Gallagher

【问题讨论】:

  • 向量是在哪里创建的,它是如何在您的程序中传递的?
  • 您在使用stable_sort时是否会受到损坏?
  • 绝对没有显示使用单词vector的代码。请显示statistics 的定义以及如何添加一些示例值。然后,展示您如何打印结果。届时我们或许可以提供帮助。
  • 也许不是问题,但看起来如果您使用BySentitivity 将一个值与自身进行比较,它会声称该值小于自身。它不应该这样做,您可能希望在if 的第一种情况下使用` ((b.col_Precision - a.col_Precision)

标签: c++ sorting stl vector corruption


【解决方案1】:

您的比较器没有实现严格的弱排序。例如两个项目 AB 等于 col_Sensitivitycol_PrecisionA B 和 B A 都是 true。正如您可以想象的那样,尝试使用实际上不提供排序的排序函数进行排序可能会产生未定义的行为。

感谢(并引用)@David Thornley 的标准参考:

标准,25.3/3 的一部分:“对于 算法正常工作,comp有 诱导严格的弱排序 值。”这意味着不 具有严格的弱排序是 未定义(标准什么也没说)。

我认为在这种情况下,您只想完全删除所有 epsilon 检查:

struct BySensitivity {
bool operator()(statisticalValues const &a, statisticalValues const &b) const {
    float sensitivityDif = b.col_Sensitivity - a.col_Sensitivity;

    if(sensitivityDif == 0.0)){
        return ((b.col_Precision - a.col_Precision) < 0.0);
    }else{
        return (sensitivityDif < 0.0);
    }
}};

【讨论】:

  • 谢谢马克。我今晚必须运行它才能看到结果。再次感谢。
  • 标准,25.3/3 的一部分:“为了使算法正常工作,comp 必须对值进行严格的弱排序。”这意味着没有严格的弱排序是未定义的(标准什么也没说)。严格弱排序的定义在 25.3/4 中:基本上是非自反性和传递性。如果A &lt; BB &lt; A,传递性给我们A &lt; A,这违反了反自反性。
  • 感谢大卫,很好的参考。
【解决方案2】:

如果比较运算符会产生不一致的结果,例如 x

您的比较运算符可能会产生不一致的结果。

【讨论】:

  • 感谢大家的时间和考虑。 #btilly,我认为你可能是对的。我今晚必须运行它才能看到结果。再次感谢。
猜你喜欢
  • 2018-10-10
  • 2011-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-13
相关资源
最近更新 更多