Kuramoto模型在Python和MATLAB中的簡單實現
事情是這樣的,我最近在研究團隊編組及內部模式對發揮團隊能力的影響,以及如何正確編組讓團隊能力發揮實現最大化,別問我爲什麼研究這個,反正稀裏糊塗就研究上了。我發現在描述團隊編組間及內部同步能力的時候,人們對Kuramoto模型(藏本模型)作了大量的研究,其中包括模型達到完全相位同步的充分條件、耦合強度對於同步的影響、一定條件下振子的收斂速率等。但具體實現一般都在MATLAB中,且網上代碼過於複雜(我運行了一遍一堆報錯),這裏我使用Python和MATLAB對Kuramoto模型簡單模擬。
模擬的話還是一遍舉個栗子,邊分析邊測試效果最好,百度學術上有一篇關於Kuramoto模型的簡單論文,我們就用它來實現模擬。空間信息支援力量編組模式分析,上連接:http://xueshu.baidu.com/usercenter/paper/show?paperid=11b7c2ef69b3ac7f6e114afeb75f8083&site=xueshu_se
好吧,那我們開始,首先是Python實現:
N維Kuramoto模型的數學描述如下:
沒錯,是討厭的數學公式,沒事,它可以改寫成這樣:
好像還是有點長,那我們在改寫一下:
看着好多了,那我就來說說式子中參數的意義,Kij爲耦合矩陣,是爲了便於描述不同振子間耦合程度不同的情形。最下面那個式子的r就是我們的目標,反應振子間的相關性,這個相關性就可以描述我們想要的編組內部同步能力。
哎呦,這個式子看起來好簡單,這裏要補充一下知識點:同步能力可不是一下子各組該怎麼同步直接確定的了,它是一個從開始到穩定的階段,也就是說隨時間變化,最終反映在各組的同步能力纔會確定,那麼最後圖像是什麼樣子纔算同步能力好呢?
同步能力好,是指隨着時間的推移,各組的同步能力r逐漸穩定,波動現象消失或固定在某一個小範圍內。需要注意的是這和各組r值之間的差距沒有關係,我們要的是一個平穩的狀態。那怎麼辦找r和t的關係呢?
注意看最上面那兩個式子,相位(第一項,等號左邊那個)上面有個點,這樣他可就不簡簡單單是個相位了,它代表的是相位的變化值,是一個微小的微分值,好吧具體意思就是,那個式子左邊展開之後是這樣的:
哎呀,t出現了,其實\theta 與t有關,這裏你可能有點繞,因爲它們之間的關係是一一對應的,就是說每個時間的t對應了一個\theta ,我下面帶入具體數值的時候你就知道了。
組間同步能力與時間t的關係出現了!
也就是說我先用上面的那個公式4計算出來\theta 的值,在帶入到公式5,那麼t-r關係就可以明確下來了,那現在我們再回過頭來看看文章中已經給的例子,看看還有沒有未知量。
栗子是這樣的栗子:
假設某機構內部有 4 個編組,每個編組包括 5 個節點(其中 1 個節點爲領導節點) 。另外,將上級領導作爲一個獨立的編組,且只包含一個節點。假設在領導機關增加4名信息傳遞人員。當以獨立編組模式編組時,指定1名信息傳遞人員爲指揮者,其指揮關係與其他編組一致; 當分散編組時,信息傳遞力量節點的關係與所在編組其他節點指揮關係一 致。其中,完全分散編組模式時,各信息傳遞力量節點之間無信息共享通道; 不完全分散編組時,在各信息傳遞人員節點之間建立一條信息共享通道。各編組模式及其拓撲結構如下圖所示:
獨立編組模式
完全分散編組
不完全分散編組
參數數據
參數確定一下有沒有未知量:
首先N,數據數目已知,這個有了。
K值是分組內的連接強度,這個是看實際情況,由甲方提供或者自己看着給的,這裏就是甲方給的編組圖,i與j點的鏈接強度一目瞭然,這個有了。
\omega _{i} 是振子i的固有頻率,也稱自然頻率,甲方會給,沒法自己估計,這個有了。
\theta ,\theta 怎麼辦,初始的\theta 會給,自己也能測的出來,但那麼多\theta {j} -\theta{i} 得多少不知道啊,這裏通過翻看文章,我發現其實文章是有一個特殊條件的,不然的話是需要研究耦合因子求三種約束條件解情況的,特殊條件就在這:
假設編組內節點的初始相位差爲π/2,且編號最小者爲0,隨編號增大而增大。
哦,初始相位差知道了,你還告訴了我各個初始相位,那麼\theta _{j} -\theta _{i} 的值就在一個範圍內的幾個固定值裏面啊!
好的,沒有未知量了,就是找K的時候麻煩點,沒辦法,這個決定了編組的不同,寫腳本算一下吧:
#codingutf-8
##ScriptName:KuramotoSimulation.py
import matplotlib.pyplot as plt
from pylab import
from sympy import
from matplotlib.ticker import MultipleLocator, FormatStrFormatter
import math
import numpy as np
N = 31 #總節點數
c=[0,0,math.pi 2,math.pi,3 math.pi 2,0,0,0,math.pi 2,math.pi,3 math.pi 2,0,0,0,math.pi 2,math.pi,3 math.pi 2,0,0,0,math.pi 2,math.pi,3 math.pi 2,0,0,0,math.pi 2,math.pi,3 math.pi 2,0,0]
w = [4,3,3,2,2,1,4,3,3,2,2,1,4,3,3,2,2,1,4,3,3,2,2,1,4,3,3,2,2,1,5]
k1 = [
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2],
[1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,1,0.9,0.9,0.9,0.9,0.9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2],
[0,0,0,0,0,0,0.9,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0.9,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0.9,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0.9,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0.9,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,1,0.8,0.8,0.8,0.8,0.8,0,0,0,0,0,0,0,0,0,0,0,0,2],
[0,0,0,0,0,0,0,0,0,0,0,0,0.8,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0.8,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0.8,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0.8,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0.8,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0.7,0.7,0.7,0.7,0.7,0,0,0,0,0,0,2],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.7,1,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.7,0,1,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.7,0,0,1,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.7,0,0,0,1,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.7,0,0,0,0,1,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0.6,0.6,0.6,0.6,0.6,2],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.6,1,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.6,0,1,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.6,0,0,1,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.6,0,0,0,1,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.6,0,0,0,0,1,0],
[2,0,0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,1]]
n = [i + 1 for i in range(22)] #目標劃分,24個值,1-24
t = [j for j in range(1000)]
ci = 0
C = []
C.append(c)
for d in range(1100)
for i in n
for j in range(22)
cj = c[j + 1] - c[i]
ci += k1[i][j + 1] math.sin(cj)
cii = ci + w[i]
h = [0.01 cii + z for z in c]
C.append(h)
c = h
def r_function(u)
y1 = 0
y2 = 0
y12 = 0
y22 = 0
r = []
for x in range(1000)
for ul in u
y1 += math.cos(C[x][ul])
y2 += math.sin(C[x][ul])
y12 = y1 2
y22 = y2 2
r.append((float(1) N ) ((y12 + y22) 0.5))
return r
r1 = r_function([1,2,3,4,5,6])
r2 = r_function([7,8,9,10,11,12])
r3 = r_function([13,14,15,16,17,18])
r4 = r_function([19,20,21,22,23,24])
r5 = r_function([25,26,27,28,29,30])
#r6 = r_function([31])
ax = subplot(111) #注意一般都在ax中設置,不再plot中設置
ymajorLocator = MultipleLocator(0.1) #將y軸主刻度標籤設置爲0.5的倍數
ax.yaxis.set_major_locator(ymajorLocator)
plt.plot(t, r1, marker='o', color='green', label='1')
plt.plot(t, r2, marker='D',color='red', label='2')
plt.plot(t, r3, marker='+',color='skyblue', label='3')
plt.plot(t, r4, marker='h', color='blue', label='4')
plt.plot(t, r5, marker='_',color='yellow', label='5')
#plt.plot(t, r6, color='red', label='6')
plt.legend() # 顯示圖例
plt.xlabel('iteration times')
plt.ylabel('r')
plt.show()
獨立編組結果如圖:
k1獨立編組
好的,從圖像我們來看看Kuramoto模型在描述這個編組的時候,5組最終穩定,我們說這個團隊編組還算科學,但我們改變一下K的值,換成分散編組:
k2 = [
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,1,0.9,0.8,0.7,0.6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2],
[1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0.9,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0.8,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0.7,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0.6,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,1,1,0.9,0.8,0.7,0.6,0,0,0,0,0,0,0,0,0,0,0,2],
[0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0.9,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0.8,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0.7,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0.6,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,1,0.9,0.8,0.7,0.6,0,0,0,0,0,0,2],
[0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0.9,0,1,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0.8,0,0,1,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0.7,0,0,0,1,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0.6,0,0,0,0,1,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0.9,0.8,0.7,0.6,2],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.9,0,1,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.8,0,0,1,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.7,0,0,0,1,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.6,0,0,0,0,1,0],
[2,0,0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,1]
k2獨立編組
這兩幅圖像都在開始階段大幅波動,而後在一定範圍內趨於穩定,那麼到底哪個分組模式最符合實際,最能突出編組能力呢?
這裏還有一個公式,來解決這個問題,編組同步能力的量化:
M_{s} 就可以描述某編組的同步效果,r_{s} 是達到穩定狀態後序參量的均值,β∈(0,1)是調節因子。我們可以用M_{s} 比較編組內部的好壞。那編組間能力的好壞怎樣比較呢?
這個Kuramoto模型同樣有所考慮,它有一個描述整個系統編組能力的公式:
其中,P是編組的數量,M_{i} 是第i個編組的同步能力,\omega _{i} 是編組在整個系統中的權重,\psi {e} 是各編組平均 相位的均值,\Delta \psi 是各編組平均相位的標準差。具體的計算不是這篇文章的重點,就不在計算M{s} 和M的值來比較上述例子獨立編組和分散編組的好壞了,本篇文章主要是講下Kuramoto模型的解決思路,尤其是上面解決\theta 值的方法可以套用在其他Kuramoto模型中,做一個目標估計綽綽有餘的。
下面是解決Kuramoto模型常用的MATLAB編程方法,具體思路與上述基本一致,這裏不再贅述,K的值我們給另一種編組模式:不完全分散編組模式,也是現在實際上最長用的編組方式,直接上代碼:
clc;
clear all;
k=[0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5;
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5;
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0.5;
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0.5;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 0.5;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0;
0.5 0 0 0 0 0.5 0 0 0 0 0.5 0 0 0 0 0.5 0 0 0 0 0.5 0 0 0 0;
]
N = 25;
Step= 10000;
Theta=zeros(Step,N);
Omega =zeros(Step,N);
DeltaT=0.01
Theta(1,:)=[0 pi/2 pi 3*pi/2 0 pi/2 pi 3*pi/2 0 pi/2 pi 3*pi/2 0 pi/2 pi 3*pi/2 0 pi/2 pi 3*pi/2 0 pi/2 pi 3*pi/2 0];
Omega(1,:)=2*pi*[2 3 3 4 4 2 3 3 4 4 2 3 3 4 4 2 3 3 4 4 2 2 3 4 1];
% 求解微分方程
for n = 1:Step
for i = 1:N
Sigma = 0;
for j = 1:N
%%判斷k對同步效果的影響
= Sigma + k(i,j) * sin( Theta(n,i) - Theta(n,j) );
end
Omega(n+1,i) = Omega(n,i) - Sigma;
Theta(n+1,i) = Omega(n+1,i)*DeltaT + Theta(n,i);
end
end
% 求解序參量r(t)
groupN = 5;
Step = 1000;
for i = 1:Step
sigma1 = 0;
sigma2 = 0;
sumTheta = 0;
for j =6:10 %表示相應的羣組
sigma1=sigma1+cos(Theta(i,j));
sigma2=sigma2+sin(Theta(i,j));
end
r(i)= sqrt( sigma1^2+sigma2^2 )/groupN;
end
x= 0.01:DeltaT:DeltaT*Step;
plot(x,r);
MATLAB版不完全分散編組結果如下圖:
不完全分散編組(MATLAB)
文章能看到最後真的很不容易,代碼及對數據的延伸都已上傳至GitHub和Gitee上,求star:
GitHub:https://github.com/wangwei39120157028/Spatial_Information_Support_Force_Grouping_Mode_Analysis
Gitee:https://gitee.com/wwy2018/Spatial_Information_Support_Force_Grouping_Mode_Analysis
歡迎再到我的GitHub和Gitee上看看我的關於逆向工程的項目,點贊求星。
GitHub:https://github.com/wangwei39120157028/IDAPythonScripts
Gitee:https://gitee.com/wwy2018/IDAPythonScripts