建模算法自学小结

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)

猜你喜欢

转载自blog.csdn.net/tiaozhanzhe1900/article/details/82754255
今日推荐