Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.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
Algorithm 与向量吻合_Algorithm_Matrix - Fatal编程技术网

Algorithm 与向量吻合

Algorithm 与向量吻合,algorithm,matrix,Algorithm,Matrix,假设给定一个向量v[1..d^2],其中包含d^2个元素 v[1]v[2]v[3]v[4]v[5]。。。v[d^2] 我们希望对角填充dxd矩阵M,而不是逐行或逐列填充 例如,如果d=4,则生成的矩阵为 v[01]v[03]v[06]v[10] v[02]v[05]v[09]v[13] v[04]v[08]v[12]v[15] v[07]v[11]v[14]v[16] 这种技术记住了吻合,但在这种情况下,我们希望完全填充平方矩阵 如何设计一个算法,在给定向量v和维数d的情况下,它能回答上述矩阵?

假设给定一个向量v[1..d^2],其中包含d^2个元素

v[1]v[2]v[3]v[4]v[5]。。。v[d^2]

我们希望对角填充dxd矩阵M,而不是逐行或逐列填充

例如,如果d=4,则生成的矩阵为

v[01]v[03]v[06]v[10]

v[02]v[05]v[09]v[13]

v[04]v[08]v[12]v[15]

v[07]v[11]v[14]v[16]

这种技术记住了吻合,但在这种情况下,我们希望完全填充平方矩阵


如何设计一个算法,在给定向量v和维数d的情况下,它能回答上述矩阵?

我研究了这个问题,我认为我找到了一种模式,可以将矩阵中的坐标映射到向量中的索引。查看4x4示例中用于填充矩阵的索引之间的差异:

 0 (+2)  2 (+3)  5 (+4)  9
(+1)    
 1 (+3)  4 (+4)  8 (+4) 12
(+2)
 3 (+4)  7 (+4) 11 (+3) 14
(+3)
 6 (+4) 10 (+3) 13 (+2) 15
列开头的偏移量以算术级数增加,元素之间的偏移量可以从列表中看到:
offsets=[2,3,4,4,3,2]
offset by The current row and column。i、 e.要从
(r,c)
转到
(r,c+1)
您需要添加
偏移量[r+c]

我们可以将此偏移定义为一个函数:

inline int 
offset(int d, int i)
{
    return i+2 - std::max(0, 2*(i-d+2)-1);
}
它生成如下序列:

d=4: 2, 3, 4, 4, 3, 2
d=5: 2, 3, 4, 5, 5, 4, 3, 2
现在,我们可以在循环中使用它来查找用于填充矩阵的索引:

for( int rOff = 0, r = 0
   ; r < d
   ; rOff += ++r
   )
    for( int i = rOff, c = 0
       ; c < d
       ; i += offset(d, r + c++)
       )
        matrix[r][c] = v[i];

作为健全性检查,这里是上述循环的输出,但是用
std::cout替换
matrix[r][c]=v[i]
时,如果您只考虑两个循环,事情就相当简单:一个循环遍历上部反三角形,另一个循环遍历下部反三角形。对于第一个循环,向下推进外循环中的行,内循环向上和向右移动。在第二种情况下,在外环中穿过立柱,在内环中再次向上向右移动。下面是一个完整的C程序:

#include <stdio.h>

int main(void) 
{
  int d = 4, v[d * d], m[d][d], start, i, j, k, i0, j0;

  // Fill v with 1,2,...d^2
  for (int i = 0; i < d * d; i++) v[i] = i+1;

  // Start dovetail. 
  k = 0;
  for (i0 = 0; i0 < d; i0++)  // Down left column
    for (i = i0, j = 0; i >= 0; i--, j++)
      m[i][j] = v[k++];

  for (j0 = 1; j0 < d; j0++)  // Across bottom row
    for (i = d - 1, j = j0; j < d; i--, j++)
      m[i][j] = v[k++];
  // End dovetail.

  for (i = 0; i < d; i++) {
    for (j = 0; j < d; j++) printf("%4d", m[i][j]);
    printf("\n");
  }
  return 0;
}
#include <stdio.h>

