实现电梯优先队列



我有以下代码来实现电梯:

public class Elevator{
   Direction dir;
   int floorNum;
   int capacity;
   public void moveUp{
      dir = Direction.Up;
   }
   public void moveDown{
     dir = Direction.Down
   }
   public boolean isMoving{
     returns dir.equals(Direction.STATIONARY);
   }
}

public class ElevatorController{
   Elevator[] elevators;
   PriorityQueue<Integer> queue = new PriorityQueue<Integer>;
   public void buttonPressed{Direction d, int fromFloot, int toFloor){ 

   }
}

我读到一个实现电梯的好方法是实现一个优先队列来获得电梯,但我不确定如何。

队列将包含目标层。

你建议如何实现它?

一种可能性是使用两个单独的TreeSets来订购楼层,updown。如果你要在currentFloor之上添加一层,那么将其添加到up中,如果你要在currentFloor之下添加一层,那么将其添加到down中;如果你添加了一个等于currentFloor的地板,那么就丢弃它。TreeSet自动丢弃重复项。当确定要访问的下一层时,如果方向== UP,则访问up中的下一个最低层,如果方向== DOWN,则访问down中的下一个最高层。

或者,你可以使用一个单独的TreeSet,并尝试想出一个聪明的Comparator来考虑电梯的方向,但这似乎比它的价值更多的麻烦。

private TreeSet<Integer> up = new TreeSet<>(); // floors above currentFloor
private TreeSet<Integer> down = new TreeSet<>(); // floors below currentFloor
private int currentFloor = 0;
private Enum direction = direction.UP;
public void addFloor(int f) {
    if(f < currentFloor) {
        down.add(f);
    } else if(f > currentFloor) {
        up.add(f);
    }
    // else f == currentFloor, so don't add the floor to either queue
}
public int nextFloor() {
    if(direction == direction.DOWN) {
        return down.pollLast(); // highest floor in down, or null if empty
    } else {
        return up.pollFirst(); // lowest floor in up, or null if empty
    }
}

我尝试使用单个TreeSet实现电梯。

这是一个完整的解决方案:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.TreeSet;
public class MyLift {
    public static void main(String[] args) {
        System.out.println("Welcome to MyLift");
        // RequestListenerThread to read requested floor and add to Set
        Thread requestListenerThread = new Thread(new RequestListener(),
                "RequestListenerThread");
        // RequestProcessorThread to read Set and process requested floor
        Thread requestProcessorThread = new Thread(new RequestProcessor(),
                "RequestProcessorThread");
        requestListenerThread.start();
        requestProcessorThread.start();
    }
}
class Elevator {
    private static Elevator elevator = null;
    private static TreeSet<Integer> requestSet = new TreeSet<Integer>();
    private int currentFloor = 0;
    private Direction direction = Direction.UP;
    private Elevator() {
    };
    /**
     * @return singleton instance
     */
    static Elevator getInstance() {
        if (elevator == null) {
            elevator = new Elevator();
        }
        return elevator;
    }
    /**
     * Add request to Set
     * 
     * @param floor
     */
    public synchronized void addFloor(int f) {
        requestSet.add(f);
        // Notify the thread that a new request has come.
        notify();
    }
    /**
     * @return next request to process based on elevator current floor and
     *         direction
     */
    public synchronized int nextFloor() {
        Integer floor = null;
        if (direction == Direction.UP) {
            if (requestSet.ceiling(currentFloor) != null) {
                floor = requestSet.ceiling(currentFloor);
            } else {
                floor = requestSet.floor(currentFloor);
            }
        } else {
            if (requestSet.floor(currentFloor) != null) {
                floor = requestSet.floor(currentFloor);
            } else {
                floor = requestSet.ceiling(currentFloor);
            }
        }
        if (floor == null) {
            try {
                System.out.println("No Request to process. Waiting");
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("Processing Request : " + floor);
            requestSet.remove(floor);
        }
        return (floor == null) ? -1 : floor;
    }
    public int getCurrentFloor() {
        return currentFloor;
    }
    /**
     * Set current floor and direction based on requested floor
     * 
     * @param currentFloor
     */
    public void setCurrentFloor(int currentFloor) {
        if (this.currentFloor > currentFloor) {
            setDirection(Direction.DOWN);
        } else {
            setDirection(Direction.UP);
        }
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.currentFloor = currentFloor;
        System.out.println("Floor : " + currentFloor);
    }
    public Direction getDirection() {
        return direction;
    }
    public void setDirection(Direction direction) {
        this.direction = direction;
    }
}
class RequestProcessor implements Runnable {
    @Override
    public void run() {
        while (true) {
            Elevator elevator = Elevator.getInstance();
            int floor = elevator.nextFloor();
            int currentFloor = elevator.getCurrentFloor();
            if (floor >= 0) {
                if (currentFloor > floor) {
                    while (currentFloor > floor) {
                        elevator.setCurrentFloor(--currentFloor);
                    }
                } else {
                    while (currentFloor < floor) {
                        elevator.setCurrentFloor(++currentFloor);
                    }
                }
            }
        }
    }
}
class RequestListener implements Runnable {
    @Override
    public void run() {
        while (true) {
            String floorNumberStr = null;
            try {
                // Read input from console
                BufferedReader bufferedReader = new BufferedReader(
                        new InputStreamReader(System.in));
                floorNumberStr = bufferedReader.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (isValidFloorNumber(floorNumberStr)) {
                System.out.println("User Pressed : " + floorNumberStr);
                Elevator elevator = Elevator.getInstance();
                elevator.addFloor(Integer.parseInt(floorNumberStr));
            } else {
                System.out.println("Floor Request Invalid : " + floorNumberStr);
            }
        }
    }
    /**
     * This method is used to define maximum floors this elevator can process.
     * @param s - requested floor
     * @return true if requested floor is integer and upto two digits. (max floor = 99)
     */
    public boolean isValidFloorNumber(String s) {
        return (s != null) && s.matches("\d{1,2}");
    }
}
enum Direction {
    UP, DOWN
}

最新更新