Java 解决N对N关系算法问题的最佳方法是什么?

Java 解决N对N关系算法问题的最佳方法是什么?,java,spring,algorithm,data-structures,big-o,Java,Spring,Algorithm,Data Structures,Big O,我试图写一个算法来组织N个房间到N个专业人员的日程安排。我有一份房间物品清单和另一份专业人员清单。我们的想法是能够为一天的特定房间指派一名专业人员。这里的转折点是,专业人员可以是某种“专业”(由布尔属性表示)。这个专业人员需要一个特殊的房间。房间有一个属性isSpecialtyRoom。理想情况下,算法将首先尝试将专业房间与专业人员匹配,但如果房间空置,则可以与常规专业人员预订 这段代码是我一直在研究的,但每次我都会遇到异常。我想知道解决这样一个问题的最好办法是什么 private List&l

我试图写一个算法来组织N个房间到N个专业人员的日程安排。我有一份房间物品清单和另一份专业人员清单。我们的想法是能够为一天的特定房间指派一名专业人员。这里的转折点是,专业人员可以是某种“专业”(由布尔属性表示)。这个专业人员需要一个特殊的房间。房间有一个属性isSpecialtyRoom。理想情况下,算法将首先尝试将专业房间与专业人员匹配,但如果房间空置,则可以与常规专业人员预订

这段代码是我一直在研究的,但每次我都会遇到异常。我想知道解决这样一个问题的最好办法是什么

private List<Room> generateDailySchedule(List<Room> roomList, List<Professional> professionalList) {
    if (roomList.size() <= 0 || professionalList.size() <=0) return roomList;

    //first run to find matches.
    int pIndex = 0;
  
    for (Room room : roomList) {
        if (pIndex < professionalList.size()) {
            if ((!room.isSpecialtyRoom() && !professionalList.get(pIndex).isRequiresSpecialtyRoom()) ||
                    (room.isSpecialtyRoom() && professionalList.get(pIndex).isRequiresSpecialtyRoom())) {
                room.setProfessional(professionalList.get(pIndex));
                professionalList.get(pIndex).setRoom(room);
            
                pIndex++;
            }
        }
    }
   
    //search for remaining professionals
    List<Professional> professionalsWaitingList = professionalList.stream()
            .filter(professional -> professional.getRoom() == null).collect(Collectors.toList());
   
    //search for remaining empty rooms
    List<Room> vacantRooms = roomList.stream().filter(room -> room.getProfessional() == null).collect(Collectors.toList());

    if (vacantRooms.size() > 0 && professionalsWaitingList.size() > 0) {
        for (Room vacantRoom : vacantRooms) {
            if (!vacantRoom.isSpecialtyRoom()) {
                vacantRoom.setProfessional(professionalsWaitingList.stream().findFirst().get());
            } else {
                Optional<Professional> specialtyProfessional = professionalsWaitingList.stream()
                        .filter(professional -> (professional.isRequiresSpecialtyRoom() && professional.getRoom() == null))
                        .findFirst();
                if (specialtyProfessional.isPresent()) {
                    vacantRoom.setProfessional(specialtyProfessional.get());
                    specialtyProfessional.get().setRoom(vacantRoom);
                } else {
                    System.out.println("No specialty professional found for room " + vacantRoom.getRoomName());
                    Optional<Professional> anyProfessional = professionalsWaitingList.stream()
                            .filter(professional -> professional.getRoom() == null)
                            .findFirst();
                    if(anyProfessional.isPresent()) {
                        vacantRoom.setProfessional(anyProfessional.get());
                        anyProfessional.get().setRoom(vacantRoom);
                    } else {
                        System.out.println("No professional found for room " + vacantRoom.getRoomName());
                    }
                }
            }
        }
    }
    return roomList;
}

StackOverflowException是由递归方法引起的,这些方法没有设置为知道何时停止递归。但是我在你发布的代码中也没有看到任何递归,所以我无法指出是什么导致了你的问题。这就是我的全部。请将异常和完整堆栈跟踪作为文本粘贴到问题中。您有一个赋值问题。我还没有读过你的算法,但是你的问题的最佳答案是一个具有适当权重的加权二部匹配算法:除非你有一个玩具问题(少量的节点和边),否则不要尝试自己重新实现它,而是使用一个成熟的库(例如在JNI中包装LEMON-OR库以便在Java中使用),从java切换到更适合任务的语言(C++)。如果唯一的限制是您有N个“专业”专业人员需要M个“专业”房间中的一个,那么这很简单。任意将前N个专业房间分配给专业人员,然后将剩余房间(专业或普通)分配给剩余专业人员。当然,如果N>M,就没有解。
@Entity
public class Professional {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@NotNull
private String name;

@OneToOne(cascade = CascadeType.ALL)
@JoinTable( name = "professional_room",
    joinColumns = { @JoinColumn(name = "professional_id", referencedColumnName = "id") },
    inverseJoinColumns = { @JoinColumn(name = "room_id", referencedColumnName = "id") })
private Room room;

private Boolean requiresSpecialtyRoom;
@Entity
public class Room {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@NotBlank
private String roomName;

@NotNull
private boolean specialtyRoom;

@OneToOne(mappedBy = "room")
private Professional professional;