-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0bd12d5
commit e8e329c
Showing
7 changed files
with
417 additions
and
7 deletions.
There are no files selected for viewing
40 changes: 40 additions & 0 deletions
40
api/src/main/scala/system/schedulers/PriorityScheduler.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package system.schedulers | ||
|
||
import server.Schemas.PickupRequest | ||
import system.Direction | ||
import system.ElevatorCab | ||
|
||
object PriorityScheduler { | ||
|
||
def findBestCab(elevatorCabs: List[ElevatorCab], request: PickupRequest, floorQuantity: Int) | ||
: ElevatorCab = { | ||
val scoredCabs = elevatorCabs.map { cab => | ||
val distanceScore = Math.abs(cab.currentFloor - request.fromFloor) | ||
val directionScore = | ||
if ( | ||
cab.direction == Direction.Idle || | ||
cab.direction == Direction.MovingUp && request.direction > 0 && cab.currentFloor <= request.fromFloor || | ||
cab.direction == Direction.MovingDown && request.direction < 0 && cab.currentFloor >= request.fromFloor | ||
) | ||
0 | ||
else | ||
Int.MaxValue | ||
val requestsSizeScore = cab.dropRequests.size * .5 | ||
(cab, distanceScore + directionScore + requestsSizeScore) | ||
} | ||
|
||
val bestCab = scoredCabs.minBy(_._2)._1 | ||
bestCab | ||
} | ||
|
||
} | ||
|
||
// val requestThatCanChangeDirection = cab | ||
// .dropRequests | ||
// .minBy(r => | ||
// if (request.direction > 0) | ||
// r.targetFloor | ||
// else | ||
// -r.targetFloor | ||
// ) | ||
// Math.abs(request.fromFloor - requestThatCanChangeDirection.targetFloor) |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import org.scalatest.funsuite.AnyFunSuite | ||
import server.Schemas.DropRequest | ||
import server.Schemas.PickupRequest | ||
import system.Building | ||
import system.ElevatorCab | ||
|
||
import scala.collection.immutable.HashMap | ||
import scala.collection.immutable.SortedSet | ||
|
||
class BuildingTest extends AnyFunSuite { | ||
implicit val dropRequestOrdering: Ordering[DropRequest] = Ordering.by(_.targetFloor) | ||
|
||
test("Add person waiting on a specific floor") { | ||
val initialFloors = HashMap(1 -> 0, 2 -> 0, 3 -> 0) | ||
val building = Building(initialFloors, List(), List()) | ||
|
||
val updatedBuilding = building.addPersonWaitingOnFloor(2) | ||
|
||
assert(updatedBuilding.floors(1) == 0) | ||
assert(updatedBuilding.floors(2) == 1) | ||
assert(updatedBuilding.floors(3) == 0) | ||
} | ||
|
||
test("Add multiple pickup requests") { | ||
val initialFloors = HashMap(1 -> 0, 2 -> 0, 3 -> 0, 4 -> 0) | ||
val pickupRequests = List( | ||
PickupRequest(2, 1), | ||
PickupRequest(3, -1), | ||
PickupRequest(2, 1), | ||
) | ||
val building = Building(initialFloors, List(), List()) | ||
|
||
val updatedBuilding = building.addPickupRequests(pickupRequests) | ||
|
||
assert(updatedBuilding.floors(1) == 0) | ||
assert(updatedBuilding.floors(2) == 2) | ||
assert(updatedBuilding.floors(3) == 1) | ||
assert(updatedBuilding.floors(4) == 0) | ||
assert(updatedBuilding.outsideRequests == pickupRequests) | ||
} | ||
|
||
test("Add person waiting on an already populated floor") { | ||
val initialFloors = HashMap(1 -> 1, 2 -> 3, 3 -> 0) | ||
val building = Building(initialFloors, List(), List()) | ||
|
||
val updatedBuilding = building.addPersonWaitingOnFloor(2) | ||
|
||
assert(updatedBuilding.floors(1) == 1) | ||
assert(updatedBuilding.floors(2) == 4) | ||
assert(updatedBuilding.floors(3) == 0) | ||
} | ||
|
||
test("Add pickup requests with existing requests") { | ||
val initialFloors = HashMap(1 -> 1, 2 -> 2, 3 -> 0) | ||
val existingRequests = List(PickupRequest(1, 1)) | ||
val newRequests = List( | ||
PickupRequest(2, 1), | ||
PickupRequest(3, -1), | ||
) | ||
val building = Building(initialFloors, List(), existingRequests) | ||
|
||
val updatedBuilding = building.addPickupRequests(newRequests) | ||
|
||
assert(updatedBuilding.floors(1) == 1) | ||
assert(updatedBuilding.floors(2) == 3) | ||
assert(updatedBuilding.floors(3) == 1) | ||
assert(updatedBuilding.outsideRequests == existingRequests ++ newRequests) | ||
} | ||
|
||
test("Add pickup request and check elevators unchanged") { | ||
val initialFloors = HashMap(1 -> 0, 2 -> 0, 3 -> 0) | ||
val initialCabs = List(ElevatorCab(1, 1, SortedSet(DropRequest(2)))) | ||
val pickupRequests = List(PickupRequest(2, 1)) | ||
val building = Building(initialFloors, initialCabs, List()) | ||
|
||
val updatedBuilding = building.addPickupRequests(pickupRequests) | ||
|
||
assert(updatedBuilding.floors(1) == 0) | ||
assert(updatedBuilding.floors(2) == 1) | ||
assert(updatedBuilding.floors(3) == 0) | ||
assert(updatedBuilding.elevatorCabs == initialCabs) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package system | ||
|
||
import org.scalatest.funsuite.AnyFunSuite | ||
import server.Schemas.DropRequest | ||
import server.Schemas.PickupRequest | ||
import system.Building | ||
import system.ElevatorCab | ||
|
||
import scala.collection.immutable.HashMap | ||
import scala.collection.immutable.SortedSet | ||
|
||
class ElevatorCabSuite extends AnyFunSuite { | ||
implicit val dropRequestOrdering: Ordering[DropRequest] = Ordering.by(_.targetFloor) | ||
|
||
test("Get target floor when moving up") { | ||
val dropRequests = SortedSet(DropRequest(5), DropRequest(10))(dropRequestOrdering) | ||
val elevator = ElevatorCab(1, 3, dropRequests, Direction.MovingUp) | ||
assert(elevator.targetFloor.contains(5)) | ||
} | ||
|
||
test("Get target floor when moving down") { | ||
val dropRequests = | ||
SortedSet(DropRequest(1), DropRequest(2), DropRequest(5))(dropRequestOrdering) | ||
val elevator = ElevatorCab(1, 4, dropRequests, Direction.MovingDown) | ||
assert(elevator.targetFloor.contains(2)) | ||
} | ||
|
||
test("Get target floor when idle") { | ||
val dropRequests = SortedSet(DropRequest(1), DropRequest(2))(dropRequestOrdering) | ||
val elevator = ElevatorCab(1, 4, dropRequests, Direction.Idle) | ||
assert(elevator.targetFloor.isEmpty) | ||
} | ||
|
||
test("Step when moving up") { | ||
val dropRequests = SortedSet(DropRequest(5))(dropRequestOrdering) | ||
val elevator = ElevatorCab(1, 3, dropRequests, Direction.MovingUp) | ||
val updatedElevator = elevator.step | ||
assert(updatedElevator.currentFloor == 4) | ||
} | ||
|
||
test("Step when moving down") { | ||
val dropRequests = SortedSet(DropRequest(1))(dropRequestOrdering) | ||
val elevator = ElevatorCab(1, 3, dropRequests, Direction.MovingDown) | ||
val updatedElevator = elevator.step | ||
assert(updatedElevator.currentFloor == 2) | ||
} | ||
|
||
test("Step when idle and on target floor") { | ||
val dropRequests = SortedSet(DropRequest(3))(dropRequestOrdering) | ||
val elevator = ElevatorCab(1, 3, dropRequests, Direction.Idle) | ||
val updatedElevator = elevator.step | ||
assert(updatedElevator.dropRequests.isEmpty) | ||
} | ||
|
||
test("Add new request when idle") { | ||
val dropRequests = SortedSet(DropRequest(5))(dropRequestOrdering) | ||
val elevator = ElevatorCab(1, 3, SortedSet.empty, Direction.Idle) | ||
val updatedElevator = elevator.addNewRequest(DropRequest(5)) | ||
assert(updatedElevator.dropRequests.contains(DropRequest(5))) | ||
assert(updatedElevator.direction == Direction.MovingUp) | ||
} | ||
|
||
test("Add new request when moving up") { | ||
val dropRequests = SortedSet(DropRequest(7))(dropRequestOrdering) | ||
val elevator = ElevatorCab(1, 5, dropRequests, Direction.MovingUp) | ||
val updatedElevator = elevator.addNewRequest(DropRequest(9)) | ||
assert(updatedElevator.dropRequests.contains(DropRequest(9))) | ||
assert(updatedElevator.direction == Direction.MovingUp) | ||
} | ||
|
||
test("Add new request when moving down") { | ||
val dropRequests = SortedSet(DropRequest(3))(dropRequestOrdering) | ||
val elevator = ElevatorCab(1, 5, dropRequests, Direction.MovingDown) | ||
val updatedElevator = elevator.addNewRequest(DropRequest(1)) | ||
assert(updatedElevator.dropRequests.contains(DropRequest(1))) | ||
assert(updatedElevator.direction == Direction.MovingDown) | ||
} | ||
|
||
test("Add multiple requests when idle") { | ||
val dropRequests = Seq(DropRequest(5), DropRequest(2)) | ||
val expectedDropRequests = SortedSet(DropRequest(2), DropRequest(5))(dropRequestOrdering) | ||
val elevator = ElevatorCab(1, 3, SortedSet.empty, Direction.Idle) | ||
val updatedElevator = elevator.addMultipleRequests(dropRequests) | ||
assert(updatedElevator.dropRequests == expectedDropRequests) | ||
assert(updatedElevator.direction == Direction.MovingDown) | ||
} | ||
|
||
test("Add multiple requests when moving up") { | ||
val initialRequests = SortedSet(DropRequest(7))(dropRequestOrdering) | ||
val newRequests = Seq(DropRequest(9), DropRequest(10)) | ||
val elevator = ElevatorCab(1, 5, initialRequests, Direction.MovingUp) | ||
val updatedElevator = elevator.addMultipleRequests(newRequests) | ||
assert( | ||
updatedElevator.dropRequests == SortedSet(DropRequest(7), DropRequest(9), DropRequest(10)) | ||
) | ||
assert(updatedElevator.direction == Direction.MovingUp) | ||
} | ||
|
||
test("Add multiple requests when moving down") { | ||
val initialRequests = SortedSet(DropRequest(3))(dropRequestOrdering) | ||
val newRequests = Seq(DropRequest(1), DropRequest(2)) | ||
val elevator = ElevatorCab(1, 5, initialRequests, Direction.MovingDown) | ||
val updatedElevator = elevator.addMultipleRequests(newRequests) | ||
assert( | ||
updatedElevator.dropRequests == SortedSet(DropRequest(1), DropRequest(2), DropRequest(3)) | ||
) | ||
assert(updatedElevator.direction == Direction.MovingDown) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package system | ||
|
||
import org.scalatest.funsuite.AnyFunSuite | ||
import server.Schemas.{DropRequest, PickupRequest} | ||
|
||
import scala.collection.immutable.HashMap | ||
import scala.util.Random | ||
|
||
class SimulationSuite extends AnyFunSuite { | ||
implicit val dropRequestOrdering: Ordering[DropRequest] = Ordering.by(_.targetFloor) | ||
private final val RNG_SEED = 42 | ||
private final val RANDOM = new Random(RNG_SEED) | ||
private final val CAB_QUANTITY = 16 | ||
private final val FLOORS = 10 | ||
private final val MAX_PICKUP_REQUESTS_PER_STEP = 10 | ||
|
||
class SimulationTest extends AnyFunSuite { | ||
|
||
test("Generate Building") { | ||
val building = Simulation.generateBuilding() | ||
assert(building.floors.size == FLOORS) | ||
assert(building.floors.forall(_._2 == 0)) | ||
assert(building.elevatorCabs.size == CAB_QUANTITY) | ||
assert(building.outsideRequests.isEmpty) | ||
} | ||
|
||
test("Run Simulation Step") { | ||
val initialBuilding = Simulation.generateBuilding() | ||
val updatedBuilding = Simulation.run(initialBuilding) | ||
|
||
assert(updatedBuilding.floors.size == FLOORS) | ||
assert(updatedBuilding.elevatorCabs.size == CAB_QUANTITY) | ||
} | ||
|
||
test("Simulation handles new requests correctly") { | ||
val initialBuilding = Simulation.generateBuilding() | ||
val newRequests = List(PickupRequest(1, 1), PickupRequest(2, -1)) | ||
val buildingWithNewRequests = initialBuilding.addPickupRequests(newRequests) | ||
assert(buildingWithNewRequests.outsideRequests == newRequests) | ||
assert(newRequests.forall(req => buildingWithNewRequests.floors(req.fromFloor) > 0)) | ||
} | ||
} | ||
|
||
} |
37 changes: 37 additions & 0 deletions
37
api/src/test/scala/system/schedulers/FIFOSchedulerSuite.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package system.schedulers | ||
|
||
import org.scalatest.funsuite.AnyFunSuite | ||
import server.Schemas.DropRequest | ||
import server.Schemas.PickupRequest | ||
import system.ElevatorCab | ||
import system.schedulers.FIFOScheduler.findBestCab | ||
|
||
import scala.collection.immutable.SortedSet | ||
|
||
class FIFOSchedulerSuite extends AnyFunSuite { | ||
implicit val dropRequestOrdering: Ordering[DropRequest] = Ordering.by(_.targetFloor) | ||
|
||
test("Single Elevator") { | ||
val elevator = ElevatorCab(1, 1, SortedSet(DropRequest(3))) | ||
val request = PickupRequest(5, 1) | ||
val result = findBestCab(List(elevator), request, 10) | ||
assert(result == elevator) | ||
} | ||
|
||
test("Second elevator is closer") { | ||
val elevator1 = ElevatorCab(1, 1, SortedSet(DropRequest(3))) | ||
val elevator2 = ElevatorCab(2, 4, SortedSet(DropRequest(4))) | ||
val request = PickupRequest(5, 1) | ||
val result = findBestCab(List(elevator1), request, 10) | ||
assert(result == elevator1) | ||
} | ||
|
||
test("Second elevator is already on the pickup floor") { | ||
val elevator1 = ElevatorCab(1, 1, SortedSet(DropRequest(3))) | ||
val elevator2 = ElevatorCab(2, 4, SortedSet(DropRequest(2))) | ||
val request = PickupRequest(4, 1) | ||
val result = findBestCab(List(elevator1, elevator2), request, 10) | ||
assert(result == elevator1) | ||
} | ||
|
||
} |
Oops, something went wrong.