Код: Выделить всё
@Serializable
class Env(
override var time: Int,
override var workstationPool: List,
override var jobPool: MutableList,
override val jobArrivalEvents: List,
override val breakdownEvents: List
,
) : AbstractEnvironment() {
override fun step(actionMap: Pair)
: Triple {
handleJobEvents()
handleDisruptiveEvents()
for (workstation in workstationPool) {
if (actionMap.second[workstation.id] != null) {
workstation.allocateOperation(actionMap.second[workstation.id]!!, time)
}
workstation.process(time)
}
val timeBufferList = mutableListOf()
for (job in jobPool) {
if (actionMap.first[job.id] == OrderAction.RELEASE && job.getState() == OrderState.RESTRICTED) {
logger.info { "Releasing order ${job.name}" }
job.release(time)
}
job.updateOrder(time)
timeBufferList.addAll(job.getTimeBufferList())
}
jobPool.forEach { job ->
job.updateShopCapacity(
workstationPool.count { it.state != WorkstationState.FAILURE },
jobPool.count { it.getState() == OrderState.PROCESSING }
)
job.details.operations.filter { it.assignee == null }.forEach { operationDetails ->
val relTimeBuffer = if (timeBufferList.max() != 0) operationDetails.timeBuffer.div(timeBufferList.max().toFloat()) else 1F
operationDetails.relTimeBuffer = relTimeBuffer
}
}
time += 1
val terminated = jobPool.all { it.getState() == OrderState.DONE }
return Triple(terminated, workstationPool, jobPool)
}
fun deepCopy(): DiscreteSchedulingEnv {
return deepCopy(this)
}
}
Код: Выделить всё
@Serializable
data class WorkstationDetails(
val id: Long,
val name: String,
@EncodeDefault var state: WorkstationState = WorkstationState.IDLE,
@EncodeDefault var workload: Int = 0,
@EncodeDefault var numSetupChanges: Int = 0,
@EncodeDefault var operationLog: MutableList = mutableListOf(),
@EncodeDefault var downtime: Int = 0,
@EncodeDefault val breakdownEvents: MutableList
= mutableListOf()
) {}
@Serializable
class Workstation(val assetDetails: WorkstationDetails):
AbstractAsset() {
override val id: Long = assetDetails.id
override val name: String = assetDetails.name
override val clientConfiguration: ClientConfiguration
get() = TODO("Not yet implemented")
var state: WorkstationState
get() = assetDetails.state
private set(value) {
assetDetails.state = value
}
private var allocatedOperation: OperationDetails? = null
fun getAllocatedOperation(): OperationDetails?{
return allocatedOperation
}
fun allocateOperation(operation: OperationDetails, time: Int) {
if (state != WorkstationState.IDLE ) return
if (allocatedOperation == null) {
allocatedOperation = operation
allocatedOperation!!.startTime = time
allocatedOperation!!.assignee = id
val setupTime = operation.getSetupTimeForProductType(getProductTypeOfLastOperation())
allocatedOperation!!.setupTime = setupTime
allocatedOperation!!.remainingSetupTime = setupTime
if (getProductTypeOfLastOperation() != null){
if (getProductTypeOfLastOperation() != operation.orderDetailsType) assetDetails.numSetupChanges += 1
} else assetDetails.numSetupChanges += 1
allocatedOperation!!.plannedEndTime = time + allocatedOperation!!.setupTime + allocatedOperation!!.duration
}
}
fun process(time: Int) {
when (state) {
WorkstationState.IDLE -> processTaskAllocation()
WorkstationState.PROCESSING -> handleTaskExecution(allocatedOperation!!, time)
WorkstationState.FAILURE -> {
assetDetails.downtime += 1
if (allocatedOperation != null) {
logger.info { "Workstation $id can not process operation (ID / name) ${allocatedOperation!!.name} / ${allocatedOperation!!.name} due to an existing breakdown." }
}
}
}
}
}
Код: Выделить всё
@Serializable
data class OrderDetails(
val id: Long,
val name: String,
val type: ProductType,
@EncodeDefault val description: String = "",
@EncodeDefault var timeBuffer: Int = 0,
val operations: List,
@EncodeDefault var incomeTime: Int = 0,
@EncodeDefault val plannedDeliveryTime: Int = 0,
@EncodeDefault var actualDeliveryTime: Int = 0,
@EncodeDefault var releaseTime: Int = 0,
@EncodeDefault var shopCapacity: Int = 0,
@EncodeDefault var state: OrderState = OrderState.RESTRICTED
) {}
@Serializable
class Order(override val id: Long,
val productType: ProductType,
val deliveryTime: Int,
val incomeTime: Int = 0
) : AbstractAsset() {
override var name: String = "$productType-order-$id"
private var operations = getOperations(productType) // fixme - getters not included in serialization
private var orderDetails: OrderDetails = OrderDetails(
id = id,
type = productType,
name = name,
operations = operations,
plannedDeliveryTime = deliveryTime,
incomeTime = incomeTime
)
override val clientConfiguration: ClientConfiguration
get() = TODO("Not yet implemented")
fun getState(): OrderState {
return orderDetails.state
}
val details: OrderDetails get() = orderDetails
fun release(time: Int) {
if (orderDetails.state != OrderState.RESTRICTED) return
orderDetails.state = OrderState.PROCESSING
orderDetails.releaseTime = time
}
fun updateOrder(time: Int) {
when (orderDetails.state) {
OrderState.RESTRICTED -> {
updateDeliveryTimeBuffer(time)
logger.info { "Order $name is not released yet." }
}
OrderState.PROCESSING -> {
orderDetails.operations.filter { it.state == OperationState.RESTRICTED }.forEach { updateOperationState(it) }
if (orderDetails.operations.all { it.state == OperationState.DONE }) {
orderDetails.state = OrderState.DONE
orderDetails.actualDeliveryTime = time
orderDetails.timeBuffer = orderDetails.plannedDeliveryTime.minus(time)
logger.info { "Order $name is finished." }
}
else {
updateDeliveryTimeBuffer(time)
logger.info { "Order $name is in process." }
}
}
OrderState.DONE -> logger.info { "Order $name is finished." }
}
}
}
Код: Выделить всё
@Serializable
data class OperationDetails(
val id: Long,
val duration: Int,
val name: String,
val previous: List,
var cumulativeProcessTime: Int = 0,
var orderDetailsType: ProductType,
var orderDetailsName: String = "",
@EncodeDefault var assignee: Long? = null,
@EncodeDefault var startTime: Int? = null,
@EncodeDefault var timeBuffer: Int = 0,
@EncodeDefault var setupTime: Int = 0,
@EncodeDefault var remainingProcessTime: Int = duration,
@EncodeDefault var remainingSetupTime: Int = setupTime,
@EncodeDefault var plannedEndTime: Int = 0,
@EncodeDefault var actualEndTime: Int = 0,
@EncodeDefault var state: OperationState = OperationState.RESTRICTED,
@EncodeDefault var relTimeBuffer: Float = 0F,
@EncodeDefault val setupTimeMatrix: MutableMap
> = OrderSetupMatrix.setupTimeMatrix
) {}
@Serializable
class Operation(override val id: Long, override val name: String, val assetDetails: OperationDetails
) : AbstractAsset(){
override val clientConfiguration: ClientConfiguration
get() = TODO("Not yet implemented")
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Operation
if (id != other.id) return false
if (name != other.name) return false
if (assetDetails != other.assetDetails) return false
return true
}
override fun hashCode(): Int {
var result = id.hashCode()
result = 31 * result + name.hashCode()
result = 31 * result + assetDetails.hashCode()
return result
}
}
Код: Выделить всё
@Serializable
data class BreakdownEvent(
val workstationId: Long,
val startTime: Int,
var endTime: Int?
)
@Serializable
data class JobArrivalEvent(
val arrivalTime: Int,
val deliveryTime: Int,
val productType: ProductType,
)
Код: Выделить всё
object SerializationUtil {
inline fun deepCopy(obj: T): T {
val json = Json
val jsonString = json.encodeToString(serializer(), obj)
return json.decodeFromString(serializer(), jsonString)
}
}
Подробнее здесь: https://stackoverflow.com/questions/785 ... g-serializ