MATLAB中的整数集数组

时间:2016-01-21 20:48:22

标签: arrays matlab set

我有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中。

2 个答案:

答案 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