Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 什么';用MATLAB删除数组中最后一个元素的时间复杂度?_Arrays_Matlab_Data Structures - Fatal编程技术网

Arrays 什么';用MATLAB删除数组中最后一个元素的时间复杂度?

Arrays 什么';用MATLAB删除数组中最后一个元素的时间复杂度?,arrays,matlab,data-structures,Arrays,Matlab,Data Structures,我不知道MATLAB中数组的数据结构。它使用FiFo吗 我尝试从列和行向量中删除最后一个元素。时间复杂度取决于大小N 如何删除O(1)中的最后一个元素 基本上pop() A = ones(1,50); B = ones(1,10); tic A(1) = []; toc tic A(49) = []; toc tic B(1) = []; toc tic B(9) = []; toc Elapsed time is 0.000195 seconds. Elapsed time is 0.00

我不知道MATLAB中数组的数据结构。它使用FiFo吗

我尝试从列和行向量中删除最后一个元素。时间复杂度取决于大小
N

如何删除
O(1)
中的最后一个元素


基本上
pop()

A = ones(1,50);
B = ones(1,10);

tic
A(1) = [];
toc
tic
A(49) = [];
toc
tic
B(1) = [];
toc
tic
B(9) = [];
toc

Elapsed time is 0.000195 seconds.
Elapsed time is 0.000085 seconds.
Elapsed time is 0.000061 seconds.
Elapsed time is 0.000051 seconds.

您可以看到,删除数组的最后一个元素要比删除第一个元素快。

根据数组长度,使用
tic toc
,来测量时间

A = ones(1,50);
B = ones(1,10);

tic
A(1) = [];
toc
tic
A(49) = [];
toc
tic
B(1) = [];
toc
tic
B(9) = [];
toc

Elapsed time is 0.000195 seconds.
Elapsed time is 0.000085 seconds.
Elapsed time is 0.000061 seconds.
Elapsed time is 0.000051 seconds.

您可以看到,删除数组的最后一个元素要比删除第一个元素快。

经过快速测试,我发现就地重新分配要比删除元素快得多。但这两种操作的性能仍然取决于向量大小。。。我只是认为这不可能如您所愿在
O(1)
中实现,因为Matlab内部处理内存的方式

第一种方法:

A = rand(100,1);

tic();
A(end) = [];
toc(); % Average elapsed time: 0.000015 seconds

B = rand(10000,1);

tic();
B(end) = [];
toc(); % Average elapsed time: 0.000061 seconds
A = rand(100,1);

tic();
A = A(1:end-1);
toc(); % Average elapsed time: 0.000007 seconds

B = rand(10000,1);

tic();
B = B(1:end-1);
toc(); % Average elapsed time: 0.000017 seconds
第二种方法:

A = rand(100,1);

tic();
A(end) = [];
toc(); % Average elapsed time: 0.000015 seconds

B = rand(10000,1);

tic();
B(end) = [];
toc(); % Average elapsed time: 0.000061 seconds
A = rand(100,1);

tic();
A = A(1:end-1);
toc(); % Average elapsed time: 0.000007 seconds

B = rand(10000,1);

tic();
B = B(1:end-1);
toc(); % Average elapsed time: 0.000017 seconds
我对Matlab的了解不够深入,无法准确解释引擎盖下发生了什么,以及为什么这两种方法之间存在如此大的差异。但我可以猜一猜

在第一种方法中,Matlab必须:

  • end
    计算为实向量偏移量
  • 找出需要移除的元素数量
  • 分配一个新的大小数组
    total_elements-removed_elements
  • 取数组中未触及的部分,缓冲区将其复制到新数组中
  • 用新的数组引用替换以前的数组引用
  • 取消分配上一个数组
在第二种情况下,Matlab必须:

  • end
    计算为实向量偏移量
  • 分配一个大小
    索引元素的新数组
  • 获取所需的数组范围并将其复制到新数组中
  • 用新的数组引用替换以前的数组引用
  • 取消分配上一个数组

然而,我们离O(1)

还有很长的路要走。经过快速测试,我发现就地重新分配要比元素删除快得多。但这两种操作的性能仍然取决于向量大小。。。我只是认为这不可能如您所愿在
O(1)
中实现,因为Matlab内部处理内存的方式

