brinado 发表于 2013-1-25 22:38:54

神经网络和遗传算法(NN&GA)

在软计算课程上,老师让我们编程实现Hopfield网、联想记忆、BM、BP、SOFM、遗传算法。正在学习Ruby,就用ruby实现了上述内容。上述实现的内容比较简单,但没有对每个程序的输入和输出做说明。如果有任何疑问可以留言。希望和大家交流!


Hopfield

w = Array.new(4)4.times do |i|w = Array.new(4,0)4.times do |j|    if j > i      w = (rand 101) / 100.0 * (-1) ** (rand 2)    else      w=w    endendendu=Array.new(4)4.times do |i|u = (rand 101) / 100.0 * (-1) ** (rand 2)endtarget = Array.new(16)16.times do |i|target = Array.new(4)    if i == 0    target = [-1,-1,-1,-1]    nextendif i > 0    4.times do |k|      t = target      target = t    end    4.times do |j|      ttt = target      if ttt == -1      target = 1      break      else      target = -1      end    endendend16.times do |k|energy = 04.times do |i|    4.times do |j|      energy += -0.5*w*target*target    end    energy+=u*targetendputs target.join(" ") +"\t\t"+ energy.to_send16.times do |i|tem = ""   puts "\n"4.times do |k|    tem += target.to_s + " "endputs temtem = ""total = 0   30.times do |j|    total = 0    4.times do |k|      kk = target      if kk == 1      total += 2 ** (3-k)      end    end    if total/10 == 1      tem += total.to_s + ""    else      tem += " " + total.to_s + " "    end      total=0    rRound = rand 4    4.times do |k|      total += w * target    end    if total-u >= 0    target = 1    else      target = -1    endend      total = 04.times do |j|    4.times do |k|      total += -0.5 * w * target * target    end    total += u * targetendtem += "   " + total.to_sputs temend





BM算法

initial=t,n=1,1000w = Array.new(4)4.times do |i|w = Array.new(4,0)4.times do |j|    if j > i      w = (rand 101) / 100.0 * (-1) ** (rand 2)    else      w=w    endendendu=Array.new(4)4.times do |i|u = (rand 101) / 100.0 * (-1) ** (rand 2)enddef p(tt,mm)1.0/(1+Math.exp( -tt/mm ))endwhile n>0.01select=rand 4hi=04.times do |j|    hi+=w*initialendhi-=uif hi>0initial=1elsea=p(hi,n)    if n>10    b=(rand 700)/1000.0else    b=0.5+(rand 200)/1000.0endif a > b    initial=1else    initial=-1endendn=1000/(1+t)t+=1endtotal=04.times do |i|4.times do |j|    total+=-0.5*w*initial*initialendtotal+=u*initialendputs initial.join("\t")+"\t\t"+total.to_sputs "\n"target = Array.new(16)16.times do |i|target = Array.new(4)    if i == 0    target = [-1,-1,-1,-1]    nextendif i > 0    4.times do |k|      t = target      target = t    end    4.times do |j|      ttt = target      if ttt == -1      target = 1      break      else      target = -1      end    endendend16.times do |k|energy = 04.times do |i|    4.times do |j|      energy += -0.5*w*target*target    end    energy+=u*targetendputs target.join(" ") +"\t\t"+ energy.to_send16.times do |i|tem = ""   puts "\n"4.times do |k|    tem += target.to_s + " "endputs temtem = ""total = 0   30.times do |j|    total = 0    4.times do |k|      kk = target      if kk == 1      total += 2 ** (3-k)      end    end    if total/10 == 1      tem += total.to_s + ""    else      tem += " " + total.to_s + " "    end      total=0    rRound = rand 4    4.times do |k|      total += w * target    end    if total-u >= 0    target = 1    else      target = -1    endend      total = 04.times do |j|    4.times do |k|      total += -0.5 * w * target * target    end    total += u * targetendtem += "   " + total.to_sputs temend





BP算法

