2013-04-30 3 views
1

У меня есть следующий код для реализации Лифт:Реализация очереди приоритета в лифте

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){ 


    } 
} 

Я прочитал хороший способ реализации лифта будет реализовать очередь приоритета, чтобы получить лифт, но я не знаю, как.

В очереди будет находиться пункт назначения.

Как вы рекомендуете его реализовать?

+0

Зависит от того, что вы хотите, чтобы вести себя как. Я думаю, что это должно зависеть от того, если и какой пункт назначения выбран изнутри лифта, не так ли? Пример: лифт находится на 5-м месте, клиент выбирает -1 (гараж), а клиент2 - на 3-м и нажимает «get». Должен ли он забрать клиента2? Есть ли getForMovingUp и getForMOvingDown или только нейтральный get? – Fildor

+0

есть направление, указывающее, вверх или вниз направление в сигнатуре метода. да, это подберет их в пути – Dejell

ответ

4

Одна из возможностей состоит в использовании двух отдельных наборов TreeSets для полов, up и down. Если вы добавляете пол выше currentFloor, то добавьте его в up, если вы добавляете пол ниже currentFloor, то добавьте его в down; если вы добавляете пол, равный currentFloor, тогда отбросьте его. TreeSet автоматически удаляет дубликаты. Когда вы определяете следующий этаж для посещения, тогда, если направление == UP, перейдите на следующий нижний этаж в up, и если направление == DOWN, то перейдите на следующий верхний этаж в down.

В качестве альтернативы вы можете использовать один TreeSet и попытаться найти умного компаратора, который учитывает направление лифта, но это похоже на больше проблем, чем это стоит.

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 
    } 
} 
2

Я попытался реализовать Лифт с помощью одного 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 
} 
Смежные вопросы