Überprüfen Sie alle - Scala
Geschätzte Punktzahl: 2m ^ n
Ich starte von jeder Maschine und iteriere über alle Aufgaben, um alle Permutationen durch die Aufgaben mit verschiedenen Maschinen zu erstellen, die die Fristen einhalten. Das heißt, wenn alles rechtzeitig ist, würde ich 9 mögliche Pfade mit 2 Maschinen und 3 Aufgaben erhalten. (m ^ n) Danach gehe ich den Weg mit den niedrigsten Kosten.
Die Eingabe ist wie folgt aufgebaut (-> erklärt die Teile und sollte daher nicht eingegeben werden):
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
Und hier ist der Code:
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)
}
}
Ich hatte auch die Idee, von hinten zu beginnen. Da Sie immer eine Maschine mit den niedrigsten Kosten wählen können, wenn die Zeit kleiner ist als die Differenz zwischen der vorherigen und der neuen Frist. Dies würde jedoch die maximale Laufzeit nicht verringern, wenn die Aufgabe mit den besseren Kosten länger dauert als die letzte Frist.
Aktualisieren
======
Hier ist eine andere Einstellung. Zeit:
M_1 2 2 2 7
M_2 1 8 5 10
Kosten:
M_1 4 4 4 4
M_2 1 1 1 1
Schaltzeit:
M_1 M_2
M_1 0 2
M_2 6 0
Wechselkosten:
M_1 M_2
M_1 0 2
M_2 2 0
Fristen:
5 10 15 20
Als Eingabe in mein Programm:
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
Dieser hat zwei Lösungen: Zeit: 18, Kosten: 15, Pfad: Liste (M_1, M_1, M_1, M_2) Zeit: 18, Kosten: 15, Pfad: Liste (M_2, M_1, M_1, M_1)
Was die Frage aufwirft, wie damit umgegangen werden soll. Sollten alle gedruckt werden oder nur einer? Und was wäre, wenn die Zeit anders wäre? Ist einer mit den niedrigsten Kosten und ohne versäumte Frist genug oder sollte es auch derjenige mit der niedrigsten Zeit sein?