如何在Matlab中存储这个结构(整数列表)?

And*_*eas 3 matlab data-structures

我需要存储一个整数列表.例如,X[1]应该能够包含[1 3 5]虽然X[2]可以包含[1 2].什么是最好的解决方案?一个单元阵列?


背景故事:

对于项目,我预先计算N行和M立方体之间的交叉点.这些是以两种方式检索的:给定一个行索引,我想要一个它通过的立方体列表,并给定一个立方体索引,我想要一个通过它的行列表.

典型值是N = 2 ^ 24且M = 2 ^ 18,这意味着交叉矩阵(NxM)是不可能的.幸运的是,平均线仅通过M ^(1/3)= 2 ^ 6个立方体.目前,我将结构存储为NxM ^(1/3)矩阵,因此这X(n,:)是第n行穿过的多维数据集向量(用零填充).

这适用于检索给定列表索引的多维数据集,但事实证明我的代码的瓶颈是给定多维数据集索引的行的检索.(我这样做,find(X==m)其中m是立方体索引.)我不能创建相反的矩阵,因为通过单个立方体的行数可能非常高,即使它平均很低.

Pur*_*uit 11

通常,单元阵列是正确的答案.这是最简单的情况.一些示例使用:

%Writes
X = {[1], [1 2 3], [1 2]};
X{4} = [1 2 3 4];

%Reads
a = X{1}
b = cat(2,X{:});
c = X([2 4]);
Run Code Online (Sandbox Code Playgroud)

但是,这不是唯一的答案.

您可以使用一组结构,每个结构都有一个名为.indexes(或根据您的问题的适当名称)的字段.如果您希望将附加信息附加到列表列表中,则可以更灵活一些,例如,可以将多维数据集位置添加为.position字段.示例用途:

%Writes
X(1).indexes = 1;
X(2).indexes = [1 2 3];
X(3).indexes = [1 2];

%Reads
a = X(1).indexes
b = cat(2,X.indexes)
c = X([2 4]);
Run Code Online (Sandbox Code Playgroud)

您还可以使用containers.Map对象.这与结构数组具有相同的优点,但在引用对象时具有更大的灵活性.而当使用结构数组时,结构是索引引用,使用容器.Map对象可以使用任意数字(不是1附近的整数)或名称(对于2 ^ 24个案例不实用)引用每个结构.这可能不是您的最佳答案,但参考示例用途如下:

%Writes
X = containers.Map('keyType','uint32','valueType','Any');
X(1) = [1];
X(2) = [1 2 3];
X(3) = [1 2];
X(4) = [1 2 3 4];

%Reads
a = X(1);
b = cat(2,X.values);
Run Code Online (Sandbox Code Playgroud)

最后,为此定义一对自定义类可能是值得的.这是设置的更多工作,但可能是将常量时间查找到预先计算的值的最简单方法.一些让你从这条路走下去的代码如下.

%A start at cube.m.  Most of the code handles smartly reallocating the list of lines.
classdef cube < handle
    properties (SetAccess = private, GetAccess = public)
        numLines = 0
        intersectingLines = [];
    end
    methods (Access = public)
        function addLine(self, lineToAdd)
            if self.numLines == 0
                self.intersectingLines = lineToAdd;
                self.numLines = 1;
            elseif self.numLines>=length(self.intersectingLines)
                self.intersectingLines(length(self.intersectingLines)*2) = line();
                self.intersectingLines(self.numLines+1) = lineToAdd;
                self.numLines = self.numLines+1;
            else
                self.intersectingLines(self.numLines+1) = lineToAdd;
                self.numLines = self.numLines+1;
            end
        end
    end
end

%A start at line.m.  A near copy/paste of cube.m
    classdef line < handle
    properties (SetAccess = private, GetAccess = public)
        numCubes = 0
        intersectingCubes = [];
    end
    methods (Access = public)
        function addCube(self, cubeToAdd)
            if self.numCubes == 0
                self.intersectingCubes = cubeToAdd;
                self.numCubes = 1;
            elseif self.numCubes>=length(self.intersectingCubes)
                self.intersectingCubes(length(self.intersectingCubes)*2) = cube();
                self.intersectingCubes(self.numCubes+1) = cubeToAdd;
                self.numCubes = self.numCubes+1;
            else
                self.intersectingCubes(self.numCubes+1) = cubeToAdd;
                self.numCubes = self.numCubes+1;
            end
        end
    end 
end
Run Code Online (Sandbox Code Playgroud)

要使用这些类作为写的,你需要调用add方法对(一个明显的升级后是正常的交叉补充.同时(因为我懒),我们将定义一个辅助函数.

function crossAdd(cube, line)
cube.addLine(line);
line.addCube(cube);
Run Code Online (Sandbox Code Playgroud)

现在示例使用是:

%Create two class arrays of cubes and lines
allCubes(1) = cube;
allCubes(2) = cube;
allCubes(3) = cube;
allCubes(4) = cube;

allLines(1) = line;
allLines(2) = line;
allLines(3) = line;
allLines(4) = line;

%Define links (matching above "writes" examples)
crossAdd(allCubes(1), allLines(1));
crossAdd(allCubes(2), allLines(1));
crossAdd(allCubes(2), allLines(2));
crossAdd(allCubes(2), allLines(3));
crossAdd(allCubes(3), allLines(1));
crossAdd(allCubes(3), allLines(2));
crossAdd(allCubes(4), allLines(1));
crossAdd(allCubes(4), allLines(2));
crossAdd(allCubes(4), allLines(3));
crossAdd(allCubes(4), allLines(4));

%Use linked values
aLines = allCubes(1).getLines   %Only one intersecting line
bLines = allCubes(2).getLines   %Three intersecting lines
cubesFromSecondLine = bLines(2).getCubes %Three cubes here (2, 3, 4)
Run Code Online (Sandbox Code Playgroud)

顺便说一句,我们实际上只是假设< handle类表现为传递引用这一事实,因此我们可以使用复杂的交叉链接数据结构.