#BP Algorithm endeavordef f(t)m=1.0/(1.0+Math.exp(-t))endnum_mode=8num_input_nerve=3num_middle_nerve=20num_output_nerve=2num_learntimes=200affix=0.5d=Array.new(num_mode)num_mode.times do |i|d=Array.new(num_output_nerve)num_output_nerve.times do |j|    d=(rand 101)/100.0endendinput=Array.new(num_mode)num_mode.times do |i|input=Array.new(num_input_nerve)num_input_nerve.times do |j|    input=(rand 101)/100.0endendv=Array.new(num_input_nerve)num_input_nerve.times do |i|v=Array.new(num_middle_nerve)num_middle_nerve.times do |j|    v=(rand 101)/100.0*(-1)**(rand 2)endendr=Array.new(num_middle_nerve)num_middle_nerve.times do |i|r=(rand 101)/100.0*(-1)**(rand 2)endmiddle=Array.new()w=Array.new(num_middle_nerve)num_middle_nerve.times do |i|w=Array.new(num_output_nerve)num_output_nerve.times do |j|    w=(rand 101)/100.0*(-1)**(rand 2)endends=Array.new(num_middle_nerve)num_middle_nerve.times do |i|s=(rand 101)/100.0*(-1)**(rand 2)endoutput=Array.new()#starts learningnum_learntimes.times do |g|num_mode.times do |k|      middle=Array.new(num_middle_nerve,0)    output=Array.new(num_output_nerve,0)    help_w=Array.new(num_output_nerve,0)    help_v=Array.new(num_middle_nerve,0)      #figure out results    num_middle_nerve.times do |i|      num_input_nerve.times do |j|      middle+=input*v      end      middle=f(middle-r)    end    num_output_nerve.times do |i|      num_middle_nerve.times do |j|      output+=middle*w      end      output=f(output-s)    end      #adjustment    num_output_nerve.times do |i|      help_w=(d-output)*output*(1-output)    end    num_middle_nerve.times do |i|      num_output_nerve.times do |j|      help_v+=help_w*w      end      help_v*=middle*(1-middle)    end      num_middle_nerve.times do |i|      num_output_nerve.times do |j|      w+=affix*help_w*middle      end    end    num_output_nerve.times do |i|      s-=affix*help_w    end      num_input_nerve.times do |i|      num_middle_nerve.times do |j|      v+=affix*help_v*input      end    end      num_middle_nerve.times do |i|      r-=affix*help_v    end      end#end learn 1 timeend#test on learning timeserrorsum=0puts "results:"num_mode.times do |k|middle=Array.new(num_middle_nerve,0)output=Array.new(num_output_nerve,0)num_middle_nerve.times do |i|    num_input_nerve.times do |j|      middle+=input*v    end    middle=f(middle-r)endnum_output_nerve.times do |i|    num_middle_nerve.times do |j|      output+=middle*w    end    output=f(output-s)    errorsum+=(d-output)**2endputs "%.2f" %output+""+"%.2f" %outputenderrorsum/=2puts "total deviation:"+errorsum.to_snum_learntimes=100#starts learningnum_learntimes.times do |g|num_mode.times do |k|      middle=Array.new(num_middle_nerve,0)    output=Array.new(num_output_nerve,0)    help_w=Array.new(num_output_nerve,0)    help_v=Array.new(num_middle_nerve,0)      #figure out results    num_middle_nerve.times do |i|      num_input_nerve.times do |j|      middle+=input*v      end      middle=f(middle-r)    end    num_output_nerve.times do |i|      num_middle_nerve.times do |j|      output+=middle*w      end      output=f(output-s)    end      #adjustment    num_output_nerve.times do |i|      help_w=(d-output)*output*(1-output)    end    num_middle_nerve.times do |i|      num_output_nerve.times do |j|      help_v+=help_w*w      end      help_v*=middle*(1-middle)    end      num_middle_nerve.times do |i|      num_output_nerve.times do |j|      w+=affix*help_w*middle      end    end    num_output_nerve.times do |i|      s-=affix*help_w    end      num_input_nerve.times do |i|      num_middle_nerve.times do |j|      v+=affix*help_v*input      end    end      num_middle_nerve.times do |i|      r-=affix*help_v    end      end#end learn 1 timeend#test on learning timeserrorsum=0puts "results:"num_mode.times do |k|middle=Array.new(num_middle_nerve,0)output=Array.new(num_output_nerve,0)num_middle_nerve.times do |i|    num_input_nerve.times do |j|      middle+=input*v    end    middle=f(middle-r)endnum_output_nerve.times do |i|    num_middle_nerve.times do |j|      output+=middle*w    end    output=f(output-s)    errorsum+=(d-output)**2endputs "%.2f" %output+""+"%.2f" %outputenderrorsum/=2puts "total deviation:"+errorsum.to_snum_learntimes=100#starts learningnum_learntimes.times do |g|num_mode.times do |k|      middle=Array.new(num_middle_nerve,0)    output=Array.new(num_output_nerve,0)    help_w=Array.new(num_output_nerve,0)    help_v=Array.new(num_middle_nerve,0)      #figure out results    num_middle_nerve.times do |i|      num_input_nerve.times do |j|      middle+=input*v      end      middle=f(middle-r)    end    num_output_nerve.times do |i|      num_middle_nerve.times do |j|      output+=middle*w      end      output=f(output-s)    end      #adjustment    num_output_nerve.times do |i|      help_w=(d-output)*output*(1-output)    end    num_middle_nerve.times do |i|      num_output_nerve.times do |j|      help_v+=help_w*w      end      help_v*=middle*(1-middle)    end      num_middle_nerve.times do |i|      num_output_nerve.times do |j|      w+=affix*help_w*middle      end    end    num_output_nerve.times do |i|      s-=affix*help_w    end      num_input_nerve.times do |i|      num_middle_nerve.times do |j|      v+=affix*help_v*input      end    end      num_middle_nerve.times do |i|      r-=affix*help_v    end      end#end learn 1 timeend#test on learning timeserrorsum=0puts "results:"num_mode.times do |k|middle=Array.new(num_middle_nerve,0)output=Array.new(num_output_nerve,0)num_middle_nerve.times do |i|    num_input_nerve.times do |j|      middle+=input*v    end    middle=f(middle-r)endnum_output_nerve.times do |i|    num_middle_nerve.times do |j|      output+=middle*w    end    output=f(output-s)    errorsum+=(d-output)**2endputs "%.2f" %output+""+"%.2f" %outputendputs "want to be:"num_mode.times do |k|puts "%.2f" %d+""+"%.2f" %denderrorsum/=2puts "total deviation:"+errorsum.to_s

