2012-04-17 2 views
1

문제가있어서 이상적인 솔루션을 제공 할 수 있는지 알고 싶습니다.행렬을 작은 행렬의 블록으로 분할하는 방법

기본적 (작은 데이터)이지만,이 같은 행렬이있는 경우 :

 0 1 0 0 
    1 1 1 0 
    0 0 0 0 
    1 1 0 0 
I 다음,이 경우의 2 × 2에서, 제 행렬과 동일한 크기의 블록으로이 행렬을 분할해야

:

0 1 
1 1 

나는 그것이 offsetX/Y 값과 (작은) 행렬의 크기에 따라 이러한 변화와 함께 할 수있는 뭔가가 알고, 난 그냥 같은 결과를 계산하는 계산을 모른다. offsetX/Y를 함수 (벡터 포함)에 전달하여 특정 블록의 합계를 계산할 수 있습니다.

누구에게 조언이 있습니까?

덕분에 당신은 다른 뭔가를 찾고하지 않는 한

+3

5x5 매트릭스로 무엇을하고 싶습니까? – chikuba

+0

안녕하세요 - 여전히 1D 매트릭스이기 때문에 작은 매트릭스 (이 경우에는 2x2 매트릭스)와 비슷한 크기의 블록으로 나눌 수 있습니다. 다음과 같이 생각했습니다 : const int ROW_BOUNDS = matrix1.size) - matrix2.size(); const int COL_BOUNDS = matrix1.size() - matrix2.size(); 이것이 어떤 의미가 있다면? – Phorce

+0

그냥 리머 컬럼과 라인으로 무엇을합니까? – chikuba

답변

1

수학적으로 예를 들어 z 커브 또는 peano 커브와 같은 커브로 매트릭스를 나눌 수 있습니다. 그렇게하면 치수 복잡성을 줄일 수 있습니다. z 곡선은 4 개의 쿼드를 사용하여 평면을 분할하고 쿼드 트리와 유사합니다.

편집 : 방금 z 차수 곡선이고 z 곡선이 아니라는 것을 배웠습니다 : http://en.wikipedia.org/wiki/Z-order_curve.z 곡선은 bionformatics에서 3d 무엇입니까 http://en.wikipedia.org/wiki/Z_curve ??? 웃음! 나는 바이오 인포 매틱스도 아니고 위키 피 디아에서도 그렇지만 그 말은 내게 말도 안되는 소리처럼 들린다. Z- 순서 곡선은 또한 3d 영역을 포함 할 수 있습니다. 어쩌면 위키피디아가 이것을 말하고 싶어할까요? 다음은 3d z- 순서 곡선 http://en.wikipedia.org/wiki/File:Lebesgue-3d-step3.png의 큰 그림입니다. 그것은 심지어 위키피디아 문서에있다 ?????

+4

음 ... 뭐라고 요? 어레이 슬라이싱 작업과 관련된 것은 무엇입니까? –

+0

@ Li-aung Yip : 내가 맥주를 마시라고 제안하는거야? – Bytemain

3
import std.stdio : writeln; 
void main(string[] args) 
{ 
    int m=4, n=4; 
    int[][] matrix = [[0, 1, 0, 0], [1, 1, 1, 0], [0, 0, 0, 0], [1, 1, 0, 0]]; 
    int mm=2, nn=2; 
    int sum; 
    for(int x=0; x<m; x+=mm) 
     for(int y=0; y<n; y+=nn) 
     sum += summation(matrix, x, y, mm, nn); 
    writeln(sum); 
}  
int summation(int[][] matrix, int offsetx, int offsety, int m, int n) 
{ 
    int sum; 
    for(int x=offsetx; x<offsetx+m; x++) 
    for(int y=offsety; y<offsety+n; y++) 
     sum += matrix[x][y]; 
    return sum; 
} 

? 귀하의 질문은 당신이 요구하는 것을 설명 할 때 모호합니다.

그것을 복사하지 않고, (즉 현장에서 매트릭스를 분할하기 위해

+1

당신은 맞습니다. 그것은 C++과 전혀 다른 것입니다. – Puppy

+0

만큼 생각했지만 필요한 것은 모두 의사 코드 –

+0

그런 다음 "가장 무서운 어떤 것 (예 : 상상할 수있는 것)"대신 원격으로 의사 코드와 같은 것을 넣으십시오. – Puppy

3

(이것은 유일한 이후 나는, ATM 할 수있는 권한이 C++로 변환 가이드로 사용, D에서 컴파일)

template <class elt> class MatRef { 
    elt* m_data; 
    unsigned m_rows, m_cols; 
    unsigned m_step; 

    unsigned index(unsigned row, unsigned col) 
    { 
     assert(row < m_rows && col < m_cols); 
     return m_step * row + col; 
    } 

public: // access 
    elt& operator() (unsigned row, unsigned col) 
    { 
     return m_data[index(row,col)]; 
    } 

public: // constructors 
    MatRef(unsigned rows, unsigned cols, elt* backing) // original matrix 
     : m_rows(rows) 
     , m_cols(cols) 
     , m_step(cols) 
     , m_data(backing) 
    {} 
    MatRef(unsigned start_row, unsigned start_col, 
      unsigned rows, unsigned cols, MatRef &orig) // sub-matrix 
     : m_rows(rows) 
     , m_cols(cols) 
     , m_step(orig.m_step) 
     , m_data(orig.m_data + orig.index(start_row, start_col)) 
    { 
     assert(start_row+rows <= orig.m_rows && start_col+cols <= orig.m_cols); 
    } 
}; 

원래 행렬 생성자는 자사의 backing 인수 포인트를 가정 등 쉽게 재귀 알고리즘을 정의 할 수 있도록하며, -), 당신은 원본과 분할 조각을 모두 처리 할 수있는 표현을 원하는 행렬 데이터를 저장하기 위해 적어도 rows*cols 길이의 데이터 요소 배열. 행렬의 크기는 데이터 멤버 m_rowsm_cols에 의해 정의됩니다.

데이터 멤버 m_step은 한 행의 시작에서 다음 행의 시작까지 얼마나 많은 데이터 요소가 있는지 나타냅니다. 원래의 행렬의 경우 이것은 m_cols과 같습니다. 부분 행렬의 m_cols은 그것이 참조하는 원래 행렬의 것보다 작을 수 있습니다. 이는 부분 행렬이 부분 행렬의 일부가 아닌 원래 행렬의 요소를 "건너 뛰는"방법입니다. 이 작업을 제대로 수행하려면 m_step이 원본 매트릭스와 반드시 동일해야합니다.

매트릭스가 요소를 건너 뛰는 지 여부에 관계없이 데이터 멤버 m_data은 항상 매트릭스의 첫 번째 요소를 가리 킵니다. 부분 행렬 생성자의 assert()은 각 새 부분 행렬이 파생 된 행렬 내부에 맞는지 확인합니다.


"흥미로운 알고리즘"으로 간주할지 모르겠지만 부분 행렬을 정의하고 액세스하는 데 효율적이고 편리한 방법입니다.

+0

"단계"는 "보폭"이라고도합니다. 또한이 표현은 BLAS와 LAPACK에 의해 이해되며, 평범하지 않은 선형 대수학을 할 계획이라면 유용 할 수 있습니다. –

관련 문제