Tümünü Kontrol Et - Scala
Tahmini puan: 2m ^ n
Her makineden başlıyorum ve son teslim tarihlerini karşılayan farklı makinelerle görevler aracılığıyla tüm permütasyonları oluşturmak için tüm görevleri tekrar ediyorum. Eğer her şey zamanında olursa, 2 makine ve 3 görev ile 9 olası yol elde edeceğim. (m ^ n) Daha sonra, en düşük maliyetle yola çıkıyorum.
Girdi şu şekilde yapılandırılmıştır (-> parçaları açıklar ve dolayısıyla girilmemelidir):
M_1:5 3 5 4;M_2:4 2 7 5 --> time
M_1:5 4 2 6;M_2:3 7 3 3 --> cost
M_1:M_1}0 M_2}1;M_2:M_1}2 M_2}0 --> switch itme
M_1:M_1}0 M_2}2;M_2:M_1}1 M_2}0 --> switch cost
5 10 15 20 --> deadlines
Ve işte kod:
package Scheduling
import scala.io.StdIn.readLine
case class Cost(task: Map[String, List[Int]])
case class Switch(machine: Map[String, Map[String, Int]])
case class Path(time: Int, cost: Int, machine: List[String])
object Main {
def main(args: Array[String]) {
val (machines, cost_time, cost_money, switch_time, switch_money, deadlines) = getInput
val s = new Scheduler(machines, cost_time, cost_money, switch_time, switch_money, deadlines)
s.schedule
}
def getInput(): (List[String], Cost, Cost, Switch, Switch, List[Int]) = {
val cost_time = Cost(readLine("time to complete task").split(";").map{s =>
val parts = s.split(":")
(parts(0) -> parts(1).split(" ").map(_.toInt).toList)
}.toMap)
val cost_money = Cost(readLine("cost to complete task").split(";").map{s =>
val parts = s.split(":")
(parts(0) -> parts(1).split(" ").map(_.toInt).toList)
}.toMap)
val switch_time = Switch(readLine("time to switch").split(";").map{s =>
val parts = s.split(":")
(parts(0) -> parts(1).split(" ").map{t =>
val entries = t.split("}")
(entries(0) -> entries(1).toInt)
}.toMap)
}.toMap)
val switch_money = Switch(readLine("time to switch").split(";").map{s =>
val parts = s.split(":")
(parts(0) -> parts(1).split(" ").map{t =>
val entries = t.split("}")
(entries(0) -> entries(1).toInt)
}.toMap)
}.toMap)
val deadlines = readLine("deadlines").split(" ").map(_.toInt).toList
val machines = cost_time.task.keys.toList
(machines, cost_time, cost_money, switch_time, switch_money, deadlines)
}
}
class Scheduler(machines: List[String], cost_time: Cost, cost_money: Cost, switch_time: Switch, switch_money: Switch, deadlines: List[Int]) {
def schedule() {
var paths = List[Path]()
var alternatives = List[(Int, Path)]()
for (i <- machines) {
if (cost_time.task(i)(0) <= deadlines(0)) {
paths = paths ::: List(Path(cost_time.task(i)(0), cost_money.task(i)(0), List(i)))
}
}
val allPaths = deadlines.zipWithIndex.tail.foldLeft(paths)((paths, b) => paths.flatMap(x => calculatePath(x, b._1, b._2)))
if (allPaths.isEmpty) {
println("It is not possible")
} else {
println(allPaths.minBy(p=>p.cost).machine)
}
}
def calculatePath(prev: Path, deadline: Int, task: Int): List[Path] = {
val paths = machines.map(m => calculatePath(prev, task, m))
paths.filter(p => p.time <= deadline)
}
def calculatePath(prev: Path, task: Int, machine: String): Path = {
val time = prev.time + switch_time.machine(prev.machine.last)(machine) + cost_time.task(machine)(task)
val cost = prev.cost + switch_money.machine(prev.machine.last)(machine) + cost_money.task(machine)(task)
Path(time, cost, prev.machine :+ machine)
}
}
Ayrıca arkadan başlamak için bir fikrim vardı. Zaman daha küçükse, her zaman en düşük maliyetle bir makine seçebileceğinizden, önceki son tarihten yeni bir makineye olan fark. Ancak, daha iyi maliyete sahip görev son süreden daha uzun sürerse, maksimum çalışma süresini azaltmaz.
Güncelleme
======
İşte başka bir kurulum. süresi:
M_1 2 2 2 7
M_2 1 8 5 10
maliyet:
M_1 4 4 4 4
M_2 1 1 1 1
geçiş zamanı:
M_1 M_2
M_1 0 2
M_2 6 0
anahtar maliyeti:
M_1 M_2
M_1 0 2
M_2 2 0
tarihleri:
5 10 15 20
Programıma girdi olarak:
M_1:2 2 2 7;M_2:1 8 5 10
M_1:4 4 4 4;M_2:1 1 1 1
M_1:M_1}0 M_2}2;M_2:M_1}6 M_2}0
M_1:M_1}0 M_2}2;M_2:M_1}2 M_2}0
5 10 15 20
Bunun iki çözümü vardır: zaman: 18, maliyet: 15, yol: Liste (M_1, M_1, M_1, M_2) zaman: 18, maliyet: 15, yol: Liste (M_2, M_1, M_1, M_1)
Bu da bunun nasıl ele alınması gerektiği sorusunu gündeme getiriyor. Hepsi yazdırılmalı mı yoksa sadece bir tane mi yazdırılmalıdır? Ya zaman farklı olsaydı? En düşük maliyete ve kaçırılmış son teslim tarihine sahip biri yeterli mi yoksa en düşük süreye sahip olanı da olmalı mı?