スターリング数

 スターリング数の理論的な解釈についてはWebで検索してください。
此処では、簡単な例で説明します。
 n個の要素をk個のグループに分ける事ですが、第1は、巡回列毎にグループ分けし、第2種は単純に纏まりとしてグループ分けします。

第1種スターリング数
 1,2,3の三個のものがあったとします、これを二つの巡回列グループに分けると
    {1}[2,3]
    [2][1,3]
    [3][1,2]
   の様になります。
  [1,2]と[2,1] の様な場合同じ順回列です。
四個の場合で二つの巡回列グループに分けると
  [1][2,3,4]
  [1][3,2,4]
  [2][1,3,4]
  [2][3,1,4]
  [3][1,2,4]
  [3][2,1,4]
  [4][1,2,3]
  [4][2,1,3]
  [1,2][3,4]
  [1,3][2,4]
  [1,4][2,3]
11個の組み合わせが出来ます。
 
 左図は、巡回列の等しいものと違うものを表しています。
リング状に並べた場合順番が同じならば同じグループです。

第2種スターリング数
 単純なグループ分けです
 三個の場合は、第1種と同じです。
 四個を二つのグループに分けると
  [1][2,3,4]
  [2][1,3,4]
  [3][1,2,4]
  [4][1,2,3]
  [1,2][3,4]
  [1,3][2,4]
  [1,4][2,3]
7個の組み合わせが出来ます。
同じものがグループ入っていれば順番に関係なく同じグループです。
第2種は第1種より組み合わせ数が少なくなります。


プログラム

unit Main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
    procedure Stirling_Numbers(no : integer);
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

// 正数の固定長string変換
// o 正数
// l string長さ
function spstr(o, l: integer) : string;
const
  sp = ' ';
var
  lng, i : integer;
  s : string;
begin
  result := '';
  s := inttostr(o);
  lng := length(s);
  for i := 1 to l - lng do result := result + sp;
  result := result + s;
end;

// n=0 k= 0時 1と定義します
// no スターリング数種類No
function Stirling(n, k , no: integer): integer;
var
  m : integer;
begin
  if k= n then begin
    result := 1;
    exit;
  end;
  if (k < 1) or (k > n) then begin
    result := 0;
    exit;
  end;
  m := 0;
  case no of
    1: m := n - 1;
    2: m := k;
  end;
  result := m * Stirling(n - 1, k, no) + Stirling(n - 1, k - 1, no);
end;

// no スターリング数種類No
procedure TForm1.Stirling_Numbers(no : integer);
const
  km = 9;
  nm = 9;
var
  n, k, st : integer;
  ostr : string;
begin
  memo1.Clear;
  case no of
    1: ostr := 'Stirling number of the first kind';
    2: ostr := 'Stirling number of the second kind';
  end;
  memo1.Lines.Append(ostr);
  memo1.Lines.Append('');
  ostr := '  k  0';
  for k := 1 to km do
    ostr := ostr + spstr(k, 7);
  memo1.Lines.Append(ostr);
  ostr := 'n ----' ;
  for k := 1 to km do
    ostr := ostr + '-------';
  memo1.Lines.Append(ostr);
  ostr := '';
  st := 0;
  for n := 0 to nm do begin
    ostr := spstr(n, 2) + '|';
    k := 0;                             // 最初の列  k=0 st数文字長さ3
    st := Stirling(n, k, no);
    ostr := ostr + spstr(st, 3);
    for k := 1 to n do begin          // k=1~ st数文字長さ7
      st := Stirling(n, k, no);
      ostr := ostr + spstr(st, 7)
    end;
    memo1.Lines.Append(ostr);
  end;
end;

// Stirling number 1
procedure TForm1.Button1Click(Sender: TObject);
begin
  Stirling_Numbers(1);
end;

// Stirling number 2
procedure TForm1.Button2Click(Sender: TObject);
begin
  Stirling_Numbers(2);
end;

// 初期設定
procedure TForm1.FormCreate(Sender: TObject);
begin
  memo1.clear;
  memo1.Text := 'Stirling number';
end;

end.


download Stirling_number.zip

  三角関数、逆三角関数、その他関数 に戻る