Algorithm 用相邻单元的平均值替换矩阵中的每个单元
要求:必须在适当的地方完成 例如: 给定矩阵Algorithm 用相邻单元的平均值替换矩阵中的每个单元,algorithm,matrix,Algorithm,Matrix,要求:必须在适当的地方完成 例如: 给定矩阵 1, 2, 3 4, 5, 6 7, 8, 9 应替换为其3*3个相邻单元和自身单元之和的平均值: (1+2+4+5)/4, (2+1+3+4+5+6)/6 , (3+2+6+5)/4 (1+2+5+4+7+8)/6, (1+2+3+4+5+6+7+8+9)/9, (2+3+5+6+8+9)/6 (4+5+7+8)/4, (4+5+6+7+8+9)/6, (5+6
1, 2, 3
4, 5, 6
7, 8, 9
应替换为其3*3个相邻单元和自身单元之和的平均值:
(1+2+4+5)/4, (2+1+3+4+5+6)/6 , (3+2+6+5)/4
(1+2+5+4+7+8)/6, (1+2+3+4+5+6+7+8+9)/9, (2+3+5+6+8+9)/6
(4+5+7+8)/4, (4+5+6+7+8+9)/6, (5+6+8+9)/4
即:
All floating number convert to int
3, 3.5(3), 4 3, 3, 4
4.5(4), 5, 5.5(5) => 4, 5, 5
6, 6.5(6), 7 6, 6, 7
我试图迭代矩阵并更新每个单元格,但我发现这会影响未来的计算:
假设我将原始1更新为3,但当我尝试更新原始2时,原始1现在变为3
复制原始矩阵来计算平均值是一个解决办法,但这不是一个好主意,我们能在不占用那么多空间的情况下实现吗 在大多数情况下,您只需创建原始矩阵的副本,并将其用于计算平均值。除非创建矩阵副本会使用比可用内存更多的内存,否则开销应该可以忽略不计 如果您有一个非常大的矩阵,您可以使用“滚动”备份(没有更好的术语)。假设您逐行更新单元格,并且当前位于第n行。您不需要备份第n-2行,因为这些单元格不再相关,第n+1行也不相关,因为它们仍然是原始值。因此,您可以只保留上一行和当前行的备份。每当前进到下一行时,放弃上一行的备份,将当前行的备份移动到上一行,并创建新的当前行的备份 一些伪代码(不考虑任何边缘情况):
(您还可以保留下一行的备份,这样您就可以对所有值只使用备份行,而不必进行区分。)在大多数情况下,您应该创建原始矩阵的副本,并使用该副本计算平均值。除非创建矩阵副本会使用比可用内存更多的内存,否则开销应该可以忽略不计 如果您有一个非常大的矩阵,您可以使用“滚动”备份(没有更好的术语)。假设您逐行更新单元格,并且当前位于第n行。您不需要备份第n-2行,因为这些单元格不再相关,第n+1行也不相关,因为它们仍然是原始值。因此,您可以只保留上一行和当前行的备份。每当前进到下一行时,放弃上一行的备份,将当前行的备份移动到上一行,并创建新的当前行的备份 一些伪代码(不考虑任何边缘情况):
(您还可以保留下一行的备份,这样您就可以对所有值仅使用备份行,而不必区分。)您必须对结果数据进行某种缓存,以便保留对原始数据的引用。我认为没有办法解决这个问题 如果数据集很大,可以通过使用较小的数据缓冲区(如通过锁孔查看)并在更新时“滚动”输入矩阵来进行优化。在您的情况下,可以使用小到3x3的缓冲区。 不过,这是速度和空间之间的折衷。缓冲区越小,性能就越差 要可视化问题,请从数据集的左上角(0,0)开始:
(为简单起见,结果值向下舍入) 第一步:更新前4个单元格(初始化缓冲区) 然后对于每个迭代..
(用[xx]表示的新值) ++从结果集中更新数据集中的第一列
// Data Set // Data Viewport // Result Set
[04],02,03,04,05 01,02,03 04,04,??
[06],07,08,09,10 06,07,08 06,07,??
11 ,12,13,14,15 11,12,13 ??,??,??
16 ,17,18,19,20
21 ,22,23,24,25
++将数据视口和结果集右移1列
// Data Set // Data Viewport // Result Set
[04],02,03,04,05 02,03,04 04,[03],??
[06],07,08,09,10 07,08,09 07,[08],??
11 ,12,13,14,15 12,13,14 ??, ?? ,??
16 ,17,18,19,20
21 ,22,23,24,25
++更新结果集的中间列
// Data Set // Data Viewport // Result Set
[04],02,03,04,05 02,03,04 04,[05],??
[06],07,08,09,10 07,08,09 07,[08],??
11 ,12,13,14,15 12,13,14 ??, ?? ,??
16 ,17,18,19,20
21 ,22,23,24,25
在以下迭代中,数据状态将为:
// Data Set // Data Viewport // Result Set
04,[04],03,04,05 03,04,05 05,[06],??
06,[07],08,09,10 08,09,10 08,[09],??
11, 12 ,13,14,15 13,14,15 ??, ?? ,??
16, 17 ,18,19,20
21, 22 ,23,24,25
。。等
别忘了处理其他边缘情况
*“数据”视口表示仅用于可视化。在代码中,实际的视口将是结果缓冲区。必须对结果数据进行某种缓存,以便保留对原始数据的引用。我认为没有办法解决这个问题 如果数据集很大,可以通过使用较小的数据缓冲区(如通过锁孔查看)并在更新时“滚动”输入矩阵来进行优化。在您的情况下,可以使用小到3x3的缓冲区。 不过,这是速度和空间之间的折衷。缓冲区越小,性能就越差 要可视化问题,请从数据集的左上角(0,0)开始:
(为简单起见,结果值向下舍入) 第一步:更新前4个单元格(初始化缓冲区) 然后对于每个迭代..
(用[xx]表示的新值) ++从结果集中更新数据集中的第一列
// Data Set // Data Viewport // Result Set
[04],02,03,04,05 01,02,03 04,04,??
[06],07,08,09,10 06,07,08 06,07,??
11 ,12,13,14,15 11,12,13 ??,??,??
16 ,17,18,19,20
21 ,22,23,24,25
++将数据视口和结果集右移1列
// Data Set // Data Viewport // Result Set
[04],02,03,04,05 02,03,04 04,[03],??
[06],07,08,09,10 07,08,09 07,[08],??
11 ,12,13,14,15 12,13,14 ??, ?? ,??
16 ,17,18,19,20
21 ,22,23,24,25
++更新结果集的中间列
// Data Set // Data Viewport // Result Set
[04],02,03,04,05 02,03,04 04,[05],??
[06],07,08,09,10 07,08,09 07,[08],??
11 ,12,13,14,15 12,13,14 ??, ?? ,??
16 ,17,18,19,20
21 ,22,23,24,25
在以下迭代中,数据状态将为:
// Data Set // Data Viewport // Result Set
04,[04],03,04,05 03,04,05 05,[06],??
06,[07],08,09,10 08,09,10 08,[09],??
11, 12 ,13,14,15 13,14,15 ??, ?? ,??
16, 17 ,18,19,20
21, 22 ,23,24,25
。。等
别忘了处理其他边缘情况
*“数据”视口表示仅用于可视化。在代码中,实际视口将是结果缓冲区。通常的方法是在更新单元格之前创建矩阵副本。如果矩阵非常非常大,您可以只保留一个“滚动”备份,例如上一行和当前行,甚至更少。假设您有一个1000x1000矩阵,并且您正在逐行更新单元格。在第n行中,您不需要第n-2行的副本(因为它不再相关),也不需要第n+1行的副本(因为它仍然具有原始值。因此仅保留上一行和当前行的备份就足够了。是否值得这样做是另一个问题。@tobias_k您能解释一下“滚动”的细节吗详细备份?我认为这可能是关键。在更新单元格之前创建矩阵副本是常用的方法。如果矩阵非常非常大,您可以进行“滚动”备份,例如上一行和当前行,甚至更少。假设您有一个1000x1000矩阵,并且您正在逐行更新单元格