中身が2行だけ書かれたプログラムを全力解説(前編)


2022年 04月 14日

先日,Visual Studio 2022のConsoleアプリをたった1行にしたカラクリという記事が公開されました.自分もそれに触発されて(?)中身が2行だけ書かれたMATLABプログラムを全力解説します. ※この記事は三部構成です.中・後編は後日

前編では,この関数がどういう動きをするものか説明します.後編でプログラムの中身について説明します.
さっそく,プログラムを見ていきましょう.

function W = SLD(H,M)
  W = nchoosek(1:H+M-1,M-1) - repmat(0:M-2,nchoosek(H+M-1,M-1),1) - 1;
  W = ([W,zeros(size(W,1),1)+H]-[zeros(size(W,1),1),W])/H;
end

こちらは,とあるプログラムから2行抜き出して作成した関数です.
プログラムを動かすには,\(H\): 1以上の整数,\(M\): 2以上の整数を指定する必要があります.

以上の情報だけで,どういうプログラムか読み解けた方は,相当凄いです.
それでは,全力解説していきます.

前提と入出力

まず,今回解説するプログラムは,MATLABで書かれています.MATLABの関数はfunctionで始まり,endで終わるのが作法です.関数の先頭は左からfunction[出力]=関数名(入力)です.変数の型は,記述しません.

適当に値を入力すると,以下のような出力が得られます.


>> SLD(1,2)

ans =

     0     1
     1     0

>> 

>> SLD(2,2)

ans =

         0    1.0000
    0.5000    0.5000
    1.0000         0

>> 

>> SLD(1,3)

ans =

     0     0     1
     0     1     0
     1     0     0

>> 

>> SLD(2,3)

ans =

         0         0    1.0000
         0    0.5000    0.5000
         0    1.0000         0
    0.5000         0    0.5000
    0.5000    0.5000         0
    1.0000         0         0

>> 

>> SLD(1,6)

ans =

     0     0     0     0     0     1
     0     0     0     0     1     0
     0     0     0     1     0     0
     0     0     1     0     0     0
     0     1     0     0     0     0
     1     0     0     0     0     0

>> 

\(M=2\),\(H=\{9,14,20\}\)のとき,得られる出力\(W\)を散布図としてプロットすると以下が得られます.

\(M=3\),\(H=\{3,4,5\}\)のとき,得られる出力\(W\)を散布図としてプロットすると以下が得られます.

だんだん分かってきましたね.このプログラムは,\(M\)次元空間の単位超平面上に均一分布する点群を生成するプログラムです.理解が簡単な\(M=\{2,3\}\)の場合だけ考えると,

  • \(M=2\)の時,点\((1,0)\)と\((0,1)\)を結ぶ直線上に,均一分布する点群が得られます.
  • \(M=3\)の時,点\((1,0,0)\),\((0,1,0)\),\((0,0,1)\)の3点を頂点とする平面上に,均一分布する点群が得られます.

Simplex-lattice design

このプログラムが生成する点群をSimplex-lattice designといいます.関数名のSLDは,この頭文字です.この点群は,「進化計算による多目的最適化」という研究分野でよく利用されています.今回解説する2行も,PlatEMOという,同研究分野でよく利用されるライブラリから抜き出してきたものです.プログラムは,ここの64,65行目です.

点の各要素は\(\{0/H, 1/H, . . . , H/H\}\)のいずれかの値を取る,点の要素の総和は1になる,点群サイズ\(N=C^{M-1}_{H+M-1}\)で計算できるという特徴があります.\(M\),\(H\)と点群サイズ\(N\)の関係性を表にすると以下になります.


M \ H
123456789
22345678910
33610152128364555
441020355684120165220
55153570126210330495715
66215612625246279212872002
772884210462924171630035005
883612033079217163432643511440

終わりに

「中身が2行だけ書かれたプログラムを全力解説」前編では中身に触れず,プログラムの入出力とその性質,利用される分野などを解説しました.
次回の中編では,プログラムを読み解くために必要なMATLABの知識を解説します.お楽しみに.