[回目錄]

 

[pso] C 語言第一個 pso 程式 這篇文章中,大致上已把 C 語言撰寫粒子移動演算法架構都寫了出來,這篇「續集」,主要是在討論一般在 C language 中,在一般數學式極值情況下,較常使用到的架構。

在該程式碼裡面,假設了適應函數 max f(x) = | x3 - 0.8x2 - 1000x + 8000 | ,

這只有單變數而已,故粒子群裡的位置,只有一個 position。

然而某些適應函式,變數個數卻不只一個的情況下,如

max f(x, y) = | x3y - 0.8x2 - 1000xy + 8000 | ,這問題便有 x, y 變數之存在,

在做 struct 定義時,是可以輕易改變成

/* 定義結構體particle */
typedef struct tag_particle{
    double position_x;  /* 目前位置 x value     */
double
position_y; /* 目前位置 y value */ double velocity; /* 目前粒子速度 */ double fitness ; /* 適應函式值 */ double pbest_pos; /* particle 目前最好位置 */ double pbest_fit; /* particle 目前最佳適應值 */ }particle;

 

新增了 position_y ,但相對的,

在速度上也必須分 x 變數上之速度與 y 變數上之速度;

而最佳位置也又分了 particle 目前最佳 x 位置與最佳 y 位置,

整體考慮下來,完整的結構體就變如下

/* 定義結構體particle */
typedef struct tag_particle{
    double position_x;  /* 目前位置 x value     */
double
position_y; /* 目前位置 y value */ double velocity_x; /* 目前粒子 x 速度 */
double
velocity_y; /* 目前粒子 y 速度 */ double fitness ; /* 適應函式值 */ double pbest_pos_x; /* particle 目前最好 x 位置 */
double pbest_pos_y; /* particle 目前最好 y 位置 */ double pbest_fit; /* particle 目前最佳適應值 */ }particle;

 

這樣下去,只要當變數個數變多時,如 f(x1, x2, x3, ..., xn) 時,

就要寫 n 次,架構會愈來愈麻煩,且不易維護,故一般考慮維護及通用性情況下,

存位置時,通常都假設有 n 維變數,裡面再放一個 double* position,

到時做動態分配,變成 double position[n],這是較為容易維護的,大致上會長這樣。

/* 定義結構體particle */
typedef struct tag_particle{
    int          dim;               /* 變數維度個數                                 */
    double* position;        /* 目前位置 (dim 維) position[dim]     */
    double* velocity;         /* 目前速度 (dim 維) velocity[dim]      */  
double fitness ; /* 適應函式值 */ double* pbest_pos; /* particle 目前最好位置 pbest_pos[dim] */ double pbest_fit; /* particle 目前最佳適應值 */ }particle;

 

這種設計模式是一種方式,但在撰程式碼中確顯得較麻煩,因會看到一堆 

particle[i].pbest_pos[j] = particle[i].position[j]

之類的敘述式,同時在分配記憶體空間時不夠連續,

雖整體架構「擬物化」 ( 專業一點叫封裝、抽像化) 是夠的,

若是用 C++ 進行 Coding ,

用 vector + class + overload operator 可改善這問題,

上述架構也算合適、適當。但若不想花這時間建構 firendly class ( C++ 需有一定程度),

或只想用 C language coding (此系列文之目的),便不再適用 struct 方式架構,

故將整個 struct 全都打散開來,

全都用 array 表示法去表示,整個架構裡之重要變數大致如下所述。

 

static unsigned pcnt;          /* 粒子群個數                       */
static unsigned  dim;          /* 解空間維度                       */

static double **particle_pos/* 各粒子目前位置[pcnt][dim]         */
static double **particle_v;    /* 各粒子目前速度[pcnt][dim]         */
static double  *particle_fv;   /* 各粒子目前適應值[pcnt]            */
static double **pbest_pos;     /* 各粒子目前找到最佳位置[pcnt][dim] */
static double  *pbest_fv ;     /* 各粒子目前最佳適應值[pcnt]        */

static double  *gbest_pos;     /* 全域目前找到最佳位置[dim]         */
static double   gbest_fv;      /* 全域目前最佳適應值                */

 

注意上面宣告之變數,用的是一維或是二維,

會用 static 方式宣告,乃因到時設計時,會將這些變數獨立出來到另一個 .c file 裡,

欲擬 private member  ( 這二行看不懂的話請暫時跳過,這是 C 語言裡一個籌範)。

 

[回目錄]

arrow
arrow
    全站熱搜

    edisonx 發表在 痞客邦 留言(3) 人氣()