Young

Summary

Young は主に組合せ論を目的とした Python 用の数学ライブラリです。

Young 図形や分割数の簡単な操作ができるので、代数的組合せ論(algebraic combinatorics)、数え上げ組合せ論(enumerative combinatorics)のちょっとした計算に威力を発揮します(して欲しいです)。

INSTALL

Young は次の URL からダウンロードできます。

[Young project page]

CVS を使って最新のソースコードを入手するには次のようにします。

$ cvs -d:pserver:anonymous@cvs.sourceforge.jp:/cvsroot/young login  
Logging in to :pserver:anonymous@cvs.sourceforge.jp:2401/cvsroot/young
CVS password:<ENTER>      # パスワードを聞かれますが、何も入力せずに <ENTER> を入力
$ cvs -z3 -d:pserver:anonymous@cvs.sourceforge.jp:/cvsroot/young co young
CVS のレポジトリをウェブから閲覧することも出来ます。
http://cvs.sourceforge.jp/cgi-bin/viewcvs.cgi/young/

インストールするには大きく分けて2通りあります。

binary

Windows 用のバイナリファイルの場合、ファイルをダブルクリックして 画面に従って操作すれば無事インストールは終了です。

現在はバイナリからのインストールは Windows からしか対応していません。

source

ソースからインストールするには、アーカイブをダウンロード後、コマンドラインから次のようにします。($VER は Young のバージョンです)

$ tar zxfv young-$VER.tar.gz
$ cd young-$VER
$ python setup.py install

Document

epydoc で作成されたAPIドキュメント(英語風?)があります。

API

Usage

Python のインタープリターから使う場合、まず young モジュールをインポートします。

>>> import young
>>> from young import *     # 手を抜く

上のスタイルでモジュールをインポートした場合、関数を呼び出すときに 毎回モジュールの名前を明示的に指定する必要があります。

>>> young.partition(10)
>>> young.factorial(5)

Python のことはあまり知らず、young モジュールしか使わないなら下の方が楽でいいと思います。

Basics

まずは、基本的な計算から

>>> factorial(5)     # 5 x 4 x 3 x 2 x 1
120
>>> factorial(5,3)   # 5 x 4 x 3
60

