ตรวจสอบทั้งหมด - สกาล่า
คะแนนโดยประมาณ: 2m ^ n
ฉันเริ่มจากแต่ละเครื่องและวนซ้ำทุกงานเพื่อสร้างการเรียงสับเปลี่ยนทั้งหมดผ่านงานด้วยเครื่องจักรต่าง ๆ ที่ตรงตามกำหนดเวลา หมายความว่าถ้าทุกอย่างตรงเวลาฉันจะได้ 9 เส้นทางที่เป็นไปได้ด้วย 2 เครื่องและ 3 งาน (m ^ n) หลังจากนั้นฉันใช้เส้นทางด้วยต้นทุนที่ต่ำที่สุด
อินพุตมีโครงสร้างเช่นนี้ (-> อธิบายชิ้นส่วนดังนั้นจึงไม่ควรป้อน):
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
และนี่คือรหัส:
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)
}
}
ฉันมีความคิดที่จะเริ่มจากด้านหลัง เนื่องจากคุณสามารถเลือกเครื่องที่มีต้นทุนต่ำที่สุดได้เสมอหากเวลามีขนาดเล็กลงดังนั้นความแตกต่างจากกำหนดเวลาก่อนหน้าไปยังเครื่องใหม่ แต่นั่นจะไม่ลดรันไทม์สูงสุดหากงานที่มีต้นทุนดีกว่าใช้เวลานานกว่ากำหนดเวลาสุดท้าย
ปรับปรุง
======
นี่คือการตั้งค่าอื่น เวลา:
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_2
M_1 0 2
M_2 6 0
เปลี่ยนค่าใช้จ่าย:
M_1 M_2
M_1 0 2
M_2 2 0
กำหนดเวลา:
5 10 15 20
เมื่อป้อนเข้าสู่โปรแกรมของฉัน:
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
วิธีนี้มีสองวิธี: เวลา: 18, ราคา: 15, เส้นทาง: รายการ (M_1, M_1, M_1, M_2) เวลา: 18, ราคา: 15, เส้นทาง: รายการ (M_2, M_1, M_1, M_1)
ซึ่งทำให้เกิดคำถามว่าจะจัดการอย่างไร ควรจะพิมพ์ทั้งหมดหรือเพียงหนึ่ง? และถ้าเวลาจะแตกต่างกันอย่างไร เป็นหนึ่งเดียวที่มีต้นทุนต่ำสุดและไม่พลาดกำหนดเวลามากพอหรือควรเป็นเวลาที่มีเวลาต่ำสุดหรือไม่