- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我试图从矩阵 NXM 中找到任何子矩阵 AXB 的最大元素。我实现了稀疏树方法。但是我无法对此进行优化。其实我需要解决范围查询,所以我需要优化代码。在进行预计算时,对于任何 N,M 值,它都需要 O(NMlog(N)log(M)) 时间复杂度。我怎样才能将其改进为 (N*M)。这是我的预计算代码
for(int i=0; i<n;i++)
for(int j=0; j<m;j++)
cin>>arr[i][j];
for(int i=0; pow(2,i) <= n; i++)
for(int j=0; pow(2,j) <= m; j++)
for(int x=0; x + pow(2,i)-1 < n; x++)
for(int y = 0; y + pow(2,j) -1 < m; y++)
{
i=(int)i;
j=(int)j;
if (i == 0 && j == 0)
M[x][y][i][j] = arr[x][y];
else if (i == 0)
M[x][y][i][j] = maxi(2,M[x][y][i][j-1], M[x][(int)(y+pow(2,(j-1)))][i][j-1]);
else if (j == 0)
M[x][y][i][j] = maxi(2,M[x][y][i-1][j], M[(int)(x+ pow(2,(i-1)))][y][i-1][j]);
else
M[x][y][i][j] = maxi(4,M[x][y][i-1][j-1], M[(int)(x + pow(2,(i-1)))][y][i-1][j-1], M[x][(int)(y+pow(2,(j-1)))][i-1][j-1], M[(int)(x + pow(2,(i-1)))][(int)(y+pow(2,(j-1)))][i-1][j-1]);
}
对于输入 x,y,x1,y1
k = log(x1 - x + 1);
l = log(y1 - y + 1);
int max_element = max(4,M[x][y][k][l], M[(int)(x1 - pow(2,k) + 1)][y][k][l], M[x][(int)(y1 - pow(2,l) + 1)][k][l], M[(int)(x1 - pow(2,k) + 1)][(int)(y1 - pow(2,l) + 1)][k][l]);
如何提高这段代码的性能。请帮忙。
最佳答案
此解决方案并不比 O(N*M*Log(N)*Log(M))
好,但比您的实现要好。
通过查看你的for
循环和访问数组M
的执行顺序,会有太多的内存跳转和缓存未命中,导致程序运行缓慢。
例子:-
查看以下循环所用的时间:
int M[1000][1000][11][11];
for(int i = 0 ; i <= 10 ; i++){
for(int j = 0 ; j <= 10 ; j++){
for(int x = 0 ; x < 1000 ; x++){
for(int y = 0 ; y < 1000 ; y++){
M[x][y][i][j] = 1;
}
}
}
}
上述执行需要 1.9 秒。
int M[11][11][1000][1000];
for(int i = 0 ; i <= 10 ; i++){
for(int j = 0 ; j <= 10 ; j++){
for(int x = 0 ; x < 1000 ; x++){
for(int y = 0 ; y < 1000 ; y++){
M[i][j][x][y] = 1;
}
}
}
}
而这个只需要 0.2 秒。因此,请始终尝试编写循环,以便顺序访问内存。
有关更多详细信息,您可以阅读 here .
因此,如果您按以下方式更改代码,速度会快得多:
M[Log(n)][Log(m)][n][m];
for(int i=0; (1<<i) <= n; i++)
for(int j=0; (1<<j) <= m; j++)
for(int x=0; x + (1<<i)-1 < n; x++)
for(int y = 0; y + (1<<j) -1 < m; y++)
{
i=(int)i;
j=(int)j;
if (i == 0 && j == 0)
M[i][j][x][y] = arr[x][y];
else if (i == 0)
M[i][j][x][y] = maxi(2,M[i][j-1][x][y], M[i][j-1][x][(y+(1<<(j-1)))]);
else if (j == 0)
M[i][j][x][y] = maxi(2,M[i-1][j][x][y], M[i-1][j][(x+ (1<<(i-1)))][y]);
else
M[i][j][x][y] = maxi(4,M[i-1][j-1][x][y], M[i-1][j-1][(x + (1<<(i-1)))][y], M[i-1][j-1][x][(y+(1<<(j-1)))], M[i-1][j-1][(x + (1<<(i-1)))][(y+(1<<(j-1)))]);
}
如果您计算 log()
的次数(即 10^5 或更大的数量级)超过您可以使用 31-__builtin_clz() 的次数,还可以进行另一项优化
而不是 log()
。
k = 31-__builtin_clz(x1 - x + 1);
l = 31-__builtin_clz(y1 - y + 1);
int max_element = max(4,M[k][l][x][y], M[k][l][(x1 - (1<<k) + 1)][y], M[k][l][x][(y1 - (1<<l) + 1)], M[k][l][(x1 - (1<<k) + 1)][(y1 - (1<<l) + 1)]);
关于c++ - NXM矩阵的所有AXB子矩阵中的最大元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37754330/
我有两个二维数组(或更高维度),一个定义平均值 (M),一个定义标准差 (S)。是否有一个 python 库(numpy、scipy、...?)允许我生成一个数组 (X),其中包含从相应分布中抽取的样
我必须解决一个问题,当给定一个网格大小 N x M 时,我必须找到“可以放入其中”的平行四边形的数量,这样它们的每个坐标都是一个整数。 这是我的代码: /* ~Keep It Simple
/* Program to demonstrate gaussian elimination on a set of linear simultaneous equations */ #inc
我想在空间上剪切视频以生成 N x M 个文件。 例如,我想把 test.video 拆分成 NxM 的瓦片? Video tiles 最佳答案 您可以使用 ffmpeg 及其 crop filter
我有 NxM 板。我想给它添加 K 个障碍物,但在某种程度上,仍然可以从每个空的空间到每个其他的空空间。我希望它看起来像这样 其中蓝色方块是障碍物。 换句话说,我有一个图形网格,我想从中随机删除 K
抱歉,这个主题很笼统,但我想不出更好的了:( 假设我有一些固定字符串(名为 s1、s2、... sn,不超过 5 或 6,在示例中为 4 个),我必须使用一些 VARCHAR(50 ) 字段(称为 t
我在我的编程书上遇到了以下我无法解决的问题: 给定一个 nxm 网格,编写一个递归算法来找出该网格可以被 3x1 和 1x3 block 填充的方式的数量。 我对 3 x M 网格的逻辑: 找出可用于
是否可以移除/删除 NxM 矩阵每行中的每个最小值创建一个新矩阵? 到目前为止我已经尝试过了,但没有任何运气: for n in range(0,len(matrix_name)): Ma =
我在一个 nxm 数组中有 5 个 numpy 数组,每个数组包含一组随机值。我需要的是根据它们的累计金额递减来打印它们。例如,我的 nXm 数组如下所示: v = [[1,2,3,4], [2,3
我已经在几个页面上搜索过这个,但我只找到了 NxN 矩阵的实现。 如何定义一个 dimBlock 和一个 dimGrid 来计算这个?另外,如何玩: int row = blockIdx.y*bloc
如果我有一个乘法表,例如 3x5: 1 2 3 4 5 2 4 6 8 10 3 6 9 12 15 我把所有这些数字按顺序排列: 1 2 2 3 3 4 4 5 6 6 8 9 1
我有 3 个有效值:a、b、c我可以将它们插入 Nx3 网格中,使得没有行或列包含相同值的单元格。如何计算使用 N 行可以创建的有效模式的数量? 例如,如果N = 4,则有效模式总数为296490。
我有 3 个有效值:a、b、c我可以将它们插入 Nx3 网格中,使得没有行或列包含相同值的单元格。如何计算使用 N 行可以创建的有效模式的数量? 例如,如果N = 4,则有效模式总数为296490。
我想要一个 NxM 矩阵,为简单起见,我们将使用 x=np.arange(25).reshape((5,5)) 我想创建一个新的矩阵 A,其中我可以为第一行中的每个元素存储一个节点,在第二行中存储其
更新:这称为 de Brujin 环面,但我仍然需要在 C# 中找出一个简单的算法。 http://en.wikipedia.org/wiki/De_Bruijn_torus http://datag
这可能是一个愚蠢的问题,但我刚刚开始使用 numpy,我必须弄清楚如何执行一些简单的操作。 假设我有 2x3 数组 array([[1, 3, 5], [2, 4, 6]]) 并且我想对第一列执
我正在实现一个带有记录和内部动态数组的 N x M 矩阵(类),如下所示。 TMat = record public // contents _Elem: array of array
我有多个 NxM 矩阵,想通过变量选择其中一个。我最好的猜测是使用 boost::MultiArray 创建一个 NxMxP 矩阵,然后通过三维选择。 我使用 array_view 实现了它: typ
到目前为止,我想出了顺时针旋转 NxM(N 不一定等于 M)矩阵(当它表示为高度和宽度变量分别存储的一维 vector 时)的唯一方法如下: struct matrix { vector data
我正在尝试使用 HTML 接收高度和宽度值。有了这些值,我希望使用 jQuery 动态创建一个表。我似乎无法显示表格。以下是代码的相关部分: var color, height, width;// S
我是一名优秀的程序员,十分优秀!