狼群算法在实木家具生产调度中的精益改善【附代码】

博主简介:擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导,毕业论文、期刊论文经验交流。

 ✅ 具体问题可以私信或扫描文章底部二维码。


(1) 构建基于多约束条件的实木家具柔性作业车间调度问题模型。实木家具生产包含开料、刨光、钻孔、雕刻、组装、涂装等多道工序,且同一工序可能存在多台功能相同或相似的设备可选,构成了典型的柔性作业车间调度问题。本研究首先建立了该问题的混合整数规划数学模型。模型以最小化最大完工时间为首要目标,同时兼顾设备负载均衡、订单交货期等。约束条件系统性地涵盖了工序顺序约束(即同一产品的各工序必须按工艺路线顺序加工)、设备唯一性约束(即同一时刻一台设备只能加工一个工件)、工序不可中断约束以及物料就绪时间约束等。此外,模型还充分考虑了实木家具生产的特性,如不同木材的加工时间差异、雕刻等特殊工序对专用设备的依赖等,使模型更贴合生产实际。该模型为后续的智能化算法求解提供了精确的数学描述和评估基准。

(2) 设计改进狼群算法求解柔性作业车间调度问题。狼群算法模拟狼群分工协作的捕猎行为,具有收敛速度快、全局搜索能力强的特点,适用于求解组合优化问题。本研究对基本狼群算法进行了针对性改进以适配调度问题。首先,采用两层编码方式:第一层为基于工序的编码,表示所有工件工序的一个排列;第二层为设备分配编码,为每一道工序选择可用的加工设备。这种编码方式能自然满足工序顺序约束。其次,重新定义了算法的“游走”、“奔袭”和“围攻”三种智能行为。“游走”行为通过局部交换工序顺序或调整设备分配进行小范围搜索,开发局部最优解;“奔袭”行为模拟头狼召唤,引导狼群向当前最优解方向进行较大步长的搜索,加快收敛;“围攻”行为则模拟狼群最后围捕,在最优解附近进行精细搜索。此外,引入基于模拟退火的接受准则,允许算法以一定概率接受劣质解,有效避免了早熟收敛,提升了全局寻优能力。通过与该领域的经典算法(如遗传算法、粒子群算法)在标准测试案例和实际企业数据上进行对比,改进狼群算法在最小化最大完工时间指标上平均提升了8%以上,证明了其优越性。

(3) 实施基于调度甘特图的生产瓶颈分析与精益化改善。算法输出最优调度方案后,系统自动生成详细的生产甘特图。本研究利用甘特图进行可视化的瓶颈分析,识别出负载率持续过高、工序等待队列最长的关键设备或工位,这些即为制约整体产出的瓶颈资源。针对识别出的瓶颈,系统性地应用精益生产工具进行改善。例如,对于数控雕刻机这一瓶颈,实施快速换模改善,通过将换刀、对刀等内作业时间转化为外作业时间,大幅缩短设备准备时间;对于涂装线瓶颈,引入“一个流”生产理念,重新布局工作站,减少在制品堆积和搬运距离;对于因物料供应不及时导致的等待,推行看板管理,建立拉动式物料配送系统。每一项改善措施实施后,其效果(如该工序作业时间缩短百分比)将被量化,并作为新的参数输入到调度模型中,重新进行优化。这种“算法优化排程→识别瓶颈→精益改善→再优化”的闭环迭代过程,不仅实现了单次调度结果的优化,更驱动了生产系统能力的持续提升,使得整体生产效率得到叠加性改善

import numpy as np
import random
import matplotlib.pyplot as plt

class FlexibleJobShopProblem:
    def __init__(self, jobs_data):
        self.jobs = jobs_data
        self.num_jobs = len(jobs_data)
        self.all_ops = []
        op_id = 0
        for job_id, job in enumerate(jobs_data):
            for step_id, step in enumerate(job):
                machine_options, processing_times = step
                for idx, machine in enumerate(machine_options):
                    self.all_ops.append((job_id, step_id, machine, processing_times[idx], op_id))
                    op_id += 1
        self.total_ops = op_id

