In [1]:
#なるほどね
men=['a','b','c']
women=['d','e','f']
pref={'a':['d','e','f'],'b':['e','d','f'],'c':['d','e','f'],'d':['b','a','c'],'e':['a','b','c'],'f':['a','b','c']}
for n in pref:
pref[n].reverse()
rank={'d':{'a':2,'b':1,'c':3},'e':{'a':1,'b':2,'c':3},'f':{'a':1,'b':2,'c':3}}
freemen=list(men)
numpart=len(men)
S={}
while freemen:
m=freemen.pop()
if len(pref[m])==0:
continue
w=pref[m].pop()
if w not in S:
S[w]=m
else:
mprime=S[w]
if rank[w][m]<rank[w][mprime]:
S[w]=m
freemen.append(mprime)
else:
freemen.append(m)
print S
In [3]:
list=['a','b']
In [ ]:
In [8]:
men.pop()
Out[8]:
In [1]:
#deferred acceptance function
#a 男リスト
#c preference list
#d 女の男ランク
def da(a,c,d):
for n in c:
c[n].reverse()
freemen=list(a)
numpart=len(a)
S={}
while freemen:
m=freemen.pop()
if len(c[m])==0:
continue
w=c[m].pop()
if w not in S:
S[w]=m
else:
mprime=S[w]
if d[w][m]<d[w][mprime]:
S[w]=m
freemen.append(mprime)
else:
freemen.append(m)
print S
In [2]:
a=['a','b','c']
c={'a':['d','e','f'],'b':['e','d','f'],'c':['d','e','f'],'d':['b','a','c'],'e':['a','b','c'],'f':['a','b','c']}
d={'d':{'a':2,'b':1,'c':3},'e':{'a':1,'b':2,'c':3},'f':{'a':1,'b':2,'c':3}}
da(a,c,d)
In [ ]:
range(1,3)
In [1]:
#引数をpref(順序付き)と人数
# a={'a':{1:'d',2:'e',3:'f'},'b':{1:'e',2:'d',3:'f'},'c':{1:'d',2:'e',3:'f'}}
#b={'d':{1:'b',2:'a',3:'c'},'e':{1:'a',2:'b',3:'c'},'f':{1:'a',2:'b',3:'c'}}
#c=3
def da2(a,b,c):
S={}
free=[]
for i in a:
free.append(i)
n=1
while free:
m=free.pop()
f=a[m][n]
if f not in S:
S[f]=m
else:
l=S[f]
for j in range(1,c+1):
if b[f][j]==m:
d=j
else: continue
for k in range(1,c+1):
if b[f][k]==l:
e=k
else: continue
if e<d:
free.append(m)
n+=1
else:
S[f]=m
free.append(l)
n+=1
if len(free)==0:
return S
In [55]:
a={'a':{1:'d',2:'e',3:'f'},'b':{1:'e',2:'d',3:'f'},'c':{1:'d',2:'e',3:'f'}}
b={'d':{1:'b',2:'a',3:'c'},'e':{1:'a',2:'b',3:'c'},'f':{1:'a',2:'b',3:'c'}}
In [3]:
da2(a,b,c)
In [56]:
#引数をpref(順序付き)と人数
#男プロポーズと女プロポーズの結果を同時に表示
# a={'a':{1:'d',2:'e',3:'f'},'b':{1:'e',2:'d',3:'f'},'c':{1:'d',2:'e',3:'f'}}
#b={'d':{1:'b',2:'a',3:'c'},'e':{1:'a',2:'b',3:'c'},'f':{1:'a',2:'b',3:'c'}}
#c=3
def da2(a,b):
S={}
free=[]
T={}
wfree=[]
for i in a:
free.append(i)
for i in b:
wfree.append(i)
c=len(free)
n=1
while free:
m=free.pop()
f=a[m][n]
if f not in S:
S[f]=m
else:
l=S[f]
for j in range(1,c+1):
if b[f][j]==m:
d=j
else: continue
for k in range(1,c+1):
if b[f][k]==l:
e=k
else: continue
if e<d:
free.append(m)
n+=1
else:
S[f]=m
free.append(l)
n+=1
if len(free)==0: continue
g=1
while wfree:
m=wfree.pop()
f=b[m][g]
if f not in T:
T[f]=m
else:
l=T[f]
for j in range(1,c+1):
if a[f][j]==m:
d=j
else: continue
for k in range(1,c+1):
if a[f][k]==l:
e=k
else: continue
if e<d:
wfree.append(m)
g+=1
else:
T[f]=m
wfree.append(l)
g+=1
if len(wfree)==0:
return S,T
In [57]:
da2(a,b)
Out[57]:
In [17]:
x={1:{'a':'b','c':'d'}}
y={2:{'e':'f'}}
In [19]:
x.update(y)
In [20]:
x
Out[20]:
In [34]:
a={'x':1,'y':8,'z':2}
b={'x':5,'y':10,'z':7}
c={'x':6,'y':1,'z':10}
d={'x':9,'y':9,'z':10}
e={'x':6,'y':6,'z':2}
f={'x':8,'y':3,'z':4}
g={'x':2,'y':5,'z':5}
h={'x':7,'y':4,'z':8}
i={'x':4,'y':10,'z':6}
j={'x':3,'y':7,'z':9}
In [35]:
x=[]
y=[]
z=[]
In [36]:
w=[a,b,c,d,e,f,g,h,i,j]
In [49]:
S={}
for l in w:
n=[]
m=['x','y','z']
for k in m:
n.append(l[k])
o=max(n)
for p in m:
if l[p]==o:
S[str(l)]=p
In [50]:
S
Out[50]:
In [1]:
#データ構造は以下のとおり
#m:numberof males
#n:number of females
#maless:[0,1///m-1]
#females:[0,1,///n-1]
#m_pref:二次元配列m*(n+1)
#f_pref:二次元配列n*(m+1)
#m_pref[i]=[0,1,2///n(unmatch)]
#f_prefも同様の順列で表記
#出力は、1次元のm_matched:長さがmのmatch相手を並べた順列
#一回誰かに取られたら-1で置き換える。
In [54]:
import numpy as np
m=np.arange(5)
n=np.arange(8)
In [55]:
m
Out[55]:
In [56]:
n
Out[56]:
In [57]:
a=np.random.permutation(9)
b=np.random.permutation(9)
c=np.random.permutation(9)
d=np.random.permutation(9)
e=np.random.permutation(9)
In [58]:
m_pref=np.vstack((a,b,c,d,e))
In [59]:
f=np.random.permutation(6)
g=np.random.permutation(6)
h=np.random.permutation(6)
i=np.random.permutation(6)
j=np.random.permutation(6)
k=np.random.permutation(6)
l=np.random.permutation(6)
o=np.random.permutation(6)
In [60]:
n_pref=np.vstack((f,g,h,i,j,k,l,o))
In [8]:
n_pref
Out[8]:
In [9]:
m_pref
Out[9]:
In [14]:
#データ形式調整済み。
#女性の選好:n_pref
#男性の選好:m_pref
#男性5人女性8人のマッチング
#unmatchは8で表記
S=[]
n=1
free=range(5)
while free:
m=free.pop()
f=m_pref[m,:][n]
if f not in S:
S.append(f)
elif f==8:
S.append(f)
else:
l=S.index(f)
for j in range(6):
if n_pref[f,:][j]==m:
d=j
else: continue
for k in range(6):
if n_pref[f,:][k]==l:
e=k
else: continue
if e<d:
free.append(m)
n+=1
else:
S.append(m)
S.pop(l)
S.insert(l,-1)
free.append(l)
n+=1
if len(free)==0:
S.reverse()
print S
In [13]:
# 修正案
#5があったらもう5を入れちゃう
S=[]
n=1
free=range(5)
while free:
m=free.pop()
f=m_pref[m,:][n]
if f not in S:
S.append(f)
elif f==8:
S.append(f)
else:
if -1 in S:
l=-1
else:
l=S.index(f)
for j in range(6):
if n_pref[f,:][j]==m:
d=j
else: continue
for k in range(6):
if n_pref[f,:][k]==l:
e=k
else: continue
for p in range(6):
if n_pref[f,:][p]==5:
if e<d:
free.append(m)
n+=1
else:
S.append(m)
S.pop(l)
S.insert(l,-1)
free.append(l)
n+=1
if len(free)==0:
S.reverse() # 修正1
print S #修正2
In [49]:
m_pref
Out[49]:
In [50]:
n_pref
Out[50]:
In [51]:
#修正版
S=np.tile([-1],5)
free=range(5)
In [52]:
S
Out[52]:
In [53]:
free
Out[53]:
In [54]:
#最新版
#nのカウントをリセットする仕組みを加えた。
#多分あってるはずです。関数化は明日やります。
n=0
while free:
A=free.pop()
F=m_pref[A,:][n]
if F not in S:
S[A]=F
n=0 #nをリセット
elif F==8:
S[A]=8
else:
for y in range(5):
if S[y]==F:
M=y #MはFがいる場所のindex
for z in range(6):
if n_pref[F,:][z]==M:
Z=z
if n_pref[F,:][z]==A:
W=z
if n_pref[F,:][z]==5:
V=z
if V<W and V<Z:
S[M]=-1
free.append(A)
free.append(M)
n+=1
elif W<Z and W<V:
S[A]=F
S[M]=-1
free.append(M)
n+=1
elif Z<W and Z<V:
free.append(A)
n+=1
if len(free)==0:
print S
In [1]:
import numpy as np
g=np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
In [3]:
g.shape[0]
Out[3]:
In [10]:
#そもそもアンマッチの場合を修正しました。
#出力が男女の結果となるように修正しました。
#Pがm_pref
#Qがn_pref
def da3(P,Q):
N=P.shape[0]
G=Q.shape[0]
S=np.tile([-1],N)
free=range(N)
n=0
while free:
A=free.pop()
F=P[A,:][n]
if F==G:
S[A]=G
else:
for J in range(N+1): #そもそもマッチしない場合を追加
if Q[F,:][J]==A:
D=J
if Q[F,:][J]==N:
E=J
if E<D:
free.append(A)
n+=1
else:
if F not in S:
S[A]=F
n=0 #nをリセット
else:
for y in range(N):
if S[y]==F:
M=y #MはFがいる場所のindex
for z in range(N+1):
if Q[F,:][z]==M:
Z=z
if Q[F,:][z]==A:
W=z
if W<Z:
S[A]=F
S[M]=-1
free.append(M)
n+=1
else:
free.append(A)
n+=1
if len(free)==0: #女性の結果も表示するように修正
s=list(S)
L=np.tile([N],G)
l=list(L)
for u in s:
if u==G: continue #アンマッチの時はスルー
else:
v=s.index(u)
l[u]=v
return s,l
In [64]:
da3(m_pref,n_pref)
Out[64]:
In [46]:
m_pref
Out[46]:
In [47]:
n_pref
Out[47]:
In [2]:
import numpy as np
a=np.arange(5)
In [3]:
a
Out[3]:
In [4]:
A=list(a)
In [5]:
A.index(0)
Out[5]:
In [7]:
A
Out[7]:
In [8]:
b=np.array(A)
In [1]:
b
In [76]:
import numpy as np
In [77]:
a=np.random.permutation(6)
b=np.random.permutation(6)
c=np.random.permutation(6)
d=np.random.permutation(6)
e=np.random.permutation(6)
In [78]:
f=np.random.permutation(9)
g=np.random.permutation(9)
h=np.random.permutation(9)
i=np.random.permutation(9)
j=np.random.permutation(9)
k=np.random.permutation(9)
l=np.random.permutation(9)
o=np.random.permutation(9)
In [79]:
m_pref=np.vstack((a,b,c,d,e))
In [80]:
n_pref=np.vstack((f,g,h,i,j,k,l,o))
In [81]:
m_pref
Out[81]:
In [82]:
n_pref
Out[82]:
In [83]:
def da3(P,Q):
import sys
if isinstance(Q, list) != True and isinstance(Q,np.ndarray) != True:
print "Input Error!!"
sys.exit()
if isinstance(P, list):
P = np.array(P)
Q = np.array(Q)
elif isinstance(P, np.ndarray):
print "ndarray"
else:
print "Input Error!!"
sys.exit()
N=P.shape[0]
G=Q.shape[0]
S=np.tile([-1],N)
free=range(N)
n=0
while free:
# print S
"""
上のシャープを外すことで男性の婚約状況の一周ごとの推移を表示することができます
正しくない結果が返ってきている疑いのある時に様子を見るため使いましょう
"""
A=free.pop()
F=P[A,:][n]
if F==G:
S[A]=G
else:
for J in range(N+1):
if Q[F,:][J]==A:
D=J
if Q[F,:][J]==N:
E=J
if E<D:
free.append(A)
n+=1
else:
if F not in S:
S[A]=F
n=0
else:
for y in range(N):
if S[y]==F:
M=y
for z in range(N+1):
if Q[F,:][z]==M:
Z=z
if Q[F,:][z]==A:
W=z
if W<Z:
S[A]=F
S[M]=-1
free.append(M)
n+=1
else:
free.append(A)
n+=1
if len(free)==0:
s=list(S)
L=np.tile([N],G)
l=list(L)
for u in s:
if u==G: continue
else:
v=s.index(u)
l[u]=v
return s,l
else: continue
In [84]:
da3(m_pref,n_pref)
In [35]:
# アルゴリズムがどうにかしているためにうまくいかない例
pl = [[0,1,2],
[0,2,1]]
pt = [[0,1,2],
[1,2,0]]
da3(pl,pt)
Out[35]: