rnm演算法
A. 模糊數學在塔里木盆地圈閉評價中的應用
袁麗珍王英呂媛娥虎北辰
(西北石油局規劃設計研究院,烏魯木齊830011)
摘要圈閉評價的目的是為了降低油氣勘探風險,提高鑽探成功率。圈閉評價的方法很多,歸納起來有如下幾種:綜合定性排隊法、評分法、概率統計法、多信息疊合評價法、灰色系統理論和模糊數學評價法等。應用「模糊數學評價法」對塔里木盆地圈閉進行的綜合評價,收到了較好的效果。
關鍵詞塔里木盆地模糊數學權重模糊評判值圈閉圈閉評價
1方法原理
1.1模糊數學的概念
美國控制專家查德(L.A.Zaden)於1965年首先提出「模糊數學」的概念,它是研究和處理模糊體系規律性的理論和方法,也就是把普遍集合論只取0或1兩個值的特徵函數推廣到[0,1]區間上取值的隸屬函數。圈閉評價中常用「好」、「較好」、「中等」、「較差」、「差」這一評價方法,更適合用模糊數學的方法對圈閉含油氣性進行綜合評價。
1.2模糊綜合評判的基本概念及方法原理
所謂模糊綜合評判,是指用多個因素的評價結果,綜合處理最終得出一個屬於哪一類的隸屬度,以供決策使用。
決定圈閉(局部構造)是否成藏的地質因素很多,如儲層、蓋層、油源等等。考慮μ1,μ2,…,μ。這n個評價圈閉因素,由此就構成了因素集合 U:
U={μ1,μ2…μm}
在評價中我們可把參評的因素分為 V1,V2,…,Vm這m個級別(如評價中常用的級別Ⅰ、Ⅱ、Ⅲ或好、中、差等),由此構成評語集合 V:
V={V1,V2…Vm}
因素集中 U中各個因素對圈閉(局部構造)成藏所起的作用是不同的,因此在圈閉(局部構造)評價中應根據我們對圈閉(局部構造)成藏規律的認識對各評價因素賦予不同權系數,由此構成權重分配集合 A:
A={A1,A2…An}
在這里
塔里木盆地北部油氣田勘探與開發論文集
應用各因素綜合判定圈閉(局部構造)的含油氣性,也就是屬於評語集合 V中的哪一個級別,這就要求建立因素集中 U與評語集合V的一個模糊變換關系R:
塔里木盆地北部油氣田勘探與開發論文集
其中R就是某個對象(這里指圈閉或局部構造)的某個因素關於各類的得分,即隸屬度。因此,R又稱單因素評價矩陣。
權重A與模糊變換矩陣R的合成,構成了圈閉的綜合評判矩陣 B:
B=AR
最後用下面公式求得每個圈閉(局部構造)的綜合評價值D:
D=BC
式中C為等級矩陣的轉置矩陣,評價級別分為好、較好等級別。C取值為(-2,-1,0,1,2),Rnm可按表1來確定。當評價級別分為好、中、差三個級別時,C取值為(-1,0,1),R。可按表2來確定。
表1五個級別的評語Table1The comments of five ranks in the table
表2三個級別的評語Table2The comments of three ranks in the table
求出每個圈閉的綜合評價值D之後,再按D值的大小對所評圈閉(局部構造)進行排隊,得到優選圈閉(局部構造),以供勘探部署。1.3關於模糊運算
模糊數學中定義的演算法有很多種,其反映的意義是不同的。根據圈閉(局部構造)評價特點,本次採用如下4種:
①取小取大法:
取小取大法分別簡記為(∨,∧),合成矩陣B中的元素bj的演算法如下:
塔里木盆地北部油氣田勘探與開發論文集
②取小求和法
取小求和法分別簡記為(∧,⊕),合成矩陣B中的元素bj的演算法如下:
塔里木盆地北部油氣田勘探與開發論文集
③乘積取大法
乘積取大法分別簡記為(·,v),合成矩陣B中的元素bj的演算法如下:
塔里木盆地北部油氣田勘探與開發論文集
④乘積求和法
乘積求和法為評價重點考慮的演算法,分別簡記為(·,⊕),合成矩陣B中的元素bj的演算法如下:
塔里木盆地北部油氣田勘探與開發論文集
2圈閉評價參數及評分標准
影響圈閉的含油氣性的地質因素很多,結合塔里木盆地實際勘探情況,主要考慮圈閉的落實程度、儲集條件、蓋條件、油源條件、油氣大量生成期與構造形成期的配製關系(圈排關系)等五個地質因素,根據區內油氣成藏規律,確定各地質因素的權重系數見表3。
表3圈閉評價地質因素及權重系數Table3Geological factor and tentative crucial coefficient of trap evaluation
在評價圈閉含油氣級別時,分為好、較好、中等、較差、差五個級別,根據各項目組提供的數據確定各地質因素評估賦值標准。
2.1圈閉落實程度
主要用地震資料進行落實,如是否有三維控制、圈閉的二維地震測線數以及對圈閉的閉合幅度等進行評價(見表4)。
2.2儲集條件
表4圈閉落實程度評語Table4The comments of practicable level for trap
碳酸鹽岩儲層非均質性極為明顯,雅克拉—輪台地區主要為寒武系、奧陶系白雲岩,且經歷了長期古岩溶作用,儲集性一般為中等—較好。在塔河油區主要為奧陶系灰岩,儲層的岩塊物性較差。由於孔、縫、洞的發育,儲層的總體物性特徵明顯改善,其劃分表見表5。
碎屑岩主要用孔隙度、滲透率指標對儲層進行評價,不同區帶其劃分標准略有差異,結果見表6。
2.3蓋層條件
表5碳酸鹽岩儲層評語Table5The comments for carbonate reservoir
表6碎屑岩儲層劃分評語Table6The partition comments of clastic reservior
雅輪與巴麥工業區帶區內蓋層分析參數不全,本次主要以區帶內綜合研究成果為依據對圈閉蓋層進行評價,對於僅靠斷裂作為側向封堵的圈閉(斷鼻、斷塊等),要考慮斷裂兩盤的對接岩性,若斷裂兩側儲層與蓋層對接,評價為好,與砂泥岩互層對接為較好—中等,與儲層對接為較差—差。艾桑工區帶蓋層劃分標准見表7。
2.4油源條件
表7艾-桑工業區帶蓋層條件評語Table7The comments of cap condition in Aixieke-Sangtamu instrial estate
主要考慮圈閉距生油坳陷的距離和油氣的運移通道兩個因素。
對於陸相油氣主要考慮圈閉距生油坳陷區的距離和斷裂發育與儲層的關系,若斷裂下斷至不整合面,上斷至儲層,則以斷裂的斷距為評價標准(表8)。
表8陸相油氣油源條件評語表Table8The comment table of land oil-gas origin
對於海相油氣,除考慮斷裂是否將源岩與儲集岩溝通外,主要還要考慮油氣資源豐度以及構造帶是否處於油氣運移指向區,其評價標准見表9。
表9海相油氣油源條件評語Table9The comment table of marine oil-gas origin
2.5圈排關系
圈排關系是指圈閉形成期與生油高峰期的配置關系,構造形成期早於生油高峰期評價為好,兩者相同評為較好—中等,構造形成期晚於生油高峰期則評為較差—差。
3圈閉評價結果與排隊
我們對未上鑽的184個圈閉按上面的評語標准對某個地質評價因素進行賦值評價,然後對賦值圈閉利用模糊數學方法對其含油氣性進行綜合評判,根據模糊評判值D將圈閉的含油氣性分為Ⅰ(D≥1)、Ⅱ(0.5<D<1)、Ⅲ(D≤0.5)類。對篩選出的Ⅰ類圈閉,適當考慮一些能反映經濟效益的有關因素,如勘探中的探井成本和影響收益的重要參數資源量等,具體參數見表10。
表10局部構造綜合評判參數與標准Table10The synthetical judge parameters and standards of local structure
對各圈閉層及各評價因素結合區內目前勘探實際情況賦予不同的權重系數(表11、12)。
表11圈閉層系權重系數Table11Tentatively crucial coefficient of trap layer
表12局部構造評價因素權重系數分配表Table12Distribution table of tentative crucial coefficients for the judge of local structure
構造評價值由下式確定
塔里木盆地北部油氣田勘探與開發論文集
其中D構造為構造評價模糊值,E為圈閉層權重系數,
利用模糊數學的方法對賦值後的局部構造含油氣性進行綜合評判,得出局部構造綜合評判值D綜合,由 D綜合值將局部構造的含油氣性劃分為Ⅰ(D綜合≥0.28)、Ⅱ(0.17<D綜合<0.28)、Ⅲ(D綜合<0.17)類。將評定出的工類局部構造25個,選定為近期勘探目標,主要分布在艾協克-桑塔木工業區帶,近期已在艾協克北(沙73井三疊系)、桑塔木2號構造高點(沙60井)、艾協克2號構造西翼(沙65井)、牧場北3號構造(沙66井)、牧場北7號構造(沙67井)、桑塔木2號構造西高點(沙69井)、艾協克南構造(TK203井) 7口鑽井在下奧陶系碳酸鹽岩獲油氣突破,鑽探成功率為75%以上。實踐證明該圈閉評價方法是有一定的參考和使用價值。
參考文獻
[1]張躍等.模糊數學方法及其應用.北京:煤炭工業出版社,1992
[2]趙旭車.石油數學地質概論.北京:石油工業出版社,1992
Application of Fuzzy Mathematics to Evaluate the Traps in Tarim Basin
Yuan LizhenWang YingLu Yua n'eHu Beichen
(Academy of planning and designing,Northwest Bureau of Petroleum Geology,Ürümqi83001 1)
Abstract:The goal of evaluating trap isfor rection the risk of the oil and gas prospecting and increases the successful ratio of the drilling.There are six kinds of methods for evaluating trap:multiple determination queuing method,comparing and assessing method,probability statistical method,multiple information evaluation method,grap system theory,fuzzy mathematic evaluation method, etc.We have got satisfactory results in the course of the evaluation of the traps in Tarim basin using the fuzzy mathematic evaluation method.
Key words:Tarim Basinfuzzy Mathematics methodEvaluation the Traps
B. 求助:人工智慧「遺傳演算法求解f(x)=xcosx+2的最大值」
為了方便我只求了-3.14到3.14之間的最大值,你可以自己改一下,不過范圍大了之後,種群也因該擴大,我的種群只有66個
結果:極值點(-3.141593,5.141593)
我又算了一下-100到100之間的極大值
結果:極值點(-97.399473,99.394504)
-1000到1000之間的極大值
結果:(999,1001)
-2000到2000之間的極大值
結果:(1998.053550,2000.053163)
以上結果我用matlab畫圖驗證了,沒問題。
希望再給加點分,呵呵
//中國電子科技集團公司
//第一研究室
//呼文韜
//[email protected]
//隨機初始種群
//編碼方式為格雷碼
//選擇方法為隨機遍歷
//採用了精英保存策略
//採用了自適應的交叉率和變異率
//採用了與模擬退火演算法相結合的尺度變換
//採用了均勻交叉法
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <iostream.h>
#include <iomanip.h>
#include <time.h>
#include <windows.h>
#define IM1 2147483563
#define IM2 2147483399
#define AM (1.0/IM1)
#define IMM1 (IM1-1)
#define IA1 40014
#define IA2 40692
#define IQ1 53668
#define IQ2 52774
#define IR1 12211
#define IR2 3791
#define NTAB 32
#define NDIV (1+IMM1/NTAB)
#define EPS 1.2e-7
#define RNMX (1.0-EPS)
#define zhenjuli 0.005
#define PI 3.14159265358
#define T0 100000//溫度要取得很高才行。
#define zhongqunshu1 200
#define zuobianjie -2000
#define youbianjie 2000
unsigned int seed=0; //seed 為種子,要設為全局變數
void mysrand(long int i) //初始化種子
{
seed = -i;
}
long a[1];
//double hunn;
//double c=4;
//設置全局變數
struct indivial
{
unsigned *chrom; //染色體;
double geti;//變數值
double shiying; //目標函數的值;
double fitness; //變換後的適應度值;
};
indivial *zuiyougeti;//精英保存策略
int zhongqunshu; //種群大小
indivial *nowpop;//當前代
indivial *newpop;//新一代
double sumfitness;//當代的總適應度fitness
double sumshiying;//當代的總適應度shiying
double maxfitness;//最大適應度
double avefitness;//平均適應度
double maxshiying;//最大適應度
double avgshiying;//平均適應度
float pc;//交叉概率
float pm;//變異概率
int lchrom;//染色體長度
int maxgen;//最大遺傳代數
int gen;//遺傳代數
//函數
int flipc(double ,double );//判斷是否交叉
int flipm(double );//判斷是否變異
int rnd(int low,int high);//產生low與high之間的任意數
void initialize();//遺傳演算法初始化
void preselectfitness(); //計算sumfiness,avefitness,maxfitness
void generation();
double suijibianli();//產生隨機遍歷指針
int fu(float );//選擇要復制的個體
void crossover(indivial ,indivial ,indivial &,indivial &);//交叉
void bianyi(indivial &);//變異
void mubiaohanshu(indivial &);//計算適應度
void chibianhuan(indivial &);//對shiying進行尺度變換賦給fitness
double ran1(long *);//隨機數初始
void bianma(double bianliang,unsigned *p);//編碼
double yima(unsigned *p);
void guanjiancanshujisuan();//計算shiying,根據shiying計算sumshiying,對shiying進行尺度變換變成fitness,根據fitness計算sumfitness,avefitness,maxfitness
void jingyingbaoliu();
void glp(int n,int s,int *,int (*)[1],float (*)[1]);//glp生成函數
BOOL Exist(int Val, int Num, int *Array);//判斷一個數在前面是否出現過
int cmpfitness(const void *p1,const void *p2)
{
float i=((indivial *)p1)->shiying;//現在是按照"適應度"排序,改成"個體"的話就是按照"個體"排序
float j=((indivial *)p2)->shiying;
return i<j ? -1:(i==j ? 0:1);//現在是按升序牌排列,將1和-1互換後就是按降序排列
}
void main()
{
initialize();
cout<<zuiyougeti->geti<<" "<<zuiyougeti->shiying<<endl;/////////////
for(gen=1;gen<maxgen;gen++)
{ generation();
}
jingyingbaoliu();
cout<<setiosflags(ios::fixed)<<setprecision(6)<<zuiyougeti->geti<<" "<<setiosflags(ios::fixed)<<setprecision(6)<<(zuiyougeti->shiying)<<endl;////////////////
delete [] newpop;
delete [] nowpop;
delete [] zuiyougeti;
system("pause");
}
void initialize()
{
int q[zhongqunshu1][1],s=1;
float xx[zhongqunshu1][1];//生成的glp用x儲存
int h[1]={1};//生成向量
zuiyougeti=new indivial;//最優個體的生成
zhongqunshu=200;//種群數量
nowpop=new indivial[zhongqunshu1];//當代
newpop=new indivial[zhongqunshu1];//新一代
maxgen=150;//最大代數
gen=0;//起始代
lchrom=22;//基因數量的初始化
mysrand(time(0));//隨機數種子
a[0]=seed;//隨機數種子
//對最優個體的初始化
zuiyougeti->geti=0;
zuiyougeti->fitness=0;
zuiyougeti->shiying=0;
//
glp(zhongqunshu,s,h,q,xx);
//for(int i=0;i<zhongqunshu1;i++)//產生初始種群
//{
// for(int j=0;j<s;j++)
// {
// nowpop[i].geti=zuobianjie+(youbianjie-zuobianjie)*xx[i][j];
// }
//}
for(int i=0;i<zhongqunshu1;i++)//產生初始種群
{
nowpop[i].geti=zuobianjie+(youbianjie-(zuobianjie))*ran1(a);
}
//nowpop[0].geti=999;//////////////////////////
guanjiancanshujisuan();
jingyingbaoliu(); //精英保留的實現
guanjiancanshujisuan();//計算shiying,根據shiying計算sumshiying,對shiying進行尺度變換變成fitness,根據fitness計算sumfitness,avefitness,maxfitness
}
void jingyingbaoliu() //精英保留的實現
{
indivial *zuiyougetiguo;
zuiyougetiguo=new indivial[zhongqunshu1];//建立一個過渡數組
for(int i=0;i<zhongqunshu;i++)//將當代個體復制到過渡數組中
zuiyougetiguo[i]=nowpop[i];
qsort(zuiyougetiguo,zhongqunshu1,sizeof(indivial),&cmpfitness);//按fitness升序排序
// cout<<"zuiyougetiguo適應度:"<<zuiyougetiguo[zhongqunshu1-1].shiying<<endl;///////////
// cout<<"zuiyougeti適應度:"<<zuiyougeti->shiying<<endl;///////////////////
//system("pause");
if(zuiyougetiguo[zhongqunshu-1].shiying>zuiyougeti->shiying)
{
*zuiyougeti=zuiyougetiguo[zhongqunshu1-1];//如果最優個體的fitness比當代最大的fitness小則用當代的代替之
//cout<<"zuiyougetiguo個體:"<<zuiyougetiguo[zhongqunshu1-1].geti<<endl;/////////////
//cout<<"zuiyougeti個體:"<<zuiyougeti->geti<<endl;/////////////
}
else
nowpop[rnd(0,(zhongqunshu1-1))]=*zuiyougeti;//否則的話從當代中隨機挑選一個用最優個體代替之
delete [] zuiyougetiguo;//釋放過渡數組
}
void guanjiancanshujisuan()//計算shiying,根據shiying計算sumshiying,對shiying進行尺度變換變成fitness,根據fitness計算sumfitness,avefitness,maxfitness
{
for(int i=0;i<zhongqunshu;i++)//計算shiying
mubiaohanshu(nowpop[i]);
for(i=0;i<zhongqunshu;i++)//對shiying進行尺度變換變成fitness
chibianhuan(nowpop[i]);
preselectfitness();//根據fitness計算sumfitness,avefitness,maxfitness
}
void mubiaohanshu(indivial &bianliang)//計算shiying
{
bianliang.shiying=(bianliang.geti*cos(bianliang.geti)+2.0);//目標函數
}
void chibianhuan(indivial &bianliang)//對shiying進行尺度變換變成fitness
{
double T;//退火溫度
T=T0*(pow(0.99,(gen+1-1)));
double sum=0;
for(int j=0;j<zhongqunshu;j++)
sum+=exp(nowpop[j].shiying/T);
bianliang.fitness=exp(bianliang.shiying/T)/sum;//算出fitness
}
void preselectfitness()//根據fitness計算sumfitness,avefitness,maxfitness
{
int j;
sumfitness=0;
for(j=0;j<zhongqunshu;j++)
sumfitness+=nowpop[j].fitness;
indivial *guo;
guo=new indivial[zhongqunshu1];
for(j=0;j<zhongqunshu;j++)
guo[j]=nowpop[j];
qsort(guo,zhongqunshu1,sizeof(indivial),&cmpfitness);
maxfitness=guo[zhongqunshu1-1].fitness;
avefitness=sumfitness/zhongqunshu1;
delete [] guo;
}
void generation()
{
indivial fuqin1,fuqin2,*pipeiguo,*pipeichi;
int *peiishuzu;//用來存放產生的隨機配對
pipeiguo=new indivial[zhongqunshu1];
pipeichi=new indivial[zhongqunshu1];
peiishuzu=new int[zhongqunshu1];
int member1,member2,j=0,fujishu=0,i=0,temp=0,tt=0;
float zhen;
//隨機遍歷的實現
for(zhen=suijibianli();zhen<1;(zhen=zhen+zhenjuli))//設定指針1/66
{
pipeichi[fujishu]=nowpop[fu(zhen)];
fujishu++;
}
//交叉與變異的實現
//交叉
for(i=0;i<zhongqunshu1;i++)
{
peiishuzu[i]=-1;
}
for (i=0; i<zhongqunshu1; i++)
{
temp =rnd(0,zhongqunshu1-1); //產生值在0-zhongqunshu1-1的隨機數
while(Exist(temp, i, peiishuzu))//判斷產生的隨機數是否已經產生過,如果是,則再產生一個隨機數
{
temp =rnd(0,zhongqunshu1-1);
}
//如果沒有的話,則把產生的隨機數放在peiishuzu中
*(peiishuzu+i) = temp;
}
for(i=0;i<zhongqunshu1-1;i=i+2)
{
fuqin1=pipeichi[peiishuzu[i]];
fuqin2=pipeichi[peiishuzu[i+1]];
crossover(fuqin1,fuqin2,newpop[i],newpop[i+1]);
}
for(j=0;j<zhongqunshu1;j++)
{
//if(newpop[j].geti<-1000)
//cout<<"個體數值小於下界了";
nowpop[j].geti=newpop[j].geti;
}
//
guanjiancanshujisuan();
//變異的實現
for(j=0;j<zhongqunshu;j++)
{
bianyi(nowpop[j]);
}
//
guanjiancanshujisuan();
//精英保留的實現
jingyingbaoliu();
//
guanjiancanshujisuan();
delete [] peiishuzu;
delete [] pipeichi;
delete [] pipeiguo;
}
void crossover(indivial parent1,indivial parent2,indivial &child1,indivial &child2)//交叉
{
int j;
unsigned *panan;
panan=new unsigned[lchrom];
parent1.chrom=new unsigned[lchrom];
parent2.chrom=new unsigned[lchrom];
child1.chrom=new unsigned[lchrom];
child2.chrom=new unsigned[lchrom];
//cout<<"jiaocha"<<endl;///////////////////////
bianma(parent1.geti,parent1.chrom);
bianma(parent2.geti,parent2.chrom);
if(flipc(parent1.fitness,parent2.fitness))
{
for(j=0;j<lchrom;j++)
panan[j]=rnd(0,1);
//for(j=0;j<lchrom;j++)////////////////
// {
// cout<<panan[j];/////////////
// }
// cout<<endl;////////////////
// system("pause");////////////////
for(j=0;j<lchrom;j++)
{
if(panan[j]==1)
child1.chrom[j]=parent1.chrom[j];
else
child1.chrom[j]=parent2.chrom[j];
}
for(j=0;j<lchrom;j++)
{
if(panan[j]==0)
child2.chrom[j]=parent1.chrom[j];
else
child2.chrom[j]=parent2.chrom[j];
}
//for(j=0;j<lchrom;j++)////////////////
//{
// cout<<child1.chrom[j];/////////////
// }
//cout<<endl;////////////////
// system("pause");////////////////
child1.geti=yima(child1.chrom);
child2.geti=yima(child2.chrom);
delete [] child2.chrom;
delete [] child1.chrom;
delete [] parent2.chrom;
delete [] parent1.chrom;
delete [] panan;
}
else
{
for(j=0;j<lchrom;j++)
{
child1.chrom[j]=parent1.chrom[j];
child2.chrom[j]=parent2.chrom[j];
}
child1.geti=yima(child1.chrom);
child2.geti=yima(child2.chrom);
delete [] child2.chrom;
delete [] child1.chrom;
delete [] parent2.chrom;
delete [] parent1.chrom;
delete [] panan;
}
}
void bianyi(indivial &child)//變異
{
child.chrom=new unsigned[lchrom];
//cout<<"變異"<<endl;
bianma(child.geti,child.chrom);
for(int i=0;i<lchrom;i++)
if(flipm(child.fitness))
{
if(child.chrom[i]=0)
child.chrom[i]=1;
else
child.chrom[i]=0;
}
child.geti=yima(child.chrom);
delete [] child.chrom;
}
void bianma(double bianliang,unsigned *p)//編碼
{
unsigned *q;
unsigned *gray;
q=new unsigned[lchrom];
gray=new unsigned[lchrom];
int x=0;
int i=0,j=0;
if(bianliang<zuobianjie)///////////////////
{
cout<<"bianliang:"<<bianliang<<endl;/////////
system("pause");
}
//cout<<youbianjie-(zuobianjie)<<endl;
//system("pause");
x=(bianliang-(zuobianjie))*((pow(2,lchrom)-1)/(youbianjie-(zuobianjie)));
//cout<<x<<endl;///////////
if(x<0)
system("pause");///////////
for(i=0;i<lchrom;i++)
{
q[i]=0;
p[i]=0;
}
i=0;
while (x!=0&&(i!=lchrom))
{
q[i]=(unsigned)(x%2);
x=x/2;
i++;
}
// for(i=0;i<lchrom;i++)//////////////////
// cout<<q[i];///////////////
// cout<<endl;///////////
int w=lchrom-1;
if(q[w]!=0&&q[w]!=1)
system("pause");
for(j=0;j<lchrom&&w>0;j++)
{
p[j]=q[w];
w--;
}
//cout<<"yuanma"<<endl;
//for(j=0;j<lchrom;j++)///////////
// cout<<p[j];////////
//cout<<endl;////////////////////
gray[0]=p[0];
for(j=1;j<lchrom;j++)
{
if(p[j-1]==p[j])
gray[j]=0;
else if(p[j-1]!=p[j])
gray[j]=1;
}
for(j=0;j<lchrom;j++)
p[j]=gray[j];
//cout<<"geleima"<<endl;
//for(j=0;j<lchrom;j++)///////////
// cout<<p[j];////////
//cout<<endl;////////////////////
//system("pause");///////////
delete [] gray;
delete [] q;
}
double yima(unsigned *p) //解碼
{
int i=0;
// for(i=0;i<lchrom;i++)/////////
// {
// cout<<p[i];//////
// }
// cout<<endl;/////////
// system("pause");//////////
int x=0;
unsigned *q;
q=new unsigned[lchrom];
q[0]=p[0];
// cout<<q[0]<<endl;//////////////////
// system("pause");//////////
for(int j=1;j<lchrom;j++)
{
if(q[j-1]==p[j])
q[j]=0;
else if(q[j-1]!=p[j])
q[j]=1;
}
// for(i=0;i<lchrom;i++)//////
// {
// cout<<q[i];//////////
// if(q[i]!=0&&q[i]!=1)
// {
// cout<<q[i];
// system("pause");
// }
// }
// cout<<endl;////////
// system("pause");///////////////////
for(i=0;i<lchrom;i++)
x=x+q[i]*pow(2,(lchrom-i-1));
if(x<0)
{
cout<<"解碼出錯1"<<endl;
system("pause");
}
//cout<<"x:"<<x<<endl;
double bianliang;
//cout<<pow(2,22)<<endl;
//cout<<2000*x<<endl;
//cout<<(x*(2000/(pow(2,22)-1)))<<endl;
bianliang=(x*((youbianjie-(zuobianjie))/(pow(2,lchrom)-1)))+zuobianjie;
if(bianliang<zuobianjie)
{
cout<<"解碼出錯2"<<endl;
system("pause");
}
delete [] q;
return bianliang;
}
double ran1(long *im)
{
int j;
long k;
static long im2=123456789;
static long iy=0;
static long iv[NTAB];
float temp;
if (*im <= 0)
{
if (-(*im) < 1) *im=1;
else *im = -(*im);
im2=(*im);
for (j=NTAB+7;j>=0;j--)
{
k=(*im)/IQ1;
*im=IA1*(*im-k*IQ1)-k*IR1;
if (*im < 0) *im += IM1;
if (j < NTAB) iv[j] = *im;
}
iy=iv[0];
}
k=(*im)/IQ1;
*im=IA1*(*im-k*IQ1)-k*IR1;
if (*im < 0) *im += IM1;
k=im2/IQ2;
im2=IA2*(im2-k*IQ2)-k*IR2;
if (im2 < 0) im2 += IM2;
j=iy/NDIV;
iy=iv[j]-im2;
iv[j] = *im;
if (iy < 1) iy += IMM1;
if ((temp=AM*iy) > RNMX) return RNMX;
else return temp;
}
double suijibianli()//隨機遍歷
{
double i=ran1(a);
while(i>zhenjuli)
{
i=ran1(a);
}
//cout<<i<<endl;//////////////
return i;
}
int fu(float p)//復制
{
int i;
double sum=0;
if(sumfitness!=0)
{
for(i=0;(sum<p)&&(i<zhongqunshu);i++)
sum+=nowpop[i].fitness/sumfitness;
}
else
i=rnd(1,zhongqunshu1);
return(i-1);
}
int rnd(int low, int high) /*在整數low和high之間產生一個隨機整數*/
{
int i;
if(low >= high)
i = low;
else
{
i =(int)((ran1(a) * (high - low + 1)) + low);
if(i > high) i = high;
}
return(i);
}
int flipc(double p,double q)//判斷是否交叉
{
double pc1=0.9,pc2=0.6;
if((p-q)>0)
{
if(p>=avefitness)
{
pc=pc1-(pc1-pc2)*(p-avefitness)/(maxfitness-avefitness);
}
else
pc=pc1;
}
else
{
if(q>=avefitness)
{
pc=pc1-(pc1-pc2)*(q-avefitness)/(maxfitness-avefitness);
}
else
pc=pc1;
}
if(ran1(a)<=pc)
return(1);
else
return(0);
}
int flipm(double p)//判斷是否變異
{
double pm1=0.001,pm2=0.0001;
if(p>=avefitness)
{
pm=(pm1-(pm1-pm2)*(maxfitness-p)/(maxfitness-avefitness));
}
else
pm=pm1;
if(ran1(a)<=pm)
return(1);
else
return(0);
}
void glp(int n,int s,int *h,int (*q)[1],float (*xx)[1])//glp
{
int i=0,j=0;
//求解q
for(i=0;i<n;i++)
{
for(j=0;j<s;j++)
{
*(*(q+i)+j)=((i+1)*(*(h+j)))%n;
}
}
i=n-1;
for(j=0;j<s;j++)
{
*(*(q+i)+j)=n;
}
//求解x
for(i=0;i<n;i++)
{
for(j=0;j<s;j++)
{
*(*(xx+i)+j)=(float)(2*(*(*(q+i)+j))-1)/(2*n);
}
}
}
BOOL Exist(int Val, int Num, int *Array)//判斷一個數是否在一個數組的前Num個數中
{
BOOL FLAG = FALSE;
int i;
for (i=0; i<Num; i++)
if (Val == *(Array + i))
{
FLAG = TRUE;
break;
}
return FLAG;
}
C. 遺傳演算法中如何實現長度可變的編碼
看來也沒人回答了,把積分送給我吧!
附送模擬退火遺傳演算法的源程序
遺傳演算法求解f(x)=xcosx+2的最大值
其中在尺度變換部分應用到了類似模擬退火演算法部分,所有變數均使用漢語拼音很好懂
//中國電子科技集團公司
//第一研究室
//呼文韜
//[email protected]
//隨機初始種群
//編碼方式為格雷碼
//選擇方法為隨機遍歷
//採用了精英保存策略
//採用了自適應的交叉率和變異率
//採用了與模擬退火演算法相結合的尺度變換
//採用了均勻交叉法
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <iostream.h>
#include <iomanip.h>
#include <time.h>
#include <windows.h>
#define IM1 2147483563
#define IM2 2147483399
#define AM (1.0/IM1)
#define IMM1 (IM1-1)
#define IA1 40014
#define IA2 40692
#define IQ1 53668
#define IQ2 52774
#define IR1 12211
#define IR2 3791
#define NTAB 32
#define NDIV (1+IMM1/NTAB)
#define EPS 1.2e-7
#define RNMX (1.0-EPS)
#define zhenjuli 0.005
#define PI 3.14159265358
#define T0 100000//溫度要取得很高才行。
#define zhongqunshu1 200
#define zuobianjie -2000
#define youbianjie 2000
unsigned int seed=0; //seed 為種子,要設為全局變數
void mysrand(long int i) //初始化種子
{
seed = -i;
}
long a[1];
//double hunn;
//double c=4;
//設置全局變數
struct indivial
{
unsigned *chrom; //染色體;
double geti;//變數值
double shiying; //目標函數的值;
double fitness; //變換後的適應度值;
};
indivial *zuiyougeti;//精英保存策略
int zhongqunshu; //種群大小
indivial *nowpop;//當前代
indivial *newpop;//新一代
double sumfitness;//當代的總適應度fitness
double sumshiying;//當代的總適應度shiying
double maxfitness;//最大適應度
double avefitness;//平均適應度
double maxshiying;//最大適應度
double avgshiying;//平均適應度
float pc;//交叉概率
float pm;//變異概率
int lchrom;//染色體長度
int maxgen;//最大遺傳代數
int gen;//遺傳代數
//函數
int flipc(double ,double );//判斷是否交叉
int flipm(double );//判斷是否變異
int rnd(int low,int high);//產生low與high之間的任意數
void initialize();//遺傳演算法初始化
void preselectfitness(); //計算sumfiness,avefitness,maxfitness
void generation();
double suijibianli();//產生隨機遍歷指針
int fu(float );//選擇要復制的個體
void crossover(indivial ,indivial ,indivial &,indivial &);//交叉
void bianyi(indivial &);//變異
void mubiaohanshu(indivial &);//計算適應度
void chibianhuan(indivial &);//對shiying進行尺度變換賦給fitness
double ran1(long *);//隨機數初始
void bianma(double bianliang,unsigned *p);//編碼
double yima(unsigned *p);
void guanjiancanshujisuan();//計算shiying,根據shiying計算sumshiying,對shiying進行尺度變換變成fitness,根據fitness計算sumfitness,avefitness,maxfitness
void jingyingbaoliu();
void glp(int n,int s,int *,int (*)[1],float (*)[1]);//glp生成函數
BOOL Exist(int Val, int Num, int *Array);//判斷一個數在前面是否出現過
int cmpfitness(const void *p1,const void *p2)
{
float i=((indivial *)p1)->shiying;//現在是按照"適應度"排序,改成"個體"的話就是按照"個體"排序
float j=((indivial *)p2)->shiying;
return i<j ? -1:(i==j ? 0:1);//現在是按升序牌排列,將1和-1互換後就是按降序排列
}
void main()
{
initialize();
cout<<zuiyougeti->geti<<" "<<zuiyougeti->shiying<<endl;/////////////
for(gen=1;gen<maxgen;gen++)
{ generation();
}
jingyingbaoliu();
cout<<setiosflags(ios::fixed)<<setprecision(6)<<zuiyougeti->geti<<" "<<setiosflags(ios::fixed)<<setprecision(6)<<(zuiyougeti->shiying)<<endl;////////////////
delete [] newpop;
delete [] nowpop;
delete [] zuiyougeti;
system("pause");
}
void initialize()
{
int q[zhongqunshu1][1],s=1;
float xx[zhongqunshu1][1];//生成的glp用x儲存
int h[1]={1};//生成向量
zuiyougeti=new indivial;//最優個體的生成
zhongqunshu=200;//種群數量
nowpop=new indivial[zhongqunshu1];//當代
newpop=new indivial[zhongqunshu1];//新一代
maxgen=150;//最大代數
gen=0;//起始代
lchrom=22;//基因數量的初始化
mysrand(time(0));//隨機數種子
a[0]=seed;//隨機數種子
//對最優個體的初始化
zuiyougeti->geti=0;
zuiyougeti->fitness=0;
zuiyougeti->shiying=0;
//
glp(zhongqunshu,s,h,q,xx);
//for(int i=0;i<zhongqunshu1;i++)//產生初始種群
//{
// for(int j=0;j<s;j++)
// {
// nowpop[i].geti=zuobianjie+(youbianjie-zuobianjie)*xx[i][j];
// }
//}
for(int i=0;i<zhongqunshu1;i++)//產生初始種群
{
nowpop[i].geti=zuobianjie+(youbianjie-(zuobianjie))*ran1(a);
}
//nowpop[0].geti=999;//////////////////////////
guanjiancanshujisuan();
jingyingbaoliu(); //精英保留的實現
guanjiancanshujisuan();//計算shiying,根據shiying計算sumshiying,對shiying進行尺度變換變成fitness,根據fitness計算sumfitness,avefitness,maxfitness
}
void jingyingbaoliu() //精英保留的實現
{
indivial *zuiyougetiguo;
zuiyougetiguo=new indivial[zhongqunshu1];//建立一個過渡數組
for(int i=0;i<zhongqunshu;i++)//將當代個體復制到過渡數組中
zuiyougetiguo[i]=nowpop[i];
qsort(zuiyougetiguo,zhongqunshu1,sizeof(indivial),&cmpfitness);//按fitness升序排序
// cout<<"zuiyougetiguo適應度:"<<zuiyougetiguo[zhongqunshu1-1].shiying<<endl;///////////
// cout<<"zuiyougeti適應度:"<<zuiyougeti->shiying<<endl;///////////////////
//system("pause");
if(zuiyougetiguo[zhongqunshu-1].shiying>zuiyougeti->shiying)
{
*zuiyougeti=zuiyougetiguo[zhongqunshu1-1];//如果最優個體的fitness比當代最大的fitness小則用當代的代替之
//cout<<"zuiyougetiguo個體:"<<zuiyougetiguo[zhongqunshu1-1].geti<<endl;/////////////
//cout<<"zuiyougeti個體:"<<zuiyougeti->geti<<endl;/////////////
}
else
nowpop[rnd(0,(zhongqunshu1-1))]=*zuiyougeti;//否則的話從當代中隨機挑選一個用最優個體代替之
delete [] zuiyougetiguo;//釋放過渡數組
}
void guanjiancanshujisuan()//計算shiying,根據shiying計算sumshiying,對shiying進行尺度變換變成fitness,根據fitness計算sumfitness,avefitness,maxfitness
{
for(int i=0;i<zhongqunshu;i++)//計算shiying
mubiaohanshu(nowpop[i]);
for(i=0;i<zhongqunshu;i++)//對shiying進行尺度變換變成fitness
chibianhuan(nowpop[i]);
preselectfitness();//根據fitness計算sumfitness,avefitness,maxfitness
}
void mubiaohanshu(indivial &bianliang)//計算shiying
{
bianliang.shiying=(bianliang.geti*cos(bianliang.geti)+2.0);//目標函數
}
void chibianhuan(indivial &bianliang)//對shiying進行尺度變換變成fitness
{
double T;//退火溫度
T=T0*(pow(0.99,(gen+1-1)));
double sum=0;
for(int j=0;j<zhongqunshu;j++)
sum+=exp(nowpop[j].shiying/T);
bianliang.fitness=exp(bianliang.shiying/T)/sum;//算出fitness
}
void preselectfitness()//根據fitness計算sumfitness,avefitness,maxfitness
{
int j;
sumfitness=0;
for(j=0;j<zhongqunshu;j++)
sumfitness+=nowpop[j].fitness;
indivial *guo;
guo=new indivial[zhongqunshu1];
for(j=0;j<zhongqunshu;j++)
guo[j]=nowpop[j];
qsort(guo,zhongqunshu1,sizeof(indivial),&cmpfitness);
maxfitness=guo[zhongqunshu1-1].fitness;
avefitness=sumfitness/zhongqunshu1;
delete [] guo;
}
void generation()
{
indivial fuqin1,fuqin2,*pipeiguo,*pipeichi;
int *peiishuzu;//用來存放產生的隨機配對
pipeiguo=new indivial[zhongqunshu1];
pipeichi=new indivial[zhongqunshu1];
peiishuzu=new int[zhongqunshu1];
int member1,member2,j=0,fujishu=0,i=0,temp=0,tt=0;
float zhen;
//隨機遍歷的實現
for(zhen=suijibianli();zhen<1;(zhen=zhen+zhenjuli))//設定指針1/66
{
pipeichi[fujishu]=nowpop[fu(zhen)];
fujishu++;
}
//交叉與變異的實現
//交叉
for(i=0;i<zhongqunshu1;i++)
{
peiishuzu[i]=-1;
}
for (i=0; i<zhongqunshu1; i++)
{
temp =rnd(0,zhongqunshu1-1); //產生值在0-zhongqunshu1-1的隨機數
while(Exist(temp, i, peiishuzu))//判斷產生的隨機數是否已經產生過,如果是,則再產生一個隨機數
{
temp =rnd(0,zhongqunshu1-1);
}
//如果沒有的話,則把產生的隨機數放在peiishuzu中
*(peiishuzu+i) = temp;
}
for(i=0;i<zhongqunshu1-1;i=i+2)
{
fuqin1=pipeichi[peiishuzu[i]];
fuqin2=pipeichi[peiishuzu[i+1]];
crossover(fuqin1,fuqin2,newpop[i],newpop[i+1]);
}
for(j=0;j<zhongqunshu1;j++)
{
//if(newpop[j].geti<-1000)
//cout<<"個體數值小於下界了";
nowpop[j].geti=newpop[j].geti;
}
//
guanjiancanshujisuan();
//變異的實現
for(j=0;j<zhongqunshu;j++)
{
bianyi(nowpop[j]);
}
//
guanjiancanshujisuan();
//精英保留的實現
jingyingbaoliu();
//
guanjiancanshujisuan();
delete [] peiishuzu;
delete [] pipeichi;
delete [] pipeiguo;
}
void crossover(indivial parent1,indivial parent2,indivial &child1,indivial &child2)//交叉
{
int j;
unsigned *panan;
panan=new unsigned[lchrom];
parent1.chrom=new unsigned[lchrom];
parent2.chrom=new unsigned[lchrom];
child1.chrom=new unsigned[lchrom];
child2.chrom=new unsigned[lchrom];
//cout<<"jiaocha"<<endl;///////////////////////
bianma(parent1.geti,parent1.chrom);
bianma(parent2.geti,parent2.chrom);
if(flipc(parent1.fitness,parent2.fitness))
{
for(j=0;j<lchrom;j++)
panan[j]=rnd(0,1);
//for(j=0;j<lchrom;j++)////////////////
// {
// cout<<panan[j];/////////////
// }
// cout<<endl;////////////////
// system("pause");////////////////
for(j=0;j<lchrom;j++)
{
if(panan[j]==1)
child1.chrom[j]=parent1.chrom[j];
else
child1.chrom[j]=parent2.chrom[j];
}
for(j=0;j<lchrom;j++)
{
if(panan[j]==0)
child2.chrom[j]=parent1.chrom[j];
else
child2.chrom[j]=parent2.chrom[j];
}
//for(j=0;j<lchrom;j++)////////////////
//{
// cout<<child1.chrom[j];/////////////
// }
//cout<<endl;////////////////
// system("pause");////////////////
child1.geti=yima(child1.chrom);
child2.geti=yima(child2.chrom);
delete [] child2.chrom;
delete [] child1.chrom;
delete [] parent2.chrom;
delete [] parent1.chrom;
delete [] panan;
}
else
{
for(j=0;j<lchrom;j++)
{
child1.chrom[j]=parent1.chrom[j];
child2.chrom[j]=parent2.chrom[j];
}
child1.geti=yima(child1.chrom);
child2.geti=yima(child2.chrom);
delete [] child2.chrom;
delete [] child1.chrom;
delete [] parent2.chrom;
delete [] parent1.chrom;
delete [] panan;
}
}
void bianyi(indivial &child)//變異
{
child.chrom=new unsigned[lchrom];
//cout<<"變異"<<endl;
bianma(child.geti,child.chrom);
for(int i=0;i<lchrom;i++)
if(flipm(child.fitness))
{
if(child.chrom[i]=0)
child.chrom[i]=1;
else
child.chrom[i]=0;
}
child.geti=yima(child.chrom);
delete [] child.chrom;
}
void bianma(double bianliang,unsigned *p)//編碼
{
unsigned *q;
unsigned *gray;
q=new unsigned[lchrom];
gray=new unsigned[lchrom];
int x=0;
int i=0,j=0;
if(bianliang<zuobianjie)///////////////////
{
cout<<"bianliang:"<<bianliang<<endl;/////////
system("pause");
}
//cout<<youbianjie-(zuobianjie)<<endl;
//system("pause");
x=(bianliang-(zuobianjie))*((pow(2,lchrom)-1)/(youbianjie-(zuobianjie)));
//cout<<x<<endl;///////////
if(x<0)
system("pause");///////////
for(i=0;i<lchrom;i++)
{
q[i]=0;
p[i]=0;
}
i=0;
while (x!=0&&(i!=lchrom))
{
q[i]=(unsigned)(x%2);
x=x/2;
i++;
}
// for(i=0;i<lchrom;i++)//////////////////
// cout<<q[i];///////////////
// cout<<endl;///////////
int w=lchrom-1;
if(q[w]!=0&&q[w]!=1)
system("pause");
for(j=0;j<lchrom&&w>0;j++)
{
p[j]=q[w];
w--;
}
//cout<<"yuanma"<<endl;
//for(j=0;j<lchrom;j++)///////////
// cout<<p[j];////////
//cout<<endl;////////////////////
gray[0]=p[0];
for(j=1;j<lchrom;j++)
{
if(p[j-1]==p[j])
gray[j]=0;
else if(p[j-1]!=p[j])
gray[j]=1;
}
for(j=0;j<lchrom;j++)
p[j]=gray[j];
//cout<<"geleima"<<endl;
//for(j=0;j<lchrom;j++)///////////
// cout<<p[j];////////
//cout<<endl;////////////////////
//system("pause");///////////
delete [] gray;
delete [] q;
}
double yima(unsigned *p) //解碼
{
int i=0;
// for(i=0;i<lchrom;i++)/////////
// {
// cout<<p[i];//////
// }
// cout<<endl;/////////
// system("pause");//////////
int x=0;
unsigned *q;
q=new unsigned[lchrom];
q[0]=p[0];
// cout<<q[0]<<endl;//////////////////
// system("pause");//////////
for(int j=1;j<lchrom;j++)
{
if(q[j-1]==p[j])
q[j]=0;
else if(q[j-1]!=p[j])
q[j]=1;
}
// for(i=0;i<lchrom;i++)//////
// {
// cout<<q[i];//////////
// if(q[i]!=0&&q[i]!=1)
// {
// cout<<q[i];
// system("pause");
// }
// }
// cout<<endl;////////
// system("pause");///////////////////
for(i=0;i<lchrom;i++)
x=x+q[i]*pow(2,(lchrom-i-1));
if(x<0)
{
cout<<"解碼出錯1"<<endl;
system("pause");
}
//cout<<"x:"<<x<<endl;
double bianliang;
//cout<<pow(2,22)<<endl;
//cout<<2000*x<<endl;
//cout<<(x*(2000/(pow(2,22)-1)))<<endl;
bianliang=(x*((youbianjie-(zuobianjie))/(pow(2,lchrom)-1)))+zuobianjie;
if(bianliang<zuobianjie)
{
cout<<"解碼出錯2"<<endl;
system("pause");
}
delete [] q;
return bianliang;
}
double ran1(long *im)
{
int j;
long k;
static long im2=123456789;
static long iy=0;
static long iv[NTAB];
float temp;
if (*im <= 0)
{
if (-(*im) < 1) *im=1;
else *im = -(*im);
im2=(*im);
for (j=NTAB+7;j>=0;j--)
{
k=(*im)/IQ1;
*im=IA1*(*im-k*IQ1)-k*IR1;
if (*im < 0) *im += IM1;
if (j < NTAB) iv[j] = *im;
}
iy=iv[0];
}
k=(*im)/IQ1;
*im=IA1*(*im-k*IQ1)-k*IR1;
if (*im < 0) *im += IM1;
k=im2/IQ2;
im2=IA2*(im2-k*IQ2)-k*IR2;
if (im2 < 0) im2 += IM2;
j=iy/NDIV;
iy=iv[j]-im2;
iv[j] = *im;
if (iy < 1) iy += IMM1;
if ((temp=AM*iy) > RNMX) return RNMX;
else return temp;
}
double suijibianli()//隨機遍歷
{
double i=ran1(a);
while(i>zhenjuli)
{
i=ran1(a);
}
//cout<<i<<endl;//////////////
return i;
}
int fu(float p)//復制
{
int i;
double sum=0;
if(sumfitness!=0)
{
for(i=0;(sum<p)&&(i<zhongqunshu);i++)
sum+=nowpop[i].fitness/sumfitness;
}
else
i=rnd(1,zhongqunshu1);
return(i-1);
}
int rnd(int low, int high) /*在整數low和high之間產生一個隨機整數*/
{
int i;
if(low >= high)
i = low;
else
{
i =(int)((ran1(a) * (high - low + 1)) + low);
if(i > high) i = high;
}
return(i);
}
int flipc(double p,double q)//判斷是否交叉
{
double pc1=0.9,pc2=0.6;
if((p-q)>0)
{
if(p>=avefitness)
{
pc=pc1-(pc1-pc2)*(p-avefitness)/(maxfitness-avefitness);
}
else
pc=pc1;
}
else
{
if(q>=avefitness)
{
pc=pc1-(pc1-pc2)*(q-avefitness)/(maxfitness-avefitness);
}
else
pc=pc1;
}
if(ran1(a)<=pc)
return(1);
else
return(0);
}
int flipm(double p)//判斷是否變異
{
double pm1=0.001,pm2=0.0001;
if(p>=avefitness)
{
pm=(pm1-(pm1-pm2)*(maxfitness-p)/(maxfitness-avefitness));
}
else
pm=pm1;
if(ran1(a)<=pm)
return(1);
else
return(0);
}
void glp(int n,int s,int *h,int (*q)[1],float (*xx)[1])//glp
{
int i=0,j=0;
//求解q
for(i=0;i<n;i++)
{
for(j=0;j<s;j++)
{
*(*(q+i)+j)=((i+1)*(*(h+j)))%n;
}
}
i=n-1;
for(j=0;j<s;j++)
{
*(*(q+i)+j)=n;
}
//求解x
for(i=0;i<n;i++)
{
for(j=0;j<s;j++)
{
*(*(xx+i)+j)=(float)(2*(*(*(q+i)+j))-1)/(2*n);
}
}
}
BOOL Exist(int Val, int Num, int *Array)//判斷一個數是否在一個數組的前Num個數中
{
BOOL FLAG = FALSE;
int i;
for (i=0; i<Num; i++)
if (Val == *(Array + i))
{
FLAG = TRUE;
break;
}
return FLAG;
}