第一种方法:

A = rand(100,1);

tic();
A(end) = [];
toc(); % Average elapsed time: 0.000015 seconds

B = rand(10000,1);

tic();
B(end) = [];
toc(); % Average elapsed time: 0.000061 seconds
A = rand(100,1);

tic();
A = A(1:end-1);
toc(); % Average elapsed time: 0.000007 seconds

B = rand(10000,1);

tic();
B = B(1:end-1);
toc(); % Average elapsed time: 0.000017 seconds
第二种方法:

A = rand(100,1);

tic();
A(end) = [];
toc(); % Average elapsed time: 0.000015 seconds

B = rand(10000,1);

tic();
B(end) = [];
toc(); % Average elapsed time: 0.000061 seconds
A = rand(100,1);

tic();
A = A(1:end-1);
toc(); % Average elapsed time: 0.000007 seconds

B = rand(10000,1);

tic();
B = B(1:end-1);
toc(); % Average elapsed time: 0.000017 seconds
我对Matlab的了解不够深入,无法准确解释引擎盖下发生了什么,以及为什么这两种方法之间存在如此大的差异。但我可以猜一猜

在第一种方法中,Matlab必须:

  • end
    计算为实向量偏移量
  • 找出需要移除的元素数量
  • 分配一个新的大小数组
    total_elements-removed_elements
  • 取数组中未触及的部分,缓冲区将其复制到新数组中
  • 用新的数组引用替换以前的数组引用
  • 取消分配上一个数组
在第二种情况下,Matlab必须:

  • end
    计算为实向量偏移量
  • 分配一个大小
    索引元素的新数组
  • 获取所需的数组范围并将其复制到新数组中
  • 用新的数组引用替换以前的数组引用
  • 取消分配上一个数组

然而,我们远远没有遵循来自的计时脚本,它处理相反的问题——增长一个向量,我尝试了两种方法来删除最后一个元素:

building_array = building_array(1:end-1);
building_array(end) = [];
如图所示,前者(蓝色)比后者(红色)快:

关于这两种形式的计时方式不同的原因,我的猜测是,MATLAB的JIT(实时编译器)针对一种语法比另一种更优化。没有技术上的理由说明一个比另一个快

我真的很惊讶,成本在元素数量上是线性的,这与当时添加元素的行为非常不同

测试代码(修改自):


按照中处理相反问题的计时脚本——增长向量,我尝试了两种方法来删除最后一个元素:

building_array = building_array(1:end-1);
building_array(end) = [];
如图所示,前者(蓝色)比后者(红色)快:

关于这两种形式的计时方式不同的原因,我的猜测是,MATLAB的JIT(实时编译器)针对一种语法比另一种更优化。没有技术上的理由说明一个比另一个快

我真的很惊讶,成本在元素数量上是线性的,这与当时添加元素的行为非常不同

测试代码(修改自):


免责声明:这不是一个真正的建议,它只是一个愚蠢的方式来实际获取O(1)运行时

对,在给出免责声明后,实际上可以在“Matlab”中生成O(1)pop命令。解决方案不是用Matlab,而是用Python。困惑

基本上,使用
py.list()
将向量转换为Python列表,然后可以执行O(1)
pop
命令。因此,您可以执行以下操作:

a = randn(1,1e4);
li=py.list(a);
b = li.pop;
然而,正如您可能已经猜到的,通过Matlab进行类型转换和运行python并不是我所说的快速。所以,即使我们可以保持一个恒定的运行时,这个常数对于它来说太大了,没有任何用处

在图中,蓝色是Matlab/Python解决方案,而红色(-ish)是最佳解决方案,如Tommaso和Cris所示

很明显,我们保持了O(1)的样子,但这是有代价的

参考代码:

num_averages = 100;
num_sims = 10000;
time_store = nan(num_sims, num_averages);
for i = 1:num_averages
    building_array = rand(1,num_sims);
    li = py.list(building_array);
    for j = 1:num_sims
        tic;
        li.pop;
        time_store(j, i) = toc;
    end
end
编辑:此方法比纯Matlab解决方案快的大小实际上在某个合理的限制范围内~150000

注:f