class ImprovedWolfPackAlgorithm:
    def __init__(self, problem, wolf_num=20, max_iter=100):
        self.problem = problem
        self.wolf_num = wolf_num
        self.max_iter = max_iter
        self.alpha_pos = None
        self.alpha_score = float('inf')
        self.beta_pos = None
        self.beta_score = float('inf')
        self.delta_pos = None
        self.delta_score = float('inf')
        self.convergence_curve = []

    def initialize_wolf(self):
        op_sequence = list(range(self.problem.total_ops))
        random.shuffle(op_sequence)
        machine_selection = []
        for op in self.problem.all_ops:
            job_id, step_id, machine_options, _, _ = op
            chosen_machine = random.choice(machine_options)
            machine_selection.append(chosen_machine)
        return (op_sequence, machine_selection)

    def decode_schedule(self, wolf):
        op_seq, mac_sel = wolf
        job_progress = [0] * self.problem.num_jobs
        machine_timeline = {}
        job_completion = [0] * self.problem.num_jobs
        for op_idx in op_seq:
            job_id, step_id, _, proc_times, orig_id = self.problem.all_ops[op_idx]
            machine = mac_sel[op_idx]
            proc_time = proc_times[mac_sel.index(machine)] if isinstance(proc_times, list) else proc_times
            start_time = max(job_completion[job_id], machine_timeline.get(machine, 0))
            end_time = start_time + proc_time
            machine_timeline[machine] = end_time
            job_completion[job_id] = end_time
        makespan = max(job_completion)
        return makespan

    def wandering(self, wolf, current_iter):
        op_seq, mac_sel = wolf
        new_op_seq = op_seq.copy()
        new_mac_sel = mac_sel.copy()
        if random.random() < 0.7:
            i, j = random.sample(range(len(new_op_seq)), 2)
            new_op_seq[i], new_op_seq[j] = new_op_seq[j], new_op_seq[i]
        else:
            idx = random.randint(0, len(new_mac_sel)-1)
            job_id, step_id, machine_options, _, _ = self.problem.all_ops[idx]
            new_mac_sel[idx] = random.choice(machine_options)
        return (new_op_seq, new_mac_sel)

    def summoning_raid(self, wolf, leader_pos, a_vector):
        op_seq_w, mac_sel_w = wolf
        op_seq_l, mac_sel_l = leader_pos
        new_op_seq = []
        new_mac_sel = []
        for i in range(len(op_seq_w)):
            if random.random() < np.linalg.norm(a_vector):
                if i < len(op_seq_l):
                    new_op_seq.append(op_seq_l[i])
                    new_mac_sel.append(mac_sel_l[i])
                else:
                    new_op_seq.append(op_seq_w[i])
                    new_mac_sel.append(mac_sel_w[i])
            else:
                new_op_seq.append(op_seq_w[i])
                new_mac_sel.append(mac_sel_w[i])
        return (new_op_seq, new_mac_sel)

    def besiege(self, wolf, a_vector):
        op_seq, mac_sel = wolf
        new_op_seq = op_seq.copy()
        new_mac_sel = mac_sel.copy()
        for _ in range(int(len(op_seq) * 0.1)):
            i = random.randint(0, len(new_op_seq)-1)
            j = random.randint(0, len(new_op_seq)-1)
            new_op_seq[i], new_op_seq[j] = new_op_seq[j], new_op_seq[i]
        return (new_op_seq, new_mac_sel)

    def solve(self):
        population = [self.initialize_wolf() for _ in range(self.wolf_num)]
        for wolf in population:
            score = self.decode_schedule(wolf)
            if score < self.alpha_score:
                self.delta_score = self.beta_score
                self.delta_pos = self.beta_pos
                self.beta_score = self.alpha_score
                self.beta_pos = self.alpha_pos
                self.alpha_score = score
                self.alpha_pos = wolf
            elif score < self.beta_score:
                self.delta_score = self.beta_score
                self.delta_pos = self.beta_pos
                self.beta_score = score
                self.beta_pos = wolf
            elif score < self.delta_score:
                self.delta_score = score
                self.delta_pos = wolf
        for t in range(self.max_iter):
            a = 2 - t * (2 / self.max_iter)
            a_vector = np.array([a * (2*random.random()-1) for _ in range(2)])
            new_population = []
            for i in range(self.wolf_num):
                wolf = population[i]
                if i < self.wolf_num // 3:
                    new_wolf = self.summoning_raid(wolf, self.alpha_pos, a_vector)
                elif i < 2 * self.wolf_num // 3:
                    new_wolf = self.summoning_raid(wolf, self.beta_pos, a_vector)
                else:
                    new_wolf = self.summoning_raid(wolf, self.delta_pos, a_vector)
                if random.random() < 0.3:
                    new_wolf = self.besiege(new_wolf, a_vector)
                if random.random() < 0.4:
                    new_wolf = self.wandering(new_wolf, t)
                new_score = self.decode_schedule(new_wolf)
                old_score = self.decode_schedule(wolf)
                if new_score < old_score or random.random() < np.exp((old_score - new_score) / (t+1)):
                    wolf = new_wolf
                    score = new_score
                else:
                    score = old_score
                if score < self.alpha_score:
                    self.delta_score = self.beta_score
                    self.delta_pos = self.beta_pos
                    self.beta_score = self.alpha_score
                    self.beta_pos = self.alpha_pos
                    self.alpha_score = score
                    self.alpha_pos = wolf
                elif score < self.beta_score:
                    self.delta_score = self.beta_score
                    self.delta_pos = self.beta_pos
                    self.beta_score = score
                    self.beta_pos = wolf
                elif score < self.delta_score:
                    self.delta_score = score
                    self.delta_pos = wolf
                new_population.append(wolf)
            population = new_population
            self.convergence_curve.append(self.alpha_score)
        return self.alpha_pos, self.alpha_score, self.convergence_curve

    def plot_gantt(self, schedule):
        op_seq, mac_sel = schedule
        fig, ax = plt.subplots(figsize=(12, 6))
        colors = plt.cm.tab20(np.linspace(0, 1, self.problem.num_jobs))
        machine_activities = {}
        current_time = 0
        job_progress = [0] * self.problem.num_jobs
        machine_time = {}
        for op_idx in op_seq:
            job_id, step_id, machine_options, proc_times, orig_id = self.problem.all_ops[op_idx]
            machine = mac_sel[op_idx]
            proc_time = proc_times[mac_sel.index(machine)] if isinstance(proc_times, list) else proc_times
            start = max(job_progress[job_id], machine_time.get(machine, 0))
            end = start + proc_time
            if machine not in machine_activities:
                machine_activities[machine] = []
            machine_activities[machine].append((start, end, job_id, step_id))
            job_progress[job_id] = end
            machine_time[machine] = end
            current_time = max(current_time, end)
        machine_ids = sorted(machine_activities.keys())
        y_ticks = []
        y_labels = []
        for idx, mac in enumerate(machine_ids):
            y_pos = idx + 1
            y_ticks.append(y_pos)
            y_labels.append(f'M{mac}')
            for start, end, job_id, step_id in machine_activities[mac]:
                ax.barh(y_pos, end-start, left=start, height=0.5, color=colors[job_id], edgecolor='black')
                ax.text(start + (end-start)/2, y_pos, f'J{job_id}-{step_id}', va='center', ha='center', fontsize=8, color='white')
        ax.set_yticks(y_ticks)
        ax.set_yticklabels(y_labels)
        ax.set_xlabel('Time')
        ax.set_title('Optimized Production Schedule Gantt Chart')
        ax.grid(axis='x', linestyle='--', alpha=0.7)
        plt.tight_layout()
        plt.show()

jobs_example = [
    [([0, 1], [4, 6]), ([1, 2], [5, 7]), ([2], [3])],
    [([0], [2]), ([1, 2], [8, 4]), ([0, 2], [6, 5])],
    [([1], [3]), ([0, 1], [3, 2]), ([2], [9])]
]
problem = FlexibleJobShopProblem(jobs_example)
iwpa = ImprovedWolfPackAlgorithm(problem, wolf_num=15, max_iter=50)
best_schedule, best_makespan, convergence = iwpa.solve()
print(f"最优调度方案的最大完工时间: {best_makespan}")
iwpa.plot_gantt(best_schedule)
plt.figure()
plt.plot(convergence)
plt.xlabel('Iteration')
plt.ylabel('Makespan')
plt.title('Convergence Curve of Wolf Pack Algorithm')
plt.grid(True)
plt.show()


如有问题,可以直接沟通

👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

坷拉博士

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

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

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

打赏作者

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

抵扣说明:

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

余额充值