基于遗传算法的延误航班调度

基于遗传算法的航班延误航班调度模型建模

可用作生产调度的课程作业
旅客失望溢出成本定义:因航空公司航班延误导致原航班的旅客不能按照原定计划到达目的地,由于航班延误,给旅客造成不良的出行体验,对航空公司的满意度和信任度大打折扣,导致旅客在下一次选择消费时不考虑该公司的航班而转向其它公司航班或选择乘坐其他交通工具给该公司造成的信用损失和经济损失。
有关旅客失望溢出函数的定义与该航班的乘客人数、飞机票价和乘客失望率有关,其函数式可写为:
在这里插入图片描述

式中v表示该航班上的乘客人数,w表示平均票价,u表示旅客失望率。
旅客失望溢出率调查表得出旅客失望率函数如下:
在这里插入图片描述
当延误航班上的所有旅客在下一次都不选择该公司的航班时,此时最大失望溢出成本为P=v×w,既失望率为100%。
其中延误航班的运营成本和航班机型以及质量有关系,对于不同的机型,其延误成本为:
在这里插入图片描述

其中,a为飞机每小时延误的运营成本,T_i为航班延误时间(小时/h)。

模型参数

我们采用时间段优化模型的思路,以时间点来代替时间段,得到航班精确的起飞时间点。
所涉及的参数或变量如下:
n:起飞航班的数量;
t_i:航班i计划起飞时刻;
e_i:航班i的最早起飞时刻;
l_i:航班i的最晚起飞时刻;
s_i:航班i的从登机口到跑道起飞线之间的滑行时间;
a_i:航班i每小时延误的运营成本;
x_i:航班i实际起飞时刻;
a_f:各航班每小时的运营成本的集合;
T_i:为航班i实际延误时间;
v_i:为航班i的乘客人数;
w_i:为航班i的平均票价;
u_i:为航班i的旅客失望率。
航班延误调度的目的是使延误成本最小化或延误时间最小,其目
标函数如下:
在这里插入图片描述
因此在进行航班调度时所需要考虑的约束条件如下:
在这里插入图片描述
式6表示延误时间,航班起飞时间超过计划时间既延误;
式7为对第i辆航班的起飞时间约束。

全文资料:https://download.csdn.net/download/qq_43627520/87379847

import random
import numpy as np
import math
from tqdm import tqdm
import matplotlib.pyplot as plt


