所以我有一个需要在Java中进行优化的搜索问题。以下示例说明了我要解决的问题。
一名士兵抵达基地并获得一个住房单位。每个基地都有一个或多个住房单元。
每个住房单元都有一个或多个房间。每间客房均配有多张床。每个房间都有一个优先级编号(1是最高优先级)。每个房间的床位数可能不同。
士兵需要被分配到一个房间。他被分配到有最多床位的房间。如果有多个房间的床位数相同,他会去更高优先级的房间。
一旦士兵被分配到一个房间,当然会更新可用床位的数量,并且将使用相同的过程添加队列中的下一名士兵,直到所有士兵被分配房间。
如果不能将士兵分配到床上,我们不必担心,因为没有可用的士兵。另一个过程负责处理这种溢出情况。
我的问题是Java数据结构的实现最适合解决士兵将被分配到哪个房间的问题?
目前我正在使用多维ArrayList,并且觉得必须有更好的方法。
答案 0 :(得分:0)
这是一个建议:
Room
类,保留名称/住房单位的字段(例如“A1”),可用的床位数和优先级。Room[] rooms
(或等效的)数组,然后将其排序为接下来的士兵(#beds和优先级)。rooms[0]
的床上取下一张床。如果房间现已满,请将其从列表中删除。rooms[0]
并通过与其下面的rooms[i]
进行比较找到它的新索引,直到找到新索引。 继续此操作,直到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更好。
从设计的角度来看,您有三个包含类 - Room
,House
和Base
。 (也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))