我一直面临着在Scala中进行算法来安排工厂生产计划的挑战。工厂遇到Orders,它有多个Task(有时间关联),有物理资源,可以由人力资源完成。
第1部分几乎完成(错过了正确的人力资源安排 - 重复:()但第2部分更有趣。在这里给出第1部分的快速概述后会解释:
INPUT XML
<Production>
<PhysicalResources>
<Physical id="PRS_1" type="PRST 1"/>
<Physical id="PRS_2" type="PRST 1"/>
<Physical id="PRS_3" type="PRST 2"/>
<Physical id="PRS_4" type="PRST 3"/>
<Physical id="PRS_5" type="PRST 4"/>
<Physical id="PRS_6" type="PRST 4"/>
<Physical id="PRS_7" type="PRST 5"/>
<Physical id="PRS_8" type="PRST 5"/>
<Physical id="PRS_9" type="PRST 5"/>
</PhysicalResources>
<Tasks>
<Task id="TSK_1" time="100">
<PhysicalResource prstype="PRST 1"/>
<PhysicalResource prstype="PRST 2"/>
<PhysicalResource prstype="PRST 3"/>
</Task>
<Task id="TSK_2" time="80">
<PhysicalResource prstype="PRST 4"/>
<PhysicalResource prstype="PRST 5"/>
</Task>
<Task id="TSK_3" time="160">
<PhysicalResource prstype="PRST 1"/>
<PhysicalResource prstype="PRST 3"/>
<PhysicalResource prstype="PRST 5"/>
</Task>
<Task id="TSK_4" time="90">
<PhysicalResource prstype="PRST 2"/>
<PhysicalResource prstype="PRST 4"/>
</Task>
<Task id="TSK_5" time="60">
<PhysicalResource prstype="PRST 1"/>
<PhysicalResource prstype="PRST 2"/>
<PhysicalResource prstype="PRST 5"/>
</Task>
<Task id="TSK_6" time="85">
<PhysicalResource prstype="PRST 3"/>
<PhysicalResource prstype="PRST 4"/>
</Task>
<Task id="TSK_7" time="145">
<PhysicalResource prstype="PRST 2"/>
<PhysicalResource prstype="PRST 1"/>
<PhysicalResource prstype="PRST 3"/>
</Task>
<Task id="TSK_8" time="35">
<PhysicalResource prstype="PRST 5"/>
<PhysicalResource prstype="PRST 4"/>
</Task>
<Task id="TSK_9" time="140">
<PhysicalResource prstype="PRST 5"/>
<PhysicalResource prstype="PRST 1"/>
<PhysicalResource prstype="PRST 3"/>
</Task>
<Task id="TSK_10" time="45">
<PhysicalResource prstype="PRST 1"/>
<PhysicalResource prstype="PRST 5"/>
<PhysicalResource prstype="PRST 2"/>
</Task>
</Tasks>
<HumanResources>
<Human id="HRS_1" name="Antonio">
<Handles type="PRST 1"/>
<Handles type="PRST 2"/>
</Human>
<Human id="HRS_2" name="Maria">
<Handles type="PRST 1"/>
<Handles type="PRST 3"/>
<Handles type="PRST 4"/>
<Handles type="PRST 5"/>
</Human>
<Human id="HRS_3" name="Manuel">
<Handles type="PRST 3"/>
<Handles type="PRST 5"/>
</Human>
<Human id="HRS_4" name="Susana">
<Handles type="PRST 2"/>
<Handles type="PRST 4"/>
</Human>
<Human id="HRS_5" name="Joao">
<Handles type="PRST 1"/>
<Handles type="PRST 3"/>
<Handles type="PRST 5"/>
</Human>
<Human id="HRS_6" name="Laura">
<Handles type="PRST 2"/>
<Handles type="PRST 3"/>
<Handles type="PRST 4"/>
</Human>
</HumanResources>
<Products>
<Product id="PRD_1" name="Product 1">
<Process tskref="TSK_1"/>
<Process tskref="TSK_3"/>
<Process tskref="TSK_5"/>
<Process tskref="TSK_10"/>
</Product>
<Product id="PRD_2" name="Product 1">
<Process tskref="TSK_1"/>
<Process tskref="TSK_2"/>
<Process tskref="TSK_3"/>
<Process tskref="TSK_4"/>
<Process tskref="TSK_5"/>
<Process tskref="TSK_10"/>
</Product>
<Product id="PRD_3" name="Product 1">
<Process tskref="TSK_2"/>
<Process tskref="TSK_3"/>
<Process tskref="TSK_6"/>
<Process tskref="TSK_7"/>
<Process tskref="TSK_9"/>
</Product>
<Product id="PRD_4" name="Product 1">
<Process tskref="TSK_8"/>
<Process tskref="TSK_7"/>
<Process tskref="TSK_6"/>
<Process tskref="TSK_5"/>
<Process tskref="TSK_10"/>
</Product>
</Products>
<Orders>
<Order id="ORD_1" prdref="PRD_1" quantity="1"/>
<Order id="ORD_2" prdref="PRD_2" quantity="2"/>
<Order id="ORD_3" prdref="PRD_3" quantity="3"/>
<Order id="ORD_4" prdref="PRD_4" quantity="1"/>
</Orders>
</Production>
输出XML
<Schedule>
<TaskSchedule order="ORD_1" productNumber="1" task="TSK_1"
start="0" end="100">
<PhysicalResources>
<Physical id="PRS_1" />
<Physical id="PRS_3" />
<Physical id="PRS_4" />
</PhysicalResources>
<HumanResources>
<Human name="Antonio" />
<Human name="Susana" />
<Human name="Maria" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_1" productNumber="1" task="TSK_3"
start="100" end="260">
<PhysicalResources>
<Physical id="PRS_1" />
<Physical id="PRS_4" />
<Physical id="PRS_7" />
</PhysicalResources>
<HumanResources>
<Human name="Antonio" />
<Human name="Maria" />
<Human name="Manuel" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_1" productNumber="1" task="TSK_5"
start="260" end="320">
<PhysicalResources>
<Physical id="PRS_1" />
<Physical id="PRS_3" />
<Physical id="PRS_7" />
</PhysicalResources>
<HumanResources>
<Human name="Antonio" />
<Human name="Susana" />
<Human name="Maria" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_1" productNumber="1" task="TSK_10"
start="320" end="365">
<PhysicalResources>
<Physical id="PRS_1" />
<Physical id="PRS_7" />
<Physical id="PRS_3" />
</PhysicalResources>
<HumanResources>
<Human name="Antonio" />
<Human name="Maria" />
<Human name="Susana" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_2" productNumber="1" task="TSK_1"
start="365" end="465">
<PhysicalResources>
<Physical id="PRS_1" />
<Physical id="PRS_3" />
<Physical id="PRS_4" />
</PhysicalResources>
<HumanResources>
<Human name="Antonio" />
<Human name="Susana" />
<Human name="Maria" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_2" productNumber="1" task="TSK_2"
start="465" end="545">
<PhysicalResources>
<Physical id="PRS_5" />
<Physical id="PRS_7" />
</PhysicalResources>
<HumanResources>
<Human name="Maria" />
<Human name="Manuel" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_2" productNumber="1" task="TSK_3"
start="545" end="705">
<PhysicalResources>
<Physical id="PRS_1" />
<Physical id="PRS_4" />
<Physical id="PRS_7" />
</PhysicalResources>
<HumanResources>
<Human name="Antonio" />
<Human name="Maria" />
<Human name="Manuel" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_2" productNumber="1" task="TSK_4"
start="705" end="795">
<PhysicalResources>
<Physical id="PRS_3" />
<Physical id="PRS_5" />
</PhysicalResources>
<HumanResources>
<Human name="Antonio" />
<Human name="Maria" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_2" productNumber="1" task="TSK_5"
start="795" end="855">
<PhysicalResources>
<Physical id="PRS_1" />
<Physical id="PRS_3" />
<Physical id="PRS_7" />
</PhysicalResources>
<HumanResources>
<Human name="Antonio" />
<Human name="Susana" />
<Human name="Maria" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_2" productNumber="1" task="TSK_10"
start="855" end="900">
<PhysicalResources>
<Physical id="PRS_1" />
<Physical id="PRS_7" />
<Physical id="PRS_3" />
</PhysicalResources>
<HumanResources>
<Human name="Antonio" />
<Human name="Maria" />
<Human name="Susana" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_2" productNumber="2" task="TSK_1"
start="900" end="1000">
<PhysicalResources>
<Physical id="PRS_1" />
<Physical id="PRS_3" />
<Physical id="PRS_4" />
</PhysicalResources>
<HumanResources>
<Human name="Antonio" />
<Human name="Susana" />
<Human name="Maria" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_2" productNumber="2" task="TSK_2"
start="1000" end="1080">
<PhysicalResources>
<Physical id="PRS_5" />
<Physical id="PRS_7" />
</PhysicalResources>
<HumanResources>
<Human name="Maria" />
<Human name="Manuel" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_2" productNumber="2" task="TSK_3"
start="1080" end="1240">
<PhysicalResources>
<Physical id="PRS_1" />
<Physical id="PRS_4" />
<Physical id="PRS_7" />
</PhysicalResources>
<HumanResources>
<Human name="Antonio" />
<Human name="Maria" />
<Human name="Manuel" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_2" productNumber="2" task="TSK_4"
start="1240" end="1330">
<PhysicalResources>
<Physical id="PRS_3" />
<Physical id="PRS_5" />
</PhysicalResources>
<HumanResources>
<Human name="Antonio" />
<Human name="Maria" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_2" productNumber="2" task="TSK_5"
start="1330" end="1390">
<PhysicalResources>
<Physical id="PRS_1" />
<Physical id="PRS_3" />
<Physical id="PRS_7" />
</PhysicalResources>
<HumanResources>
<Human name="Antonio" />
<Human name="Susana" />
<Human name="Maria" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_2" productNumber="2" task="TSK_10"
start="1390" end="1435">
<PhysicalResources>
<Physical id="PRS_1" />
<Physical id="PRS_7" />
<Physical id="PRS_3" />
</PhysicalResources>
<HumanResources>
<Human name="Antonio" />
<Human name="Maria" />
<Human name="Susana" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_3" productNumber="1" task="TSK_2"
start="1435" end="1515">
<PhysicalResources>
<Physical id="PRS_5" />
<Physical id="PRS_7" />
</PhysicalResources>
<HumanResources>
<Human name="Maria" />
<Human name="Manuel" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_3" productNumber="1" task="TSK_3"
start="1515" end="1675">
<PhysicalResources>
<Physical id="PRS_1" />
<Physical id="PRS_4" />
<Physical id="PRS_7" />
</PhysicalResources>
<HumanResources>
<Human name="Antonio" />
<Human name="Maria" />
<Human name="Manuel" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_3" productNumber="1" task="TSK_6"
start="1675" end="1760">
<PhysicalResources>
<Physical id="PRS_4" />
<Physical id="PRS_5" />
</PhysicalResources>
<HumanResources>
<Human name="Maria" />
<Human name="Susana" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_3" productNumber="1" task="TSK_7"
start="1760" end="1905">
<PhysicalResources>
<Physical id="PRS_3" />
<Physical id="PRS_1" />
<Physical id="PRS_4" />
</PhysicalResources>
<HumanResources>
<Human name="Antonio" />
<Human name="Maria" />
<Human name="Manuel" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_3" productNumber="1" task="TSK_9"
start="1905" end="2045">
<PhysicalResources>
<Physical id="PRS_7" />
<Physical id="PRS_1" />
<Physical id="PRS_4" />
</PhysicalResources>
<HumanResources>
<Human name="Maria" />
<Human name="Antonio" />
<Human name="Manuel" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_3" productNumber="2" task="TSK_2"
start="2045" end="2125">
<PhysicalResources>
<Physical id="PRS_5" />
<Physical id="PRS_7" />
</PhysicalResources>
<HumanResources>
<Human name="Maria" />
<Human name="Manuel" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_3" productNumber="2" task="TSK_3"
start="2125" end="2285">
<PhysicalResources>
<Physical id="PRS_1" />
<Physical id="PRS_4" />
<Physical id="PRS_7" />
</PhysicalResources>
<HumanResources>
<Human name="Antonio" />
<Human name="Maria" />
<Human name="Manuel" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_3" productNumber="2" task="TSK_6"
start="2285" end="2370">
<PhysicalResources>
<Physical id="PRS_4" />
<Physical id="PRS_5" />
</PhysicalResources>
<HumanResources>
<Human name="Maria" />
<Human name="Susana" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_3" productNumber="2" task="TSK_7"
start="2370" end="2515">
<PhysicalResources>
<Physical id="PRS_3" />
<Physical id="PRS_1" />
<Physical id="PRS_4" />
</PhysicalResources>
<HumanResources>
<Human name="Antonio" />
<Human name="Maria" />
<Human name="Manuel" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_3" productNumber="2" task="TSK_9"
start="2515" end="2655">
<PhysicalResources>
<Physical id="PRS_7" />
<Physical id="PRS_1" />
<Physical id="PRS_4" />
</PhysicalResources>
<HumanResources>
<Human name="Maria" />
<Human name="Antonio" />
<Human name="Manuel" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_3" productNumber="3" task="TSK_2"
start="2655" end="2735">
<PhysicalResources>
<Physical id="PRS_5" />
<Physical id="PRS_7" />
</PhysicalResources>
<HumanResources>
<Human name="Maria" />
<Human name="Manuel" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_3" productNumber="3" task="TSK_3"
start="2735" end="2895">
<PhysicalResources>
<Physical id="PRS_1" />
<Physical id="PRS_4" />
<Physical id="PRS_7" />
</PhysicalResources>
<HumanResources>
<Human name="Antonio" />
<Human name="Maria" />
<Human name="Manuel" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_3" productNumber="3" task="TSK_6"
start="2895" end="2980">
<PhysicalResources>
<Physical id="PRS_4" />
<Physical id="PRS_5" />
</PhysicalResources>
<HumanResources>
<Human name="Maria" />
<Human name="Susana" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_3" productNumber="3" task="TSK_7"
start="2980" end="3125">
<PhysicalResources>
<Physical id="PRS_3" />
<Physical id="PRS_1" />
<Physical id="PRS_4" />
</PhysicalResources>
<HumanResources>
<Human name="Antonio" />
<Human name="Maria" />
<Human name="Manuel" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_3" productNumber="3" task="TSK_9"
start="3125" end="3265">
<PhysicalResources>
<Physical id="PRS_7" />
<Physical id="PRS_1" />
<Physical id="PRS_4" />
</PhysicalResources>
<HumanResources>
<Human name="Maria" />
<Human name="Antonio" />
<Human name="Manuel" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_4" productNumber="1" task="TSK_8"
start="3265" end="3300">
<PhysicalResources>
<Physical id="PRS_7" />
<Physical id="PRS_5" />
</PhysicalResources>
<HumanResources>
<Human name="Maria" />
<Human name="Susana" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_4" productNumber="1" task="TSK_7"
start="3300" end="3445">
<PhysicalResources>
<Physical id="PRS_3" />
<Physical id="PRS_1" />
<Physical id="PRS_4" />
</PhysicalResources>
<HumanResources>
<Human name="Antonio" />
<Human name="Maria" />
<Human name="Manuel" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_4" productNumber="1" task="TSK_6"
start="3445" end="3530">
<PhysicalResources>
<Physical id="PRS_4" />
<Physical id="PRS_5" />
</PhysicalResources>
<HumanResources>
<Human name="Maria" />
<Human name="Susana" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_4" productNumber="1" task="TSK_5"
start="3530" end="3590">
<PhysicalResources>
<Physical id="PRS_1" />
<Physical id="PRS_3" />
<Physical id="PRS_7" />
</PhysicalResources>
<HumanResources>
<Human name="Antonio" />
<Human name="Susana" />
<Human name="Maria" />
</HumanResources>
</TaskSchedule>
<TaskSchedule order="ORD_4" productNumber="1" task="TSK_10"
start="3590" end="3635">
<PhysicalResources>
<Physical id="PRS_1" />
<Physical id="PRS_7" />
<Physical id="PRS_3" />
</PhysicalResources>
<HumanResources>
<Human name="Antonio" />
<Human name="Maria" />
<Human name="Susana" />
</HumanResources>
</TaskSchedule>
</Schedule>
里程碑之一就是:
在这个里程碑中,将放宽对完整问题的一些限制。 此里程碑中生成计划的生成假设为: 1)产品按输入文件规定的顺序生产; 2)在设施中一次只处理一个任务 3)处理任务是唯一可以访问所有物理和人力资源的处理任务。 里程碑1的工件的执行应该提供最大的生产时间 输入订单。随后的里程碑将尝试改善这个生产时间。 示例:对于2个产品的一个订单,其中每个产品有2个任务
我的算法如下(几乎完美地工作):
package core
import reader._
import model._
import util.control.Breaks._
import scala.xml.XML
object Algorithm {
def initSchedule( listTasks: List[Task], listPhysical : List[Physical], listHResources: List[HumanResource], listProducts: List[Product], listOrders: List[Order]) = {
val (passToNext, finalList) = runOrders(0, listOrders, listPhysical, listHResources, listProducts, listTasks, List())
printToXML(finalList.reverse)
}
//old time first time is 0
def runOrders (oldTime: Int, ordersLeft: List[Order], listPhysical: List[Physical], listHResources: List[HumanResource], productList: List[Product], listTask: List[Task], listTaskSchedule: List[TaskSchedule]): (Int, List[TaskSchedule]) = {
ordersLeft match {
case Nil => (0, listTaskSchedule)
case order :: otherOrders => {
// get product information
val productToExecute = order.prdref
val productInstance = productList.filter(_.id.equalsIgnoreCase(productToExecute))(0)
val productId = productInstance.id
val processesToExecute = productInstance.processes
// time to pass from order to order
val (newTime, list) = repeatProcessByQuantity(order, oldTime, listPhysical, listHResources, processesToExecute, listTask, listTaskSchedule, 1, order.quantity.toInt)
runOrders(newTime, otherOrders, listPhysical, listHResources, productList, listTask, list)
}
}
}
def repeatProcessByQuantity(order: Order, oldTime: Int, listPhysical: List[Physical], listHResources: List[HumanResource], listProcesses: List[Process], listTasks: List[Task], listTaskSchedule : List[TaskSchedule], quantityIterator: Int, quantityToRepeat: Int ): (Int, List[TaskSchedule]) = {
quantityIterator match {
case `quantityToRepeat` => {
val (newTime, taskScheduleList) = runProcesses(order, oldTime, listPhysical,listHResources, listProcesses, listTasks, List(), quantityIterator, quantityToRepeat)
val newTaskScheduleList = taskScheduleList ::: listTaskSchedule
// return to main instance
(newTime, newTaskScheduleList)
}
case _ => {
val (newTime, taskScheduleList) = runProcesses(order, oldTime, listPhysical, listHResources, listProcesses, listTasks, List(), quantityIterator, quantityToRepeat)
val newTaskScheduleList = taskScheduleList ::: listTaskSchedule
// call recursive function again with new iterator
repeatProcessByQuantity(order, newTime, listPhysical, listHResources, listProcesses, listTasks, newTaskScheduleList, quantityIterator + 1, quantityToRepeat)
}
}
}
def runProcesses(order: Order, oldTime: Int, listPhysical: List[Physical], listHResources: List[HumanResource], listProcesses: List[Process], listTasks: List[Task], listTaskSchedule : List[TaskSchedule], quantity: Int, orderQty : Int ): (Int, List[TaskSchedule]) = {
listProcesses match {
case Nil => (oldTime, listTaskSchedule)
case currentOrder :: others => {
val taskId = currentOrder.tskref
val taskInstance = listTasks.filter(_.id.equalsIgnoreCase(taskId))(0)
// get physical resources and human resources list
val taskPhysicalResources = taskInstance.pResources
val newHumanResources = runHumanResources(taskInstance, taskPhysicalResources, listHResources, List())
// map to get all physicals from task physical resource
val newPhysicalList : List[Physical] = taskPhysicalResources.map(phResTask => {
val physicalCore = listPhysical.filter(_.phtype.equalsIgnoreCase(phResTask.prstype))(0)
val prsType = phResTask.prstype
new Physical(physicalCore.id, physicalCore.phtype)
}).toList
// new time is the old time + the time the task needs to run
val newTime = oldTime + taskInstance.time.toInt
val newQuantity = quantity - 1
val taskScheduleInstance = new TaskSchedule(order.id, order.quantity, newPhysicalList, newHumanResources, taskInstance.id, oldTime, newTime)
val newScheduleList = List(taskScheduleInstance) ::: listTaskSchedule
// call recursive function
runProcesses(order, newTime, listPhysical, listHResources, others, listTasks, newScheduleList, quantity, orderQty)
}
}
}
def runHumanResources(currentTask: Task, physicalResourcesList: List[PhysicalResource], listHResources: List[HumanResource], humanResources: List[HumanResource]): List[HumanResource] = {
physicalResourcesList match {
case Nil => {
(humanResources)
}
case physicalRes :: otherPhysicalRes => {
val prsType = physicalRes.prstype
val humansToPrstype = listHResources.find(_.handles.exists(_.handleType.equalsIgnoreCase(prsType)))
if(!humansToPrstype.isEmpty){
val humanInstance = humansToPrstype.get
val newHResourcesList = List(humanInstance) ::: humanResources
runHumanResources(currentTask, otherPhysicalRes, listHResources, newHResourcesList)
}
else {
//se nao encontrar
runHumanResources(currentTask, otherPhysicalRes, listHResources, humanResources)
}
}
}
}
}
第2部分 - 使用订单上的并行指令对其进行优化(订单可以同时运行,但其任务必须在没有并行命令的情况下运行 - 就像现在一样)。这是问题所在:
此里程碑试图通过允许多个任务来最小化完整的生产时间 同时进行。生产特定产品的任务不能包含在内 并行但是,两个或更多产品的相同订单的任务可以并行放置。在这种情况下, 优化按订单处理。 在这个里程碑中,生产计划的生成假定: 1)产品按输入文件规定的顺序生产; 2)一次可以执行多个任务 3)如果有足够的物理和工作,任务只能彼此并行执行。 人力资源。
有关如何处理此事的任何想法吗?