C2-3实心菱形

题目描述

 

打印 n 阶实心菱形

输入描述

 

输入一个整数n,0 < n <= 10

输出描述

 

输出 n 阶实心菱形 , 占 2*n-1 行

样例输入

3

样例输出

  *
 ***
*****
 ***
  *

 

#include<iostream>
#include<math.h>
using namespace std;

int main() {
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n - 1 - i; j++)
		{
			cout << " ";
		};
		for (int k = 0; k < 2*i+1; k++)
		{
			cout << "*";
		};
		for (int j = 0; j < n - 1 - i; j++)
		{
			cout << " ";
		};
		cout << endl;
	}
	for (int i = n-2; i >=0; i--)
	{
		for (int j = 0; j < n - 1 - i; j++)
		{
			cout << " ";
		};
		for (int k = 0; k < 2 * i + 1; k++)
		{
			cout << "*";
		};
		for (int j = 0; j < n - 1 - i; j++)
		{
			cout << " ";
		};
		cout << endl;
	}

	return 0;
}

C++初试,利用对称性

import numpy as np import matplotlib.pyplot as plt import pandas as pd from scipy.spatial.distance import euclidean from shapely.geometry import Polygon, Point, LineString import random from datetime import datetime import os import math # -------------------------- 从Excel读取任务参数(新增ABCD类任务筛选) -------------------------- EXCEL_PATH = "附件2:问题二任务清单.xlsx" REQUIRED_CYCLE_TYPES = {&#39;A&#39;, &#39;B&#39;, &#39;C&#39;, &#39;D&#39;} # 核心约束:ABCD类任务 try: task_df = pd.read_excel(EXCEL_PATH) required_columns = [ "任务类别", "任务持续时间", "跟踪距离", "移动任务", "航速", "航向", "点位X轴坐标", "点位Y轴坐标" ] missing_cols = [col for col in required_columns if col not in task_df.columns] if missing_cols: raise ValueError(f"Excel文件缺少必需列:{&#39;, &#39;.join(missing_cols)},请检查列名是否匹配模板") # 读取所有任务参数 TASK_TYPES = task_df["任务类别"].tolist() TASK_DURATIONS = task_df["任务持续时间"].astype(float).tolist() TASK_TRACKING_DIST = task_df["跟踪距离"].astype(float).tolist() MOVING_TASKS = task_df["移动任务"].astype(bool).tolist() MOVING_SPEEDS = task_df["航速"].astype(float).tolist() MOVING_COURSES = task_df["航向"].astype(float).tolist() TASK_LOCATIONS = list(zip( task_df["点位X轴坐标"].astype(float).tolist(), task_df["点位Y轴坐标"].astype(float).tolist() )) TASK_LOCATIONS = [(round(x, 2), round(y, 2)) for x, y in TASK_LOCATIONS] TOTAL_TASKS_FROM_EXCEL = len(TASK_TYPES) # 筛选ABCD类任务的ID REQUIRED_CYCLE_TASK_IDS = [ idx for idx, task_type in enumerate(TASK_TYPES) if task_type in REQUIRED_CYCLE_TYPES ] print(f"成功从Excel读取{TOTAL_TASKS_FROM_EXCEL}个任务的参数") print(f"需要12小时周期约束的ABCD类任务ID:{REQUIRED_CYCLE_TASK_IDS}") if not REQUIRED_CYCLE_TASK_IDS: print("警告:未检测到ABCD类任务,周期约束自动失效") except FileNotFoundError: raise FileNotFoundError(f"未找到Excel文件:{EXCEL_PATH},请检查文件路径是否正确") except Exception as e: raise Exception(f"读取Excel失败:{str(e)}") # -------------------------- 基础参数设置(新增周期参数) -------------------------- plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] plt.rcParams[&#39;axes.unicode_minus&#39;] = False # 解决负号显示问题 SHIP_SPEEDS = [20, 24, 26, 30] # 节 SHIP_START_POINTS = [(187, 175), (169, 112), (50, 88), (73, 214)] # 4艘舰艇初始位置 EXIT_POLYGON = Polygon([(194.0, 177.6), (173.4, 106.9), (42.5, 81.2), (68.1, 220.7), (144.6, 211.5)]) Cruise_line = [(187.05, 175.1), (168.65, 112.1), (50, 88.75), (73, 214.05), (142.45, 205.75)] cruise_polygon = Polygon(Cruise_line) cruise_boundary = LineString(cruise_polygon.exterior.coords) SHIP_Handling_radius=[5,3,1,1] #处置半径 SHIP_Handling_amount=[6,5,3,2] #处置数量 # 遗传算法参数 + 周期约束参数 POP_SIZE = 8 MAX_GEN = 300 CX_PROB = 0.85 MUT_PROB = 0.15 ELITE_RATIO = 0.1 KNOTS_TO_KMH = 1.852 NAUTICAL_TO_KM = 1.852 CYCLE_DURATION = 12 # 约束周期:12小时 PENALTY_FACTOR = 0.5 # 约束不满足时的适应度惩罚系数 # 新增:舰艇航迹配置(颜色、线型、标记,4艘舰艇各不同) SHIP_TRAJECTORY_CONFIG = [ {"color": "#1f77b4", "line_style": "-", "init_marker": "D", "task_marker": "o", "label": "舰艇1"}, {"color": "#ff7f0e", "line_style": "--", "init_marker": "D", "task_marker": "s", "label": "舰艇2"}, {"color": "#2ca02c", "line_style": "-.", "init_marker": "D", "task_marker": "^", "label": "舰艇3"}, {"color": "#d62728", "line_style": ":", "init_marker": "D", "task_marker": "p", "label": "舰艇4"} ] # == == == == == 新增:周期约束辅助函数 == == == == == def get_time_cycles(total_time): if total_time <= 0: return [] cycle_count = int(np.ceil(total_time / CYCLE_DURATION)) return [[cycle * CYCLE_DURATION, (cycle + 1) * CYCLE_DURATION] for cycle in range(cycle_count)] def is_task_executed_in_cycle(task_start, task_end, cycle_start, cycle_end): return (task_start >= cycle_start and task_start < cycle_end) or \ (task_end > cycle_start and task_end <= cycle_end) or \ (task_start <= cycle_start and task_end >= cycle_end) def check_cycle_constraint(ship_tasks, total_time): if not REQUIRED_CYCLE_TASK_IDS: return {"约束状态": "无ABCD类任务,约束失效"}, 0 cycles = get_time_cycles(total_time) constraint_result = { "总周期数": len(cycles), "周期详情": [f"{cycle[0]}-{cycle[1]}h" for cycle in cycles], "任务约束检查": {} } unmet_count = 0 for task_id in REQUIRED_CYCLE_TASK_IDS: task_type = TASK_TYPES[task_id] task_executions = [] for ship_idx in range(len(ship_tasks)): for task in ship_tasks[ship_idx]: if task["任务编号"] == task_id: task_executions.append({ "舰艇编号": task["舰艇编号"], "开始时间": task["处置任务开始时刻(小时)"], "结束时间": task["处置任务结束时刻(小时)"] }) cycle_check = [] for cycle_idx, (cycle_start, cycle_end) in enumerate(cycles): executed = any( is_task_executed_in_cycle( exec["开始时间"], exec["结束时间"], cycle_start, cycle_end ) for exec in task_executions ) if not executed: unmet_count += 1 cycle_check.append(f"周期{cycle_idx + 1}({cycle_start}-{cycle_end}h):未执行❌") else: cycle_check.append(f"周期{cycle_idx + 1}({cycle_start}-{cycle_end}h):已执行✅") constraint_result["任务约束检查"][f"任务{task_id}({task_type}类)"] = cycle_check constraint_result["约束状态"] = f"共{unmet_count}个(任务-周期)对未满足约束" return constraint_result, unmet_count # == == == == == 原有辅助函数(保持不变) == == == == == def calc_course(from_pos, to_pos): dx = to_pos[0] - from_pos[0] dy = to_pos[1] - from_pos[1] if dx == 0 and dy == 0: return 0.0 math_angle = np.arctan2(dy, dx) course = (90 - np.degrees(math_angle)) % 360 return round(course, 2) def get_closest_cruise_point(end_pos): end_point = Point(end_pos) proj_dist = cruise_boundary.project(end_point) closest_point = cruise_boundary.interpolate(proj_dist) closest_pos = (round(closest_point.x, 2), round(closest_point.y, 2)) boundary_vertices = list(cruise_boundary.coords)[:-1] min_x = min(v[0] for v in boundary_vertices) max_x = max(v[0] for v in boundary_vertices) min_y = min(v[1] for v in boundary_vertices) max_y = max(v[1] for v in boundary_vertices) cx, cy = closest_pos if not (min_x - 1e-6 <= cx <= max_x + 1e-6 and min_y - 1e-6 <= cy <= max_y + 1e-6): vertex_dists = [euclidean(end_pos, v) for v in boundary_vertices] closest_idx = np.argmin(vertex_dists) closest_pos = boundary_vertices[closest_idx] return closest_pos def calc_end_course_to_cruise(end_pos): closest_pos = get_closest_cruise_point(end_pos) return calc_course(end_pos, closest_pos) def get_target_position(task_id, t): if not MOVING_TASKS[task_id]: return TASK_LOCATIONS[task_id] x0, y0 = TASK_LOCATIONS[task_id] speed_kmh = MOVING_SPEEDS[task_id] * KNOTS_TO_KMH course_rad = np.deg2rad(MOVING_COURSES[task_id]) dx = speed_kmh * t * np.sin(course_rad) dy = speed_kmh * t * np.cos(course_rad) return (round(x0 + dx, 2), round(y0 + dy, 2)) def is_target_exited(task_id, t): if not MOVING_TASKS[task_id]: return False pos = get_target_position(task_id, t) return not EXIT_POLYGON.contains(Point(pos)) def calc_distance(pos1, pos2): return round(euclidean(pos1, pos2), 2) def calc_travel_time(ship_speed, distance): if distance == 0: return 0.0 speed_kmh = ship_speed * KNOTS_TO_KMH return round(distance / speed_kmh, 2) def calc_time_in_polygon(init_point, speed, direction_angle, polygon_vertices): """ 计算移动点从多边形外进入、再离开的总时间(简化验证版) :param init_point: 初始点坐标(元组):(x0, y0) :param speed: 移动速度(正数) :param direction_angle: 移动方向角(度,与x轴正方向夹角) :param polygon_vertices: 多边形顶点列表:[(x1,y1), ..., (xn,yn)] :return: 总时间,无有效交点时返回0 """ # 提取初始坐标 init_x, init_y = init_point # 1. 初始化多边形和轨迹 polygon = Polygon(polygon_vertices) theta = math.radians(450-direction_angle) vx = speed * math.cos(theta) vy = speed * math.sin(theta) # 生成足够长的轨迹线段 end_x = init_x + vx * 1e6 end_y = init_y + vy * 1e6 trajectory = LineString([(init_x, init_y), (end_x, end_y)]) # 2. 计算轨迹与多边形边界的交点 intersection = trajectory.intersection(polygon.boundary) if intersection.is_empty: return 0.0 # 无交点 # 3. 提取并排序交点(按到初始点的距离) if intersection.geom_type == "Point": intersections = [intersection] elif intersection.geom_type == "MultiPoint": intersections = list(intersection.geoms) else: return 0.0 # 非点类型交点视为无效 print(intersection) # 按轨迹顺序排序(确保进入点在前,离开点在后) intersections.sort(key=lambda p: math.hypot(p.x - init_x, p.y - init_y)) # 4. 取前两个交点计算距离(假设存在两个有效交点) if len(intersections) < 2: return 0.0 # 交点不足 enter_point, leave_point = intersections[0], intersections[1] distance = math.hypot(leave_point.x - enter_point.x, leave_point.y - enter_point.y) return round(distance / speed, 6) # == == == == == 遗传算法核心(保持不变) == == == == == class GAOptimizer: def __init__(self, num_ships=4, forced_task_count=3): self.num_ships = num_ships self.total_tasks = TOTAL_TASKS_FROM_EXCEL self.forced_task_count = min(forced_task_count, self.total_tasks) self.forced_tasks = list(range(self.forced_task_count)) self.normal_tasks = list(range(self.forced_task_count, self.total_tasks)) print(f"任务划分:强制任务{self.forced_tasks},普通任务{self.normal_tasks}") def init_population(self): population = [] for _ in range(POP_SIZE): forced_shuffled = random.sample(self.forced_tasks, len(self.forced_tasks)) normal_shuffled = random.sample(self.normal_tasks, len(self.normal_tasks)) if self.normal_tasks else [] chrom = forced_shuffled + normal_shuffled population.append(chrom) return population def evaluate_individual(self, individual): ship_times = [0.0] * self.num_ships ship_positions = [pos for pos in SHIP_START_POINTS] used_ships_for_forced = set() task_execution_records = [[] for _ in range(self.num_ships)] for task_id in individual: if task_id in self.forced_tasks: for ship_idx in range(self.num_ships): if ship_idx not in used_ships_for_forced: target_ship_idx = ship_idx used_ships_for_forced.add(ship_idx) break current_time = 0.0 else: target_ship_idx = np.argmin(ship_times) current_time = ship_times[target_ship_idx] ship_speed = SHIP_SPEEDS[target_ship_idx] current_pos = ship_positions[target_ship_idx] target_pos = get_target_position(task_id, current_time) if MOVING_TASKS[task_id] else TASK_LOCATIONS[ task_id] distance = calc_distance(current_pos, target_pos) travel_time = calc_travel_time(ship_speed, distance) if TASK_TYPES[task_id] in [&#39;S2&#39;, &#39;S3&#39;]: # 修正:S2/S3任务需要跟踪目标移动一段距离 # 计算舰艇到达目标位置的时间(考虑目标移动) travel_time = calc_travel_time( ship_speed, calc_distance(current_pos, TASK_LOCATIONS[task_id]) ) # 修正:计算追踪时间(目标移动指定距离所需时间) tracking_time = TASK_TRACKING_DIST[task_id] / MOVING_SPEEDS[task_id] exit_time = calc_time_in_polygon(target_pos, MOVING_SPEEDS[task_id], MOVING_COURSES[task_id], EXIT_POLYGON) # 修正:总任务时间 = 航行时间 + 追踪时间 task_time = travel_time + tracking_time + exit_time # 修正:任务结束位置应为目标移动后的位置 end_pos = get_target_position(task_id, current_time + travel_time + tracking_time + exit_time) ship_times[target_ship_idx] = current_time + task_time ship_positions[target_ship_idx] = end_pos else: task_time = travel_time + TASK_DURATIONS[task_id] ship_times[target_ship_idx] = current_time + task_time ship_positions[target_ship_idx] = get_target_position(task_id, ship_times[target_ship_idx]) total_time = max(ship_times) base_fitness = 1 / (total_time + 1e-6) if REQUIRED_CYCLE_TASK_IDS: _, unmet_count = check_cycle_constraint(task_execution_records, total_time) constrained_fitness = base_fitness * (PENALTY_FACTOR ** unmet_count) if unmet_count > 0: print( f" 警告:该个体有{unmet_count}个(任务-周期)对未满足12小时约束,适应度惩罚后:{constrained_fitness:.4f}") else: constrained_fitness = base_fitness return constrained_fitness, total_time def evaluate_population(self, population): fitness_list = [] total_time_list = [] for ind in population: fit, total_time = self.evaluate_individual(ind) fitness_list.append(fit) total_time_list.append(total_time) return fitness_list, total_time_list def select_parents(self, population, fitness): parents = [] for _ in range(POP_SIZE): candidates = random.sample(range(POP_SIZE), 3) winner = max(candidates, key=lambda i: fitness[i]) parents.append(population[winner]) return parents def crossover(self, parent1, parent2): size = len(parent1) forced_size = len(self.forced_tasks) start_forced, end_forced = sorted(random.sample(range(forced_size), 2)) if forced_size >= 2 else (0, 0) start_normal = forced_size end_normal = size - 1 start_normal_rand, end_normal_rand = sorted(random.sample(range(start_normal, end_normal + 1), 2)) if ( end_normal - start_normal + 1) >= 2 else ( start_normal, start_normal) child1 = [-1] * size child1[start_forced:end_forced + 1] = parent1[start_forced:end_forced + 1] child1[start_normal_rand:end_normal_rand + 1] = parent1[start_normal_rand:end_normal_rand + 1] idx = 0 for gene in parent2[:forced_size]: if gene not in child1[:forced_size] and idx < forced_size: while child1[idx] != -1: idx += 1 child1[idx] = gene idx = start_normal for gene in parent2[start_normal:]: if gene not in child1[start_normal:] and idx <= end_normal: while child1[idx] != -1: idx += 1 child1[idx] = gene child2 = [-1] * size child2[start_forced:end_forced + 1] = parent2[start_forced:end_forced + 1] child2[start_normal_rand:end_normal_rand + 1] = parent2[start_normal_rand:end_normal_rand + 1] idx = 0 for gene in parent1[:forced_size]: if gene not in child2[:forced_size] and idx < forced_size: while child2[idx] != -1: idx += 1 child2[idx] = gene idx = start_normal for gene in parent1[start_normal:]: if gene not in child2[start_normal:] and idx <= end_normal: while child2[idx] != -1: idx += 1 child2[idx] = gene return child1, child2 def mutate(self, individual): forced_size = len(self.forced_tasks) if len(individual) < 2: return individual if random.random() < 0.5 and forced_size >= 2: idx1, idx2 = random.sample(range(forced_size), 2) else: idx_range = range(forced_size, len(individual)) if (len(individual) - forced_size) >= 2 else range( len(individual)) idx1, idx2 = random.sample(idx_range, 2) individual[idx1], individual[idx2] = individual[idx2], individual[idx1] return individual def optimize(self): population = self.init_population() best_fitness_history = [] avg_fitness_history = [] current_gen_best_time_history = [] current_gen_avg_time_history = [] best_solution = None best_fitness = 0 best_total_time = float(&#39;inf&#39;) best_constraint_result = None for gen in range(MAX_GEN): fitness_list, total_time_list = self.evaluate_population(population) current_best_fit = max(fitness_list) current_avg_fit = sum(fitness_list) / POP_SIZE current_best_time = min(total_time_list) current_avg_time = sum(total_time_list) / POP_SIZE if current_best_fit > best_fitness: best_fitness = current_best_fit best_total_time = current_best_time best_solution = population[np.argmax(fitness_list)].copy() best_ship_tasks = self.decode_solution(best_solution) best_constraint_result, _ = check_cycle_constraint(best_ship_tasks, best_total_time) best_fitness_history.append(current_best_fit) avg_fitness_history.append(current_avg_fit) current_gen_best_time_history.append(current_best_time) current_gen_avg_time_history.append(current_avg_time) parents = self.select_parents(population, fitness_list) offspring = [] for i in range(0, POP_SIZE, 2): if i + 1 < POP_SIZE: p1, p2 = parents[i], parents[i + 1] if random.random() < CX_PROB: c1, c2 = self.crossover(p1, p2) else: c1, c2 = p1.copy(), p2.copy() offspring.append(c1) offspring.append(c2) offspring = [self.mutate(ind) for ind in offspring] elite_size = max(int(ELITE_RATIO * POP_SIZE), 1) elite_indices = np.argsort(fitness_list)[-elite_size:] for i in range(elite_size): offspring[i] = population[elite_indices[i]].copy() population = offspring if gen % 10 == 0: print(f"\nGeneration {gen}: " f"Best Time = {current_best_time:.2f}h, " f"Avg Time = {current_avg_time:.2f}h, " f"Best Fitness = {current_best_fit:.4f}") self.best_constraint_result = best_constraint_result return (best_solution, best_fitness, best_total_time, best_fitness_history, avg_fitness_history, current_gen_best_time_history, current_gen_avg_time_history) def decode_solution(self, solution): ship_times = [0.0] * self.num_ships ship_positions = [pos for pos in SHIP_START_POINTS] ship_tasks = [[] for _ in range(self.num_ships)] used_ships_for_forced = set() for task_id in solution: if task_id in self.forced_tasks: for ship_idx in range(self.num_ships): if ship_idx not in used_ships_for_forced: target_ship_idx = ship_idx used_ships_for_forced.add(ship_idx) break depart_time = 0.0 else: target_ship_idx = np.argmin(ship_times) depart_time = ship_times[target_ship_idx] ship_speed = SHIP_SPEEDS[target_ship_idx] depart_pos = ship_positions[target_ship_idx] task_start_pos = get_target_position(task_id, depart_time) if MOVING_TASKS[task_id] else TASK_LOCATIONS[ task_id] travel_dist = calc_distance(depart_pos, task_start_pos) travel_time = calc_travel_time(ship_speed, travel_dist) task_start_time = depart_time + travel_time depart_course = calc_course(depart_pos, task_start_pos) if TASK_TYPES[task_id] in [&#39;S2&#39;, &#39;S3&#39;]: # 修正:S2/S3任务需要追踪目标移动 # 计算航行时间 travel_dist = calc_distance(depart_pos, TASK_LOCATIONS[task_id]) travel_time = calc_travel_time(ship_speed, travel_dist) # 修正:计算追踪时间(目标移动指定距离所需时间) tracking_time = TASK_TRACKING_DIST[task_id] / MOVING_SPEEDS[task_id] # 修正:任务开始时间 = 出发时间 + 航行时间 task_start_time = depart_time + travel_time exit_time = calc_time_in_polygon(task_start_pos,MOVING_SPEEDS[task_id],MOVING_COURSES[task_id],EXIT_POLYGON) # 修正:任务结束时间 = 开始时间 + 追踪时间 task_end_time = task_start_time + tracking_time + exit_time # 到达任务点位置 task_start_pos = get_target_position(task_id, task_start_time) # 修正:任务结束位置 = 目标在结束时刻的位置 task_end_pos = get_target_position(task_id, task_end_time) # 修正:任务总耗时 = 航行时间 + 追踪时间 task_duration = travel_time + tracking_time + exit_time else: task_duration = TASK_DURATIONS[task_id] task_end_time = task_start_time + task_duration task_end_pos = get_target_position(task_id, task_end_time) is_required_cycle = task_id in REQUIRED_CYCLE_TASK_IDS task_detail = { "舰艇编号": target_ship_idx + 1, "任务编号": task_id, "任务类型": TASK_TYPES[task_id], "是否ABCD类任务": "是" if is_required_cycle else "否", "舰艇速度(节)": ship_speed, "舰艇出发时刻(小时)": round(depart_time, 2), "舰艇出发坐标(x,y)": depart_pos, # 航迹关键坐标1:舰艇出发位置 "舰艇出发航向(°)": depart_course, "处置任务开始时刻(小时)": round(task_start_time, 2), "处置任务开始坐标(x,y)": task_start_pos, # 航迹关键坐标2:任务开始位置 "处置任务结束时刻(小时)": round(task_end_time, 2), "处置任务结束坐标(x,y)": task_end_pos, # 航迹关键坐标3:任务结束位置 "任务结束后航向(°)": None, "任务耗时(小时)": round(task_duration, 2) } ship_tasks[target_ship_idx].append(task_detail) ship_times[target_ship_idx] = task_end_time ship_positions[target_ship_idx] = task_end_pos for ship_idx in range(self.num_ships): tasks = ship_tasks[ship_idx] num_tasks = len(tasks) for i in range(num_tasks): current_task = tasks[i] current_end_pos = current_task["处置任务结束坐标(x,y)"] if i == num_tasks - 1: end_course = calc_end_course_to_cruise(current_end_pos) else: next_task = tasks[i + 1] next_task_id = next_task["任务编号"] next_depart_time = current_task["处置任务结束时刻(小时)"] next_task_start_pos = get_target_position(next_task_id, next_depart_time) if MOVING_TASKS[ next_task_id] else TASK_LOCATIONS[next_task_id] end_course = calc_course(current_end_pos, next_task_start_pos) current_task["任务结束后航向(°)"] = end_course return ship_tasks # == == == == == 主程序(核心新增:舰艇航迹绘制) == == == == == if __name__ == "__main__": optimizer = GAOptimizer(num_ships=4) (best_sol, best_fit, best_total_time, best_fit_hist, avg_fit_hist, gen_best_time_hist, gen_avg_time_hist) = optimizer.optimize() # 输出结果(含约束检查结果) print("\n" + "=" * 80) print("优化完成!基础结果如下:") print(f"Excel总任务数: {TOTAL_TASKS_FROM_EXCEL}") print(f"需要12小时周期约束的ABCD类任务ID:{REQUIRED_CYCLE_TASK_IDS}") print(f"最佳任务序列: {best_sol}") print(f"历史最佳总完成时间: {best_total_time:.2f} 小时") print(f"历史最佳适应度: {best_fit:.4f}") print(f"巡航线闭合线圈顶点: {Cruise_line}") print("\n【ABCD类任务12小时周期约束检查结果】") if optimizer.best_constraint_result: for key, value in optimizer.best_constraint_result.items(): if isinstance(value, dict): print(f" {key}:") for task_key, task_value in value.items(): print(f" {task_key}:") for item in task_value: print(f" - {item}") else: print(f" {key}: {value}") print("=" * 80) # 导出Excel(含ABCD类任务标记) ship_tasks = optimizer.decode_solution(best_sol) all_tasks = [] for ship in ship_tasks: all_tasks.extend(ship) df = pd.DataFrame(all_tasks) column_order = [ "舰艇编号", "任务编号", "任务类型", "是否ABCD类任务", "舰艇速度(节)", "舰艇出发时刻(小时)", "舰艇出发坐标(x,y)", "舰艇出发航向(°)", "处置任务开始时刻(小时)", "处置任务开始坐标(x,y)", "处置任务结束时刻(小时)", "处置任务结束坐标(x,y)", "任务结束后航向(°)", "任务耗时(小时)" ] df = df[column_order] timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") excel_filename = f"第二问舰艇任务分配详情_含ABCD约束_{timestamp}.xlsx" try: with pd.ExcelWriter(excel_filename, engine="openpyxl") as writer: df.to_excel(writer, sheet_name="任务分配详情", index=False) if optimizer.best_constraint_result: constraint_data = [] for key, value in optimizer.best_constraint_result.items(): if isinstance(value, list) and key == "周期详情": for i, cycle in enumerate(value): constraint_data.append( {"约束项": "周期详情", "周期序号": i + 1, "周期范围": cycle, "备注": ""}) elif isinstance(value, dict) and key == "任务约束检查": for task_key, task_cycles in value.items(): task_id = task_key.split("(")[0] task_type = task_key.split("(")[1].replace("类)", "") for cycle_idx, cycle_check in enumerate(task_cycles): cycle_range = optimizer.best_constraint_result["周期详情"][cycle_idx] status = "已执行" if "✅" in cycle_check else "未执行" constraint_data.append({ "约束项": task_key, "周期序号": cycle_idx + 1, "周期范围": cycle_range, "执行状态": status, "备注": cycle_check.split(":")[1] }) else: constraint_data.append( {"约束项": key, "周期序号": "", "周期范围": "", "执行状态": "", "备注": value}) constraint_df = pd.DataFrame(constraint_data) constraint_df.to_excel(writer, sheet_name="ABCD类任务约束结果", index=False) print(f"\nExcel表格已生成:{excel_filename}") print(f"文件路径:{os.path.abspath(excel_filename)}") print(f"表格包含2个工作表:") print(f" 1. 任务分配详情:所有任务的执行信息(含是否ABCD类任务标记)") print(f" 2. ABCD类任务约束结果:12小时周期约束的详细检查结果") except Exception as e: print(f"\n导出Excel失败:{str(e)}") print("请确保已安装依赖库:pip install pandas openpyxl shapely") # -------------------------- 1. 绘制适应度图(保持) -------------------------- plt.figure(figsize=(12, 8)) plt.plot(best_fit_hist, label="最佳适应度(含约束惩罚)", color="#1f77b4", linewidth=2.5) plt.plot(avg_fit_hist, label="平均适应度(含约束惩罚)", color="#ff7f0e", linewidth=2.5) plt.xlabel("迭代次数", fontsize=20) plt.ylabel("适应度(总完成时间倒数+约束惩罚)", fontsize=20) plt.title("遗传算法迭代过程中适应度变化(含ABCD类任务12小时约束)", fontsize=24, pad=20) plt.legend(fontsize=18, loc="upper right") plt.grid(alpha=0.3, linestyle="--") plt.xticks(fontsize=16) plt.yticks(fontsize=16) plt.tight_layout() plt.show() # -------------------------- 2. 绘制完成时间图(保持) -------------------------- plt.figure(figsize=(12, 8)) plt.plot(gen_best_time_hist, label="每代最佳总完成时间", color="#2ca02c", linewidth=2.5) plt.plot(gen_avg_time_hist, label="每代平均总完成时间", color="#d62728", linewidth=2.5, linestyle="--") plt.axhline(y=best_total_time, color="#2ca02c", linestyle=":", linewidth=2, label=f"历史最佳总时间:{best_total_time:.2f}h") plt.xlabel("迭代次数", fontsize=20) plt.ylabel("总完成时间(小时)", fontsize=20) plt.title("遗传算法每代任务总完成时间变化", fontsize=24, pad=20) plt.legend(fontsize=18, loc="upper right") plt.grid(alpha=0.3, linestyle="--") plt.xticks(fontsize=16) plt.yticks(fontsize=16) last_gen = MAX_GEN - 1 plt.annotate( f&#39;历史最佳:{best_total_time:.2f}h&#39;, xy=(last_gen, best_total_time), xytext=(last_gen - 80, best_total_time + 2), fontsize=16, arrowprops=dict(arrowstyle="->", color="#2ca02c", lw=2) ) plt.tight_layout() plt.show() # -------------------------- 3. 绘制任务结束航向可视化(保持) -------------------------- plt.figure(figsize=(12, 10)) cruise_x = [p[0] for p in Cruise_line] + [Cruise_line[0][0]] cruise_y = [p[1] for p in Cruise_line] + [Cruise_line[0][1]] plt.plot(cruise_x, cruise_y, color="#1f77b4", linewidth=3, label="巡航线闭合线圈") plt.fill(cruise_x, cruise_y, color="#1f77b4", alpha=0.1) for task in all_tasks: end_x, end_y = task["处置任务结束坐标(x,y)"] end_course = task["任务结束后航向(°)"] ship_num = task["舰艇编号"] task_id = task["任务编号"] is_abcd = task["是否ABCD类任务"] scatter_color = "#d62728" if is_abcd == "是" else "#ff7f0e" plt.scatter(end_x, end_y, color=scatter_color, s=180, zorder=5, label="ABCD类任务" if is_abcd == "是" and "ABCD类任务" not in plt.gca().get_legend_handles_labels()[ 1] else "") arrow_len = 15 angle_rad = np.deg2rad(90 - end_course) dx = arrow_len * np.cos(angle_rad) dy = arrow_len * np.sin(angle_rad) plt.arrow(end_x, end_y, dx, dy, color=scatter_color, width=0.8, head_width=3, head_length=3, zorder=6) plt.text(end_x, end_y + 8, f"舰艇{ship_num}", color=scatter_color, fontsize=17, fontweight="bold", ha="center", va="center", zorder=7) plt.text(end_x, end_y - 8, f"任务{task_id}", color="black", fontsize=14, ha="center", va="center", zorder=7) plt.text(end_x + dx + 3, end_y + dy + 3, f"{end_course}°", color="#483D8B", fontsize=14, ha="center", va="center", zorder=7) plt.xlabel("X坐标", fontsize=20) plt.ylabel("Y坐标", fontsize=20) plt.title("任务结束后航向可视化(红色=ABCD类任务,橙色=其他任务)", fontsize=24, pad=20) plt.legend(fontsize=16, loc="upper left") plt.grid(alpha=0.3, linestyle="--") plt.axis("equal") plt.tight_layout() plt.show() # -------------------------- 4. 核心新增:绘制每艘舰艇的航迹图 -------------------------- plt.figure(figsize=(14, 12)) # 4.1 绘制背景元素(巡航线、任务区域边界) # 巡航线 cruise_x = [p[0] for p in Cruise_line] + [Cruise_line[0][0]] cruise_y = [p[1] for p in Cruise_line] + [Cruise_line[0][1]] plt.plot(cruise_x, cruise_y, color="#808080", linewidth=2, linestyle="--", label="巡航线") plt.fill(cruise_x, cruise_y, color="#808080", alpha=0.05) # 任务区域边界(EXIT_POLYGON) exit_x, exit_y = EXIT_POLYGON.exterior.xy plt.plot(exit_x, exit_y, color="#000000", linewidth=2.5, label="任务区域边界") # 4.2 为每艘舰艇提取航迹点并绘制 for ship_idx in range(4): # 遍历4艘舰艇 ship_task_list = ship_tasks[ship_idx] # 当前舰艇的所有任务 traj_config = SHIP_TRAJECTORY_CONFIG[ship_idx] # 当前舰艇的航迹样式配置 # 初始化航迹点列表(第一个点是舰艇初始位置) traj_points = [SHIP_START_POINTS[ship_idx]] # 遍历当前舰艇的每个任务,提取关键航迹点 for task in ship_task_list: # 航迹点顺序:舰艇出发位置 → 任务开始位置 → 任务结束位置 traj_points.append(task["舰艇出发坐标(x,y)"]) traj_points.append(task["处置任务开始坐标(x,y)"]) traj_points.append(task["处置任务结束坐标(x,y)"]) # 4.3 绘制航迹线(连接所有航迹点) traj_x = [p[0] for p in traj_points] traj_y = [p[1] for p in traj_points] plt.plot(traj_x, traj_y, color=traj_config["color"], linestyle=traj_config["line_style"], linewidth=3, label=traj_config["label"], zorder=3) # 4.4 标记关键节点(初始位置、任务开始/结束位置) # 标记初始位置(菱形,更大尺寸) init_x, init_y = traj_points[0] plt.scatter(init_x, init_y, color=traj_config["color"], marker=traj_config["init_marker"], s=300, edgecolor="#000000", linewidth=2, zorder=5) plt.text(init_x + 5, init_y + 5, f"{traj_config[&#39;label&#39;]}初始位置", color=traj_config["color"], fontsize=14, fontweight="bold", zorder=6) # 标记任务节点(任务开始+结束位置,用任务编号标注) task_idx = 0 for i in range(1, len(traj_points), 3): # 每3个点对应一个任务(出发→开始→结束) if task_idx >= len(ship_task_list): break current_task = ship_task_list[task_idx] task_id = current_task["任务编号"] is_abcd = current_task["是否ABCD类任务"] # 任务开始位置(空心标记) start_x, start_y = traj_points[i+1] plt.scatter(start_x, start_y, color=traj_config["color"], marker=traj_config["task_marker"], s=200, facecolor="none", edgecolor="#000000", linewidth=2, zorder=4) # 任务结束位置(实心标记,ABCD类任务用红色边框突出) end_x, end_y = traj_points[i+2] edge_color = "#d62728" if is_abcd == "是" else traj_config["color"] plt.scatter(end_x, end_y, color=traj_config["color"], marker=traj_config["task_marker"], s=200, edgecolor=edge_color, linewidth=2.5, zorder=4) # 标注任务编号(ABCD类任务用红色) text_color = "#d62728" if is_abcd == "是" else "#000000" plt.text(end_x + 5, end_y - 5, f"任务{task_id}", color=text_color, fontsize=12, fontweight="bold", zorder=6) task_idx += 1 # 4.5 图表格式设置 plt.xlabel("X坐标", fontsize=22) plt.ylabel("Y坐标", fontsize=22) plt.title("每艘舰艇航迹可视化(含初始位置、任务节点)", fontsize=26, pad=20) plt.legend(fontsize=16, loc="upper left") plt.grid(alpha=0.3, linestyle="--") plt.axis("equal") # 等比例坐标,确保航迹方向准确 plt.tight_layout() plt.show()纠正上述代码航迹图的绘制
最新发布
10-20
function main_plot() close all; clear; clc; %绘图 pronum = 5; plot_result(pronum); end %成果图:cdpro proname cdinj injname well nadaout function plot_result(pronum) %画井位,写井位名称 % cdpro = dlmread(&#39;out_cdpro&#39;); % cdinj = dlmread(&#39;out_cdinj&#39;); % [cdpro,procdname] = xlsread( &#39;coord_pro.xlsx&#39;); %cdpro(n,:)--第n口井xy坐标,procdname(1,2:end)列井名 % [cdinj,injcdname] = xlsread( &#39;coord_inj.xlsx&#39;);%cdinj(n,:)--第n口井xy坐标,injcdname(1,2:end)列井名 [proname, cdx, cdy] = textread(&#39;coord_pro.txt&#39;,&#39;%s %f %f&#39;); %cdpro(n,:)--第n口井xy坐标,procdname(1,:)列井名 fprintf(&#39;输出整数是: %f\n&#39;, cdx); fprintf(&#39;输出整数是: %f\n&#39;, cdy) cdpro = [cdx,cdy]; [injname cdx, cdy] = textread(&#39;coord_inj.txt&#39;,&#39;%s %f %f&#39;);%cdinj(n,:)--第n口井xy坐标,injcdname(1,2:end)列井名 cdinj = [cdx,cdy]; cdpro = vpa(cdpro); cdinj = vpa(cdinj); cdpro = subs(cdpro);cdinj = subs(cdinj); well = dlmread(&#39;out_well&#39;); nadaout = dlmread(&#39;out_nadaout&#39;); [num,txt]=xlsread(&#39;连通系数.xlsx&#39;,&#39;连通系数&#39;); % injname = txt(1,2:end)&#39;; % proname = txt(2:end,1); figure(100); plot((double(cdpro(:,1))),(double(cdpro(:,2))),&#39;ro&#39;,&#39;MarkerFaceColor&#39;,&#39;r&#39;,&#39;MarkerSize&#39;,5);hold on; text(double((cdpro(:,1))+5),double((cdpro(:,2))+5), proname&#39;,&#39;fontsize&#39;,8); hold on; plot((double(cdinj(:,1))),(double(cdinj(:,2))),&#39;bo&#39;,&#39;MarkerFaceColor&#39;,&#39;b&#39;,&#39;MarkerSize&#39;,5);hold on; text(double((cdinj(:,1))+5),double((cdinj(:,2))+5), injname&#39;,&#39;fontsize&#39;,8); hold on; %自动计算小三角形的高度 mindis = inf; for i=1:size(well,2) for j = 1:pronum if(nadaout(j,i) > 0) inj_pro_dis = norm(double(cdinj(i,:))-double(cdpro(well(j,i),:)))/nadaout(j,i); if (mindis > inj_pro_dis) mindis = inj_pro_dis; end end end end mindis = mindis; %计算得到的小三角形的高度置于变量mindis中 mindis = 1*mindis; %如果图像显示结果你感觉小三角形太短,可以使用这条语句加大mindis的值 mindis = 46; for i=1:size(well,2) plot_nada(cdinj(i,:),cdpro(well(1,i),:),nadaout(1,i),mindis);hold on; plot_nada(cdinj(i,:),cdpro(well(2,i),:),nadaout(2,i),mindis);hold on; plot_nada(cdinj(i,:),cdpro(well(3,i),:),nadaout(3,i),mindis);hold on; plot_nada(cdinj(i,:),cdpro(well(4,i),:),nadaout(4,i),mindis);hold on; plot_nada(cdinj(i,:),cdpro(well(5,i),:),nadaout(5,i),mindis);hold on; % plot_nada(cdinj(i,:),cdpro(well(6,i),:),nadaout(6,i),mindis);hold on; % plot_nada(cdinj(i,:),cdpro(well(7,i),:),nadaout(7,i),mindis);hold on; % plot_nada(cdinj(i,:),cdpro(well(8,i),:),nadaout(8,i),mindis);hold on; % plot_nada(cdinj(i,:),cdpro(well(9,i),:),nadaout(9,i),mindis);hold on; % plot_nada(cdinj(i,:),cdpro(well(10,i),:),nadaout(10,i),mindis);hold on; end %axis equal %axis([15355250 15364250 506100 506550]); %get(gca,&#39;ylim&#39;); get(gca,&#39;xlim&#39;) %axis square; print(gcf,&#39;-dpng&#39;,&#39;成果图.png&#39;); nadaout end % %注入点坐标,生产井坐标,连通系数(0-1),三角形高度(最小距离的一半) % function plot_nada(injpos,propos,nada,heigh) % if nada > 0.001 % % arf = propos(2) - propos(1) % % distmp = norm(injpos-propos); % fdk = nada*heigh/(distmp - nada*heigh); % B = (injpos + fdk*propos )/(1+fdk); % l = nada * heigh * tan(nada/2); % a = injpos(1); b = injpos(2); % m = B(1); n = B(2); % % C1x = m - l*(a-m)/sqrt((a - m)^2 + (b - n)^2); % C2x = m + l*(a-m)/sqrt((a - m)^2 + (b - n)^2);; % C1y = n - (b - n)*(C1x - m)/(a-m); % C2y = n - (b - n)*(C2x - m)/(a-m); % % fill([a C1x C2x a],[b C1y C2y b],&#39;r&#39;); % end % end %注入点坐标,生产井坐标,连通系数(0-1),三角形高度 function plot_nada(injpos,propos,nada,heigh) if(nada > 0.001) arf = atan((propos(2) - injpos(2))/(propos(1) - injpos(1))); if(arf > 0) if(propos(2) - injpos(2) < 0) arf = arf + pi; end end if(arf < 0) if(propos(2) - injpos(2) < 0) arf = arf + 2 * pi; else arf = arf + pi; end end darf = pi/60.0; %偏移180/27度,如果图像显示结果你觉得三角形角度太大,可以把27修改得更大 N2 = nada * heigh /cos(darf); %注水井到一个顶点的距离 x1 = injpos(1) + N2 * cos(arf + darf); y1 = injpos(2) + N2 * sin(arf + darf); x2 = injpos(1) + N2 * cos(arf - darf); y2 = injpos(2) + N2 * sin(arf - darf); fill([double(injpos(1)) double(x1) double(x2) double(injpos(1))],[double(injpos(2)) double(y1) double(y2) double(injpos(2))],&#39;r&#39;); end end 我是外行每一步详细解释我看不懂
07-02
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值