Kuramoto模型在Python和MATLAB中的簡單實現

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章