神经网络和遗传算法(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]