文章目录
1 Floyd(遍历)求有向图最短路
%zhangjinming0908.m
adjacent_matrix=[0, 5, 3, inf, inf, inf, inf, inf, inf, inf;
5, 0, inf, 1, 3, 6, inf, inf, inf, inf;
3, inf, 0, inf, 8, 7, 6, inf, inf, inf;
inf, 1, inf, 0, inf, inf, inf, 6, 8, inf;
inf, 3, 8, inf, 0, inf, inf, 3, 5, inf;
inf, 6, 7, inf, inf, 0, inf, inf, 3, 3;
inf, inf, 6, inf, inf, inf, 0, inf, 8, 4;
inf, inf, inf, 6, 3, inf, inf, 0, inf, inf;
inf, inf, inf, 8, 5, 3, 8, inf, 0, inf;
inf, inf, inf, inf, inf, 3, 4, inf, inf, 0]
D=shortdf(adjacent_matrix)
%shortdf.m
%连接图中各顶点间最短距离的计算
function D=shortdf(W)
n=length(W);
D=W;
m=1;
while m<=n
for i=1:n
for j=1:n
if D(i,j)>D(i,m)+D(m,j)
D(i,j)=D(i,m)+D(m,j);
end
end
end
m=m+1;
end
D;
结果为
D =
0 5 3 6 8 10 9 11 13 13
5 0 8 1 3 6 13 6 8 9
3 8 0 9 8 7 6 11 10 10
6 1 9 0 4 7 14 6 8 10
8 3 8 4 0 8 13 3 5 11
10 6 7 7 8 0 7 11 3 3
9 13 6 14 13 7 0 16 8 4
11 6 11 6 3 11 16 0 8 14
13 8 10 8 5 3 8 8 0 6
13 9 10 10 11 3 4 14 6 0
2 Dijkstra算法
解决单源最短路径的有效算法,但是局限于边的权值非负的情况
%zhangjinming0908.m
adjacent_matrix=[0, 5, 3, inf, inf, inf, inf, inf, inf, inf;
5, 0, inf, 1, 3, 6, inf, inf, inf, inf;
3, inf, 0, inf, 8, 7, 6, inf, inf, inf;
inf, 1, inf, 0, inf, inf, inf, 6, 8, inf;
inf, 3, 8, inf, 0, inf, inf, 3, 5, inf;
inf, 6, 7, inf, inf, 0, inf, inf, 3, 3;
inf, inf, 6, inf, inf, inf, 0, inf, 8, 4;
inf, inf, inf, 6, 3, inf, inf, 0, inf, inf;
inf, inf, inf, 8, 5, 3, 8, inf, 0, inf;
inf, inf, inf, inf, inf, 3, 4, inf, inf, 0]
D=Dijkstra(adjacent_matrix,3)
%Dijkstra.m
function r=Dijkstra(W,v)
%用Dijkstra算法
n=size(W,1);
s=ones(1,n);
s(v)=0;
r=zeros(3,n);
r(1,:)=1:n;
r(2,1:end)=realmax;
r(2,v)=0;
for i=1:n-1;
min=realmax;
for j=find(s==0);
for k=find(s==1);
if(r(2,j)+W(j,k)<r(2,k))
r(2,k)=r(2,j)+W(j,k);
r(3,k)=j;
end
if(min>r(2,k))
min=r(2,k);
minv=k;
end
end
end
s(minv)=0;
end
结果为
D =
1 2 3 4 5 6 7 8 9 10
3 8 0 9 8 7 6 11 10 10
3 1 0 2 3 3 3 5 6 7
3 Bellman-Ford算法求单源有向图最短路径
%Bell_Ford.m
%输入连接矩阵W和源点n
function D=Bell_Ford(W,n)
v=size(W,1);
e=0;
E=zeros(v,3);
for i=1:v;
for j=1:v;
if ((W(i,j)~=inf)&& (W(i,j)~=0))
e=e+1;
E(e,1)=i;
E(e,2)=j;
E(e,3)=W(i,j);
end
end
end
D=W(n,:);
for i=1:v-1;
for j=1:e;
if(D(E(j,1))+ E(j,3)<D(E(j,2)))
D(E(j,2))=D(E(j,1))+ E(j,3);
end
end
end
4 遗传算法
%f.m
function y=f(x)
y=10*sin(5*x)+7*abs(x-5)+10;
bin2dec.m
function y=bin2dec(pop)
[px,py] =size(pop);
for i=1:py
pop1(:,i)=(2.^(i-1)).*pop(:,i);
end
pop2=sum(pop1,2);
y=pop2*10/1023;
%Genetic Algorithm
%zhangjinming0918.m
clear;
clc;
popsize=100;
pc=0.2;
chromlength=10;
pm=0.01;
disp('hhh');
%initialization
pop=round(rand(popsize,chromlength));
for i=1:100
%selection
newpop1=zeros(popsize,chromlength);
newpop2=zeros(popsize,chromlength);
value=f(bin2dec(pop))
minvalue=min(value)
totalvalue=sum(value)-popsize*minvalue;
p_fitvalue=(value-minvalue)/totalvalue
p_fitvalue=cumsum(p_fitvalue);
ms=sort(rand(popsize,1));
fitin=1;
newin=1;
while newin<popsize
if(ms(newin)<p_fitvalue(fitin))
newpop1(newin,:)=pop(fitin,:);
newin=newin+1;
else
fitin=fitin+1;
end
end
%crossover
for j=1:2:popsize-1
cpoint=round(rand*chromlength);
if(cpoint<=0)
cpoint=1;
end
if(rand<pc)
newpop2(j,:)=[newpop1(j,1:cpoint),newpop1(j+1,cpoint+1:chromlength)];
newpop2(j+1,:)=[newpop1(j+1,1:cpoint),newpop1(j,cpoint+1:chromlength)];
else
newpop2(j,:)=newpop1(j,:);
newpop2(j+1,:)=newpop1(j+1,:);
end
end
%mutation
for j=1:popsize
if(rand<pm)
mpoint=round(rand*chromlength);
if(mpoint<=0)
mpoint=1;
end
newpop2(j,mpoint)=1-newpop2(j,mpoint);
end
end
pop=newpop2
%find the best solution
x1=bin2dec(pop);
y1=f(x1);
x2=0:0.01:10;
y2=f(x2);
if(mod(i,20)==0)
figure;
plot(x2,y2);
hold on;
plot(x1,y1,'*');
title(['n=' num2str(i)]);
end
end
5 模拟退火算法
参数分析
###1 退火起始温度、终止温度
这两个参数决定着晃锅的剧烈程度。起始温度越大,晃锅越剧烈,越容易接收差解,状态跳动随机性越大。终止温度决定着算法将要停止时,晃锅的幅度,要是算法稳定的收敛,终止温度要设置的比较低(比如,是起始温度的1000倍)。
###2 降温速度
这个参数一般设置为0.99或0.98,越小降温越快,如果设置过小,就如同淬火一下,算法来不及充分寻优。
###3 迭代次数
迭代次数控制着算法寻优的充分程度,需根据具体问题调节
模拟退火算法求函数最小值
1 #include <stdio.h>
2 #include <math.h>
3 #include <stdlib.h>
4 #include <time.h>
5
6 double f(double x){
7 return (x-2)*(x+3)*(x+8)*(x+9);
8 }
9
10 double rnd(){
11 return (double)rand()/RAND_MAX;
12 }
13
14 int main(){
15 int i;
16 double decayscale=0.95;
17 double stepfactor=0.02;
18 double temperature=100;
19 double x,nextx,bestx;
20 double change=0;
21 //time t;
22 srand((unsigned int) time(NULL));
23 x=(2*rnd()-1)*10;
24 while (temperature>1){
25 temperature*=decayscale;
26 for(i=0;i++;i<1000){
27 do{
28 nextx=x+stepfactor*10*(rnd()-0.5);
29 }
30 while (nextx<=10&&nextx>=-10);
31 if (f(nextx)<f(x))
32 x=nextx;
33 else{
34 change=-(f(nextx)-f(x))/temperature;
35 if(exp(change)>rnd())
36 x=nextx;
37 }
38 }
39 }
40 printf("the min of the x is %f\n",x);
41 printf("%f",f(x));
42 }
模拟退火算法求解旅行商问题
import math
import random
import datetime
import copy
import matplotlib.pyplot as plt
import numpy as np
def calu_city_length(city):
sum_distance=0
for i in range(len(city)-1):
x_diff=city[i][0]-city[i][0]
y_diff=city[i][1]-city[i][1]
sum_distance+=math.sqrt(x_diff*x_diff+y_diff*y_diff)
x_diff=city[len(city)-1][0]-city[0][0]
y_diff=city[len(city)-1][1]-city[0][1]
sum_distance+=math.sqrt(x_diff*x_diff+y_diff*y_diff)
return sum_distance
def show(city):
x_list=[]
y_list=[]
for i in range(len(city)):
x_list.append(city[i][0])
y_list.append(city[i][1])
plt.plot(x_list,y_list)
plt.show()
#perturb用来产生新解
def perturb(city):
a=range(len(city))
c1,c2=random.sample(a,2)
temp_x,temp_y=city[c1][0],city[c1][1]
city[c1][0],city[c1][1]=city[c2][0],city[c2][1]
city[c2][0],city[c2][1]=temp_x,temp_y
return city
if __name__=="__main__":
n=10
temperature=50
city=np.random.randint(1,100,size=(n,2))
cost=[]
while temperature>1:
for i in range(100):
len1=calu_city_length(city)
orignal_city=copy.deepcopy(city)
perturb_city=perturb(city)
len2=calu_city_length(perturb_city)
delta=len2-len1
if delta < 0:
city=perturb_city
else:
if math.exp(((-delta)/temperature))>random.random():
city=perturb_city
else:
city=orignal_city
temperature=float(temperature)*0.99
cost.append(calu_city_length(city))
plt.plot(cost)
plt.show()
#print(city)
show(city)