以下の無向グラフと隣接行列において、0から3へ至るパスを検索するプログラムを考える。下線部の【ア】に入るプログラム片のうち、最も適切なものはどれか。
          
          〔プログラム〕
          mm=[[0, 1, 1, 0], [1, 0, 1, 1], [1, 1, 0, 1], [0, 1, 1, 0]]
          def gsearch(l, r):
           for i, c in enumerate(l):
            if     【ア】    
             if i==3:
              print(r+[i])
             else:
              gsearch(mm[i], r+[i])
          gsearch(mm[0], [0])
          
          〔実行結果〕
          [0, 1, 2, 3]
          [0, 1, 3]
          [0, 2, 1, 3]
          [0, 2, 3]
@ (c==1) or (i not in r):
A (c==0) and (i in r):
B (c==0) or (i in r):
C (c==1) and (i not in r):
D (c==1) or (i in r):
C
隣接行列は、頂点同士が辺でつながっているかどうかを表す行列である。
          例えば、頂点0の隣接行列は、頂点1と頂点2につながっているので、
          [0, 1, 1, 0]と表せる。
          
          0から3へ至るパスは以下の4通りある。
          0 ⇒ 1 ⇒ 2 ⇒ 3
          0 ⇒ 1 ⇒ 3
          0 ⇒ 2 ⇒ 1 ⇒ 3
          0 ⇒ 2 ⇒ 3
          これらを正しく出力できるようにプログラムを考える。
          
          
          配列mmが定義され、次に
          def gsearch(l, r) 
           〜
            gsearch(mm[i], r+[i]) で
          引数が l と r の関数grearch()を定義する。
          
          プログラムは
          gsearch(mm[0], [0]) から実行し、gsearch()内で再帰的に呼び出される。
          
          なお、enumerate()関数は for文でインデックスと要素を同時に取得する関数である。for i, c in enumerate(l): によって、引数のmmのリストを i と c に以下のように 取り出していく。
          mm[0]のとき: (i, c) ⇒ (0, 0), (1, 1), (2, 1), (3, 0)
          
          また、r+[i]は、リスト r の最後に i を加えたリストとなる。
          
          これらを踏まえ、gsearch(mm[0], [0]) をトレースすると次のようになる。
          
          for 1回目 (r=[0])
           (i, c) = (0, 0)
            ここで、c = 0ということは隣接していないため、処理する必要がない。また、リストr の中に自分自身や、すでに検索した点があれば、処理する必要がない。この時点で 正解はCと予想できる。
          
          for 2回目 (r=[0])
           (i, c) = (1, 1) ・・・ 0が1と隣接していることが分かる。
           gsearch(mm[1], [0]+[1]) = gsearch(mm[1], [0, 1])
            for 1回目 (r = [0, 1])
             (i, c) = (0, 1) ・・・i = 0がリスト r の中にある。
            for 2回目 (r = [0, 1])
             (i, c) = (1, 0)
             for 3回目 (r = [0, 1])
             (i, c) = (2, 1)
              gsearch(mm[2], [0, 1]+[2]) 
                 for 1回目 (r = [0, 1, 2])
                 (i, c) = (0, 1)
                 for 2回目 (r = [0, 1, 2])
                 (i, c) = (1, 1)
                 for 3回目 (r = [0, 1, 2])
                 (i, c) = (2, 0)
                 for 4回目 (r = [0, 1, 2])
                 (i, c) = (3, 1)
                  print([0, 1, 2]+[3]) ・・・[0, 1, 2, 3]を出力
            for 4回目 (r = [0, 1])
             (i, c) = (3, 1)
              print([0,1]+[3]) ・・・[0, 1, 3]を出力
          for 3回目 (r=[0])
           (i, c) = (2, 1)
           gsearch(mm[2], [0]+[2]) = gsearch(mm[2], [0, 2])
            for 1回目 (r = [0, 2])
             (i, c) = (0, 1) 
            for 2回目 (r = [0, 2])
             (i, c) = (1, 1)
              gsearch(mm[1], [0, 2]+[1]) 
                 for 1回目 (r = [0, 2, 1])
                 (i, c) = (0, 1)
                 for 2回目 (r = [0, 2, 1])
                 (i, c) = (1, 0)
                 for 3回目 (r = [0, 2, 1])
                 (i, c) = (2, 1)
                 for 4回目 (r = [0, 2, 1])
                 (i, c) = (3, 1)
                  print([0, 2, 1]+[3]) ・・・[0, 2, 1, 3]を出力
             for 3回目 (r = [0, 2])
             (i, c) = (2, 0)
            for 4回目 (r = [0, 2])
             (i, c) = (3, 1)
              print([0,2]+[3]) ・・・[0, 2, 3]を出力
          for 4回目 (r=[0])
           (i, c) = (3, 0)
               
| V−1 | 目次 | V−3 |