├── TEMP1.m ├── Cross.m ├── NSGA2.m ├── test.m ├── Mutation.m ├── popinit.m ├── similar.m ├── NSGA2_old.m ├── oilSpill.mat ├── concentration.m ├── land_cost.mat ├── riskPosition.mat ├── constructionCost.mat ├── islandPosition.mat ├── comOptimalSolution.m ├── immune.m ├── TEMP2.m ├── README.md ├── multiSorting.m ├── crowdingDistanceCalculation.m ├── nonDominatedSorting.m ├── fitness.m └── fitness_old.m /TEMP1.m: -------------------------------------------------------------------------------- 1 | %% 局部测试 2 | 3 | TSET = fitness([1,2,3,4]); 4 | -------------------------------------------------------------------------------- /Cross.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septemc/MATLAB-I-NSGA2-Site-Selection/HEAD/Cross.m -------------------------------------------------------------------------------- /NSGA2.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septemc/MATLAB-I-NSGA2-Site-Selection/HEAD/NSGA2.m -------------------------------------------------------------------------------- /test.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septemc/MATLAB-I-NSGA2-Site-Selection/HEAD/test.m -------------------------------------------------------------------------------- /Mutation.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septemc/MATLAB-I-NSGA2-Site-Selection/HEAD/Mutation.m -------------------------------------------------------------------------------- /popinit.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septemc/MATLAB-I-NSGA2-Site-Selection/HEAD/popinit.m -------------------------------------------------------------------------------- /similar.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septemc/MATLAB-I-NSGA2-Site-Selection/HEAD/similar.m -------------------------------------------------------------------------------- /NSGA2_old.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septemc/MATLAB-I-NSGA2-Site-Selection/HEAD/NSGA2_old.m -------------------------------------------------------------------------------- /oilSpill.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septemc/MATLAB-I-NSGA2-Site-Selection/HEAD/oilSpill.mat -------------------------------------------------------------------------------- /concentration.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septemc/MATLAB-I-NSGA2-Site-Selection/HEAD/concentration.m -------------------------------------------------------------------------------- /land_cost.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septemc/MATLAB-I-NSGA2-Site-Selection/HEAD/land_cost.mat -------------------------------------------------------------------------------- /riskPosition.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septemc/MATLAB-I-NSGA2-Site-Selection/HEAD/riskPosition.mat -------------------------------------------------------------------------------- /constructionCost.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septemc/MATLAB-I-NSGA2-Site-Selection/HEAD/constructionCost.mat -------------------------------------------------------------------------------- /islandPosition.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Septemc/MATLAB-I-NSGA2-Site-Selection/HEAD/islandPosition.mat -------------------------------------------------------------------------------- /comOptimalSolution.m: -------------------------------------------------------------------------------- 1 | function [solution, fitness] = comOptimalSolution(pareto_fronts, pareto_fitness) 2 | % 综合评价择优 3 | % pareto_fronts input 帕累托前沿种群 4 | % pareto_fitness input 帕累托前沿种群适应度 5 | % solution output 最优解个体 6 | % fitness output 最优解适应度 7 | 8 | % 通过综合评价得出平衡各个目标的最优解 9 | 10 | [~, sort_rel] = sort(pareto_fitness(:,2), 'descend'); 11 | pareto_fronts = pareto_fronts(sort_rel, :); 12 | pareto_fitness = pareto_fitness(sort_rel, :); 13 | [~, sort_c] = sort(pareto_fitness(:,1), 'descend'); 14 | pareto_fronts = pareto_fronts(sort_c, :); 15 | pareto_fitness = pareto_fitness(sort_c, :); 16 | [~, sort_t] = sort(pareto_fitness(:,3), 'descend'); 17 | pareto_fronts = pareto_fronts(sort_t, :); 18 | pareto_fitness = pareto_fitness(sort_t, :); 19 | 20 | solution = pareto_fronts(1, :); 21 | fitness = pareto_fitness(1, :); 22 | end -------------------------------------------------------------------------------- /immune.m: -------------------------------------------------------------------------------- 1 | function ret = immune(individuals, similarityThreshold, memorySize) 2 | % 免疫个体选择函数 3 | % individuals input 种群 4 | % similarityThreshold input 相似度阈值 5 | % memorySize input 记忆库大小 6 | % ret output 受进化免疫的特异个体 7 | 8 | % 通过免疫机制可以尽可能保留种群的多样性,以跳出局部最优解 9 | 10 | num_obj = size(individuals.fitness', 1); 11 | 12 | % 找到每轮中单目标函数最优的个体 13 | [~, best_indices] = min(individuals.fitness); 14 | bestObj_chrom = individuals.chrom(best_indices, :); 15 | 16 | % 找到相似度低的个体 17 | for i=1:length(individuals.chrom) 18 | concentrations(i) = concentration(i, length(individuals.chrom), individuals, similarityThreshold); 19 | end 20 | [~, sort_con] = sort(concentrations', 'descend'); 21 | con_chrom = individuals.chrom(sort_con,:); 22 | bestCon_chrom = con_chrom(1:memorySize - num_obj, :); 23 | ret = [bestObj_chrom; bestCon_chrom]; 24 | end -------------------------------------------------------------------------------- /TEMP2.m: -------------------------------------------------------------------------------- 1 | %% 随机生成新的仿真数据 2 | 3 | % 设置参数 4 | M = 15; % 岛屿数量 5 | N = 20; % 事故风险点数量 6 | % 生成岛屿数据 7 | islandPosition = []; 8 | constructionCost = []; 9 | for i = 1:M 10 | islandPosition(i, :) = [randi([0, 1000]), randi([0, 1000])]; % 随机生成岛屿的位置 11 | constructionCost(i) = randi([500, 5000]); % 随机生成岛屿的建设成本 12 | end 13 | 14 | % 生成事故风险点数据 15 | riskPosition = zeros(N, 2); 16 | oilSpill = zeros(N, 1); 17 | for i = 1:N 18 | riskPosition(i, :) = [randi([0, 1000]), randi([0, 1000])]; % 随机生成事故风险点的位置 19 | oilSpill(i) = randi([1000, 5000]); % 随机生成溢油量 20 | end 21 | 22 | % 可视化岛屿和事故风险点 23 | figure; 24 | hold on; 25 | 26 | % 绘制岛屿 27 | for i = 1:M 28 | scatter(islandPosition(i, 1), islandPosition(i, 2), [], constructionCost(i), 'MarkerEdgeColor', 'k'); 29 | end 30 | 31 | % 绘制事故风险点 32 | for i = 1:N 33 | scatter(riskPosition(i, 1), riskPosition(i, 2), [], oilSpill(i), 'filled', 'MarkerEdgeColor', 'k'); 34 | end 35 | 36 | % 设置图例和标签 37 | colorbar; 38 | colormap('jet'); 39 | xlabel('X坐标'); 40 | ylabel('Y坐标'); 41 | title('岛屿和事故风险点可视化'); 42 | 43 | hold off; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MATLAB-I-NSGA2-Site-Selection-Latest-2023-11-21 2 | 3 | 免疫机制的函数介绍暂时没有补充 4 | 5 | NSGA2.m:该脚本文件是整个项目的主程序,它包含了多目标遗传算法的实现和选址问题的解决方案。该脚本文件会调用其他脚本文件中的函数,以完成种群初始化、进化寻优、结果分析等任务。 6 | 7 | fitness.m:该脚本文件包含了计算目标函数的函数,它接受一个个体作为输入,然后计算该个体对应的总成本、系统可靠性和救援总用时,并将这些值作为一个向量返回。 8 | 9 | popinit.m:该脚本文件包含了初始化种群的函数,它接受三个参数:种群数量n、抗体长度length和风险可能点数量num_points。函数会随机产生n个长度为length的抗体,每个抗体由num_points个风险可能点中的一些点组成。 10 | 11 | Cross.m:该脚本文件包含了交叉遗传的函数,它接受三个参数:抗体群chrom、种群规模sizepop和基因长度nGenes。函数会对抗体群中的每个个体进行交叉操作,随机选择两个个体和一个交叉位置,然后将两个个体在交叉位置处的基因进行交换。 12 | 13 | Mutation.m:该脚本文件包含了变异遗传的函数,它接受四个参数:抗体群chrom、种群规模sizepop、基因长度nGenes和风险可能点数量num_points。函数会对抗体群中的每个个体进行变异操作,随机选择一个个体和一个基因位置,然后将该位置的基因随机替换为一个新的基因。 14 | 15 | nonDominatedSorting.m:该脚本文件包含了进行非支配排序的函数,它接受一个矩阵fitness作为输入,其中每行表示一个个体的多个目标函数值。函数会对所有个体进行非支配排序,将它们划分为不同的前沿。 16 | 17 | crowdingDistanceCalculation.m:该脚本文件包含了计算拥挤距离的函数,它接受一个结构体individuals和一个单元格数组fronts作为输入,其中individuals包含了种群中每个个体的信息,fronts是一个单元格数组,其中每个单元格包含了一个前沿中的个体索引。 18 | 19 | multiSorting.m:该脚本文件包含了进行综合排序的函数,它接受一个结构体individuals作为输入,其中包含了种群中每个个体的信息。函数会根据拥挤距离和支配等级对个体进行排序,并将排序后的个体信息存储在一个新的结构体new_individuals中。 20 | -------------------------------------------------------------------------------- /multiSorting.m: -------------------------------------------------------------------------------- 1 | %% 定义多目标优秀程度计算函数 2 | function new_individuals = multiSorting(individuals) 3 | % 定义综合函数 4 | % individuals input 种群 5 | % new_individuals output 排序后新种群 6 | 7 | % 根据支配等级与拥挤度进行优秀种群的综合排序 8 | M = length(individuals.chrom); 9 | new_individuals = struct('chrom',[], 'fitness',zeros(M,2), 'concentration',zeros(M,1), ... 10 | 'excellence',zeros(M,1), 'crowdingDistance',zeros(M, 1), ... 11 | 'ranks',zeros(M,1)); 12 | 13 | % 根据拥挤距离与支配等级进行排序 14 | [~, sort_cd] = sort(individuals.crowdingDistance, 'descend'); 15 | new_individuals.chrom = individuals.chrom(sort_cd,:); 16 | new_individuals.crowdingDistance = individuals.crowdingDistance(sort_cd); 17 | new_individuals.ranks = individuals.ranks(sort_cd); 18 | new_individuals.fitness = individuals.fitness(sort_cd,:); 19 | [~, sort_ra] = sort(new_individuals.ranks, 'ascend'); 20 | new_individuals.chrom = new_individuals.chrom(sort_ra,:); 21 | new_individuals.crowdingDistance = new_individuals.crowdingDistance(sort_ra); 22 | new_individuals.ranks = new_individuals.ranks(sort_ra); 23 | new_individuals.fitness = new_individuals.fitness(sort_ra,:); 24 | 25 | end -------------------------------------------------------------------------------- /crowdingDistanceCalculation.m: -------------------------------------------------------------------------------- 1 | function individuals = crowdingDistanceCalculation(individuals, fronts) 2 | % 定义拥挤距离计算函数 3 | % individuals input 种群 4 | % fronts input 帕累托前沿 5 | % individuals output 计算拥挤度后的种群 6 | 7 | % 通过计算拥挤度可以评估目标函数值的相似程度,以便得到更多整个层级的解集 8 | 9 | nfronts = numel(fronts); % 读取支配等级数 10 | for k = 1 : nfronts 11 | Objs = individuals.fitness(fronts{k},:); % 遍历每个等级,将其中的个体目标值取出,便于后续计算 12 | nObj = size(Objs', 1); % 读取优化目标数 13 | n = numel(fronts{k}); % 读取当前等级中共有多少个个体 14 | crowdingDistance = zeros(n, nObj); % 创建一个新的拥挤度矩阵用于结果存放 15 | for j = 1 : nObj 16 | [obj, index] = sort(Objs(:,j), 'ascend'); % 对目标值进行升序排列 17 | current_sum_cd = 1; 18 | for i = 2 : n - 1 19 | current_cd = abs(obj(i+1) - obj(i-1))/abs(obj(1) - obj(end)); 20 | if isnan(current_cd) 21 | current_cd = 0; 22 | end 23 | crowdingDistance(index(i), j) = current_cd; 24 | current_sum_cd = current_sum_cd + current_cd; 25 | end 26 | crowdingDistance(index(1), j) = current_sum_cd; % 边界个体的适应度值为无穷大 27 | crowdingDistance(index(end), j) = current_sum_cd; % 边界个体的适应度值为无穷大 28 | end 29 | for i = 1 : n 30 | individuals.crowdingDistance(fronts{k}(i)) = sum(crowdingDistance(i, :)); %每个个体的总拥挤度值等于各优化目标中拥挤度值之和 31 | end 32 | end 33 | individuals.crowdingDistance = individuals.crowdingDistance'; 34 | end 35 | 36 | -------------------------------------------------------------------------------- /nonDominatedSorting.m: -------------------------------------------------------------------------------- 1 | function [fronts, ranks] = nonDominatedSorting(fitness) 2 | % 非支配排序 3 | % fitness input 种群的适应度 4 | % fronts output 帕累托前沿 5 | % ranks output 支配等级 6 | 7 | % 通过排序可以得到每一个个体再种群中的等级,作为进化选择的重要指标 8 | n = size(fitness, 1); 9 | fronts{1} = []; 10 | ranks = zeros(1, n); 11 | dominated_By = zeros(1, n); 12 | dominates = cell(1, n); 13 | for i = 1:n 14 | dominates{i} = []; 15 | for j = 1:n 16 | if i ~= j 17 | if all(fitness(i, :) <= fitness(j, :)) && any(fitness(i, :) < fitness(j, :)) 18 | dominates{i} = [dominates{i}, j]; 19 | elseif all(fitness(i, :) >= fitness(j, :)) && any(fitness(i, :) > fitness(j, :)) 20 | dominated_By(i) = dominated_By(i) + 1; 21 | end 22 | end 23 | end 24 | if dominated_By(i) == 0 25 | fronts{1} = [fronts{1}, i]; 26 | ranks(i) = 1; 27 | end 28 | end 29 | 30 | frontIndex = 1; 31 | while length(fronts) == frontIndex 32 | nextFront = []; 33 | for i = fronts{frontIndex} 34 | for j = dominates{i} 35 | dominated_By(j) = dominated_By(j) - 1; 36 | if dominated_By(j) == 0 37 | nextFront = [nextFront, j]; 38 | ranks(j) = frontIndex + 1; 39 | end 40 | end 41 | end 42 | frontIndex = frontIndex + 1; 43 | if ~isempty(nextFront) 44 | fronts{frontIndex} = nextFront; 45 | end 46 | end 47 | ranks = ranks'; 48 | end 49 | -------------------------------------------------------------------------------- /fitness.m: -------------------------------------------------------------------------------- 1 | function fit = fitness(individual) 2 | % 计算个体适应度 3 | % individual input 个体 4 | % fit output 适应度 5 | 6 | % 通过计算得到了总成本、系统可靠性与救援总时间 7 | 8 | %% 加载仿真数据 9 | % 定义参数 10 | islandPosition = load("islandPosition.mat").islandPosition; % 岛屿坐标 11 | riskPosition = load("riskPosition.mat").riskPosition; % 风险点坐标 12 | V = load("oilSpill.mat").oilSpill'; % 溢油量情况 13 | c_l = load("constructionCost.mat").constructionCost; % 地形建设成本 14 | M = size(islandPosition, 1); % 救助点建设数量 15 | P = 2; % 救助力量的数量 16 | 17 | %% 集结点成本 18 | % 定义参数 19 | c_p = [150, 2000]; % 救助船(飞机)建造成本 20 | o_p = [50, 180]; % 救助船(飞机)年运营成本 21 | C_maintenance = 30; % 海上应急救助站点的年维护保养费用 22 | C_human = 200; % 人工成本 23 | 24 | 25 | % 假设 y_m 是一个大小为 M 的向量,表示每个救助站点候选点是否被选为站点 26 | y_m = zeros(1, M); 27 | y_m(individual) = 1; 28 | % 假设 x_mp 是一个大小为 MxP 的矩阵,表示在每个救助站点候选点m处配置救助船(飞机)的数量 29 | x_mp = zeros(M, P); 30 | x_mp(:,1) = 2; % 救助船的数量 31 | x_mp(:,2) = 1; % 救助飞机的数量 32 | 33 | 34 | % 计算总成本函数 35 | total_cost = 0; 36 | for m = 1:M 37 | for p = 1:P 38 | total_cost = total_cost + y_m(m) * ((c_p(p) + o_p(p)) * x_mp(m, p)); 39 | end 40 | total_cost = total_cost + (C_maintenance + C_human + c_l(m)) * y_m(m); 41 | end 42 | 43 | %% 响应时间 44 | % 定义参数 45 | points = islandPosition(individual,:); % 集结点的坐标 46 | speed = [22, 200]; % 应急力量的速度,单位为km/h 47 | dragSpeed = [2, 15]; % 受阻力减小的速度,单位为km/h 48 | preparationTime = 1; % 准备救援的时间,单位为小时 49 | responseTimeThreshold = [18, 2]; % 响应时间阈值,单位为小时 50 | 51 | distance_mat = zeros(size(riskPosition, 1), size(points, 1)); 52 | for i = 1:size(points, 1) 53 | for j = 1:size(riskPosition, 1) 54 | distance = norm(points(i, :) - riskPosition(j, :)); 55 | distance_mat(j, i) = distance; 56 | end 57 | end 58 | 59 | [a1,b1]=min(distance_mat'); 60 | temp_distance_mat = distance_mat; 61 | for i = 1:size(riskPosition, 1) 62 | temp_distance_mat(i,b1(i)) = inf; 63 | end 64 | [a2,b2]=min(temp_distance_mat'); 65 | 66 | % 计算每个集结点到事故可能点的响应时间 67 | response_times = zeros(size(riskPosition, 1), size(points, 1)); 68 | for i = 1:size(points, 1) 69 | for j = 1:size(riskPosition, 1) 70 | distance = norm(points(i, :) - riskPosition(j, :)); 71 | response_times(j, i) = distance / speed(1) + preparationTime; 72 | end 73 | end 74 | 75 | % 找到每个事故可能点到最近的集结点的响应时间 76 | min_response_times = min(response_times'); 77 | response_times = sum(min_response_times)/size(points, 1); 78 | 79 | 80 | %% 覆盖范围 81 | % 定义参数 82 | rescue_ships_coverage_radius = responseTimeThreshold(1) * (speed(1) - dragSpeed(1)); % 救援船只覆盖半径,单位为km 83 | rescue_helicopters_coverage_radius = responseTimeThreshold(2) * (speed(2) - dragSpeed(2)); % 救援直升机覆盖半径,单位为km 84 | 85 | % 计算救援船只、救援直升机的覆盖范围 86 | rescue_ships_coverage = zeros(size(riskPosition, 1), size(points, 1)); 87 | rescue_helicopters_coverage = zeros(size(riskPosition, 1), size(points, 1)); 88 | 89 | for i = 1:size(riskPosition, 1) 90 | if a1(i) <= rescue_ships_coverage_radius 91 | rescue_ships_coverage(i, b1(i)) = 1; 92 | end 93 | if a2(i) <= rescue_ships_coverage_radius 94 | rescue_ships_coverage(i, b2(i)) = 1; 95 | end 96 | end 97 | rescue_ships_coverage = sum(rescue_ships_coverage'); 98 | rescue_ships_coverage(rescue_ships_coverage<2) = 0; 99 | rescue_ships_coverage(rescue_ships_coverage>=2) = 1; 100 | rescue_ships_coverage = sum(rescue_ships_coverage)/size(riskPosition, 1); 101 | 102 | for i = 1:size(riskPosition, 1) 103 | if a1(i) <= rescue_helicopters_coverage_radius 104 | rescue_helicopters_coverage(i, b1(i)) = 1; 105 | end 106 | if a2(i) <= rescue_helicopters_coverage_radius 107 | rescue_helicopters_coverage(i, b2(i)) = 1; 108 | end 109 | end 110 | rescue_helicopters_coverage = sum(rescue_helicopters_coverage'); 111 | rescue_helicopters_coverage(rescue_helicopters_coverage<2) = 0; 112 | rescue_helicopters_coverage(rescue_helicopters_coverage>=2) = 1; 113 | rescue_helicopters_coverage = sum(rescue_helicopters_coverage)/size(riskPosition, 1); 114 | 115 | 116 | %% 溢油清理成本 117 | % 定义参数 118 | C_per_ton = 0.05; % 每吨溢油清理成本 119 | % 计算溢油清理成本 120 | temp = V .* C_per_ton; 121 | cleanup_cost = sum(V .* C_per_ton); 122 | 123 | %% 溢油清理时间与救援时间 124 | % 定义参数 125 | T_per_ton = 0.5; % 每吨溢油清理时间,单位为小时/吨 126 | rescueTimeCoefficient = 0.02; % 海上救援时间系数 127 | % oil_spill_cleaning_labor_cost = 0.5; % 溢油清理人工费用,万/小时 128 | % 计算溢油清理时间 129 | T_cleaning_time = sum(V .* T_per_ton); 130 | rescue_time = rescueTimeCoefficient * T_cleaning_time / size(points, 1); 131 | 132 | %% 系统可靠性 133 | % 定义参数 134 | rescue_ships_success_rate = 0.6; % 救援船只完成任务概率 135 | rescue_helicopters_success_rate = 0.7; % 救援直升机完成任务概率 136 | rescue_ships_power = x_mp(1, 1); 137 | rescue_helicopters_power = x_mp(1, 2); 138 | 139 | % 计算系统可靠性 140 | rescue_ships_reliability = rescue_ships_coverage*rescue_ships_power*rescue_ships_success_rate; 141 | rescue_helicopters_reliability = rescue_helicopters_coverage*rescue_helicopters_power*rescue_helicopters_success_rate; 142 | 143 | 144 | system_reliability = (rescue_ships_reliability + rescue_helicopters_reliability) / 2; 145 | all_cost = total_cost + cleanup_cost; 146 | all_time = response_times + rescue_time; 147 | if system_reliability > 1 148 | system_reliability = 1; 149 | end 150 | fit = [all_cost, 1./system_reliability, all_time]; 151 | end -------------------------------------------------------------------------------- /fitness_old.m: -------------------------------------------------------------------------------- 1 | function fit = fitness_old(individual) 2 | 3 | % 加载仿真数据 4 | islandData = load("islandData.mat").islandData; 5 | riskPointData = load("riskPointData.mat").riskPointData; 6 | oil_spill_volume = riskPointData.oilSpill; 7 | 8 | %% 集结点成本 9 | % 定义参数 10 | all_land_cost = islandData.constructionCost; % 地形成本 11 | land_cost = all_land_cost(individual); 12 | building_cost = 200; % 建筑费用 13 | equipment_cost = 50; % 设备费用 14 | labor_cost = 100; % 人工费用 15 | maintenance_cost = 5; % 日常维护费用 16 | repair_cost = 10; % 修缮费用 17 | update_cost = 20; % 更新费用 18 | 19 | % 集结点数量 20 | num_points = length(individual); 21 | 22 | % 定义成本数组 23 | costs = zeros(1, num_points); 24 | 25 | % 计算每个点的成本 26 | for i = 1:num_points 27 | % 这里可以根据实际情况进行调整,比如可以使用不同的参数 28 | costs(i) = land_cost(i) + building_cost + equipment_cost + labor_cost + maintenance_cost + repair_cost + update_cost; 29 | end 30 | 31 | % 计算总成本 32 | total_cost = sum(costs); 33 | 34 | 35 | %% 响应时间 36 | % 定义参数 37 | points = riskPointData(individual, :); % 集结点的坐标 38 | speed = 20; % 应急力量的速度,单位为km/h 39 | wait_time = 1; % 等待时间,单位为小时 40 | 41 | distance_mat = zeros(size(riskPointData, 1), num_points); 42 | for i = 1:num_points 43 | for j = 1:size(riskPointData, 1) 44 | distance = norm(points(i, :) - riskPointData(j, :)); 45 | distance_mat(j, i) = distance; 46 | end 47 | end 48 | 49 | [a1,b1]=min(distance_mat'); 50 | temp_distance_mat = distance_mat; 51 | for i = 1:size(riskPointData, 1) 52 | temp_distance_mat(i,b1(i)) = inf; 53 | end 54 | [a2,b2]=min(temp_distance_mat'); 55 | 56 | % 计算每个集结点到事故可能点的响应时间 57 | response_times = zeros(size(riskPointData, 1), num_points); 58 | for i = 1:num_points 59 | for j = 1:size(riskPointData, 1) 60 | distance = norm(points(i, :) - riskPointData(j, :)); 61 | response_times(j, i) = distance / speed + wait_time; 62 | end 63 | end 64 | response_times(response_times == 1) = inf; 65 | % 找到每个事故可能点到最近的集结点的响应时间 66 | min_response_times = min(response_times'); 67 | response_times = sum(min_response_times); 68 | 69 | %% 应急力量数量 70 | % 定义参数 71 | rescue_ships = 2; % 救援船只数量 72 | rescue_helicopters = 1; % 救援直升机数量 73 | rescue_personnel = 50; % 救援人员数量 74 | cleaning_equipment = 10; % 清洁设备数量 75 | rescue_ships_coefficient = 1; % 救援船只配置系数 76 | rescue_helicopters_coefficient = 2; % 救援直升机配置系数 77 | rescue_personnel_coefficient = 0.06; % 救援人员配置系数 78 | cleaning_equipment_coefficient = 0.2; % 清洁设备配置系数 79 | 80 | % 计算应急力量的数量 81 | rescue_ships_number = rescue_ships_coefficient * rescue_ships; 82 | rescue_helicopters_number = rescue_helicopters_coefficient * rescue_helicopters; 83 | rescue_personnel_number = rescue_personnel_coefficient * rescue_personnel; 84 | cleaning_equipment_number = cleaning_equipment_coefficient * cleaning_equipment; 85 | 86 | 87 | 88 | %% 覆盖范围 89 | % 定义参数 90 | rescue_ships_coverage_radius = 130; % 救援船只覆盖半径,单位为km 91 | rescue_helicopters_coverage_radius = 180; % 救援直升机覆盖半径,单位为km 92 | rescue_personnel_coverage_radius = 100; % 救援人员覆盖半径,单位为km 93 | cleaning_equipment_coverage_radius = 200; % 清洁设备覆盖半径,单位为km 94 | 95 | 96 | % 计算救援船只、救援直升机、救援人员、清洁设备的覆盖范围 97 | rescue_ships_coverage = zeros(size(riskPointData, 1), size(points, 1)); 98 | rescue_helicopters_coverage = zeros(size(riskPointData, 1), size(points, 1)); 99 | rescue_personnel_coverage = zeros(size(riskPointData, 1), size(points, 1)); 100 | cleaning_equipment_coverage = zeros(size(riskPointData, 1), size(points, 1)); 101 | 102 | for i = 1:size(riskPointData, 1) 103 | if a1(i) <= rescue_ships_coverage_radius 104 | rescue_ships_coverage(i, b1(i)) = 1; 105 | end 106 | if a2(i) <= rescue_ships_coverage_radius 107 | rescue_ships_coverage(i, b2(i)) = 1; 108 | end 109 | end 110 | rescue_ships_coverage = sum(rescue_ships_coverage'); 111 | rescue_ships_coverage(rescue_ships_coverage<2) = 0; 112 | rescue_ships_coverage(rescue_ships_coverage>=2) = 1; 113 | rescue_ships_coverage = sum(rescue_ships_coverage)/size(riskPointData, 1); 114 | 115 | for i = 1:size(riskPointData, 1) 116 | if a1(i) <= rescue_helicopters_coverage_radius 117 | rescue_helicopters_coverage(i, b1(i)) = 1; 118 | end 119 | if a2(i) <= rescue_helicopters_coverage_radius 120 | rescue_helicopters_coverage(i, b2(i)) = 1; 121 | end 122 | end 123 | rescue_helicopters_coverage = sum(rescue_helicopters_coverage'); 124 | rescue_helicopters_coverage(rescue_helicopters_coverage<2) = 0; 125 | rescue_helicopters_coverage(rescue_helicopters_coverage>=2) = 1; 126 | rescue_helicopters_coverage = sum(rescue_helicopters_coverage)/size(riskPointData, 1); 127 | 128 | for i = 1:size(riskPointData, 1) 129 | if a1(i) <= rescue_personnel_coverage_radius 130 | rescue_personnel_coverage(i, b1(i)) = 1; 131 | end 132 | if a2(i) <= rescue_personnel_coverage_radius 133 | rescue_personnel_coverage(i, b2(i)) = 1; 134 | end 135 | end 136 | rescue_personnel_coverage = sum(rescue_personnel_coverage'); 137 | rescue_personnel_coverage(rescue_personnel_coverage<2) = 0; 138 | rescue_personnel_coverage(rescue_personnel_coverage>=2) = 1; 139 | rescue_personnel_coverage = sum(rescue_personnel_coverage)/size(riskPointData, 1); 140 | 141 | for i = 1:size(riskPointData, 1) 142 | if a1(i) <= cleaning_equipment_coverage_radius 143 | cleaning_equipment_coverage(i, b1(i)) = 1; 144 | end 145 | if a2(i) <= cleaning_equipment_coverage_radius 146 | cleaning_equipment_coverage(i, b2(i)) = 1; 147 | end 148 | end 149 | cleaning_equipment_coverage = sum(cleaning_equipment_coverage'); 150 | cleaning_equipment_coverage(cleaning_equipment_coverage<2) = 0; 151 | cleaning_equipment_coverage(cleaning_equipment_coverage>=2) = 1; 152 | cleaning_equipment_coverage = sum(cleaning_equipment_coverage)/size(riskPointData, 1); 153 | 154 | 155 | %% 溢油清理成本 156 | % 定义参数 157 | oil_spill_cleaning_cost_per_ton = 1; % 每吨溢油清理成本,单位为万元/吨 158 | % 计算溢油清理成本 159 | for i = 1:size(riskPointData, 1) 160 | oil_spill_cleaning_cost = oil_spill_volume(i) * oil_spill_cleaning_cost_per_ton; 161 | end 162 | 163 | %% 溢油清理时间 164 | % 定义参数 165 | oil_spill_cleaning_time_per_ton = 1; % 每吨溢油清理时间,单位为小时/吨 166 | % oil_spill_cleaning_labor_cost = 0.5; % 溢油清理人工费用,万/小时 167 | % 计算溢油清理时间 168 | for i = 1:size(riskPointData, 1) 169 | oil_spill_cleaning_time = oil_spill_volume(i) * oil_spill_cleaning_time_per_ton; 170 | end 171 | rescue_time = oil_spill_cleaning_time / size(points, 1); 172 | %% 系统可靠性 173 | % 定义参数 174 | rescue_ships_success_rate = 0.6; % 救援船只完成任务概率 175 | rescue_helicopters_success_rate = 0.7; % 救援直升机完成任务概率 176 | rescue_personnel_success_rate = 0.5; % 救援人员完成任务概率 177 | cleaning_equipment_success_rate = 0.5; % 清洁设备完成任务概率 178 | 179 | % 计算系统可靠性 180 | rescue_ships_reliability = rescue_ships_coverage*rescue_ships_number*rescue_ships_success_rate; 181 | rescue_helicopters_reliability = rescue_helicopters_coverage*rescue_helicopters_number*rescue_helicopters_success_rate; 182 | rescue_personnel_reliability = rescue_personnel_coverage*rescue_personnel_number*rescue_personnel_success_rate; 183 | cleaning_equipment_reliability = cleaning_equipment_coverage*cleaning_equipment_number*cleaning_equipment_success_rate; 184 | 185 | 186 | system_reliability = (rescue_ships_reliability + rescue_helicopters_reliability + rescue_personnel_reliability + cleaning_equipment_reliability) / 4; 187 | all_cost = total_cost + oil_spill_cleaning_cost; 188 | all_time = response_times + rescue_time; 189 | if system_reliability > 1 190 | system_reliability = 1; 191 | end 192 | fit = [all_cost, 1./system_reliability, all_time]; 193 | end 194 | 195 | --------------------------------------------------------------------------------