Skip to content

Commit

Permalink
Bug fixes: Fix hang when clearing reqs in both dirn at same floor
Browse files Browse the repository at this point in the history
Bug fixes:
 * Fixed an issue where the program would sometimes hang (infinte loop) when using `clearRequestType = inDirn` (default) when there was both hall up and down requests at the same floor.
  • Loading branch information
klasbo committed Apr 16, 2018
1 parent 42b1fb2 commit 7e48074
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 17 deletions.
10 changes: 6 additions & 4 deletions cost_fns/hall_request_assigner/elevator_algorithm.d
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,16 @@ ElevatorState clearReqsAtFloor(ElevatorState e, void delegate(CallType c) onClea

final switch(e.direction) with(Dirn){
case up:
clear(CallType.hallUp);
if(!e2.requestsAbove){
if(e2.requests[e2.floor][CallType.hallUp]){
clear(CallType.hallUp);
} else if(!e2.requestsAbove){
clear(CallType.hallDown);
}
break;
case down:
clear(CallType.hallDown);
if(!e2.requestsBelow){
if(e2.requests[e2.floor][CallType.hallDown]){
clear(CallType.hallDown);
} else if(!e2.requestsBelow){
clear(CallType.hallUp);
}
break;
Expand Down
49 changes: 49 additions & 0 deletions cost_fns/hall_request_assigner/main.d
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,53 @@ unittest {

string output = optimalHallRequests(i.hallRequests.to!(bool[2][]), i.states).jsonEncode;
assert(output == correctOutput);

}

unittest {
import std.regex;

auto prev = includeCab;
includeCab = true;
scope(exit) includeCab = prev;

Input i = jsonDecode!Input(q{
{
"hallRequests":
[[true,false],[false,false],[true,true],[false,false]],
"states" : {
"a" : {
"behaviour":"doorOpen",
"floor":1,
"direction":"down",
"cabRequests":[false,false,false,false]
},
"b" : {
"behaviour":"moving",
"floor":0,
"direction":"up",
"cabRequests":[true,true,true,true]
},
"c" : {
"behaviour":"moving",
"floor":3,
"direction":"down",
"cabRequests":[false,false,false,false]
}
}
}
}.replaceAll(regex(r"\s"), ""));

string correctOutput = q{
{
"a" : [[true,false,false],[false,false,false],[false,false,false],[false,false,false]],
"b" : [[false,false,true],[false,false,true],[false,false,true],[false,false,true]],
"c" : [[false,false,false],[false,false,false],[true,true,false],[false,false,false]]
}
}.replaceAll(regex(r"\s"), "");

string output = optimalHallRequests(i.hallRequests.to!(bool[2][]), i.states).jsonEncode;
assert(output == correctOutput);

}

37 changes: 24 additions & 13 deletions cost_fns/hall_request_assigner/optimal_hall_requests.d
Original file line number Diff line number Diff line change
Expand Up @@ -160,25 +160,27 @@ void performSingleMove(ref State s, ref Req[2][] reqs){

debug(optimal_hall_requests) writefln("single move: %s", s);

auto e = s.withReqs!(a => a.active && (a.assignedTo == string.init || a.assignedTo == s.id))(reqs);
auto e = s.withReqs!(a => a.active && (a.assignedTo == string.init))(reqs);

debug(optimal_hall_requests) writefln("%s", e);

auto onClearRequest = (CallType c){
final switch(c) with(CallType){
case hallUp, hallDown:
reqs[s.state.floor][c].assignedTo = s.id;
break;
case cab:
s.state.cabRequests[s.state.floor] = false;
}
};

final switch(s.state.behaviour) with(ElevatorBehaviour){
case moving:
if(e.shouldStop){
debug(optimal_hall_requests) writefln(" stopping");
s.state.behaviour = doorOpen;
s.time += doorOpenDuration.msecs;
e.clearReqsAtFloor((CallType c){
final switch(c) with(CallType){
case hallUp, hallDown:
reqs[s.state.floor][c].assignedTo = s.id;
break;
case cab:
s.state.cabRequests[s.state.floor] = false;
}
});
e.clearReqsAtFloor(onClearRequest);
} else {
debug(optimal_hall_requests) writefln(" continuing");
s.state.floor += s.state.direction;
Expand All @@ -187,9 +189,14 @@ void performSingleMove(ref State s, ref Req[2][] reqs){
break;
case idle, doorOpen:
s.state.direction = e.chooseDirection;
if(s.state.direction == Dirn.stop){
s.state.behaviour = idle;
debug(optimal_hall_requests) writefln(" idling");
if(s.state.direction == Dirn.stop){
if(e.anyRequestsAtFloor){
e.clearReqsAtFloor(onClearRequest);
debug(optimal_hall_requests) writefln(" taking req in opposite dirn");
} else {
s.state.behaviour = idle;
debug(optimal_hall_requests) writefln(" idling");
}
} else {
s.state.behaviour = moving;
debug(optimal_hall_requests) writefln(" departing");
Expand Down Expand Up @@ -340,6 +347,10 @@ unittest {
unittest {
// Two hall requests at the same floor, but the closest elevator also has a cab call further in the same direction
// Should give the two hall orders to different elevators, the one in the "opposite" direction to the one without a cab order
auto prev = clearRequestType;
clearRequestType = ClearRequestType.inDirn;
scope(exit) clearRequestType = prev;

LocalElevatorState[string] states = [
"1" : LocalElevatorState(ElevatorBehaviour.moving, 3, Dirn.down, [1, 0, 0, 0].to!(bool[])),
"2" : LocalElevatorState(ElevatorBehaviour.idle, 3, Dirn.down, [0, 0, 0, 0].to!(bool[])),
Expand Down

0 comments on commit 7e48074

Please sign in to comment.