2017-12-15 1 views
0

, 나는 마법의 인구 정방 행렬을 얻을 수 magic()를 사용할 수의 NumPy와 동등한 :예 matlab에의 마법() Ocatave/매트랩

magic(4) 

    16 2 3 13 
    5 11 10 8 
    9 7 6 12 
    4 14 15 1 

정의 : 마법 광장 숫자의 N 그리드 ×는 N입니다 각 행, 열 및 주요 대각선의 항목은 동일한 번호 (N(N^2+1)/2과 동일)에 합산됩니다.

어떻게 NumPy를 사용하여 동일하게 생성 할 수 있습니까?

+4

https://scipython.com/book/chapter-6-numpy/examples/creating-a-magic-square/ – m7913d

+0

@ m7913d 링크를 사용할 수 없게 될 수도 있으므로 답변을 올리십시오 ... – MaxU

+0

@ 저작권은 어떨까요? – m7913d

답변

1

Matlab처럼 n = 2 일 때 비 매직 사각형 [[1, 3], [4, 2]]을 반환하지 않고 n < 3이면 오류가 발생합니다.

평소와 같이 홀수, 4로 나눌 수 있지만 4로 나눌 수는 없지만 마지막 하나는 가장 복잡합니다.

def test_magic(ms): 
    n = ms.shape[0] 
    s = n*(n**2+1)//2 
    columns = np.all(ms.sum(axis=0) == s) 
    rows = np.all(ms.sum(axis=1) == s) 
    diag1 = np.diag(ms).sum() == s 
    diag2 = np.diag(ms[::-1, :]).sum() == s 
    return columns and rows and diag1 and diag2 

은 정확성을 확인하기 위해 [test_magic(magic(n)) for n in range(3, 20)]을 시도해보십시오

def magic(n): 
    n = int(n) 
    if n < 3: 
    raise ValueError("Size must be at least 3") 
    if n % 2 == 1: 
    p = np.arange(1, n+1) 
    return n*np.mod(p[:, None] + p - (n+3)//2, n) + np.mod(p[:, None] + 2*p-2, n) + 1 
    elif n % 4 == 0: 
    J = np.mod(np.arange(1, n+1), 4) // 2 
    K = J[:, None] == J 
    M = np.arange(1, n*n+1, n)[:, None] + np.arange(n) 
    M[K] = n*n + 1 - M[K] 
    else: 
    p = n//2 
    M = magic(p) 
    M = np.block([[M, M+2*p*p], [M+3*p*p, M+p*p]]) 
    i = np.arange(p) 
    k = (n-2)//4 
    j = np.concatenate((np.arange(k), np.arange(n-k+1, n))) 
    M[np.ix_(np.concatenate((i, i+p)), j)] = M[np.ix_(np.concatenate((i+p, i)), j)] 
    M[np.ix_([k, k+p], [0, k])] = M[np.ix_([k+p, k], [0, k])] 
    return M 

나는이를 테스트 할 수있는 기능을 썼다.

+0

나는 옥타브가 깨진'마법 (2)'을 구현한다는 것을 몰랐다. 건배! –

1

다음은 홀수 및 이중 짝수 경우에 대한 빠른 구현입니다.

def magic_odd(n): 
    if n % 2 == 0: 
     raise ValueError('n must be odd') 
    return np.mod((np.arange(n)[:, None] + np.arange(n)) + (n-1)//2+1, n)*n + \ 
      np.mod((np.arange(1, n+1)[:, None] + 2*np.arange(n)), n) + 1 


def magic_double_even(n): 
    if n % 4 != 0: 
     raise ValueError('n must be a multiple of 4') 
    M = np.empty([n, n], dtype=int) 
    M[:, :n//2] = np.arange(1, n**2//2+1).reshape(-1, n).T 
    M[:, n//2:] = np.flipud(M[:, :n//2]) + (n**2//2) 
    M[1:n//2:2, :] = np.fliplr(M[1:n//2:2, :]) 
    M[n//2::2, :] = np.fliplr(M[n//2::2, :]) 
    return M 

홀수의 경우는 here에서 내가 How to construct magic squares of even order에서 휴식을 얻었다. 그렇다면 나는 하나의 짝수 경우에 대해서 게으르다. 그러나 그 생각은 비슷하다.