Excel应用_给成绩按比例划分ABCD等的几种方法

本文介绍了如何使用Excel公式根据分数比例将成绩划分为ABCD四个等级。第一种方法依据四分位数,分别计算A、B、C、D的比例。提供了多个不同的Excel公式实现。第二种方法设定固定分数线,135分及以上为A,120-134分为B,90-119分为C,89分以下为D。同样给出了多种实现公式的示例。
部署运行你感兴趣的模型镜像

        假如学生姓名存在a3:a762中,某科成绩存在g3:g762中,满分150分,四个等次的划分有两种分法:

        一、分数从高到低算,总人数的第一个四分之一为A,第二个四分之一为B,第三个四分之一为C,第四个四分之一为D,将等次填入到H列。

          有几个公式可以实现,下面只给出H3的公式,其他下拉即可。

          =LOOKUP(RANK(G3,G$3:G$762),COUNT($G:$G)*{0,0.25,0.5,0.75}+1,{"A","B","C","D"})

          =CHOOSE(MATCH(RANK(G3,G$3:G$762),COUNT($G:$G)*{0,0.25,0.5,0.75}+1),"A","B","C","D")

          =HLOOKUP(PERCENTRANK($G$3:$G$762,G3,2),{0,0.25,0.5,0.75;"D","C","B","A"},2)

          =IF(G3>PERCENTILE($G$3:$G$762,0.75),"A",IF(G3>PERCENTILE($G$3:$G$762,0.5),"B",IF(G3>PERCENTILE($G$3:$G$762,0.25),"C","D")))

          =CHAR(64+MATCH(RANK(G3,G$3:G$762),COUNT($G:$G)*{0,0.25,0.5,0.75}+1))

        二、分数大于等于150的0.9(135分及其以上)为A,小于150的0.9大于等于150的0.8(120分到134分)的为B,小于150的0.8大于等于150的0.6(90分到119分)的为C,小于150的0.6(89分及其以下)的为D,将等次填入J列。

         有几个公式可以实现,下面只给出J3的公式,其他下拉即可。

=LOOKUP(G3,150*{0,0.6,0.8,0.9},{"D","C","B","A"})

=VLOOKUP(G3,{0,"D";90,"C";120,"B";135,"A"},2)

=HLOOKUP(G3,{0,90,120,135;"D","C","B","A"},2)

=CHOOSE(MATCH(G3,150*{0,0.6,0.8,0.9}),"D","C","B","A")

=HLOOKUP(G3,CHOOSE({1;2},{0,90,120,135},{"D","C","B","A"}),2)

=IF(G3>=135,"优",IF(G3>=120,"好",IF(G3>=60,"中","差")))

您可能感兴趣的与本文相关的镜像

AutoGPT

AutoGPT

AI应用

