Erlang 写算法

看了两天Erlang,先拿微分进化算法练练手。首先附上微分进化算法的流程图。


基本的进化操作我在此就不赘述了,感兴趣的同学可以跟我联系。附上Erlang的实现源码。

%
%   基于Erlang的微分进化算法
%   串行版本
%   CopyRight(c) Yang Xiao-dong 2014
%
-module(de).
-export([gener_ind/1,gener_pop/2,select_ind/3,fitness/1,crossOne/2,mutation/2,selection/2,start/1,insert/3]).
-define (F,0.4).
-define (CR,0.6).
-define (LOW,-100).
-define (UP,100).
-define (POPSIZE,50).
-define (VAR,20). %变量的维数为3
-author("YangXiaodong").
%create individual
%产生一个个体向量
gener_ind(N) when N>0 ->
[?LOW + random:uniform()*(?UP-?LOW) || X<-lists:seq(1,N)].
%生成初始种群
gener_pop(1,VN)->
[gener_ind(VN)];
gener_pop(N,VN)->
[gener_ind(VN)] ++ gener_pop(N-1,VN).


%选择三个不同个体
select_ind(1,L,U) ->
insert([],L,U);
select_ind(N,L,U)->
insert(select_ind(N-1,L,U),L,U).
insert(A,L,U) ->
X= trunc (L+random :uniform ()*(U-L)),
case  lists:member(X,A) of
 true -> 
  insert(A,L,U);
 false ->
  A++[X]
end.
%
% 产生变异后的中间向量
%
vectorMute([H1|[]],[H2|[]],[H3|[]],FX)->
[float (H1) + FX*( float(H2)-float(H3) )];
vectorMute([H1|T1],[H2|T2],[H3|T3],FX)->
[float (H1)+FX*(float (H2)-float (H3))]++ vectorMute(T1,T2,T3,FX).
%
% 注意 : 将变异 、交叉、选择操作集成到一个函数中了
%
muteOne(Pop,ID) ->
Len = length (Pop),
Inds = select_ind(3,1,Len),
P = random :uniform (),
R1=lists:nth(1,Inds),
R2 = lists:nth(2,Inds ),
R3 = lists:nth(3,Inds ),
X1 = lists:nth(R1,Pop),
X2 = lists:nth(R2,Pop),
X3 = lists:nth(R3,Pop),
Y  = vectorMute(X1,X2,X3,?F),
Z  = crossOne(ID,Y),
[selection(ID,Z)].
mutation(Pop,[H|[]])->
muteOne(Pop,H);
mutation(Pop,[H|T])->
muteOne(Pop,H) ++ mutation(Pop,T).
%
%交叉
%
crossOne([XH|[]],[VH|[]])->
Rd = random :uniform (),
J  = trunc (random :uniform () * (?VAR)),
if
Rd < ?CR ->
[VH];
Rd >= ?CR->
[XH];
true ->
false
end;
crossOne([XH|XT],[VH|VT])->
Rd = random :uniform (),
if 
 Rd < ?CR->
  [VH | crossOne(XT,VT)];
 Rd >= ?CR->
  [XH | crossOne(XT,VT)];
 true ->
  false
 end.
%
% 选择。最小化问题选择目标函数小的个体,此处为贪婪选择
%
selection(X,Y)->
FitX = fitness (X),
FitY = fitness (Y),
if
FitX < FitY ->
X;
FitX >=FitY ->
Y;
true ->
false 
end.
fitness(L)-> i_fitness(0,L).
i_fitness(Res,[]) -> Res;
i_fitness(Res,[H|T])-> i_fitness(Res+H*H,T).
%
%运行指定进化代数
%
runDE(Pop,1)->
mutation(Pop,Pop);
runDE(Pop ,N)->
XPop = runDE(Pop,N-1),
mutation(XPop ,XPop ).
% start函数为主函数,编译完成后在Shell窗口中通过命令 
% de:start(1000)来调用,括号内参数为进化代数
start(N)->
Pop = gener_pop(?POPSIZE,?VAR),
X=runDE(Pop,N),
lists :sort(X),
Y = lists:nth (1,X),
fitness(Y).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

上面的代码是用来寻找Sphere函数的最小点。但是DE算法是 通用的,可以用来求解任何最大/最小值的优化

寻优问题。目前这个版本是串行执行的,后面会把它改成并行版本,并打算用于实际项目中去。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值