# git による管理
# http://ni66ling.hatenadiary.jp/entry/2018/01/02/022905
from sympy import *
from sympy.plotting import plot
from IPython.display import display
init_printing(use_latex='mathjax')
X = Matrix([
[Rational(3,1),0,0],
[0,Rational(3,1),0],
[0,0,Rational(3,1)]
])
Y = Matrix([
[0,Rational(1,1),Rational(2,1)],
[Rational(1,1),0,Rational(1,1)],
[Rational(2,1),Rational(2,1),0]
])
'''
X = Matrix([
[Rational(3,1),0,0,0],
[0,Rational(3,1),0,0],
[0,0,Rational(3,1),0],
[0,0,0,Rational(3,1)],
])
Y = Matrix([
[0,Rational(1,1),Rational(1,1),0],
[Rational(2,1),0,Rational(2,1),2],
[Rational(0,1),Rational(1,1),0,1],
[Rational(1,1),Rational(1,1),Rational(0,1),0]
])
'''
print("供給行列")
display(X)
print("需要行列")
display(Y)
A=Y-X # Xp=Yp を解く
p1, p2, p3 = symbols('p1, p2, p3')
#p1, p2, p3,p4 = symbols('p1, p2, p3, p4')
p = Matrix([[p1],[p2],[p3]])
#p = Matrix([[p1],[p2],[p3],[p4]])
eqivprice = solve(A*p,p)
ep = [eqivprice[p1]/p3,eqivprice[p2]/p3,p3/p3]
#ep = [eqivprice[p1]/p4,eqivprice[p2]/p4,eqivprice[p3]/p4,p4/p4]
print("各自の収入=支出となるような価格ベクトル =")
display((ep))
print("交換比率は、価格の逆数。\nリンネル{} <=> 上衣{} <=> 茶{},つまり...".format(1/ep[0],1/ep[1],1/ep[2]))
display((1,ep[0]/ep[1],ep[0]/ep[2]))
#display((1,ep[0]/ep[1],ep[0]/ep[2],ep[0]/ep[3]))
def exchange(w1,i,j,l,m):# (i,j)が、(l,m)から、m財をw1だけ取得
xrate = ep[m]/ep[j]
w2 = w1*xrate #(i,j) が交換で相手に与えるj財の量
X[i,m] += w1 # i が需要する
X[l,m] += -w1 #lが供給する
X[i,j] += -w2 #iが供給
X[l,j] += w2 #lが需要
man = ['A','B','C','D','E']
ware = ['リンネル','上衣','茶','砂糖','鉄']
print("{}の{}:{}単位が、{}の{}:{}単位と、1:{}の比率で交換される".format(man[i],ware[j],w2,man[l],ware[m],w1,xrate))
display(X)
print("\n<<交換開始>>")
'''
交換のプロセスをプログラミング
A,B,C,... と順に自分の需要をみたす
- B->A という交換はなし B->C,D,...のみ
- 自分の余剰の状態をチェックして、その財kを記憶する。
--TODO:初期値では対角要素だが、交換のプロセスで別のように変わる可能性があるので注意
--TODO:変わっても余剰財は1種類だと仮定してコーディングしてある。ここにバグの可能性?
--TODO:対策 余剰財のリストをつくっておいて、A[i,k1]で足りなければA[i,k2]....
--TODO:とすればよいが面倒
- 自分の不足分A[i,m]をA[0,m] から下に向かって探してゆき
- この人l が見つかったら exchange 関数をよぶ。
- exchange(A[i,m],i,k, l,m) :不足分A[i,m]を、(i,k)財を渡して、(l,m)財と得る
'''
(r,c) = Y.shape
for i in range(r-1): # A,B,C,.. の順に需要を満たしてゆく(最後は予定調和的に満たされる)
A = Y - X # 過不足をしめす行列をreset
for j in range(c):
if A[i,j] < 0:# 余剰がある財(初期値では対角要素だが、ズレる可能性があるのでチェック。注意!)
k =j
for m in range(c): #リンネル、上衣、茶...... の順に みていって
if A[i,m] > 0:# もしm 財の交換が必要なら
for l in range(r):# m財をもっている人たちの保有状態を順にあたってゆき
if A[l,m] < 0 : #マイナスなら余剰をもっているということになるので、
exchange(A[i,m],i,k,l,m) #自分の余剰財(i,k) を、この人の余剰財 (l,m) と交換して、A[i,m]を手に入れる。
#A[i,k] ->A[l,k] and A[l,m] -> A[i,m] というタテ方向の財の移動
'''
print("アプローチ:主体ベースで(行ごとに)需給調整を考える")
#Aがリンネルで上衣を手に入れる
w1 = Y[0,1] - X[0,1]
exchange(w1,0,0,1,1)
#Aがリンネルで茶を手に入れる
w1 = Y[0,2] - X[0,2]
exchange(w1,0,0,2,2)
#Bが上衣で、Cからリンネルを手に入れる
w1 = Y[1,0] - X[1,0]
exchange(w1,1,1,2,0)
#Bが砂糖を、Cから手に入れる
w1 = Y[1,2]-X[1,2]
exchange(w1,1,1, 2,2)
'''
print("<<完了>>")