메뉴 건너뛰기

tnt_db

Oracle 행렬(matrix)계산을위한 준비

운영자 2002.09.18 14:19 조회 수 : 2887 추천:14

행렬 계산을 위한 준비

준비.
    TEST15 TABLE 에 다음과 같은 DATA가 있다.

     F_OBJ T_OBJ VAL      
     ----- ----- ----------
     A     A            100
     A     B             20
     A     C             30
     B     A             60
     B     C             40
     C     B             70
     C     C             30

     TEST16 에는 다음과 같은 DATA가 있다.

     OBJ   CONST    
     ----- ----------
     A           2000
     B           1000
     C           2000

문제.
    n * n 정방행렬을 계산하기위해서 DATA 를
    가공하는 경우를 생각해보자.

    행 : FROM 기준  
    열 : TO   기준

                A    B    C
         ---|---------------|--     -----
         A  | 100           | a     2000
         B  |  20   60   70 | b     1000
         C  |  30   40   30 | c     2000
    
    TEST15 에는 FROM 부문에서 TO 부문으로 의 해당 값을 가지고 있으며
    TEST16 에는 각부문별 총 상수값을 가지고 있다.

    DATABASE에서 보관하는 자료는 실제로 값이 있는 부분만이다.
    B => A 또는 C => A 의 값은 없더라도 그러한 행렬구조는 맞춰야한다.
    강제로 0을 넣어 줄 필요는 없다.
    한가지 더, 2차원 배열을 이용하기위해 각부문에 고유번호를 붙여
    DATA를 가져와야한다.
    즉 2차원 배열로 DATA를 넘겨서 계산을 하기 직전단계 DATA를 추출
    하고자 하는것이다.
    위의 자료를 이용해 다음과 같은 결과를 만들면 된다.

         행번호     열번호 행부문 열부문        값        
        ------- ---------- ------ ------ ---------
              1          1 A      A            100
              1          2 A      B             20
              1          3 A      C             30
              2          1 B      A              
              2          2 B      B             60
              2          3 B      C             40
              3          1 C      A              
              3          2 C      B             70
              3          3 C      C             30

   상수 부분은 별도로 넘기기로 하고 TEST15만을 이용하자.
    
생각.
    엿보기1.요점은 값이 없는 부문간 이라도 구조는 만들어져 나와야
            한다는 것이다.
    엿보기2.그러기 위해서는 FROM 부문과 TO 부문을 통털어서 존재하는
            모든 부문이 FROM 부문에도 와야한고 TO부문에도 와야 한다.
    엿보기3.배열상의 첨자에 해당하는 순서는 FROM과 TO를 통털어
            읽어온 부문에 올림차순으로 강제 번호를 부여한다.
    엿보기4.FROM과 TO 에 번호를 붙여 만든 두개의 DATASET을
            연결하면 DATA를 제외한 부문의 구조가 완성될 것이다.
    엿보기5.구조와 값을 연결하면 된다.
            이때 기준이 되는 것이 구조이므로 값을 가지고 있는
            원 TABLE에 (+) 부호를 붙여준다.

해법.
    엿보기를 통해 구상한 내용을 그대로 옮겨보자.
    항상 그럿듯이 스스로 해법을 찾아내는 훈련을 하는 것이 중요하다.
    어떤 문제이든 그것을 자기 스스로 풀고나면 절대로 잊지 않기 때문이다.
    단계1.엿보기1에서 우리는 구조를 먼저 만들기로 했다.
          먼저 FROM과 TO의 존재하는 모든 부문을 UNIQUE 하게 읽어보자.
  
        SELECT  F_OBJ  F_OBJ
                FROM    TEST15
                UNION    
                SELECT  T_OBJ  F_OBJ
                FROM  TEST15

          다음과 같은 결과가 나온다.  

        F_OBJ
        -----
        A    
        B    
        C    

    단계2.단계1을 이용해 가져온 부문앞에 번호를 붙여주자.
  
         SELECT ROWNUM C_NO,
                F_OBJ  F_OBJ
         FROM ( SELECT  F_OBJ  F_OBJ
                FROM    TEST15
                UNION    
                SELECT  T_OBJ  F_OBJ
                FROM  TEST15
              )
  
         결과

         C_NO       F_OBJ
         ---------- -----
                  1 A    
                  2 B    
                  3 C    

    단계3.똑같은 방식으로 TO부문의 구조도 만들어준다.
          그리고 JOIN을 걸어주면 된다.
      
         SELECT C_NO,R_NO,A.F_OBJ,B.T_OBJ
             FROM
                ( SELECT ROWNUM C_NO,
                         F_OBJ  F_OBJ
                  FROM ( SELECT  F_OBJ  F_OBJ
                         FROM    TEST15
                         UNION    
                         SELECT  T_OBJ  F_OBJ
                         FROM  TEST15
                       )
                ) A,
                ( SELECT ROWNUM R_NO,
                         T_OBJ  T_OBJ
                  FROM ( SELECT F_OBJ T_OBJ
                         FROM   TEST15
                         UNION
                         SELECT T_OBJ T_OBJ
                         FROM   TEST15
                       )
                ) B

         결과는

          C_NO       R_NO       F_OBJ T_OBJ
          ---------- ---------- ----- -----
                   1          1 A     A    
                   2          1 B     A    
                   3          1 C     A    
                   1          2 A     B    
                   2          2 B     B    
                   3          2 C     B    
                   1          3 A     C    
                   2          3 B     C    
                   3          3 C     C    

    단계4.구조를 만드는 작업이 끝났다.
          빠짐없이 만들어졌는지 보자.
          3*3 = 9 니까 아홉개의 RECORD가 RETURN 되었다.
          이제 실제값을 구조에 붙여보자.
          만들어진 구조와 실 TABLE을 FROM 과 TO 를 기준으로
          JOIN을 걸어주자.
                    
       SELECT STRUCTURE.C_NO,
              STRUCTURE.R_NO,
              STRUCTURE.F_OBJ,
              STRUCTURE.T_OBJ,
              VAL
       FROM
          (SELECT C_NO,R_NO,A.F_OBJ,B.T_OBJ
           FROM
              ( SELECT ROWNUM C_NO,
                       F_OBJ  F_OBJ
                FROM ( SELECT  F_OBJ  F_OBJ
                       FROM    TEST15
                       UNION    
                       SELECT  T_OBJ  F_OBJ
                       FROM  TEST15
                     )
              ) A,
              ( SELECT ROWNUM R_NO,
                       T_OBJ  T_OBJ
                FROM ( SELECT F_OBJ T_OBJ
                       FROM   TEST15
                       UNION
                       SELECT T_OBJ T_OBJ
                       FROM   TEST15
                     )
              ) B
           ) STRUCTURE,
             TEST15
       WHERE TEST15.F_OBJ(+) = STRUCTURE.F_OBJ
       AND   TEST15.T_OBJ(+) = STRUCTURE.T_OBJ

    실행시켜보자.
    답이 틀림없이 나온다.

뒷풀이.
    행렬을 푸는 알고리즘을 이용해 행렬 계산을 마친후
    같은 원리를 이용해 DATABASE 에 저장하면
    DATABASE는 FROM부문 과 TO부문 두개의 KEY를 이용해
    DATA를 CONTROL 하고
    배열에서는 각부문과 연결된 첨자값을 이용해 DATA를
    CONTROL 하게 된다.
    흔히 발생하는 경우다 잘 알아두자.    
위로