我有一个未分类的特征值和特征向量矩阵的载体。我想根据分类的特征值集对矩阵的列进行排序。 (例如,如果特征值[3]移至特征值[2],我希望特征值矩阵的第3列移至第2列。)

我知道我可以在 O(N log N) 通过 std::sort. 。如果不滚动我自己的排序算法,我如何确保矩阵的列(相关的特征向量)随着他们的特征值而在后者进行分类时跟随其特征值?

有帮助吗?

解决方案

通常只是创建这样的结构:

struct eigen { 
    int value;
    double *vector;

    bool operator<(eigen const &other) const { 
        return value < other.value;
    }
};

另外,只需将特征值/特征向量放入 std::pair - 虽然我喜欢 eigen.valueeigen.vector 超过 something.firstsomething.second.

其他提示

在不同情况下,我已经多次做到这一点。而不是对数组进行排序,而只需创建一个带有排序索引的新数组即可。

例如,您有一个长度n数组(向量)evals,而2D NXN数组的Evects。创建一个包含值[0,n-1]的新数组索引。

然后,您没有以evals [i]访问evals,而是作为evals [index [i]]访问它,而不是Exects [i] [j],而是访问它的Evects [index [i] [j] [j]。

现在您编写排序程序以对索引数组进行排序,而不是evals数组,因此索引中的索引数组中的值将以越来越多evals数组中的值。

因此,在排序之后,如果您这样做:

for (int i=0;i<n;++i)
{
  cout << evals[index[i]] << endl;
}

您将获得一个排序的Evals列表。

这样,您可以对与Evals数组相关的任何内容进行整理,而无需实际移动内存。当n变大时,这很重要,您不想在Evects矩阵的列周围移动。

基本上,最小的评估将位于索引[i],这对应于索引[i] exect。

编辑要添加。这是我为与STD ::合作的一种类别函数来做我刚才说的事情:

template <class DataType, class IndexType>
class SortIndicesInc
{
protected:
    DataType* mData;
public:
    SortIndicesInc(DataType* Data) : mData(Data) {}
    Bool operator()(const IndexType& i, const IndexType& j) const
    {
        return mData[i]<mData[j];
    }
};

该解决方案纯粹依赖于您存储特征向量矩阵的方式。

如果您可以实施,将实现排序时最好的性能 swap(evector1, evector2) 这样它只会重新定位指针,而真实数据则保持不变。

这可以使用类似 double* 或可能更复杂的东西取决于您的矩阵实现。

如果这样做, swap(...) 不会影响您的排序操作性能。

在C ++中进行企业和矩阵的结合的想法可能是完成此操作的最佳方法。我正在考虑如何在R中做到这一点,看看是否可以将其翻译成C ++。在r中非常容易,简单地evec <-evec [,order(eval)]。不幸的是,我不知道在C ++中执行Order()操作的内置方式。也许其他人会这样做,在这种情况下,这可以以类似的方式完成。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top