class GA(object):
    # 初始化种群 生成chromosome_length大小的population_size个个体的种群
    def __init__(self, population_size, chromosome_length, max_value, pc, pm):

        self.population_size = population_size
        self.choromosome_length = chromosome_length
        # self.population=[[]]
        self.max_value = max_value
        self.pc = pc
        self.pm = pm
        self.data_list = np.array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
                                   [10000, 13000, 10000, 15000, 14000, 10000, 9000, 11000, 12000, 12000],
                                   [10, 10, 8, 10, 6, 7, 10, 12, 6, 7],
                                   [10, 20, 15, 30, 40, 47, 50, 55, 60, 70],
                                   [220, 200, 240, 220, 180, 180, 200, 240, 160, 200],
                                   [870, 1230, 850, 1600, 760, 960, 480, 830, 1340, 840]])

        # self.fitness_value=[]

    def rand_list(self):
        list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        random.shuffle(list)
        return list
    def species_origin(self):
        population = [[1, 2, 3, 4, 5, 6, 7, 8, 9,10]]
        for i in range(self.population_size):
            list = self.rand_list()
            while list in population:
                list = self.rand_list()
            population.append(list)
            # 将染色体添加到种群中
        population = np.array(population)
        return population
        # 将种群返回,种群是个二维数组,个体和染色体两维

    def function(self, population):
        # data_list:航班信息表,0代表航班号,1代表运输成本,2代表滑行时间,3代表起飞时刻,4代表旅客人数,5代表平均票价
        function_data = []
        temporary = np.array(population)
        # 获取一条染色体
        for i in range(len(temporary)):
            now_time = 0
            # 获取一个基因
            sum_P_i = 0
            sum_T_i = 0
            for j in range(self.choromosome_length):
                gene = temporary[i][j]-1 # 当前染色体下的基因数
                now_time += self.data_list[2][gene]
                if now_time>self.data_list[3][gene]:
                    T_i = now_time-self.data_list[3][gene]
                    u_i = pow((T_i/60)**2,1/3)/29
                    sum_P_i += self.data_list[4][gene]*self.data_list[5][gene]*u_i + self.data_list[5][gene]*T_i/60
                    sum_T_i +=T_i
            function_data.append(sum_P_i)
        return function_data

    # 定义适应度
    def fitness(self, function_value):
        fitness_value = []
        for i in range(len(function_value)):
            temporary = 1-function_value[i]/sum(function_value)
            fitness_value.append(temporary)
        # 将适应度添加到列表中
        return fitness_value

    # 3.选择种群中个体适应度最大的个体
    def selection(self, population, fitness_value):
        zip_list = zip(fitness_value,population)
        sort_zipped = sorted(zip_list, key=lambda x: (x[0]),reverse=True)
        result = zip(*sort_zipped)
        fitness_value_, population_ = [list(x) for x in result]
        population = population_[0:400]
        population = np.array(population)
        return population


    # 4.交叉操作
    def crossover(self, population):
        # pc是概率阈值,选择单点交叉还是多点交叉,生成新的交叉个体,这里没用
        new_population = [x for x in population]
        pop_len = len(population)//2
        for i in range(pop_len):
            if (random.random() < self.pc):
                rand_list = []
                for j in range(self.choromosome_length):
                    rand_list.append(random.randint(0,1))
                temporary1 = population[i*2]*rand_list
                temporary2 = population[i*2+1]*rand_list
                #构造子代
                for g in range(len(temporary1)):
                    if temporary1[g]==0:
                        for c in range(len(population[i*2+1])):
                            if population[i*2+1][c] in temporary1:
                                continue
                            else:
                                temporary1[g]=population[i*2+1,c]
                for g in range(len(temporary2)):
                    if temporary2[g]==0:
                        for c in range(len(population[i*2])):
                            if population[i*2][c] in temporary2:
                                continue
                            else:
                                temporary2[g]=population[i*2,c]
                if np.min(temporary2)==0 or np.min(temporary1)==0:
                    print(rand_list,"f1:",population[i*2],"f2:",population[i*2+1],"c1:",temporary1,"c2:",temporary2)
                new_population.append(temporary1)
                new_population.append(temporary2)
        new_population = np.array(new_population)
        return new_population

    def mutation(self, population):
        new_population = population
        for i in range(len(population)):
            c_population = population[i].copy()
            if (random.random() < self.pm):
                m1 = random.randint(0,self.choromosome_length-1)
                m2 = random.randint(0,self.choromosome_length-1)
                if m1!=m2:
                    new_population[i][m1] = c_population[m2]
                    new_population[i][m2] = c_population[m1]
        return new_population

    # 寻找最好的适应度和个体
    def best(self, population, fitness_value):
        zip_list = zip(fitness_value, population)
        sort_zipped = sorted(zip_list, key=lambda x: (x[0]), reverse=True)
        result = zip(*sort_zipped)
        fitness_value_, population_ = [list(x) for x in result]
        best_individual = population_[0]
        best_fitness = fitness_value_[0]
        return best_individual, best_fitness

    def plot(self, results):
        X = []
        Y = []
        #print(len(results))
        for i in range(500):
            X.append(i)
            Y.append(results[i][0])
        plt.plot(X, Y)
        plt.show()

    def main(self):
        results = []
        # 种群初始化
        population = self.species_origin()
        for i in tqdm(range(100)):
            function_value = self.function(population)
            # print('fit funtion_value:',function_value)
            fitness_value = self.fitness(function_value)
            # print('fitness_value:',fitness_value)
            best_individual, best_fitness = self.best(population, fitness_value)
            results.append(best_individual)
            # 将最好的个体和最好的适应度保存
            s_population = self.selection(population, fitness_value) #新一轮父代选择
            c_population = self.crossover(s_population)             #新一轮染色体交叉变异
            population = self.mutation(c_population)                #新一轮染色体交换变异
        return results
        #self.plot(results)

    def test_function(self, population):
        # data_list:航班信息表,0代表航班号,1代表运输成本,2代表滑行时间,3代表起飞时刻,4代表旅客人数,5代表平均票价
        result_data = []
        temporary = np.array(population)
        # 获取一条染色体
        for i in range(len(temporary)):
            now_time = 0
            # 获取一个基因
            sum_P_i = 0
            sum_T_i = 0
            for j in range(self.choromosome_length):
                gene = temporary[i][j]-1 # 当前染色体下的基因数
                now_time += self.data_list[2][gene]
                if now_time>self.data_list[3][gene]:
                    T_i = (now_time-self.data_list[3][gene])
                    u_i = pow((T_i/60)**2,1/3)/29
                    sum_P_i += self.data_list[4][gene]*self.data_list[5][gene]*u_i + self.data_list[5][gene]*T_i/60
                    sum_T_i +=T_i
            result_data.append([temporary[i],sum_P_i,sum_T_i])
        result_data = np.array(result_data)
        best_min = np.min(result_data[:,1])
        best_list = []
        for x in range(len(result_data[:, 0])):
            if result_data[x,1]==best_min:
                best_list.append(result_data[x,0])
        return best_list
    def draw_plt(self,result):
        for best_list in result:
            now_time = 0
            for i in best_list:
                plt.barh(i, self.data_list[2][i-1], left=(now_time))
                plt.vlines(self.data_list[3][i-1], i-0.5, i+0.5, colors='r')
                now_time += self.data_list[2][i - 1]
                if now_time > self.data_list[3][i-1]:
                    plt.hlines(i,self.data_list[3][i-1],now_time)  # 横线
                    plt.vlines(now_time, i - 0.5, i + 0.5)
            plt.yticks(np.arange(max(best_list)+1), np.arange(0, max(best_list)+1))
            plt.show()

# short_time: 1, 2, 4, 3, 5, 6, 9, 7, 10, 8
# short_money: 3, 2, 4, 5, 6, 8, 9, 10, 1, 7



调度结果

在这里插入图片描述

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LuLaDe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值