我有n个不同的唯一无符号32位整数。对于for循环中的每个整数,我将生成一个随机索引(地址),我想将该数字设置为该索引(地址)指定的集合。例如,在for-loop中我达到7号,我的代码产生13作为地址,然后我需要将数字7添加到第13组。索引(地址)范围为1到k,我将需要k个不同的集合。目前我正在使用" cell" MATLAB中的数据结构。
array_of_sets=cell(n,1);
当我想将新成员添加到第i组时,我将通过array_of_sets {i}进行索引,然后我将连接我的新数字。
我的问题是这种方法不是内存效率,也不是时间效率。任何人都可以指导我以更有效的方式来做到这一点。
这是我的代码到目前为止的简化版本:
array_of_sets=cell(k,1);
for i=1:n
address=something_genrated_randomly;
array_of_sets{address}=[array_of_sets{address},uint32(i)]; %Add to the corresponding set(One specific Cell)
end
输出:给定索引ind,输出第n组整数。
基本上我要找的是类似于Java的ArrayList<Set<Integer>>
但是在MATLAB中。
答案 0 :(得分:0)
单元格需要一些额外的内存才能存储您需要的信息。对于完整单元独立的矩阵大小和数据类型,这似乎是112字节。对于空单元,分配8个字节,这与64位指针相同(可以假设这使得每个单元的标头112-8 = 104字节)。这意味着如果您的阵列很短,您将会遇到巨大的内存浪费。如果您可以保证所有单元格都小于28个元素(112/4),那么对于每种情况(零填充),三维向量都会更便宜。但是,如果某些单元格过度表示,您可能会使用单元格来节省内存。此外,正如其他人所说,细胞也很慢。因此,如果执行时间有问题,可能需要考虑这一点。此外,如果RAM已满,您将开始交换,这将大大减慢执行速度。如果这是问题,那么降低内存应该是主要问题。
a = cell(1,2);
a{1} = zeros(100);
b=zeros(100);
c = cell(1,2);
d = cell(10,10);
e = cell(10,10);
d(:,:) = {zeros(10)};
e(:,:) = {zeros(10,10,10)};
f = zeros(100,1000);
whos
Name Size Bytes Class Attributes
a 1x2 80120 cell
b 100x100 80000 double
c 1x2 16 cell
d 10x10 91200 cell
e 10x10 811200 cell
f 100x1000 800000 double
修改强>
使用零填充数组时,这种方法可以创建非重复的整数集。假设您需要100组,每组大约1000个值。此外,如果您假设随机值的分布是均匀的,它们可能会相当均匀地分布。假设每组平均值为10的变化。这意味着10 * number_of_sets值将为零。
maxVal = 100000;
nSets = 100;
nonAssigned = 1000;
sets = randperm(maxVal);
sets(sets > (maxVal-nonAssigned)) = 0;
sets = reshape(vec,100,1000);
这会将所有“空”值设置为零,在这种情况下,我们有大约1%的内存开销。这仍然比使用占用32 * SIZE位的HashSet或TreeSet更好。如果这1%太多,您可能需要迭代迭代并生成一些集合。如果您需要这么多数据,我认为您没有太多选择。如果这会导致内存问题,您可能需要查看是否在c和mex中编写代码,该函数将解决您的问题。
答案 1 :(得分:0)
我认为你的问题归结为:
问题: 如何有效地将一组n
整数随机分配到k
个子集中?
如果这确实是您所要求的,那么这是一个简单的解决方案,只需要在内存中存储2*n
值,避免使用单元格和零填充数组,并使用逻辑索引速度。
解决方案:分配随机&#34;地址&#34;的向量,然后在需要引用特定集合时使用逻辑索引:
%// for example:
n = 10;
k = 4;
%// 1-by-n vector of integers, for example:
ints = 1:n;
%// 1-by-n vector of random "addresses" between 1 and k
address = randi([1,k],[1,n]);
现在,您可以使用逻辑索引访问任何子集:
set1 = ints(address==1);
set2 = ints(address==2);
...
setk = ints(address==k);
在内存方面,您需要存储2*n
值:整数及其地址。如果子集的大小大致相同,则使用零填充阵列可能更便宜。
示例:强>
>> [ints;address]
ans =
1 2 3 4 5 6 7 8 9 10
4 4 1 4 3 1 2 3 4 4
>> set1=ints(address==1)
>> set2=ints(address==2)
>> set3=ints(address==3)
>> set4=ints(address==4)
set1 =
3 6
set2 =
7
set3 =
5 8
set4 =
1 2 4 9 10
您还可以使用sortrows
重新排序整数和地址:
>> sortrows([ints;address]',2)'
ans =
3 6 7 5 8 1 2 4 9 10
1 1 2 3 3 4 4 4 4 4