AutoGPT于2023年3月30日由游戏公司Significant Gravitas Ltd.的创始人Toran Bruce Richards发布,AutoGPT是一个AI agent(智能体),也是开源的应用程序,结合了GPT-4和GPT-3.5技术,给定自然语言的目标,它将尝试通过将其分解成子任务,并在自动循环中使用互联网和其他工具来实现这一目标

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读取任务参数 -------------------------- EXCEL_PATH = "output.xlsx" 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文件缺少必需列:{', '.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] TASK_START_TIMES = task_df["时间"].astype(float).tolist() # 新增:任务开始时间 TOTAL_TASKS_FROM_EXCEL = len(TASK_TYPES) # 筛选必须执行的任务(S1, S2, S3)和可选任务(S4) REQUIRED_TASK_IDS = [ idx for idx, task_type in enumerate(TASK_TYPES) if task_type in ['S1', 'S2', 'S3'] ] OPTIONAL_TASK_IDS = [ idx for idx, task_type in enumerate(TASK_TYPES) if task_type == 'S4' ] print(f"成功从Excel读取{TOTAL_TASKS_FROM_EXCEL}个任务的参数") print(f"必须执行的任务(S1,S2,S3)ID:{REQUIRED_TASK_IDS}") print(f"可选执行的任务(S4)ID:{OPTIONAL_TASK_IDS}") if not REQUIRED_TASK_IDS: print("警告:未检测到必须执行的任务(S1,S2,S3)") except FileNotFoundError: raise FileNotFoundError(f"未找到Excel文件:{EXCEL_PATH},请检查文件路径是否正确") except Exception as e: raise Exception(f"读取Excel失败:{str(e)}") # -------------------------- 基础参数设置 -------------------------- plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = 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] # 处置数量 # 周期检查点(ABCD点) - 新增需求 CHECK_POINTS = { 'A': (187.05, 175.1), 'B': (168.65, 112.1), 'C': (50, 88.75), 'D': (73, 214.05) } CHECK_POINT_ORDER = ['A', 'B', 'C', 'D'] # 检查点顺序 CYCLE_DURATION = 12 # 约束周期:12小时 # 任务优先级和响应时间约束 - 新增需求 TASK_PRIORITIES = { 'S1': 1, # 最高优先级 'S2': 2, 'S3': 3, 'S4': 4 # 最低优先级 } MAX_RESPONSE_TIMES = { 'S1': 5, # 小时 'S2': 6, 'S3': 6, 'S4': 24 } # 算法参数 KNOTS_TO_KMH = 1 NAUTICAL_TO_KM = 1 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 check_checkpoint_constraint(ship_tasks, total_time): """检查每12小时必须经过ABCD点的约束""" cycles = get_time_cycles(total_time) constraint_result = { "总周期数": len(cycles), "周期详情": [f"{cycle[0]}-{cycle[1]}h" for cycle in cycles], "舰艇检查点检查": {} } unmet_count = 0 for ship_idx in range(len(ship_tasks)): ship_task_history = [] # 收集舰艇的所有位置和时间点 for task in ship_tasks[ship_idx]: ship_task_history.append({ "时间": task["舰艇出发出发时刻(小时)"], "位置": task["舰艇出发坐标(x,y)"] }) ship_task_history.append({ "时间": task["处置任务开始时刻(小时)"], "位置": task["处置置任务开始坐标(x,y)"] }) ship_task_history.append({ "时间": task["处置任务结束时刻(小时)"], "位置": task["处置任务结束坐标(x,y)"] }) # 按时间排序 ship_task_history.sort(key=lambda x: x["时间"]) cycle_check = [] for cycle_idx, (cycle_start, cycle_end) in enumerate(cycles): # 检查该周期内是否经过所有检查点 visited_checkpoints = set() # 检查任务历史中的点 for record in ship_task_history: if cycle_start <= record["时间"] < cycle_end: pos = record["位置"] # 检查是否接近任何检查点(考虑一定的误差范围) for cp_name, cp_pos in CHECK_POINTS.items(): distance = calc_distance(pos, cp_pos) if distance < 0.5: # 0.5单位范围内视为经过 visited_checkpoints.add(cp_name) # 检查是否经过所有检查点 if visited_checkpoints == set(CHECK_POINT_ORDER): cycle_check.append(f"周期{cycle_idx + 1}({cycle_start}-{cycle_end}h):已经过所有检查点✅") else: missing_points = set(CHECK_POINT_ORDER) - visited_checkpoints cycle_check.append(f"周期{cycle_idx + 1}({cycle_start}-{cycle_end}h):缺少检查点{missing_points}❌") unmet_count += 1 constraint_result["舰艇检查点检查"][f"舰艇{ship_idx + 1}"] = cycle_check constraint_result["约束状态"] = f"共{unmet_count}个(舰艇-周期)对未满足检查点约束" return constraint_result, unmet_count # == == == == == 新增:任务中断中断管理 == == == == == class TaskInterruptManager: """任务中断管理器""" @staticmethod def check_pending_tasks(current_time, ship_positions, ship_available_times): """ 检查是否有需要立即处理的高优先级任务 返回需要中断当前任务的新任务ID列表 """ pending_tasks = [] for task_id in range(TOTAL_TASKS_FROM_EXCEL): task_type = TASK_TYPES[task_id] task_start_time = TASK_START_TIMES[task_id] # 如果任务已经超过最大响应时间,需要立即处理 if current_time > task_start_time + MAX_RESPONSE_TIMES[task_type]: # 检查是否有舰艇可以更快到达 for ship_idx in range(len(ship_positions)): if ship_available_times[ship_idx] <= current_time: # 计算舰艇到达任务点的时间 target_pos = get_target_position(task_id, current_time) distance = calc_distance(ship_positions[ship_idx], target_pos) travel_time = calc_travel_time(SHIP_SPEEDS[ship_idx], distance) # 如果能在剩余响应时间内到达,则需要处理 if travel_time <= MAX_RESPONSE_TIMES[task_type]: pending_tasks.append({ "task_id": task_id, "task_type": task_type, "priority": TASK_PRIORITIES[task_type], "ship_idx": ship_idx, "urgency": (current_time - task_start_time) / MAX_RESPONSE_TIMES[task_type] }) # 按优先级和紧急程度排序 pending_tasks.sort(key=lambda x: (x["priority"], x["urgency"]), reverse=True) return pending_tasks @staticmethod def can_interrupt(current_task, new_task): """ 判断是否可以中断当前任务以执行新任务 当前任务是S4且新任务优先级更高时可以中断 """ if current_task is None: return True if current_task["任务类型"] == 'S4' and TASK_PRIORITIES[new_task["task_type"]] < TASK_PRIORITIES['S4']: return True return False # == == == == == 原有辅助函数(保持不变) == == == == == 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 # 非点类型交点视为无效 # 按轨迹顺序排序(确保进入点在前,离开点在后) intersections.sort(key=lambda p: math.hypot(p.x - init_x, p.y - init_y)) # 4. 取前两个交点计算距离(假设存在两个有效交点) if len(intersections) < 2: leave_point = intersections[0] distance = math.hypot(leave_point.x - init_x, leave_point.y - init_y) else: enter_point, leave_point = intersections[0], intersections[1] distance = math.hypot(init_x - leave_point.x, init_y - leave_point.y) return round(distance / speed, 6) # == == == == == 优先级调度算法核心 == == == == == class PriorityScheduler: def __init__(self, num_ships=4): self.num_ships = num_ships self.total_tasks = TOTAL_TASKS_FROM_EXCEL self.required_tasks = REQUIRED_TASK_IDS.copy() self.optional_tasks = OPTIONAL_TASK_IDS.copy() self.interrupt_manager = TaskInterruptManager() print(f"任务划分:必须执行任务{self.required_tasks},可选执行任务{self.optional_tasks}") print(f"任务优先级:S1(1) > S2(2) > S3(3) > S4(4)") print(f"最大响应时间:S1({MAX_RESPONSE_TIMES['S1']}h)、S2({MAX_RESPONSE_TIMES['S2']}h)、" f"S3({MAX_RESPONSE_TIMES['S3']}h)、S4({MAX_RESPONSE_TIMES['S4']}h)") print(f"周期检查点:每{CYCLE_DURATION}小时必须经过{CHECK_POINT_ORDER}点") def schedule_tasks(self): """ 基于优先级的任务调度算法 1. 按时间顺序处理任务 2. 高优先级任务优先分配 3. 支持任务中断 4. 满足响应时间约束 5. 满足周期检查点约束 """ # 舰艇状态初始化 ship_states = [] for i in range(self.num_ships): ship_states.append({ "position": SHIP_START_POINTS[i], "available_time": 0.0, "current_task": None, # 当前执行的任务(可能被中断) "completed_tasks": [], "interrupted_tasks": [], "checkpoint_history": [] }) # 任务执行记录 task_execution_records = [[] for _ in range(self.num_ships)] required_tasks_completed = set() optional_tasks_completed = set() current_time = 0.0 max_simulation_time = 100.0 # 最大模拟时间 # 创建任务事件队列(按开始时间排序) task_events = [] for task_id in range(TOTAL_TASKS_FROM_EXCEL): task_events.append({ "task_id": task_id, "task_type": TASK_TYPES[task_id], "priority": TASK_PRIORITIES[TASK_TYPES[task_id]], "start_time": TASK_START_TIMES[task_id], "is_required": task_id in self.required_tasks }) # 按开始时间和优先级排序 task_events.sort(key=lambda x: (x["start_time"], x["priority"])) # 主调度循环 while current_time < max_simulation_time: # 1. 检查是否有需要立即处理的紧急任务(响应时间即将超时) pending_tasks = self.interrupt_manager.check_pending_tasks( current_time, [state["position"] for state in ship_states], [state["available_time"] for state in ship_states] ) # 2. 处理紧急任务 for pending_task in pending_tasks: self.handle_emergency_task(pending_task, current_time, ship_states, task_execution_records, required_tasks_completed, optional_tasks_completed) # 3. 处理新到达的任务 new_tasks = [event for event in task_events if event["start_time"] <= current_time and event["task_id"] not in required_tasks_completed and event["task_id"] not in optional_tasks_completed and not any(state["current_task"] and state["current_task"]["任务编号"] == event["task_id"] for state in ship_states)] # 按优先级排序新任务 new_tasks.sort(key=lambda x: (x["priority"], x["start_time"])) # 分配新任务 for task_event in new_tasks: # 为任务找到最合适的舰艇 best_ship_idx = self.find_best_ship_for_task(task_event["task_id"], current_time, ship_states) if best_ship_idx is not None: # 检查是否需要中断当前任务 if ship_states[best_ship_idx]["current_task"] is not None: current_task = ship_states[best_ship_idx]["current_task"] if self.interrupt_manager.can_interrupt(current_task, task_event): # 中断当前任务 self.interrupt_current_task(best_ship_idx, current_time, ship_states, task_execution_records) # 分配新任务 if ship_states[best_ship_idx]["current_task"] is None: self.assign_task(best_ship_idx, task_event["task_id"], current_time, ship_states, task_execution_records, required_tasks_completed, optional_tasks_completed) # 4. 检查周期性检查点 self.check_periodic_checkpoints(current_time, ship_states) # 5. 更新时间 next_event_time = self.get_next_event_time(ship_states, task_events, current_time, max_simulation_time) if next_event_time == current_time: break # 没有更多事件 # 6. 处理在时间推进过程中完成的任务 self.process_completed_tasks(current_time, next_event_time, ship_states, task_execution_records, required_tasks_completed, optional_tasks_completed) current_time = next_event_time # 计算调度结果指标 metrics = self.calculate_metrics(required_tasks_completed, optional_tasks_completed, task_execution_records, current_time) return task_execution_records, metrics def handle_emergency_task(self, emergency_task, current_time, ship_states, task_execution_records, required_tasks_completed, optional_tasks_completed): """处理紧急任务""" ship_idx = emergency_task["ship_idx"] task_id = emergency_task["task_id"] # 如果舰艇正在执行任务,检查是否可以中断 if ship_states[ship_idx]["current_task"] is not None: current_task = ship_states[ship_idx]["current_task"] if self.interrupt_manager.can_interrupt(current_task, emergency_task): # 中断当前任务 self.interrupt_current_task(ship_idx, current_time, ship_states, task_execution_records) # 分配紧急任务 if ship_states[ship_idx]["current_task"] is None: self.assign_task(ship_idx, task_id, current_time, ship_states, task_execution_records, required_tasks_completed, optional_tasks_completed) def interrupt_current_task(self, ship_idx, current_time, ship_states, task_execution_records): """中断当前任务""" current_task = ship_states[ship_idx]["current_task"] if current_task is None: return # 更新任务状态 current_task["任务状态"] = "已中断" current_task["实际结束时刻(小时)"] = current_time current_task["已完成时间比例"] = (current_time - current_task["处置任务开始时刻(小时)"]) / current_task[ "任务耗时(小时)"] # 记录中断的任务 ship_states[ship_idx]["interrupted_tasks"].append(current_task) # 更新舰艇状态 ship_states[ship_idx]["current_task"] = None ship_states[ship_idx]["available_time"] = current_time def find_best_ship_for_task(self, task_id, current_time, ship_states): """为任务找到最合适的舰艇""" task_type = TASK_TYPES[task_id] task_start_time = TASK_START_TIMES[task_id] best_ship_idx = None best_score = float('inf') for ship_idx in range(self.num_ships): state = ship_states[ship_idx] # 如果舰艇不可用,跳过 if state["available_time"] > current_time + MAX_RESPONSE_TIMES[task_type]: continue # 计算舰艇到达任务点的时间 target_pos = get_target_position(task_id, max(current_time, state["available_time"])) distance = calc_distance(state["position"], target_pos) travel_time = calc_travel_time(SHIP_SPEEDS[ship_idx], distance) # 计算响应时间 actual_start_time = max(current_time, state["available_time"]) + travel_time response_time = actual_start_time - task_start_time # 如果超过最大响应时间,跳过 if response_time > MAX_RESPONSE_TIMES[task_type]: continue # 计算评分(考虑响应时间、舰艇优先级等) score = response_time * TASK_PRIORITIES[task_type] if score < best_score: best_score = score best_ship_idx = ship_idx return best_ship_idx def assign_task(self, ship_idx, task_id, current_time, ship_states, task_execution_records, required_tasks_completed, optional_tasks_completed): """分配任务给舰艇""" state = ship_states[ship_idx] task_type = TASK_TYPES[task_id] task_start_time = TASK_START_TIMES[task_id] # 计算出发时间(舰艇可用时间和任务开始时间的最大值) depart_time = max(current_time, state["available_time"], task_start_time) # 计算航行时间和任务开始时间 ship_speed = SHIP_SPEEDS[ship_idx] depart_pos = state["position"] target_pos = get_target_position(task_id, depart_time) distance = calc_distance(depart_pos, target_pos) travel_time = calc_travel_time(ship_speed, distance) task_start_time_actual = depart_time + travel_time # 计算响应时间 response_time = task_start_time_actual - task_start_time # 如果超过最大响应时间,不分配(仅对必须执行的任务) if task_type in ['S1', 'S2', 'S3'] and response_time > MAX_RESPONSE_TIMES[task_type]: return False # 计算任务执行时间 if task_type in ['S2', 'S3']: # 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_actual = depart_time + travel_time exit_time = calc_time_in_polygon(target_pos, MOVING_SPEEDS[task_id], MOVING_COURSES[task_id], EXIT_POLYGON) # 任务结束时间 = 开始时间 + 追踪时间 task_end_time = task_start_time_actual + exit_time - travel_time # 到达任务点位置 task_start_pos = get_target_position(task_id, task_start_time_actual) # 任务结束位置 = 目标在结束时刻的位置 task_end_pos = get_target_position(task_id, task_end_time) # 任务总耗时 task_duration = exit_time - task_start_time_actual else: # S1/S4任务 task_duration = TASK_DURATIONS[task_id] task_end_time = task_start_time_actual + task_duration task_start_pos = target_pos task_end_pos = get_target_position(task_id, task_end_time) # 创建任务详情 task_detail = { "舰艇编号": ship_idx + 1, "任务编号": task_id, "任务类型": task_type, "任务优先级": TASK_PRIORITIES[task_type], "最大响应时间": MAX_RESPONSE_TIMES[task_type], "实际响应时间": round(response_time, 2), "舰艇速度(节)": ship_speed, "舰艇出发时刻(小时)": round(depart_time, 2), "舰艇出发坐标(x,y)": depart_pos, "舰艇出发航向(°)": calc_course(depart_pos, task_start_pos), "处置任务开始时刻(小时)": round(task_start_time_actual, 2), "处置任务开始坐标(x,y)": task_start_pos, "处置任务结束时刻(小时)": round(task_end_time, 2), "处置任务结束坐标(x,y)": task_end_pos, "任务结束后航向(°)": None, "任务耗时(小时)": round(task_duration, 2), "任务状态": "执行中" } # 更新舰艇状态 state["current_task"] = task_detail state["available_time"] = task_end_time # 添加到执行记录 task_execution_records[ship_idx].append(task_detail) return True def check_periodic_checkpoints(self, current_time, ship_states): """检查周期性检查点""" # 检查是否需要前往检查点 for ship_idx in range(self.num_ships): state = ship_states[ship_idx] # 如果舰艇当前没有任务且不在检查点附近 if state["current_task"] is None: current_cycle = int(current_time / CYCLE_DURATION) next_checkpoint_time = (current_cycle + 1) * CYCLE_DURATION # 检查是否需要前往下一个检查点 time_until_next_checkpoint = next_checkpoint_time - current_time if time_until_next_checkpoint < 1.0: # 1小时内需要到达检查点 # 找到最近的检查点 closest_cp = None min_distance = float('inf') for cp_name, cp_pos in CHECK_POINTS.items(): distance = calc_distance(state["position"], cp_pos) if distance < min_distance: min_distance = distance closest_cp = cp_name # 如果距离检查点较远,规划前往检查点的任务 if min_distance > 1.0: # 距离超过1单位 travel_time = calc_travel_time(SHIP_SPEEDS[ship_idx], min_distance) if travel_time <= time_until_next_checkpoint: # 创建前往检查点的任务 checkpoint_task = { "舰艇编号": ship_idx + 1, "任务编号": -1, # 特殊任务编号 "任务类型": "检查点任务", "任务优先级": 5, # 低于所有其他任务 "最大响应时间": time_until_next_checkpoint, "实际响应时间": 0, "舰艇速度(节)": SHIP_SPEEDS[ship_idx], "舰艇出发时刻(小时)": round(current_time, 2), "舰艇出发坐标(x,y)": state["position"], "舰艇出发航向(°)": calc_course(state["position"], CHECK_POINTS[closest_cp]), "处置任务开始时刻(小时)": round(current_time, 2), "处置任务开始坐标(x,y)": state["position"], "处置任务结束时刻(小时)": round(current_time + travel_time, 2), "处置任务结束坐标(x,y)": CHECK_POINTS[closest_cp], "任务结束后航向(°)": None, "任务耗时(小时)": round(travel_time, 2), "任务状态": "执行中" } # 更新舰艇状态 state["current_task"] = checkpoint_task state["available_time"] = current_time + travel_time def get_next_event_time(self, ship_states, task_events, current_time, max_simulation_time): """获取下一个事件的时间""" # 舰艇可用时间 ship_available_times = [state["available_time"] for state in ship_states] # 未处理任务的开始时间 unprocessed_task_times = [] for event in task_events: task_id = event["task_id"] # 检查任务是否已经完成或正在执行 task_completed = any(task_id in state["completed_tasks"] for state in ship_states) task_running = any(state["current_task"] and state["current_task"]["任务编号"] == task_id for state in ship_states) if not task_completed and not task_running and event["start_time"] > current_time: unprocessed_task_times.append(event["start_time"]) # 周期检查点时间 next_cycle_start = ((int(current_time / CYCLE_DURATION) + 1) * CYCLE_DURATION) # 所有可能的事件时间 all_event_times = ship_available_times + unprocessed_task_times + [next_cycle_start, max_simulation_time] # 找到最近的事件时间 next_event_time = min([t for t in all_event_times if t > current_time]) return next_event_time def process_completed_tasks(self, current_time, next_event_time, ship_states, task_execution_records, required_tasks_completed, optional_tasks_completed): """处理在时间推进过程中完成的任务""" for ship_idx in range(self.num_ships): state = ship_states[ship_idx] # 如果舰艇有当前任务且任务在这个时间段内完成 if state["current_task"] is not None: task_end_time = state["current_task"]["处置任务结束时刻(小时)"] if current_time < task_end_time <= next_event_time: # 任务完成 current_task = state["current_task"] current_task["任务状态"] = "已完成" # 更新任务完成状态 task_id = current_task["任务编号"] if task_id != -1: # 不是检查点任务 task_type = TASK_TYPES[task_id] if task_type in ['S1', 'S2', 'S3']: required_tasks_completed.add(task_id) elif task_type == 'S4': optional_tasks_completed.add(task_id) # 记录完成的任务 state["completed_tasks"].append(task_id) # 更新舰艇状态 state["position"] = current_task["处置任务结束坐标(x,y)"] state["current_task"] = None state["available_time"] = task_end_time def calculate_metrics(self, required_tasks_completed, optional_tasks_completed, task_execution_records, total_time): """计算调度结果指标""" # 1. 必须执行的任务是否全部完成 required_all_completed = len(required_tasks_completed) == len(self.required_tasks) # 2. S4任务完成数量 s4_completed = len([t for t in optional_tasks_completed if TASK_TYPES[t] == 'S4']) # 3. 检查约束 checkpoint_constraint_result, unmet_checkpoint_count = check_checkpoint_constraint(task_execution_records, total_time) # 4. 响应时间约束检查 response_time_violations = 0 for task_id in required_tasks_completed: task_type = TASK_TYPES[task_id] task_start_time = TASK_START_TIMES[task_id] # 找到任务的执行记录 for ship_tasks in task_execution_records: for task in ship_tasks: if task["任务编号"] == task_id: actual_start_time = task["处置任务开始时刻(小时)"] response_time = actual_start_time - task_start_time if response_time > MAX_RESPONSE_TIMES[task_type]: response_time_violations += 1 break else: continue break # 5. 计算适应度(S4任务完成数量) if not required_all_completed: fitness = 0.0 else: # 基础适应度 = S4任务完成数量 base_fitness = s4_completed # 约束惩罚 constraint_penalty = (PENALTY_FACTOR ** (unmet_checkpoint_count + response_time_violations)) # 最终适应度 fitness = base_fitness * constraint_penalty return { "fitness": fitness, "s4_completed": s4_completed, "required_completed": len(required_tasks_completed), "required_total": len(self.required_tasks), "checkpoint_violations": unmet_checkpoint_count, "response_time_violations": response_time_violations, "total_time": total_time, "checkpoint_constraint_result": checkpoint_constraint_result } def decode_schedule(self, task_execution_records): """解码调度计划,生成详细的任务执行记录""" # 完成所有任务后更新航向 for ship_idx in range(self.num_ships): tasks = task_execution_records[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] if next_task["任务编号"] == -1: # 检查点任务 end_course = calc_course(current_end_pos, next_task["处置任务开始坐标(x,y)"]) else: 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 task_execution_records # == == == == == 主程序== == == == == if __name__ == "__main__": # 创建优先级调度器 scheduler = PriorityScheduler(num_ships=4) # 执行调度 print("\n开始优先级调度...") ship_tasks, metrics = scheduler.schedule_tasks() # 解码调度计划 ship_tasks = scheduler.decode_schedule(ship_tasks) # 统计任务完成情况 required_completed = metrics["required_completed"] required_total = metrics["required_total"] s4_completed = metrics["s4_completed"] s4_total = len(OPTIONAL_TASK_IDS) # 输出结果 print("\n" + "=" * 80) print("优先级调度完成!") print(f"Excel总任务数: {TOTAL_TASKS_FROM_EXCEL}") print(f"必须执行任务(S1,S2,S3):{required_completed}/{required_total}") print(f"可选执行任务(S4):{s4_completed}/{s4_total}") print(f"最佳适应度: {metrics['fitness']:.2f}") print(f"检查点约束违反次数: {metrics['checkpoint_violations']}") print(f"响应时间约束违反次数: {metrics['response_time_violations']}") print(f"总完成时间: {metrics['total_time']:.2f} 小时") print("=" * 80) # 输出检查点约束详细结果 print("\n【周期检查点约束检查结果】") if metrics["checkpoint_constraint_result"]: for key, value in metrics["checkpoint_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 all_tasks = [] for ship in ship_tasks: all_tasks.extend(ship) if all_tasks: df = pd.DataFrame(all_tasks) column_order = [ "舰艇编号", "任务编号", "任务类型", "任务优先级", "最大响应时间", "实际响应时间", "舰艇速度(节)", "舰艇出发时刻(小时)", "舰艇出发坐标(x,y)", "舰艇出发航向(°)", "处置任务开始时刻(小时)", "处置任务开始坐标(x,y)", "处置任务结束时刻(小时)", "处置任务结束坐标(x,y)", "任务结束后航向(°)", "任务耗时(小时)", "任务状态" ] # 确保所有列都存在 for col in column_order: if col not in df.columns: df[col] = None df = df[column_order] timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") excel_filename = f"优先级调度舰艇任务分配详情_{timestamp}.xlsx" try: with pd.ExcelWriter(excel_filename, engine="openpyxl") as writer: # 任务分配详情 df.to_excel(writer, sheet_name="任务分配详情", index=False) # 任务完成统计 stats_data = [ {"统计项目": "总任务数", "数值": TOTAL_TASKS_FROM_EXCEL}, {"统计项目": "必须执行任务数(S1,S2,S3)", "数值": len(REQUIRED_TASK_IDS)}, {"统计项目": "必须执行任务完成数", "数值": required_completed}, {"统计项目": "可选任务数(S4)", "数值": len(OPTIONAL_TASK_IDS)}, {"统计项目": "可选任务完成数(S4)", "数值": s4_completed}, {"统计项目": "S4任务完成率", "数值": f"{s4_completed / len(OPTIONAL_TASK_IDS) * 100:.1f}%" if OPTIONAL_TASK_IDS else "0%"}, {"统计项目": "总完成时间(小时)", "数值": round(metrics["total_time"], 2)}, {"统计项目": "检查点约束违反次数", "数值": metrics["checkpoint_violations"]}, {"统计项目": "响应时间约束违反次数", "数值": metrics["response_time_violations"]} ] stats_df = pd.DataFrame(stats_data) stats_df.to_excel(writer, sheet_name="任务完成统计", index=False) # 检查点约束结果 if metrics["checkpoint_constraint_result"]: constraint_data = [] for key, value in metrics["checkpoint_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 ship_key, ship_cycles in value.items(): for cycle_idx, cycle_check in enumerate(ship_cycles): cycle_range = metrics["checkpoint_constraint_result"]["周期详情"][cycle_idx] status = "已满足" if "✅" in cycle_check else "未满足" constraint_data.append({ "约束项": ship_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="检查点约束结果", index=False) print(f"\nExcel表格已生成:{excel_filename}") print(f"文件路径:{os.path.abspath(excel_filename)}") print(f"表格包含3个工作表:") print(f" 1. 任务分配详情:所有任务的执行信息") print(f" 2. 任务完成统计:任务完成情况汇总") print(f" 3. 检查点约束结果:周期检查点约束的详细检查结果") except Exception as e: print(f"\n导出Excel失败:{str(e)}") print("请确保已安装依赖库:pip install pandas openpyxl shapely") # 绘制任务执行甘特图 plt.figure(figsize=(15, 8)) colors = {'S1': '#ff4444', 'S2': '#ff8800', 'S3': '#ffcc00', 'S4': '#00cc44', '检查点任务': '#8888ff'} y_positions = range(1, len(ship_tasks) + 1) for i, (ship_idx, tasks) in enumerate(zip(y_positions, ship_tasks)): for task in tasks: start_time = task["处置任务开始时刻(小时)"] duration = task["任务耗时(小时)"] task_type = task["任务类型"] task_id = task["任务编号"] # 检查点任务特殊处理 if task_type == "检查点任务": label = "检查点" else: label = f'{task_type}-{task_id}' if task_id != -1 else "检查点" plt.barh(ship_idx, duration, left=start_time, color=colors.get(task_type, '#888888'), alpha=0.7, height=0.6) # 添加任务标签 plt.text(start_time + duration / 2, ship_idx, label, ha='center', va='center', fontsize=8, fontweight='bold') # 添加检查点垂直线 cycles = get_time_cycles(metrics["total_time"]) for cycle_start, cycle_end in cycles: plt.axvline(x=cycle_start, color='gray', linestyle='--', alpha=0.5) plt.text(cycle_start, len(ship_tasks) + 0.5, f'周期{int(cycle_start / 12) + 1}开始', rotation=90, ha='center', va='bottom', fontsize=8, color='gray') plt.yticks(y_positions, [f'舰艇{i}' for i in range(1, len(ship_tasks) + 1)]) plt.xlabel('时间(小时)') plt.ylabel('舰艇编号') plt.title('舰艇任务执行甘特图') plt.grid(True, alpha=0.3) # 添加图例 legend_elements = [plt.Rectangle((0, 0), 1, 1, color=color, alpha=0.7, label=task_type) for task_type, color in colors.items()] plt.legend(handles=legend_elements, loc='upper right') plt.tight_layout() plt.savefig(f'task_gantt_chart_{timestamp}.png', dpi=300, bbox_inches='tight') plt.close() print(f"任务执行甘特图已保存:task_gantt_chart_{timestamp}.png") print("\n所有结果文件已生成完成!") 纠正上述代码
最新发布
10-21
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值