>>> permutation(1,2,3)   # (1,2,3) の順列
[[3, 1, 2], [2, 1, 3], [1, 3, 2], [2, 3, 1], [1, 2, 3], [3, 2, 1]]
>>> permutation('xyz')   # 'x', 'y', 'z' の順列
[['z', 'x', 'y'], ['y', 'x', 'z'], ['x', 'z', 'y'], ['y', 'z', 'x'], ['x', 'y',
'z'], ['z', 'y', 'x']]
>>> combination(4, 2)    # 4個から2個を選ぶ組合せの数
6
>>> combination('python', 2)   # 文字列 "python" から2文字選ぶ
[['p', 'y'], ['p', 't'], ['p', 'h'], ['p', 'o'], ['p', 'n'], ['y', 't'], ['y', '
h'], ['y', 'o'], ['y', 'n'], ['t', 'h'], ['t', 'o'], ['t', 'n'], ['h', 'o'], ['h
', 'n'], ['o', 'n']]

カタラン数を少し。

>>> catalan(20)
6564120420L
>>> for i in range(0, 10):       # 0 から 9 までのカタラン数を表示 
...     print i, catalan(i)
...
0 1
1 1
2 2
3 5
4 14
5 42
6 132
7 429
8 1430
9 4862

Partition

次に自然数 N に対して分割を与えます。

>>> partition(5)
(5)
(4,1)
(3,2)
(3,1,1)
(2,2,1)
(2,1,1,1)
(1,1,1,1,1)
>>> p = partition(10)
>>> p.size()        # 10 の分割はどれだけあるのか
42
>>> for x in take(p, 5):  # 10 の分割のうち、最初の 5 個を表示
        print x
(10)
(9,1)
(8,2)
(8,1,1)
(7,3)
>>> for x in drop(p, 37): # 最後の 5 個を表示(42 - 37 = 5)
        print x
(2,2,2,2,1,1)
(2,2,2,1,1,1,1)
(2,2,1,1,1,1,1,1)
(2,1,1,1,1,1,1,1,1)
(1,1,1,1,1,1,1,1,1,1)

置換群

置換群の簡単な計算もできます。 [1,2,3] を [2,1,3] に移す置換の場合、(2,1,3) で表します。

>>> from young import *
>>> p = permgroup(3,2,1)
>>> p
PermGroup([3 2 1])
>>> p.get_inv()            # 転倒数
3
>>> p.get_sgn()            # 符号(-1 or +1)
-1
>>> p.isodd()              # 奇置換ですか?
True
>>> p.iseven()             # 偶置換ですか?
False
>>> p.get_inverse()        # 逆元
PermGroup([3 2 1])
>>> p = permgroup(5,3,2,1,4)
>>> p.to_cycle()           # 巡回置換分解
Cycle([(1 4 5) (2 3)])
>>> p.get_inverse()        # 逆元
PermGroup([4 3 2 5 1])
>>> p1 = permgroup(4,3,1,2)
>>> p2 = permgroup(3,1,4,2)
>>> p1 * p2                # 置換群の間の演算は * で行います。
PermGroup([2 4 3 1])
>>> p2 * p1
PermGroup([1 4 2 3])
>>> p3 = p1 * p2
>>> p3
PermGroup([2 4 3 1])
>>> p4 = p3.get_inverse()  # 逆元
>>> p4
PermGroup([4 1 3 2])
>>> p3 * p4                # 単位元になるかチェック
PermGroup([1 2 3 4])
>>> p4 * p3                # 単位元になるかチェック
PermGroup([1 2 3 4])
>>> p3.to_cycle()          # 巡回置換分解
Cycle([(1 2 4) (3)])
>>>
上の結果からわかるように、 置換群 a,b に対して、
a * b
は普通の数学の本だと
b o a

と書かれているものと同じ演算になっています。

同様に、
b * a
a o b

と同じです。

このあたりは将来的に変わる可能性が高いです。

Young

次がメインのヤング図形です。

>>> y = young(4)
>>> y
(4)
1 2 3 4

(3,1)
1 2 3
4

1 2 4
3

1 3 4
2

(2,2)
1 2
3 4

1 3
2 4

(2,1,1)
1 2
3
4

1 3
2
4

1 4
2
3

(1,1,1,1)
1
2
3
4

>>> y.report()      # 各分割に対して、どれだけ標準盤があるか
partition             number  square
----------------------------------------
(4)                        1       1
(3,1)                      3       9
(2,2)                      2       4
(2,1,1)                    3       9
(1,1,1,1)                  1       1
----------------------------------------
total                     10      24

>>> factorial(4)    # チェック
24

>>> young(3,1,1)    # 分割が (3,1,1) の標準盤
(3, 1, 1)
1 2 3
4
5

1 2 4
3
5

1 2 5
3
4

1 3 4
2
5

1 3 5
2
4

1 4 5
2
3

>>> y = young(6)
>>> y.size()       # 6 の分割を元にした標準盤がどれだけあるか
76
>>> for x in take(y, 4):  # 6 を元にした標準盤から4個を表示
        print x
1 2 3
4 5 6

1 2 4
3 5 6

1 2 5
3 4 6

1 3 4
2 5 6

# Young 盤の up/down など
>>> y = young(2,1)        # 最初に標準盤を与える
>>> y.get_partition()     # チェック
[(2, 1)]
>>> y.up()                # up
>>> y.get_partition()
[(3,1), (2,2), (2,1,1)]
>>> for i in range(3):
...     y.up()
...     y.get_partition()
...
[(4,1), (3,2), (3,1,1), (2,2,1), (2,1,1,1)]
[(5,1), (4,2), (4,1,1), (3,3), (3,2,1), (3,1,1,1), (2,2,2), (2,2,1,1), (2,1,1,1, 1)]
[(6,1), (5,2), (5,1,1), (4,3), (4,2,1), (4,1,1,1), (3,3,1), (3,2,2), (3,2,1,1),
(3,1,1,1,1), (2,2,2,1), (2,2,1,1,1), (2,1,1,1,1,1)]

>>> y = young(2,1,1)       # 最初に標準盤を与える
>>> y.get_partition()      # チェック
[(2, 1, 1)]
>>> for i in range(4):
...     y.down()
...     y.get_partition()
...
[(2,1), (1,1,1)]
[(2), (1,1)]
[(1)]
[()]
>>>

注意点

young の take/dropは partition の take/drop とは異なり、 表示順序がきれいにソートされていません。

サンプル

>>> y = young(4)
>>> for x in take(y, 6):print x
1
2
3
4

1 2 3
4

1 2 4
3

1 3 4
2

1 2 3 4

1 2
3 4

ただし、これは将来的にはかわる可能性があります。

MEMO

Young について書き残したことなど

Young の特徴

GOOD

  • 一部の数学ソフトにしか実装されていないような計算を手軽に出来てしまう。
  • 対象をかなり絞っているので、ファイルサイズが小さい(light weight)
  • スクリプト言語で書かれているので、インタープリターで直接実験できる。(当然、コンパイルの必要もない)
  • Python が動くプラットフォームなら、どこでも実行できる
  • itertools など Python2.3 で追加された新機能をいち早く体験できる
  • フリーソフトウェア(Mathematica/Maple のような商用ソフトではない)

BAD

  • 計算が遅い (young(100) などとすると、、、)
  • 手でやっていることをそのままコンピューターにやらせているので、計算量が多く、 アルゴリズムなどにかなり改善の余地がある。
  • ツボにはまらないと使い道がない。

分割はどのくらいあるのか

50 の分割(partition(50).size()) は 204226, 100 の分割は 190569292 あります。 自分がこのモジュールでテストした範囲では、partition(50) くらいまでは 正しく(時間内に)計算出来ています。

また、分割の近似値を与えるものとして、Hardy-Ramanujan(-Rademacher) による公式も知られています。

jeu de taquin

Young 図形の本を読んでいると、たまに "jeu de taquin" という言葉を目にすることがあります。 初めて目にすると一体どんなものなのか想像もつきませんが、taquin は 数字並べゲーム(のフランス名)のことです。 Python で書かれた taquin のスクリプトを見つけたので、興味のある方は一度遊んでみてください。

young/samples/taquin/ 以下のディレクトリにスクリプトはあります。
http://cvs.sourceforge.jp/cgi-bin/viewcvs.cgi/young/young/samples/taquin/taquin.py

jeu de taquin

今後の方向

しばらくは分割数の方をメインにライブラリを充実させていく予定です。

Bibliography

下に挙げるもの以外にもヤング図形や分割数に関する本は多数あります。

[1]寺田至, ヤング図形のはなし, 日本評論社, 2002.
[2]堀田良之, 加群十話, 朝倉書店, 1988.
[3]Richard P. Stanley, Enumerative Combinatorics volume 1, Cambridge University Press, 2001.