Pythonで学ぶ数学 集合編
この前の心意気虚しく紹介したページの内容全然分かりませんでした。数学以前にPython力が足りてなかったです。抽象基底クラスとかイミフです。
というわけで、まずは簡単な数学からやってレベルを上げてくことにします。
とりあえず適当に作った問題をPythonで解いていきます。問題は一部、すぐわかる代数(東京図書)を参考に作りました。
今回は基本ということで集合から。
問題1 部分集合
このとき
を証明せよ。
ほんとはがやりたかったのですが、まあ無理なので有限の集合にしときました。
解答
A = {12*n for n in range(1,5)} B = {6*n for n in range(1,10)} print A.issubset(B)
リスト内包表記は集合を表すset型({}のやつ)でも使えます。数学とほとんど表記が一緒なので分かりやすいです。
これならもっと近いです。数学的にこういう書き方(左側が素の文字じゃない)していいのか知らないですけど。意味は通じるのでたぶんあり?
3行目は A is subset of B で、AはBの部分集合(subset)だって主張です。真偽値を返します。
実行結果
True
というわけで証明できました。証明・・・?
問題2 直積
のときとの直積を求めよ。
ちなみに直積は数学ではこう書きます。
解答(3通り)
def tyokuseki(A,B): li = [] for x in A: for y in B: li.append((x,y)) return li def gentyoku(A,B): for x in A: for y in B: yield (x,y) A = range(1,4) B = range(2,7,2) print tyokuseki(A,B) print [x for x in gentyoku(A,B)] print [(a,b) for a in A for b in B]
実行結果
[(1, 2), (1, 4), (1, 6), (2, 2), (2, 4), (2, 6), (3, 2), (3, 4), (3, 6)] [(1, 2), (1, 4), (1, 6), (2, 2), (2, 4), (2, 6), (3, 2), (3, 4), (3, 6)] [(1, 2), (1, 4), (1, 6), (2, 2), (2, 4), (2, 6), (3, 2), (3, 4), (3, 6)]
無駄に3つも載せました。思いついた順です。一つ目は普通に繰り返し、二つ目はジェネレータとリスト内包、三つ目はネストしたリスト内包表記です。
最後のネストしたリスト内包表記は数学の表記に近いですね。おまけに楽だし。
問題3 集合の演算
とする。
のとき
を求めよ。
+(たす)は今までの意味とか考えずに、新しい演算として定義されていることに注意です。
関数でもできるんでしょうが、ここはせっかくなので演算子のオーバーロードでやりたいところですね。
解答
class Cup(object): def __init__(self, a): self.a = a def __add__(self, other): return self.a | other.a set1 = {"a","b","c"} set2 = {"c","d","e"} A = Cup(set1) B = Cup(set2) print A+B
実行結果
set(['a', 'c', 'b', 'e', 'd'])
set型は | で和集合を取ります。通常+になってる部分を | に変えました。
補足 演算子のオーバーロードとは何か
上の例で行くとA+Bの定義を変えるのを、__add__という特殊メソッドを上書きしてしまうことで実現することです。
他の簡単な例も考えてみます。
- 足し算を引き算にする。
class Gyaku: def __init__(self, x): self.x = x def __add__(self, other): return self.x - other.x go = Gyaku(5) san = Gyaku(3) print go + san
実行結果
2
go + sanと書くとgo.__add__(san)が呼び出されます。
go.x - san.x が返されるわけです。
- ベクトルの計算(足し算のみ)をする。
class Vector(object): def __init__(self, x, y): self.x = x self.y = y def __add__(self, other): return Vector(self.x + other.x , self.y + other.y) v1 = Vector(1,5) v2 = Vector(2,6) V = v1+v2 print V.x, V.y