将士兵分配给房间算法问题

时间:2016-03-14 15:20:26

标签: java search data-structures

所以我有一个需要在Java中进行优化的搜索问题。以下示例说明了我要解决的问题。

一名士兵抵达基地并获得一个住房单位。每个基地都有一个或多个住房单元。

每个住房单元都有一个或多个房间。每间客房均配有多张床。每个房间都有一个优先级编号(1是最高优先级)。每个房间的床位数可能不同。

士兵需要被分配到一个房间。他被分配到有最多床位的房间。如果有多个房间的床位数相同,他会去更高优先级的房间。

一旦士兵被分配到一个房间,当然会更新可用床位的数量,并且将使用相同的过程添加队列中的下一名士兵,直到所有士兵被分配房间。

如果不能将士兵分配到床上,我们不必担心,因为没有可用的士兵。另一个过程负责处理这种溢出情况。

我的问题是Java数据结构的实现最适合解决士兵将被分配到哪个房间的问题?

目前我正在使用多维ArrayList,并且觉得必须有更好的方法。

VisualGraph

3 个答案:

答案 0 :(得分:0)

这是一个建议:

  1. 首先,您不必担心“住房单位”,因为它决不会在决策过程中出现问题。
  2. 也许创建一个Room类,保留名称/住房单位的字段(例如“A1”),可用的床位数和优先级。
  3. 创建一个Room[] rooms(或等效的)数组,然后将其排序为接下来的士兵(#beds和优先级)。
  4. 当一名士兵进来时,他在rooms[0]的床上取下一张床。如果房间现已满,请将其从列表中删除。
  5. 然后选择rooms[0]并通过与其下面的rooms[i]进行比较找到它的新索引,直到找到新索引。
  6. 继续此操作,直到rooms为空

答案 1 :(得分:0)

听起来您可以使用PriorityQueue使用Room类的自定义比较器:

PriorityQueue<Room> queue = new PriorityQueue<>(new Comparator<Room>() {
  @Override
  public int compare(Room a, Room b) {
    int compareByAvailableBeds = Integer.compare(
        b.getAvailableBeds(), a.getAvailableBeds());
    if (compareByAvailableBeds != 0) {
      return compareByAvailableBeds;
    }

    return Integer.compare(a.getPriority(), b.getPriority());
  }
});

现在,要将一名士兵分配到一个房间,你可以选择最低的&#34;优先级Room,将其从队列中删除,将士兵分配给它,然后将其添加回队列:

Room room = queue.poll();
room.assign(soldier);  // Assuming this decrements the number of available beds.
queue.add(room);

答案 2 :(得分:0)

在设计和时间复杂度方面,你当然可以做到比多维ArrayLists更好。

从设计的角度来看,您有三个包含类 - RoomHouseBase。 (也Soldier,但就我们的目的而言Soldier并不需要任何额外的信息。)

public class Soldier{}

首先,Room非常简单。它必须包含Soldier s并知道它剩下多少个开放的房间

public class Room {

    private int totalBeds;
    public final int priority;
    private ArrayList<Soldier> soldiers;

    public Room(int totalBeds, int priority) {
        this.totalBeds = totalBeds;
        this.priority = priority;
        soldiers = new ArrayList<>();
    }

    public boolean add(Solider s) {
        if(soldiers.size() >= totalBeds) {
            return false;
        }
        return soldiers.add(s);
    }

    public int getRemainingBeds() {
        return totalBeds - soldiers.size();
    }

    public boolean isFull() {
        return totalBeds <= soldiers.size();
    }
}

从那里,我们需要一个House课程。这是Rooms的优先级队列,必须能够根据其优先级将士兵添加到房间。

public class House {

    private final String name;
    private PriorityQueue<Room> rooms;

    public House(String name, Room... rooms) {
        this.name = name;
        this.rooms = new PriorityQueue<>(new Comparator<Room>() {
            public int compare(Room a, Room b) {

                //Always prioritize an open room to a full one
                if(a.isFull() && b.isFull()) {
                    return 0;
                } else if (a.isFull()) {
                    return 1;
                } else if (b.isFull()) {
                    return -1;
                } else {
                    //Now try to get the room with the most available rooms
                    int bedDiff = b.getRemainingBeds() - a.getRemainingBeds();
                    if(bedDiff != 0) {
                        return bedDiff;
                    }
                    return a.priority - b.priority;
                }
           }
       });
       for(Room r : rooms) {
           this.rooms.add(r)
       }
    }

    public boolean add(Soldier s) {
        Room r = rooms.poll();
        boolean ok = r.add(s);
        rooms.add(r);
        return ok;
    }

    public String getName() {
        return name;
    }
}

最后,Base类应该使用Map<String, House>来快速找到一个名字的房子

public class Base {

    private Map<String, House> houses;

    public Base(House... houses) {
        houses = new HashMap<>();
        for(House h : houses) {
            houses.put(h.getName(), h);
        }
    }

    public boolean add(String houseName, Soldier s) {
        return houses.get(houseName).add(s);
    }
}

将士兵添加到基地的全职复杂性:

- Finding the correct House: O(1)
- Adding to the House:
    - Poll: O(log(#rooms in house))
    - Add to room: O(1)
    - Add: O(log(#rooms in house))