Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
/ JAAPSS Public

Just Another Advanced Planning and Scheduling Solver

Notifications You must be signed in to change notification settings

LYL232/JAAPSS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

2 Commits

Repository files navigation

只是一个APS问题求解器

求解问题描述

现有一批任务和一批设备. 除了最终的任务, 每个任务都有一个后继任务, 在当前任务未完成前, 后继任务不可开始. 每个任务都需要一段给定的连续的工作时间(当天工作结束时间可以看做与第二天工作开始时间连续). 设备分为设备组, 设备组里每个设备可以看做相同, 每个任务分配生产时都需要指定某个设备组里的一个设备进行生产. 同一时间同一个设备不可以执行两个任务. 给定某些任务的计划完成时间.

求: 在不同排程策略, 不同排程规则下的生产计划.

目前程序提供的排程策略:

  1. 最少超时时间总和且每个设备超时的时间越少越好 (最少超时时间)
  2. 最少超时任务数
  3. 最高设备利用率(由于每个任务的所需完成时间一定, 所以等价于最短工时)

目前程序提供的排程规则: 正排, 倒排

使用方式

该程序是一个命令行交互程序, 计算输入输出和算法参数配置从标准输入中读出的用户命令控制.

当程序准备就绪需要读入用户命令时: 屏幕上会输出一行":)".

基础使用方式:

设当前工作目录在项目根目录下

java -jar JAAPSS.jar

运行程序命令行

依次在标准输入中输入

set taskCSV ./data/example-task.csv
set machineCSV ./data/example-machine.csv
set outputCSV ./data/output.csv
start
exit

当start命令执行结束且输出了":)"时即可得到输出结果: ./data/output.csv

命令:

  • help: 输出程序使用指南和参数名
  • set [参数名] [参数值...]: 设置程序运行时参数
  • showParameters 或 SP: 显示当前程序运行参数
  • start: 按照程序当前运行参数求解问题
  • exit: 退出程序

输入:

两个csv文件: 由程序运行时参数 taskCSV 和 machineCSV 指出其路径

  • taskCSV: 任务信息csv文件, 格式可参见 data/example-task.csv, 其中任务所需时间 = 准备时间 + 任务数量 $\times$ 运行时间
  • machineCS V: 设备信息csv文件 格式可参见 data/example-machine.csv

输出:

一个csv文件: 由程序运行时参数outputCSV指出其路径

运行时参数:

通用参数

  • taskCSV: 输入任务信息csv文件, 默认: ./data/example-task.csv
  • machineCSV: 输入设备信息csv文件, 默认: ./data/example-machine.csv
  • hasHeader: 输入csv文件是否有表头, 默认: true
  • outputCSV: 输出csv文件, 默认: ./data/output.csv
  • encoding: 输入输出编码, 默认: GBK
  • verbose: 是否显示算法运行时信息和调度访问信息, 默认: false
  • workHours: 每天的工作时间, 默认: 8:00-24:00, 示例: 'set workHours 8 0 24 0'
  • timeunit: 任务中时间的时间单位, 默认: minute (分), 可选: ['ms', 's', 'm', 'h', 'd']
  • SR as scheduleRule: 排程规则 默认: 'FORWARD' (正排), 可选:['0' 或者 'FORWARD', '1' 或者 'BACKWARD']
  • SS as scheduleStrategy: 排程策略 默认: 'LEAST_EXCEED_TIME' (最少超时时间), 可选 :['0' 或者 'LEAST_EXCEED_TIME', '1' 或者 'LEAST_EXPIRED_TASK' (最少超时任务数) , '2' 或者 'HIGHEST_MACHINE_UTILIZATION' (最大设备利用率)]
  • algorithm: 求解算法 默认: 'GA', 可选 :['GA': Genetic Algorithm (遗传算法)]
  • VMG as virtualMachineGroups: 虚拟设备组, 该设备组内的设备可以无限并行执行任务, 默认: 空集, 示例: 'set virtualMachineGroups 58 59'

遗传算法参数:

  • GA.population: 种群大小, 默认: 200
  • GA.maxGeneration: 最大迭代次数, 默认: 100
  • GA.MSCrossoverRepeat: MS基因段尝试交叉个数, 默认: 10
  • GA.mutateRate: 个体变异概率, 默认: 0.01
  • GA.crossoverRate: 个体交叉概率, 默认: 0.6
  • GA.selectBetterRate: 二选一锦标赛选择策略中选择较强个体的概率. 默认: 0.8
  • GA.seed: 随机种子, 默认:当前时间戳
  • GA.workers: 算法工作线程个数, 默认: 当前可用处理器个数

实现简述

遗传算法

注意到问题与FJSSP(Flexible Job Shop Scheduling Problem 柔性作业调度问题)相似, 所以借鉴了mnmalist博客柔性作业车间调度问题的两级遗传算法的基于MS(机器选择段)和OS(工序选择段)的编码方式对遗传算法个体进行编码解码.

但是本问题与FJSSP的仍有不同点:

  1. 本问题中没有工件的概念, 任务与FJSSP中的工序概念不能直接对应, 因为FJSSP中的工件包含了一连串的工序, 这些工序需要严格按顺序执行. 而本问题中的任务间依赖是一颗多叉树(因为一个任务只有一个后继任务), 不能直接将任务转换为工序.
  2. 本问题中所有任务的执行所需时间与设备无关.

使用MS,OS编码方式的关键是解决不同点1.

解决方式如下:

注意到一个任务只有一个后继任务, 所以从一个最终任务开始搜索前驱任务能够形成一棵依赖多叉树. 可以将这棵依赖树分解成若干连续的依赖链条, 举例如下:

1<-2<-3
 \
 4<-7<-8<-9
 /
 5<-6

任务9是最终需要完成的任务, 箭头指向前驱任务, 注意到1<-2<-3是一个严格顺序的任务链, 那么可以把[1<-2<-3]看做一个工件的工序链, 即把1, 2, 3看做一个虚拟的工件的工序, 工件编号为1, 那么依赖树变成如下的工件依赖

[1<-2<-3] {1}
 \ \
 [4]<-[7<-8<-9] => {2}<-{4}
 / /
 [5<-6] {3}

那么OS基因段长度为9, 包含3个1, 1个2, 2个3, 3个4, 只需保证4的右边不会出现1, 2, 3就能保证该OS基因是一个可行解的编码. 每次生成一个OS基因段时, 只需使用一个检错纠错算法将其修正成满足依赖条件OS基因序列即可. 本程序借鉴了拓扑排序实现了O(n)的检错纠错算法. 实现了本问题到FJSSP的转化.

至此, 按照FJSSP的遗传算法求解转化完的问题即可.

参考文献:

https://blog.csdn.net/mnmlist/article/details/79056883

http://www.cnki.com.cn/Article/CJFDTotal-JXXB200704020.htm

About

Just Another Advanced Planning and Scheduling Solver

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

AltStyle によって変換されたページ (->オリジナル) /