Algorithms—75.Sort Colors

思路:从左开始查看,找到非0数,标记,从右开始查看,查看到0,标记,交换,然后从左标记开始继续,以此类推,可使得所有的0集中在数组的左端,同理可得答案。

public class Solution {
    public void sortColors(int[] nums) {
	int t=0;
	int b=0;
	int e=nums.length-1;
	boolean flag=true;
    for (int i = 0; i < nums.length; i++) {
			if (flag) {
				if (nums[b]!=0) {
					t=b;
					flag=false;
				}else {
					t++;
				}
				b++;
			}else {
				if (nums[e]==0) {
					nums[e]=nums[t];
					nums[t]=0;
					flag=true;
					t++;
				}
				e--;
			}
	}
	b=t;
	e=nums.length-1;
	flag=true;
	 for (int i = t; i < nums.length; i++) {
			if (flag) {
				if (nums[b]!=1) {
					t=b;
					flag=false;
				}
				b++;
			}else {
				if (nums[e]==1) {
					nums[e]=nums[t];
					nums[t]=1;
					flag=true;
				}
				e--;
			}
	}
    
        
    }
}


import matplotlib.pyplot as plt import matplotlib.patches as patches from matplotlib import font_manager import numpy as np from typing import List, Dict, Tuple import heapq class Process: """进程类""" def __init__(self, pid: int, arrive_time: int, burst_time: int): self.pid = pid # 进程ID self.arrive_time = arrive_time # 到达时间 self.burst_time = burst_time # 运行时间 self.remaining_time = burst_time # 剩余运行时间(用于RR算法) self.start_time = -1 # 开始时间 self.finish_time = -1 # 完成时间 self.wait_time = 0 # 等待时间 self.turnaround_time = 0 # 周转时间 def __lt__(self, other): """用于优先队列比较""" return self.burst_time < other.burst_time class Scheduler: """调度器基类""" def __init__(self): self.timeline = [] # 甘特图时间线 self.current_time = 0 def schedule(self, processes: List[Process]) -> Dict: """调度方法,子类需要重写""" pass def calculate_metrics(self, processes: List[Process]) -> Tuple[float, float]: """计算平均等待时间和平均周转时间""" total_wait = sum(p.wait_time for p in processes) total_turnaround = sum(p.turnaround_time for p in processes) avg_wait = total_wait / len(processes) avg_turnaround = total_turnaround / len(processes) return avg_wait, avg_turnaround class FCFSScheduler(Scheduler): """先来先服务调度算法""" def schedule(self, processes: List[Process]) -> Dict: # 按到达时间排序 sorted_processes = sorted(processes, key=lambda x: x.arrive_time) self.current_time = 0 self.timeline = [] for process in sorted_processes: # 如果当前时间小于进程到达时间,等待进程到达 if self.current_time < process.arrive_time: self.current_time = process.arrive_time process.start_time = self.current_time process.wait_time = self.current_time - process.arrive_time # 记录时间线 self.timeline.append((process.pid, self.current_time, self.current_time + process.burst_time)) self.current_time += process.burst_time process.finish_time = self.current_time process.turnaround_time = process.finish_time - process.arrive_time return { 'timeline': self.timeline, 'avg_wait': self.calculate_metrics(sorted_processes)[0], 'avg_turnaround': self.calculate_metrics(sorted_processes)[1] } class SJFScheduler(Scheduler): """短作业优先调度算法(非抢占式)""" def schedule(self, processes: List[Process]) -> Dict: processes_copy = [Process(p.pid, p.arrive_time, p.burst_time) for p in processes] processes_copy.sort(key=lambda x: x.arrive_time) self.current_time = 0 self.timeline = [] completed = 0 n = len(processes_copy) completed_processes = [False] * n ready_queue = [] while completed < n: # 将已到达但未完成的进程加入就绪队列 for i in range(n): if not completed_processes[i] and processes_copy[i].arrive_time <= self.current_time: heapq.heappush(ready_queue, (processes_copy[i].burst_time, i, processes_copy[i])) if ready_queue: # 选择最短作业 _, idx, process = heapq.heappop(ready_queue) completed_processes[idx] = True process.start_time = self.current_time process.wait_time = self.current_time - process.arrive_time # 记录时间线 self.timeline.append((process.pid, self.current_time, self.current_time + process.burst_time)) self.current_time += process.burst_time process.finish_time = self.current_time process.turnaround_time = process.finish_time - process.arrive_time completed += 1 # 清空就绪队列,因为时间已经推进,需要重新检查到达的进程 ready_queue = [] else: # 如果没有就绪进程,时间推进到下一个进程到达 next_arrival = min([p.arrive_time for i, p in enumerate(processes_copy) if not completed_processes[i]]) self.current_time = next_arrival return { 'timeline': self.timeline, 'avg_wait': self.calculate_metrics(processes_copy)[0], 'avg_turnaround': self.calculate_metrics(processes_copy)[1] } class RRScheduler(Scheduler): """时间片轮转调度算法""" def __init__(self, time_quantum: int = 2): super().__init__() self.time_quantum = time_quantum def schedule(self, processes: List[Process]) -> Dict: processes_copy = [Process(p.pid, p.arrive_time, p.burst_time) for p in processes] processes_copy.sort(key=lambda x: x.arrive_time) self.current_time = 0 self.timeline = [] ready_queue = [] n = len(processes_copy) completed = 0 i = 0 # 初始化,将到达时间为0的进程加入就绪队列 while i < n and processes_copy[i].arrive_time <= self.current_time: ready_queue.append(processes_copy[i]) i += 1 while completed < n: if ready_queue: process = ready_queue.pop(0) if process.start_time == -1: process.start_time = self.current_time # 执行一个时间片或剩余时间(取较小值) execution_time = min(self.time_quantum, process.remaining_time) start_time = self.current_time # 记录时间线 self.timeline.append((process.pid, start_time, start_time + execution_time)) self.current_time += execution_time process.remaining_time -= execution_time # 将在此期间到达的新进程加入就绪队列 while i < n and processes_copy[i].arrive_time <= self.current_time: ready_queue.append(processes_copy[i]) i += 1 if process.remaining_time > 0: # 进程未完成,重新加入就绪队列 ready_queue.append(process) else: # 进程完成 completed += 1 process.finish_time = self.current_time process.turnaround_time = process.finish_time - process.arrive_time process.wait_time = process.turnaround_time - process.burst_time else: # 没有就绪进程,时间推进到下一个进程到达 if i < n: self.current_time = processes_copy[i].arrive_time while i < n and processes_copy[i].arrive_time <= self.current_time: ready_queue.append(processes_copy[i]) i += 1 else: break return { 'timeline': self.timeline, 'avg_wait': self.calculate_metrics(processes_copy)[0], 'avg_turnaround': self.calculate_metrics(processes_copy)[1] } class ProcessSchedulerSimulator: """进程调度模拟器""" def __init__(self): self.processes = [] self.schedulers = { 'FCFS': FCFSScheduler(), 'SJF': SJFScheduler(), 'RR': RRScheduler(time_quantum=2) } def add_process(self, pid: int, arrive_time: int, burst_time: int): """添加进程""" self.processes.append(Process(pid, arrive_time, burst_time)) def input_processes(self): """手动输入进程信息""" self.processes = [] print("请输入进程信息(输入-1结束):") pid = 0 while True: try: arrive_time = int(input(f"进程{pid}的到达时间(-1结束):")) if arrive_time == -1: break burst_time = int(input(f"进程{pid}的运行时间:")) if burst_time <= 0: print("运行时间必须大于0!") continue self.add_process(pid, arrive_time, burst_time) pid += 1 except ValueError: print("请输入有效数字!") def run_scheduler(self, algorithm: str) -> Dict: """运行指定的调度算法""" if algorithm not in self.schedulers: raise ValueError(f"不支持的调度算法: {algorithm}") if not self.processes: raise ValueError("没有可调度的进程!") scheduler = self.schedulers[algorithm] return scheduler.schedule(self.processes) def print_results(self, results: Dict, algorithm: str): """打印调度结果""" print(f"\n{algorithm}调度算法结果:") print("=" * 50) print("调度顺序甘特图:") # 打印甘特图 for pid, start, end in results['timeline']: print(f"P{pid}: [{start}-{end}]", end=" ") print() print(f"\n平均等待时间: {results['avg_wait']:.2f}") print(f"平均周转时间: {results['avg_turnaround']:.2f}") print("=" * 50) def plot_gantt_chart(self, results: Dict, algorithm: str): """绘制甘特图""" fig, ax = plt.subplots(figsize=(12, 6)) # 为每个进程分配颜色 colors = plt.cm.Set3(np.linspace(0, 1, len(self.processes))) color_map = {p.pid: colors[i % len(colors)] for i, p in enumerate(self.processes)} # 绘制时间条 y_pos = 0 for pid, start, end in results['timeline']: duration = end - start ax.barh(y_pos, duration, left=start, height=0.6, color=color_map[pid], edgecolor='black', alpha=0.7) # 添加文本 ax.text(start + duration/2, y_pos, f'P{pid}', ha='center', va='center', fontweight='bold') y_pos += 1 ax.set_xlabel('时间') ax.set_ylabel('进程') ax.set_title(f'{algorithm}调度算法 - 甘特图') ax.set_yticks(range(len(results['timeline']))) ax.set_yticklabels([f'时间段{i+1}' for i in range(len(results['timeline']))]) ax.grid(True, alpha=0.3) plt.tight_layout() plt.show() def compare_algorithms(self): """比较不同算法的性能""" algorithms = ['FCFS', 'SJF', 'RR'] wait_times = [] turnaround_times = [] print("\n算法性能比较:") print("=" * 60) print(f"{'算法':<10} {'平均等待时间':<15} {'平均周转时间':<15}") print("-" * 60) for algo in algorithms: try: results = self.run_scheduler(algo) wait_times.append(results['avg_wait']) turnaround_times.append(results['avg_turnaround']) print(f"{algo:<10} {results['avg_wait']:<15.2f} {results['avg_turnaround']:<15.2f}") except Exception as e: print(f"{algo:<10} 错误: {e}") # 绘制比较图 if wait_times and turnaround_times: fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5)) x = range(len(algorithms)) ax1.bar(x, wait_times, color=['skyblue', 'lightgreen', 'lightcoral']) ax1.set_title('平均等待时间比较') ax1.set_xticks(x) ax1.set_xticklabels(algorithms) ax1.set_ylabel('时间') ax2.bar(x, turnaround_times, color=['skyblue', 'lightgreen', 'lightcoral']) ax2.set_title('平均周转时间比较') ax2.set_xticks(x) ax2.set_xticklabels(algorithms) ax2.set_ylabel('时间') plt.tight_layout() plt.show() def main(): """主函数""" simulator = ProcessSchedulerSimulator() # 示例进程数据 example_processes = [ (0, 0, 5), (1, 1, 3), (2, 2, 8), (3, 3, 6) ] print("进程调度模拟系统") print("=" * 40) while True: print("\n选项:") print("1. 使用示例数据") print("2. 手动输入进程数据") print("3. 运行FCFS算法") print("4. 运行SJF算法") print("5. 运行RR算法") print("6. 比较所有算法") print("7. 退出") choice = input("请选择操作: ").strip() if choice == '1': simulator.processes = [] for pid, arrive, burst in example_processes: simulator.add_process(pid, arrive, burst) print("已加载示例数据!") elif choice == '2': simulator.input_processes() print(f"已输入{len(simulator.processes)}个进程") elif choice in ['3', '4', '5']: if not simulator.processes: print("请先输入进程数据!") continue algorithms = {'3': 'FCFS', '4': 'SJF', '5': 'RR'} algorithm = algorithms[choice] try: results = simulator.run_scheduler(algorithm) simulator.print_results(results, algorithm) # 询问是否显示甘特图 show_plot = input("是否显示甘特图?(y/n): ").strip().lower() if show_plot == 'y': simulator.plot_gantt_chart(results, algorithm) except Exception as e: print(f"错误: {e}") elif choice == '6': if not simulator.processes: print("请先输入进程数据!") continue simulator.compare_algorithms() elif choice == '7': print("再见!") break else: print("无效选择,请重新输入!") if __name__ == "__main__": main() 这个代码里面有几个可视化表格,分别是什么
11-04
C:\Users\1\PycharmProjects\pythonProject1\.venv\Scripts\python.exe C:\Users\1\PycharmProjects\pythonProject1\2.3.py ============================================================ 加载数据: C:\Users\1\Desktop\处理后结果.xlsx 数据加载成功,样本数: 1082 前5行数据预览: 孕妇ID 孕妇BMI Y染色体浓度 检测孕周_天数 0 A001 28.125000 0.025936 77 1 A001 28.515625 0.034887 105 2 A001 28.515625 0.066171 140 3 A001 28.906250 0.061192 154 4 A002 33.331832 0.059230 91 检测到Y染色体浓度单位为小数,转换为百分比形式 BMI范围: 20.7 - 46.9 孕周范围: 11.0 - 29.0周 成功率预测模型训练完成,准确率: 0.87 开始遗传算法优化... 种群大小: 100, 迭代次数: 80 -------------------------------------------------- gen nevals avg min max 0 100 -998.213 -1482 -179.06 1 73 -803.356 -1482 -177.195 2 77 -542.667 -1882 -173.709 3 73 -413.302 -1082 -170.318 4 70 -337.335 -1478.17 -170.318 错误: Bin edges must be unique: Index([20.603125, 20.841649368938768, 20.841649368938768, 44.11430769656502, 46.975], dtype='float64'). You can drop duplicate edges by setting the 'duplicates' kwarg Traceback (most recent call last): File "C:\Users\1\PycharmProjects\pythonProject1\2.3.py", line 363, in <module> best_solution = optimizer.run_optimization() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\1\PycharmProjects\pythonProject1\2.3.py", line 228, in run_optimization pop, log = algorithms.eaSimple( ^^^^^^^^^^^^^^^^^^^^ File "C:\Users\1\PycharmProjects\pythonProject1\.venv\Lib\site-packages\deap\algorithms.py", line 173, in eaSimple for ind, fit in zip(invalid_ind, fitnesses): ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\1\PycharmProjects\pythonProject1\2.3.py", line 164, in fitness self.data['group'] = pd.cut( ^^^^^^^ File "C:\Users\1\PycharmProjects\pythonProject1\.venv\Lib\site-packages\pandas\core\reshape\tile.py", line 257, in cut fac, bins = _bins_to_cuts( ^^^^^^^^^^^^^^ File "C:\Users\1\PycharmProjects\pythonProject1\.venv\Lib\site-packages\pandas\core\reshape\tile.py", line 443, in _bins_to_cuts raise ValueError( ValueError: Bin edges must be unique: Index([20.603125, 20.841649368938768, 20.841649368938768, 44.11430769656502, 46.975], dtype='float64'). You can drop duplicate edges by setting the 'duplicates' kwarg 进程已结束,退出代码为 0
11-02
import numpy as np import pandas as pd import matplotlib # 设置matplotlib后端为Agg,避免PyCharm科学模式的问题 matplotlib.use('Agg') import matplotlib.pyplot as plt import seaborn as sns from typing import List, Dict, Tuple, Optional import time import random import copy from enum import Enum import logging from dataclasses import dataclass from abc import ABC, abstractmethod # 设置日志 logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') logger = logging.getLogger(__name__) # 设备类型枚举 class DeviceType(Enum): JIA = "甲种设备" YI = "乙种设备" BING = "丙种设备" # 工位枚举 class Workstation(Enum): W1 = 1 W2 = 2 W3 = 3 W4 = 4 W5 = 5 W6 = 6 W7 = 7 W8 = 8 W9 = 9 # 轨道枚举 class Track(Enum): TRACK1 = 1 TRACK2 = 2 @dataclass class ProcessTime: """工序时间数据类""" G01: int = 0 G02: int = 0 G03: int = 0 G04: int = 0 G05: int = 0 G06: int = 0 G07: int = 0 G08: int = 0 G09: int = 0 class Device: """设备类""" def __init__(self, device_id: str, device_type: DeviceType, process_times: ProcessTime): self.device_id = device_id self.device_type = device_type self.process_times = process_times self.required_workstations = self._get_required_workstations() def _get_required_workstations(self) -> List[Workstation]: """根据设备类型确定需要的工位""" workstations = [] if self.device_type == DeviceType.JIA: workstations = [Workstation.W7, Workstation.W8, Workstation.W9] elif self.device_type == DeviceType.YI: workstations = [Workstation.W4, Workstation.W5, Workstation.W6, Workstation.W7, Workstation.W8, Workstation.W9] elif self.device_type == DeviceType.BING: workstations = [Workstation.W1, Workstation.W2, Workstation.W3, Workstation.W4, Workstation.W5, Workstation.W6, Workstation.W7, Workstation.W8, Workstation.W9] return workstations def get_process_time(self, workstation: Workstation) -> int: """获取指定工位的处理时间""" if workstation == Workstation.W1: return self.process_times.G01 elif workstation == Workstation.W2: return self.process_times.G02 elif workstation == Workstation.W3: return self.process_times.G03 elif workstation == Workstation.W4: return self.process_times.G04 elif workstation == Workstation.W5: return self.process_times.G05 elif workstation == Workstation.W6: return self.process_times.G06 elif workstation == Workstation.W7: return self.process_times.G07 elif workstation == Workstation.W8: return self.process_times.G08 elif workstation == Workstation.W9: return self.process_times.G09 return 0 class WorkstationSchedule: """工位调度类""" def __init__(self, workstation: Workstation): self.workstation = workstation self.schedule = [] # 存储(设备, 开始时间, 结束时间)元组 def add_device(self, device: Device, start_time: int) -> int: """添加设备到工位调度,返回结束时间""" process_time = device.get_process_time(self.workstation) end_time = start_time + process_time # 检查是否有冲突 for _, s, e in self.schedule: if not (end_time <= s or start_time >= e): # 如果有冲突,调整开始时间 start_time = e end_time = start_time + process_time self.schedule.append((device, start_time, end_time)) self.schedule.sort(key=lambda x: x[1]) # 按开始时间排序 return end_time def get_last_end_time(self) -> int: """获取最后结束时间""" if not self.schedule: return 0 return max(end_time for _, _, end_time in self.schedule) class TrackSchedule: """轨道调度类""" def __init__(self, track: Track, max_capacity: int = 3): self.track = track self.max_capacity = max_capacity self.device_sequence = [] # 设备序列 self.workstation_schedules = {ws: WorkstationSchedule(ws) for ws in Workstation} self.current_time = 0 # 轨道当前时间 def add_device(self, device: Device) -> int: """添加设备到轨道,返回完成时间""" self.device_sequence.append(device) # 计算设备在轨道上的开始时间 # 考虑轨道容量限制:最多同时有3台设备 if len(self.device_sequence) <= self.max_capacity: start_time = 0 else: # 设备必须等待前面的设备离开轨道 prev_device = self.device_sequence[-self.max_capacity - 1] start_time = self.get_device_completion_time(prev_device) # 按工序顺序处理设备 current_time = start_time for workstation in device.required_workstations: # 获取工位的最早可用时间 workstation_schedule = self.workstation_schedules[workstation] available_time = self._get_workstation_available_time(workstation_schedule, current_time) try: end_time = workstation_schedule.add_device(device, available_time) current_time = end_time except ValueError as e: logger.error(f"添加设备 {device.device_id} 到工位 {workstation.name} 时出错: {e}") raise return current_time def _get_workstation_available_time(self, workstation_schedule: WorkstationSchedule, earliest_start: int) -> int: """获取工位在指定时间之后的最早可用时间""" if not workstation_schedule.schedule: return earliest_start # 找到第一个可以容纳新设备的时间段 last_end = 0 for _, start, end in workstation_schedule.schedule: if earliest_start <= start and (start - last_end) >= 0: return max(earliest_start, last_end) last_end = end return max(earliest_start, last_end) def get_device_completion_time(self, device: Device) -> int: """获取设备的完成时间""" for ws in device.required_workstations: for d, start, end in self.workstation_schedules[ws].schedule: if d.device_id == device.device_id: return end return 0 def get_makespan(self) -> int: """获取轨道的最大完成时间""" return max(ws.get_last_end_time() for ws in self.workstation_schedules.values()) class TestFacility: """测试场地类""" def __init__(self): self.tracks = { Track.TRACK1: TrackSchedule(Track.TRACK1), Track.TRACK2: TrackSchedule(Track.TRACK2) } def assign_device(self, device: Device, track: Track) -> int: """分配设备到指定轨道,返回完成时间""" return self.tracks[track].add_device(device) def get_makespan(self) -> int: """获取整个测试场地的最大完成时间""" return max(track.get_makespan() for track in self.tracks.values()) def reset(self): """重置测试场地""" self.tracks = { Track.TRACK1: TrackSchedule(Track.TRACK1), Track.TRACK2: TrackSchedule(Track.TRACK2) } class Chromosome: """遗传算法染色体类""" def __init__(self, device_assignments: List[Tuple[Device, Track]]): self.device_assignments = device_assignments # 设备分配列表 self.fitness = 0 # 适应度值 self.makespan = 0 # 最大完成时间 def evaluate(self, test_facility: TestFacility) -> int: """评估染色体,返回最大完成时间""" test_facility.reset() for device, track in self.device_assignments: test_facility.assign_device(device, track) self.makespan = test_facility.get_makespan() self.fitness = 1 / self.makespan # 适应度与完成时间成反比 return self.makespan def crossover(self, other: 'Chromosome') -> 'Chromosome': """交叉操作""" # 单点交叉 crossover_point = random.randint(1, len(self.device_assignments) - 1) new_assignments = self.device_assignments[:crossover_point] + other.device_assignments[crossover_point:] return Chromosome(new_assignments) def mutate(self, mutation_rate: float = 0.1): """变异操作""" for i in range(len(self.device_assignments)): if random.random() < mutation_rate: # 随机改变设备分配轨道 device, _ = self.device_assignments[i] new_track = random.choice([Track.TRACK1, Track.TRACK2]) self.device_assignments[i] = (device, new_track) class GeneticAlgorithm: """遗传算法类""" def __init__(self, population_size: int = 100, elitism_count: int = 10, crossover_rate: float = 0.8, mutation_rate: float = 0.1): self.population_size = population_size self.elitism_count = elitism_count self.crossover_rate = crossover_rate self.mutation_rate = mutation_rate self.population = [] self.best_chromosome = None self.test_facility = TestFacility() self.fitness_history = [] def initialize_population(self, devices: List[Device]): """初始化种群""" self.population = [] for _ in range(self.population_size): assignments = [] for device in devices: track = random.choice([Track.TRACK1, Track.TRACK2]) assignments.append((device, track)) chromosome = Chromosome(assignments) chromosome.evaluate(self.test_facility) self.population.append(chromosome) self.population.sort(key=lambda x: x.fitness, reverse=True) self.best_chromosome = copy.deepcopy(self.population[0]) def selection(self) -> Chromosome: """选择操作 - 锦标赛选择""" tournament_size = 3 tournament = random.sample(self.population, tournament_size) tournament.sort(key=lambda x: x.fitness, reverse=True) return tournament[0] def evolve(self, devices: List[Device], generations: int = 100): """进化过程""" self.initialize_population(devices) for generation in range(generations): # 评估种群 for chromosome in self.population: chromosome.evaluate(self.test_facility) # 排序种群 self.population.sort(key=lambda x: x.fitness, reverse=True) # 更新最佳染色体 if self.population[0].fitness > self.best_chromosome.fitness: self.best_chromosome = copy.deepcopy(self.population[0]) # 记录适应度历史 self.fitness_history.append(self.population[0].fitness) # 创建新种群 new_population = [] # 保留精英 for i in range(self.elitism_count): new_population.append(copy.deepcopy(self.population[i])) # 生成剩余个体 while len(new_population) < self.population_size: # 选择 parent1 = self.selection() parent2 = self.selection() # 交叉 if random.random() < self.crossover_rate: child = parent1.crossover(parent2) else: child = copy.deepcopy(parent1) # 变异 child.mutate(self.mutation_rate) new_population.append(child) self.population = new_population if generation % 10 == 0: logger.info( f"Generation {generation}: Best Fitness = {self.best_chromosome.fitness}, Makespan = {self.best_chromosome.makespan}") return self.best_chromosome def plot_fitness_history(self): """绘制适应度历史""" plt.figure(figsize=(10, 6)) plt.plot(self.fitness_history) plt.title('Fitness History') plt.xlabel('Generation') plt.ylabel('Fitness') plt.grid(True) # 保存图像而不是显示 plt.savefig('fitness_history.png') plt.close() class DataLoader: """数据加载类""" @staticmethod def load_devices_from_excel(file_path: str) -> List[Device]: """从Excel文件加载设备数据""" try: # 读取Excel文件,使用第一行作为列名 df = pd.read_excel(file_path, sheet_name='Sheet1', header=0) # 打印列名和前几行数据以进行调试 logger.info(f"数据列: {df.columns.tolist()}") logger.info(f"前几行数据:\n{df.head()}") # 清理数据:去除可能的空格和NaN值 df['设备编号'] = df['设备编号'].astype(str).str.strip() # 过滤掉空设备编号的行 df = df[df['设备编号'] != 'nan'] df = df[df['设备编号'] != ''] # 过滤掉非设备编号的行(如"单位:min(分钟)") valid_prefixes = ['J', 'Y', 'B'] df = df[df['设备编号'].str.startswith(tuple(valid_prefixes), na=False)] # 检查是否有有效数据 if len(df) == 0: raise ValueError("Excel文件中没有有效的设备数据") # 填充NaN值为0 process_columns = ['G01工序', 'G02工序', 'G03工序', 'G04工序', 'G05工序', 'G06工序', 'G07工序', 'G08工序', 'G09工序'] for col in process_columns: if col in df.columns: df[col] = df[col].fillna(0).astype(int) devices = [] for _, row in df.iterrows(): device_id = row['设备编号'] # 确定设备类型 if device_id.startswith('J'): device_type = DeviceType.JIA elif device_id.startswith('Y'): device_type = DeviceType.YI elif device_id.startswith('B'): device_type = DeviceType.BING else: logger.warning(f"未知设备类型: {device_id}, 使用默认类型: 乙种设备") device_type = DeviceType.YI # 创建工序时间对象 process_times = ProcessTime( G01=row.get('G01工序', 0), G02=row.get('G02工序', 0), G03=row.get('G03工序', 0), G04=row.get('G04工序', 0), G05=row.get('G05工序', 0), G06=row.get('G06工序', 0), G07=row.get('G07工序', 0), G08=row.get('G08工序', 0), G09=row.get('G09工序', 0) ) devices.append(Device(device_id, device_type, process_times)) logger.info(f"成功加载 {len(devices)} 台设备") return devices except Exception as e: logger.error(f"加载设备数据时出错: {e}") logger.error(f"文件路径: {file_path}") if 'df' in locals(): logger.error(f"数据形状: {df.shape}") logger.error( f"设备编号列的值: {df['设备编号'].unique() if '设备编号' in df.columns else '设备编号列不存在'}") raise class SolutionVisualizer: """解决方案可视化类""" @staticmethod def visualize_schedule(test_facility: TestFacility, chromosome: Chromosome): """可视化调度结果""" fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 10)) # 绘制轨道1的甘特图 track1_schedule = test_facility.tracks[Track.TRACK1] SolutionVisualizer._plot_track_gantt(ax1, track1_schedule, "Track 1") # 绘制轨道2的甘特图 track2_schedule = test_facility.tracks[Track.TRACK2] SolutionVisualizer._plot_track_gantt(ax2, track2_schedule, "Track 2") plt.tight_layout() # 保存图像而不是显示 plt.savefig('schedule_visualization.png') plt.close() @staticmethod def _plot_track_gantt(ax, track_schedule: TrackSchedule, title: str): """绘制单个轨道的甘特图""" colors = sns.color_palette("hsv", len(Workstation)) workstation_colors = {ws: colors[i] for i, ws in enumerate(Workstation)} for workstation in Workstation: schedule = track_schedule.workstation_schedules[workstation].schedule for device, start, end in schedule: ax.barh( y=workstation.value, width=end - start, left=start, color=workstation_colors[workstation], edgecolor='black', alpha=0.7 ) ax.text( x=start + (end - start) / 2, y=workstation.value, s=device.device_id, ha='center', va='center', fontsize=8 ) ax.set_yticks([ws.value for ws in Workstation]) ax.set_yticklabels([ws.name for ws in Workstation]) ax.set_xlabel('Time (min)') ax.set_title(title) ax.grid(True, axis='x') @staticmethod def print_schedule_details(test_facility: TestFacility, chromosome: Chromosome): """打印调度详情""" print("=" * 80) print("批量设备测试流程优化结果") print("=" * 80) for track in [Track.TRACK1, Track.TRACK2]: print(f"\n{track.name}:") track_schedule = test_facility.tracks[track] for workstation in Workstation: schedule = track_schedule.workstation_schedules[workstation].schedule if schedule: print(f" {workstation.name}:") for device, start, end in schedule: print(f" {device.device_id}: {start}-{end} min") print(f"\n总完成时间: {chromosome.makespan} min") print("=" * 80) # 使用示例 def main(): """主函数""" try: # 加载数据 data_loader = DataLoader() devices = data_loader.load_devices_from_excel('D:/地大/2025年数学竞赛/第二轮数学建模竞赛/C批量设备测试流程优化(1)/C 批量设备测试流程优化/附件1 每台设备工序测试时间表.xls') # 创建遗传算法实例 ga = GeneticAlgorithm( population_size=50, elitism_count=5, crossover_rate=0.8, mutation_rate=0.1 ) # 运行遗传算法 start_time = time.time() best_chromosome = ga.evolve(devices, generations=100) end_time = time.time() logger.info(f"优化完成,耗时: {end_time - start_time:.2f} 秒") logger.info(f"最佳完成时间: {best_chromosome.makespan} min") # 可视化结果 test_facility = TestFacility() best_chromosome.evaluate(test_facility) SolutionVisualizer.print_schedule_details(test_facility, best_chromosome) SolutionVisualizer.visualize_schedule(test_facility, best_chromosome) # 绘制适应度历史 ga.plot_fitness_history() print("优化完成!结果已保存到文件中:") print("- schedule_visualization.png: 甘特图") print("- fitness_history.png: 适应度历史曲线") except Exception as e: logger.error(f"程序执行出错: {e}") raise if __name__ == "__main__": main() 每一步具体是什么意思请用#解释出来
09-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值