2024年深圳杯&东三省数学建模联赛A题遗传算法

问题简述

        1.单个残骸定位:确定用于精确测定单个空中火箭残骸音爆位置的最少监测设备数量,并计算指定数据中的残骸位置。

        2.多个残骸定位:开发一个模型来分析和确定哪些震动波数据来自哪个残骸,并确定在空中有多个残骸同时发生音爆时的残骸位置和时间。

                                   43108d7f904b4059a5e62f8fa65b3d22.png

算法思路

        e7001f1b6db140ec818d0004066ad278.png

根据遗传算法进行近似解的寻找。

#问题一
import numpy as np
from itertools import combinations
latition_dis=111263
longtition_dis=97304
'''初始化探测器'''
class detector():
    def __init__(self,latitude,longtitude,high,time):
        #经度:longtitude
        #纬度:latitude
        #高度:high
        #时间:time
        self.loc=(latitude,longtitude)
        self.h=high
        self.t=time     
        self.v=343  #声速

    # '''计算距离'''
    # def cal_distance(self,point,high):
    #     return (distance(self.loc,point)**2+high**2)**0.5
    '''计算总适应度'''
    def cal_fit(self,x,y,high,t):
        fitness=((((x-self.loc[1])*longtition_dis)**2+((y-self.loc[0])*latition_dis)**2+(high-self.h)**2)**0.5/self.v+t-self.t)**2
        return fitness
    '''计算适应度函数'''
    def cal_fitness(self,x,y,high,t):
        fits=[]
        for i in range(len(x)):
            fitness=1/((((x[i]-self.loc[1])*longtition_dis)**2+((y[i]-self.loc[0])*latition_dis)**2+(high[i]-self.h)**2)**0.5/self.v+t[i]-self.t)**2
            fits.append(fitness)
        return np.array(fits)

'''以下为遗传算法'''

'''解码'''
def translateDNA(pop):
    x_pop=pop[:,::4]#第一列为x
    y_pop=pop[:,1::4]#第二列为y
    h_pop=pop[:,2::4]#第三列为h
    t_pop=pop[:,3::4]#第四列为t
    x = x_pop.dot(2**np.arange(DNA_SIZE)[::-1])/float(2**DNA_SIZE-1)*(X_BOUND[1]-X_BOUND[0])+X_BOUND[0]
    y = y_pop.dot(2**np.arange(DNA_SIZE)[::-1])/float(2**DNA_SIZE-1)*(Y_BOUND[1]-Y_BOUND[0])+Y_BOUND[0]
    h = h_pop.dot(2**np.arange(DNA_SIZE)[::-1])/float(2**DNA_SIZE-1)*(H_BOUND[1]-H_BOUND[0])+H_BOUND[0]
    t = t_pop.dot(2**np.arange(DNA_SIZE)[::-1])/float(2**DNA_SIZE-1)*(T_BOUND[1]-T_BOUND[0])+T_BOUND[0]
    return x,y,h,t
'''单点交叉'''
def crossover_and_mutation(pop, CROSSOVER_RATE = 0.8):
    new_pop = []
    for father in pop:
        child = father
        if np.random.rand() < CROSSOVER_RATE:
            mother = pop[np.random.randint(POP_SIZE)]
            cross_points = np.random.randint(low=0, high=DNA_SIZE*4)
            child[cross_points:] = mother[cross_points:]
            mutation(child)
        new_pop.append(child)
    return new_pop
'''位点变异'''
def mutation(child, MUTATION_RATE=0.003):
    if np.random.rand() < MUTATION_RATE:
        mutate_point = np.random.randint(0, DNA_SIZE*4)
        child[mutate_point] = child[mutate_point]^1
'''轮盘赌'''
def select(pop, fitness):
    idx = np.random.choice(np.arange(POP_SIZE), size=POP_SIZE, replace=True,p=(fitness)/(fitness.sum()) )
    return pop[idx]
'''计算适应度'''
def get_fitness(pop,i):
    x,y,h,t=translateDNA(pop)
    #计算到四个探测器的适应度
    fitness=dectors[i[0]].cal_fitness(x,y,h,t)+dectors[i[1]].cal_fitness(x,y,h,t)\
        +dectors[i[2]].cal_fitness(x,y,h,t)+dectors[i[3]].cal_fitness(x,y,h,t)\
        +dectors[i[4]].cal_fitness(x,y,h,t)
    return fitness
'''显示信息'''
def print_info(pop,i):
    fitness = get_fitness(pop,i)
    max_fitness_index = np.argmax(fitness)
    x,y,h,t = translateDNA(pop)
    print(i)
    print("(x, y,h,t):", (x[max_fitness_index], y[max_fitness_index],h[max_fitness_index],t[max_fitness_index]))
    print("max_fitness:", fitness[max_fitness_index])
    total=0
    for j in range(7):
        total+=dectors[j].cal_fit(x[max_fitness_index], y[max_fitness_index],h[max_fitness_index],t[max_fitness_index])
    print("total_fitness:",total)
    return total
dectors=[]
longtitudes=[110.241,110.780,110.712,110.251,110.524,110.467,110.047]
latitudes=[27.204,27.456,27.785,27.825,27.617,28.921,27.121]
highs=[824,727,742,850,786,678,575]
times=[100.767,112.220,188.020,258.985,118.443,266.871,163.024]
'''创建7个探测器'''
for i in range(7):
    dectors.append(detector(latitudes[i],longtitudes[i],highs[i],times[i]))
a=[0,1,2,3,4,5,6]
b=list(combinations(a,5))
DNA_SIZE = 24     #DNA长度
POP_SIZE = 400		#种群大小
CROSSOVER_RATE = 0.8	#交叉概率
MUTATION_RATE = 0.005	#变异概率
N_GENERATIONS = 500		#迭代次数
X_BOUND = [110, 111]      #x的范围
Y_BOUND = [27, 28]		#y的范围
H_BOUND= [500,1000]       #h的范围
T_BOUND= [0,100.767]    #t的范围
pop = np.random.randint(2, size=(POP_SIZE, DNA_SIZE*4)) #随机产生初始种群的二进制矩阵
totallist=[]
for i in b:
    for _ in range(N_GENERATIONS):
        x,y,h,t = translateDNA(pop)
        pop = np.array(crossover_and_mutation(pop, CROSSOVER_RATE))
        fitness = get_fitness(pop,i)
        pop = select(pop, fitness)
    totallist.append(print_info(pop,i))
print(totallist)

得到结果可视化后的示意图

6bfa37a68c234c6790997ee09d3ac450.png

多残骸定位可以增加DNA支链数量,时间匹配可以采取模拟算法进行搜索。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值