操作系统课程设计 —— 磁盘调度算法
talk is easy, show the code
import java.util.*
import kotlin.math.abs
/**
* 磁盘调度算法工厂类, 构造器私有化, 防止外部类实例化
*/
class DiskScheduleFactory private constructor() {
/**
* 磁盘调度算法接口, 不对外开放
*/
private interface DiskScheduling {
/**
* 磁头移动路径数据
* @property moveCount Int
* @property allDistance Int
* @property lastPosition Int
* @constructor
*/
data class Data(val moveCount: Int, val allDistance: Int, val lastPosition: Int) {
/**
* 重载 + 号, 方便合并两部分数据
* @param other Data
* @return Data
*/
operator fun plus(other: Data) = Data(
other.moveCount + moveCount,
other.allDistance + allDistance,
lastPosition
)
/**
* 将数据以人类能看的方式显示出来
* @return String
*/
override fun toString(): String {
return "moveCount -> $moveCount allDistance = $allDistance"
}
}
/**
* 具体算法实现方法
* @param visitList IntArray
* @param currentPosition Int
* @param upList LinkedList<Int>
* @param downList LinkedList<Int>
*/
fun doStuff(visitList: IntArray, currentPosition: Int, upList: LinkedList<Int>, downList: LinkedList<Int>)
/**
* 遍历列表辅助方法
* @param visitList IntArray
* @param currentPosition Int
* @return Data
*/
fun forEach(visitList: IntArray, currentPosition: Int): Data {
var head = currentPosition
var currentDistance: Int
var allDistance = 0
var moveCount = 0
visitList.forEach {
currentDistance = abs(head - it)
println("磁头移动 $head -> $it, 移动距离为 $currentDistance")
head = it
allDistance += currentDistance
moveCount += 1
}
return Data(moveCount, allDistance, visitList.last())
}
/**
* 输出数据
* @param data Data
*/
fun outData(data: Data) {
println("总共移动了 ${data.moveCount} 下, 移动距离为 ${data.allDistance} 平均移动距离为 ${data.allDistance / data.moveCount}")
}
}
/**
* 算法实现枚举类, 不对外开放
*/
private enum class DiskScheduleImpl : DiskScheduling {
/**
* 先来先服务算法
*/
FCFS {
override fun doStuff(
visitList: IntArray,
currentPosition: Int,
upList: LinkedList<Int>,
downList: LinkedList<Int>
) {
outData(forEach(visitList, currentPosition))
}
},
/**
* 最短寻道时间算法
*/
SSTF {
override fun doStuff(
visitList: IntArray,
currentPosition: Int,
upList: LinkedList<Int>,
downList: LinkedList<Int>
) {
val allData = forEach(visitList.sortedWith(compareBy {
abs(it - currentPosition)
}).toIntArray(), currentPosition)
outData(allData)
}
},
/**
* 电梯算法 自下往上
*/
SCAN_UP {
override fun doStuff(
visitList: IntArray,
currentPosition: Int,
upList: LinkedList<Int>,
downList: LinkedList<Int>
) {
// 从大到小排序
downList.reverse()
// 先往上走
val upData = forEach(upList.toIntArray(), currentPosition)
// 再往上走
val downData = forEach(downList.toIntArray(), upData.lastPosition)
// 算出总共的
val allData = downData + upData
outData(allData)
}
},
/**
* 电梯算法 自上往下
*/
SCAN_DOWN {
override fun doStuff(
visitList: IntArray,
currentPosition: Int,
upList: LinkedList<Int>,
downList: LinkedList<Int>
) {
// 从大到小排序
downList.reverse()
// 先往下走
val downData = forEach(downList.toIntArray(), currentPosition)
// 再往上走
val upData = forEach(upList.toIntArray(), downData.lastPosition)
// 算出总共的
val allData = downData + upData
outData(allData)
}
},
/**
* 单项扫描算法
*/
C_SCAN {
override fun doStuff(
visitList: IntArray,
currentPosition: Int,
upList: LinkedList<Int>,
downList: LinkedList<Int>
) {
// 走到头后归零
downList.push(0)
// 先往上走
val upData = forEach(upList.toIntArray(), currentPosition)
// 再往上走
val downData = forEach(downList.toIntArray(), upData.lastPosition)
// 算出总共的
val allData = downData + upData
outData(allData)
}
}
}
/**
* 伴生对象, 创建实例的方法
*/
companion object {
private lateinit var instance: DiskScheduleImpl
/**
* 根据算法名获取相应的算法对象
* @param algorithm String
* @return DiskScheduleFactory
*/
fun getInstance(algorithm: String): DiskScheduleFactory {
runCatching {
instance = DiskScheduleImpl.valueOf(algorithm)
}.onFailure {
throw IllegalArgumentException("算法不支持!")
}
return DiskScheduleFactory()
}
}
/**
* 代理调用算法
* @param visitList IntArray
* @param currentPosition Int
*/
fun doStuff(visitList: IntArray, currentPosition: Int) {
val downList = LinkedList<Int>()
val upList = LinkedList<Int>()
// 除了先来先服务算法, 其他都需要升序排序
if (instance != DiskScheduleImpl.FCFS)
visitList.sort()
// 电梯算法和单向扫描算法需要分离上下层
if (
instance == DiskScheduleImpl.SCAN_DOWN ||
instance == DiskScheduleImpl.SCAN_UP ||
instance == DiskScheduleImpl.C_SCAN
) {
// 分离 上层 与 下层
visitList.forEach {
if (it <= currentPosition)
downList.add(it)
else
upList.add(it)
}
}
instance.doStuff(visitList, currentPosition, upList, downList)
}
object Main {
@JvmStatic
fun main(args: Array<String>) {
// 一共 8 条记录
val visitDisk = intArrayOf(98, 183, 37, 122, 14, 124, 65, 67)
DiskScheduleFactory.getInstance("SCAN_DOWN")
.doStuff(visitDisk, 53)
}
}