联想记忆(Hopfield)
def ppp( aa )note = ""15.times do |i|    if aa == 1      note += " 1\t"    else      note += "-1\t"    endendnoteenddef change( bb, cc )15.times do |i|    if bb == 1      if ((rand 2) + (rand 2)) / 2 == 0      cc = 1      else      next      end    else      next    endendccendu=Array.new(15)15.times do |i|u=(rand 101)/100.0*(-1)**(rand 2)endw = Array.new(15,0)15.times do |i|w = Array.new(15,0)15.times do |j|    if j > i      w=(rand 101)/100.0*(-1)**(rand 2)    else      w=w    endendend# inital statusini_status = Array.new(15,0)15.times do |i|if (rand 2) == 0    ini_status = -1else    ini_status = 1endendputs "Forehead status",ppp(ini_status)120.times do |i|now = rand 15tt = 015.times do |j|    tt += w * ini_statusendif tt-u >= 0    ini_status = 1else    ini_status = -1endendputs "\nMemory status(->forehead status)",ppp(ini_status)temp = 015.times do |i|15.times do |j|    temp += -0.5 * w * ini_status * ini_statusendendputs "Engergy is" + temp.to_starget = [-1,1,-1,1,-1,1,1,1,1,1,-1,1,1,-1,1]puts "\nA letter target(what we want to become)",ppp(target)test = Array.new(15,-1)test = [-1,-1,-1,1,-1,1,-1,-1,-1,1,-1,-1,-1,-1,-1]puts "\nTest object(we want it to become A letter)",ppp(test)simulate = Array.new(15,0)15.times do |i|if test != target    simulate = -1 * ini_statuselse    simulate = ini_statusendendputs "\n#Hopfield new initial status(->memory status(generated by above 3))",ppp(simulate)120.times do |i|now = rand 15tt = 015.times do |j|    tt += w * simulateendif tt-u >= 0    simulate = 1else    simulate = -1endendputs "\nFinal status(->hopfield new initial status(by the same w[]))",ppp(simulate)temp = 015.times do |i|15.times do |j|    temp += -0.5 * w * simulate * simulateendendputs "Engergy is" + temp.to_sjudge = "Y"15.times do |i|if ini_status != simulate    judge = "N"    puts "\nMemory lost!!!"    breakendendif judge == "Y"puts "\nWe learnt it!! "end

SOFM网(输入为sin曲线。实现了点的文件生成,再用C语言画图,ruby是在不容易实现画图,除非在Mac系统里)
#SOM another try!#by Brinado on Apr. 17th, 2008#initializationnum_mode=80num_matrix=10num_learn=60ita=0.5sigma=1#input -- Math.sininput=Array.new(num_mode)num_mode.times do |i|input=Array.new(2)2.times do |j|    input=1.0*i/num_mode    input=Math.sin(Math::PI*2.0*i/num_mode)/2+0.5endend#ww=Array.new(100)100.times do |i|w=Array.new(2)2.times do |j|    w=0.5+(rand 100)/1000*(-1)**(rand 2)endend#outputoutput=Array.new(num_mode)num_mode.times do |i|output=Array.new(2)2.times do |j|    output=1.0*i/num_mode    output=Math.sin(Math::PI*2.0*i/num_mode)endendnum_learn.times do |g|num_mode.times do |k|    distance=Array.new(100)    a,b,tt3=0,0,999    100.times do |i|      tt=Math.sqrt((input-w)**2+(input-w)**2)      #puts tt      distance=tt      if tt<tt3      a,tt3=i,tt      end    end      100.times do |i|      2.times do |j|      tta1,tta2=(a/9-i/9)**2+(a%9-i%9)**2,sigma**2      w+=ita*Math.exp(-1.0*tta1/sigma)*(input-w)      end    end      #insertion here...endif sigma<0.005   sigma==0.005else   sigma-=0.005endendtxt = ""f = File.open("db.txt", "w")100.times do |i|    txt = "%.15f" %w + " " + "%.15f" %w + " "    f.write(txt)endf.close

