我想生成一个具有固定稀疏性和随机索引和值的矩阵。
为了简化问题,以数组为例:生成一个只有3个非零值位置的arr [10]。如果我只是逐个随机选择这3个索引,那么由于重复,算法的效率很差。
更难,我还想生成一个排名为k的随机矩阵,因为空cols和行可能会导致我的代码出错...这次如何制作?
谢谢!
答案 0 :(得分:5)
您可以使用STL的 random_shuffle :
来完成此操作#include <vector>
#include <algorithm>
// Function that generates random array elements
int random_element();
const int n = 10; // Size of the array
const int k = 4; // Number of random (non-zero) elements in the array
int a[n]; // The array, filled with zeros
int main()
{
for (size_t i = 0; i < k; ++i)
a[i] = random_element();
std::random_shuffle(a, a + n);
// Now 'a' contains k random elements and (n-k) zeros, in a random order
}
答案 1 :(得分:0)
如果数组的大小为N且K是非零条目的数量,则执行以下操作:
ARRAY_ELT_TYPE a[N];
int r[N];
for (i = 0; i < N; i++) { a[i] = 0; r[i] = i; }
for (i = 0; i < K; i++) {
swap(r[i], i + random_nonneg_less_than(N - i));
a[r[i]] = nonzero_value();
}
正如已经指出的那样,你也可以将非零元素放在数组的开头并将其洗牌。如果你只是初始化一次,这显然是一个更好的算法。
当您必须多次将a
重新初始化为不同的随机矩阵时,才能实现上述算法的优势。只需保持r
。不需要重新初始化。每次后续插入K个非零元素只需要K步。如果K与N相比较小,这可能是一个巨大的胜利:
ARRAY_ELT_TYPE a[N];
int r[N];
// Initialize one time.
for (i = 0; i < N; i++) { a[i] = 0; r[i] = i; }
j = 0;
for (many, many iterations) {
// Insert non-zero values in K steps.
for (i = 0; i < K; i++) {
swap(r[i], i + random_nonneg_less_than(N - i));
a[r[i]] = nonzero_value();
}
//
// USE RANDOM ARRAY a HERE
//
// Re-zero a in only K steps.
for (i = 0; i < K; i++) a[r[i]] = 0;
}
答案 2 :(得分:0)
任何N维数组都可以展平为1维(为了枚举其所有元素)。假设您有一个5x7数组 - 这意味着它中总共有35个元素。
一旦你“填写”了第一个元素,可用插槽的总数就会减少一个,这样你就可以将阵列视为现在只有34个“空”点 - 所以你现在需要做的只是填写索引在0到33之间的元素,并且在找到该元素时记得跳过已填充的元素。
这第二部分可能会耗费时间,所以如果你的数组总是非常稀疏,你可以在一个单独的数组中列出所有那些“采取”点...不,这对你没有多大帮助。所有点的单独链接列表也将是低效的 - 需要花费太多时间(相对)来为每次迭代分配和遍历。
本质上问题是在修改后的数组中找到一种快速的索引方法,其中元素的总数表示尚未采用的点和任何方式的稀疏数组记录那些被捕获的点数将超过在发生碰撞时生成下一个随机索引所需的时间。
只有当数组的密度大大或多或少(其中“或多或少”是我未知的值,但我预计它会高于60%-70%)才可能是保留已使用元素的记录可能会超过生成非重复索引所需的时间。
答案 3 :(得分:-2)
a
嗯,我是编程的新手,我正在寻找一种创建随机条目矩阵的方法,我这样做并且实际上有效,希望这对你有用。 :d