int main(void) 
{
  int d = 4, v[d * d], m[d][d], start, i, j, k, i0, j0;

  // Fill v with 1,2,...d^2
  for (int i = 0; i < d * d; i++) v[i] = i+1;

  // Start dovetail. 
  k = 0;
  for (i0 = 0; i0 < d; i0++)  // Down left column
    for (i = i0, j = 0; i >= 0; i--, j++)
      m[i][j] = v[k++];

  for (j0 = 1; j0 < d; j0++)  // Across bottom row
    for (i = d - 1, j = j0; j < d; i--, j++)
      m[i][j] = v[k++];
  // End dovetail.

  // Print the result.
  for (i = 0; i < d; i++) {
    for (j = 0; j < d; j++) printf("%4d", m[i][j]);
    printf("\n");
  }
  return 0;
}
#包括
内部主(空)
{
int d=4,v[d*d],m[d][d],开始,i,j,k,i0,j0;
//用1,2,…d^2填充v
对于(inti=0;i=0;i--,j++)
m[i][j]=v[k++];
对于(j0=1;j0
如果您只考虑两个循环嵌套,事情就相当简单:一个用于遍历上部反三角形,另一个用于下部反三角形。使用此功能,您只需要简单的计数器,不需要执行
max
min
操作

对于第一个循环,在外部循环中向下推进左列的行,内部循环向上和向右移动

在第二个循环中,在外部循环中穿过底部行的列,然后再次与内部循环一起向上和向右移动。下面是一个C程序:

#include <stdio.h>

int main(void) 
{
  int d = 4, v[d * d], m[d][d], start, i, j, k, i0, j0;

  // Fill v with 1,2,...d^2
  for (int i = 0; i < d * d; i++) v[i] = i+1;

  // Start dovetail. 
  k = 0;
  for (i0 = 0; i0 < d; i0++)  // Down left column
    for (i = i0, j = 0; i >= 0; i--, j++)
      m[i][j] = v[k++];

  for (j0 = 1; j0 < d; j0++)  // Across bottom row
    for (i = d - 1, j = j0; j < d; i--, j++)
      m[i][j] = v[k++];
  // End dovetail.

  for (i = 0; i < d; i++) {
    for (j = 0; j < d; j++) printf("%4d", m[i][j]);
    printf("\n");
  }
  return 0;
}
#include <stdio.h>

int main(void) 
{
  int d = 4, v[d * d], m[d][d], start, i, j, k, i0, j0;

  // Fill v with 1,2,...d^2
  for (int i = 0; i < d * d; i++) v[i] = i+1;

  // Start dovetail. 
  k = 0;
  for (i0 = 0; i0 < d; i0++)  // Down left column
    for (i = i0, j = 0; i >= 0; i--, j++)
      m[i][j] = v[k++];

  for (j0 = 1; j0 < d; j0++)  // Across bottom row
    for (i = d - 1, j = j0; j < d; i--, j++)
      m[i][j] = v[k++];
  // End dovetail.

  // Print the result.
  for (i = 0; i < d; i++) {
    for (j = 0; j < d; j++) printf("%4d", m[i][j]);
    printf("\n");
  }
  return 0;
}

请注意,每次迭代,放置向量元素的索引都会被交换。此外,坐标的最高维度与下面的维度交替使用,因此它们的总和总是相同的:例如:对于
v4 v5 v6
(3,1)(2,2)(1,3)
:因此,在这种情况下,所有坐标的总和都是4。这和最后一个都是非常好的简单解决方案,我喜欢它。我不能选择一个答案来支持另一个,因为有不止一个解决方案,但我正在投票。嗯。。。谢谢我不知道为什么创建了两个不同的帖子(一个bug!)。我刚把原稿编辑了一点,很好。我也在想类似的事情,我发现
矩阵[r][c]=(I+I^2+2ij+j(j+3))/2
对于高于上二次/反对角线的值,但我没有找到另一部分的闭合形式。这是一个很好的答案,我不能选择一个答案来支持另一个,因为提出的解决方案不止一个,但我正在投票支持它。
#include <stdio.h>

int main(void) 
{
  int d = 4, v[d * d], m[d][d], start, i, j, k, i0, j0;

  // Fill v with 1,2,...d^2
  for (int i = 0; i < d * d; i++) v[i] = i+1;

  // Start dovetail. 
  k = 0;
  for (i0 = 0; i0 < d; i0++)  // Down left column
    for (i = i0, j = 0; i >= 0; i--, j++)
      m[i][j] = v[k++];

  for (j0 = 1; j0 < d; j0++)  // Across bottom row
    for (i = d - 1, j = j0; j < d; i--, j++)
      m[i][j] = v[k++];
  // End dovetail.

  // Print the result.
  for (i = 0; i < d; i++) {
    for (j = 0; j < d; j++) printf("%4d", m[i][j]);
    printf("\n");
  }
  return 0;
}
1   3   6  10
2   5   9  13
4   8  12  15
7  11  14  16