SOFM网C语言画图实现
#include<stdio.h>#include<stdlib.h>#include<graphics.h>#define MM 19main(){ char ch; int i=0,j=0; int object; int graphdriver=VGA; int graphmode=VGAHI; FILE *f; if((f=fopen("c:/turboc2/brinado/db2.txt","r"))==NULL) {printf("db.txt open error.\n");exit(0); } while(i<200) {fgets(ch,MM,f);object=(int)((ch-'0')*10+ch-'0'+(ch-'0')*0.1)*4;i++; } fclose(f); initgraph(&graphdriver,&graphmode," "); cleardevice(); /* setcolor(RED); for(j=0;j<200;j+=2) {if(j==18||j==38||j==58||j==78||j==98||j==118||j==138||j==158||j==178||j==198){   if(j!=198){line(object,object,object,object);}   continue;}line(object,object,object,object);if(j<180){   line(object,object,object,object);} } */ for(j=0;j<200;j+=2) {putpixel(object,object,2);putpixel(object+1,object,1);putpixel(object,object+1,1);putpixel(object,object-1,1);putpixel(object-1,object,1); } setcolor(WHITE); rectangle(0,0,639,479); getch(); closegraph();}

GA-遗传算法
#target: #evaluate fitnessdef godbenchmark(god)result=010.times do |i|    if i<5      if god==0      result+=1      end    else      if god==1      result+=1      end    endendresult #return fitness valueend#crossover using single point method#change from 0~10 points totally. When set position===10, operation equals to completely change 2 chrommosomesdef crossover(a,b,position)10.times do |j|    if j>=position      tt=a      a=b      b=tt    endendend#initialize chromosomechromosome=Array.new(6)6.times do |i|chromosome=Array.new(10,0)10.times do |j|    if (rand 2)==1      chromosome=1    endendend#parameters#p_crossover=0.4#p_mutation=3/60#num_chromosome=6#num_gene=10iterates=50step=0record=Array.new(50)init=Array.new(6,0)6.times do |i|init=Array.new(2)init=iinit=godbenchmark(chromosome)end#pop rankingttt,t1=init,06.times do |i|for j in 0..(5-i)    if j==0      ttt,t1=init,0    end    if init > ttt      mm1,mm2=init,init      init,init=init,init      init,init=mm1,mm2      ttt,t1=init,j    else      ttt,t1=init,j    endendend#select using tournament methodmiddle=Array.new(6)6.times do |i|middle=Array.new(10)if i==0    10.times do |j|      middle=chromosome]    endelse    10.times do |j|      middle=chromosome]    endendendchromosome=middle#iteration begins...iterates.times do |k|#crossover begin3.times do |i|    if (rand 10)/10.0 >= 0.6      case i      when 0          crossover chromosome,chromosome,(rand 10) #must change anyway!!!      when 1          crossover chromosome,chromosome,(rand 10)      when 2          crossover chromosome,chromosome,(rand 10)      end    endend#crossover end    #mutation begin6.times do |i|    percentage=0.85    if (rand 100)/100.0 >= percentage      tt=rand 10      if chromosome==0      chromosome=1      else      chromosome=0      end    endend#mutation end    #selection begininit=Array.new(6,0)6.times do |i|    init=Array.new(2)    init=i    init=godbenchmark(chromosome)end#pop rankingttt,t1=init,06.times do |i|    for j in 0..(5-i)      if j==0      ttt,t1=init,0      end      if init > ttt      mm1,mm2=init,init      init,init=init,init      init,init=mm1,mm2      ttt,t1=init,j      else      ttt,t1=init,j      end    endend#select using tournament methodmiddle=Array.new(6)6.times do |i|    middle=Array.new(10)    if i==0      10.times do |j|      middle=chromosome]      end    else      10.times do |j|      middle=chromosome]      end    endendchromosome=middle#select endrecord=godbenchmark(chromosome)step+=1#exit conditionif godbenchmark(chromosome)==10    breakendend#print initial chromosomeprint="--Final Result--\n"6.times do |i|10.times do |j|    print+=chromosome.to_s+"\t"endprint+="\n"endputs printputs "\n*Note:this result is the No.#{step} generation's reproduction!","\n*Step change(fitness result) in detail:\n","\n"step.times do |i|puts "No.#{i} step best: "+record.to_send
页: [1]
查看完整版本: 神经网络和遗传算法(NN&GA)