Skip to content

Commit

Permalink
Room unavailable timeslots
Browse files Browse the repository at this point in the history
  • Loading branch information
ge0ffrey committed Dec 16, 2017
1 parent 78b229a commit 630bcf5
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 13 deletions.
Expand Up @@ -24,6 +24,8 @@ public class Room extends AbstractPersistable {


private String name; private String name;


private Set<Timeslot> unavailableTimeslotSet;

private Set<String> tagSet; private Set<String> tagSet;


public boolean hasTag(String tag) { public boolean hasTag(String tag) {
Expand All @@ -47,6 +49,14 @@ public void setName(String name) {
this.name = name; this.name = name;
} }


public Set<Timeslot> getUnavailableTimeslotSet() {
return unavailableTimeslotSet;
}

public void setUnavailableTimeslotSet(Set<Timeslot> unavailableTimeslotSet) {
this.unavailableTimeslotSet = unavailableTimeslotSet;
}

public Set<String> getTagSet() { public Set<String> getTagSet() {
return tagSet; return tagSet;
} }
Expand Down
Expand Up @@ -49,6 +49,13 @@ public boolean hasSpeaker(Speaker speaker) {
return speakerList.contains(speaker); return speakerList.contains(speaker);
} }


public boolean hasUnavailableRoom() {
if (timeslot == null || room == null) {
return false;
}
return room.getUnavailableTimeslotSet().contains(timeslot);
}

public boolean hasAnyUnavailableSpeaker() { public boolean hasAnyUnavailableSpeaker() {
if (timeslot == null) { if (timeslot == null) {
return false; return false;
Expand Down
Expand Up @@ -220,10 +220,17 @@ private void createRoomList(ConferenceSolution solution, int roomListSize) {
Room room = new Room(); Room room = new Room();
room.setId((long) i); room.setId((long) i);
room.setName("R " + ((i / roomsPerFloor * 100) + (i % roomsPerFloor) + 1)); room.setName("R " + ((i / roomsPerFloor * 100) + (i % roomsPerFloor) + 1));
LinkedHashSet<Timeslot> unavailableTimeslotSet = new LinkedHashSet<>();
Set<String> tagSet = new LinkedHashSet<>(roomTagProbabilityList.size()); Set<String> tagSet = new LinkedHashSet<>(roomTagProbabilityList.size());
if (i % 5 == 4) { if (i % 5 == 4) {
tagSet.add(LAB_ROOM_TAG); tagSet.add(LAB_ROOM_TAG);
unavailableTimeslotSet.addAll(solution.getTimeslotList().stream()
.filter(timeslot -> timeslot.getTalkType() != LAB_TALK_TYPE).collect(Collectors.toList()));
} else {
unavailableTimeslotSet.addAll(solution.getTimeslotList().stream()
.filter(timeslot -> timeslot.getTalkType() == LAB_TALK_TYPE).collect(Collectors.toList()));
} }
room.setUnavailableTimeslotSet(unavailableTimeslotSet);
for (Pair<String, Double> roomTagProbability : roomTagProbabilityList) { for (Pair<String, Double> roomTagProbability : roomTagProbabilityList) {
if (random.nextDouble() < roomTagProbability.getValue()) { if (random.nextDouble() < roomTagProbability.getValue()) {
tagSet.add(roomTagProbability.getKey()); tagSet.add(roomTagProbability.getKey());
Expand Down
Expand Up @@ -59,13 +59,16 @@


public class ConferenceSchedulingXslxFileIO implements SolutionFileIO<ConferenceSolution> { public class ConferenceSchedulingXslxFileIO implements SolutionFileIO<ConferenceSolution> {


public static final DateTimeFormatter DAY_FORMATTER protected static final Pattern VALID_TAG_PATTERN = Pattern.compile("(?U)^[\\w\\d _\\-\\.\\(\\)]+$");
= DateTimeFormatter.ofPattern("E yyyy-MM-dd", Locale.ENGLISH); protected static final Pattern VALID_NAME_PATTERN = VALID_TAG_PATTERN;
protected static final Pattern VALID_CODE_PATTERN = Pattern.compile("(?U)^[\\w\\d_\\-\\.\\(\\)]+$");


public static final DateTimeFormatter TIME_FORMATTER protected static final DateTimeFormatter DAY_FORMATTER
= DateTimeFormatter.ofPattern("E yyyy-MM-dd", Locale.ENGLISH);
protected static final DateTimeFormatter TIME_FORMATTER
= DateTimeFormatter.ofPattern("HH:mm", Locale.ENGLISH); = DateTimeFormatter.ofPattern("HH:mm", Locale.ENGLISH);


private static final IndexedColors UNAVAILABLE_COLOR = IndexedColors.GREY_80_PERCENT; protected static final IndexedColors UNAVAILABLE_COLOR = IndexedColors.GREY_80_PERCENT;


@Override @Override
public String getInputFileExtension() { public String getInputFileExtension() {
Expand All @@ -85,10 +88,6 @@ public ConferenceSolution read(File inputSolutionFile) {


private static class ConferenceSchedulingXslxReader { private static class ConferenceSchedulingXslxReader {


protected final Pattern VALID_TAG_PATTERN = Pattern.compile("(?U)^[\\w\\d _\\-\\.\\(\\)]+$");
protected final Pattern VALID_NAME_PATTERN = VALID_TAG_PATTERN;
protected final Pattern VALID_CODE_PATTERN = Pattern.compile("(?U)^[\\w\\d_\\-\\.\\(\\)]+$");

protected final Workbook workbook; protected final Workbook workbook;


protected ConferenceSolution solution; protected ConferenceSolution solution;
Expand Down Expand Up @@ -180,6 +179,10 @@ private void readRoomList() {
Room room = new Room(); Room room = new Room();
room.setId(id++); room.setId(id++);
room.setName(nextCell().getStringCellValue()); room.setName(nextCell().getStringCellValue());
if (!VALID_NAME_PATTERN.matcher(room.getName()).matches()) {
throw new IllegalStateException(currentPosition() + ": The speaker's name (" + room.getName()
+ ") must match to the regular expression (" + VALID_NAME_PATTERN + ").");
}
room.setTagSet(Arrays.stream(nextCell().getStringCellValue().split(", ")) room.setTagSet(Arrays.stream(nextCell().getStringCellValue().split(", "))
.filter(tag -> !tag.isEmpty()).collect(Collectors.toCollection(LinkedHashSet::new))); .filter(tag -> !tag.isEmpty()).collect(Collectors.toCollection(LinkedHashSet::new)));
for (String tag : room.getTagSet()) { for (String tag : room.getTagSet()) {
Expand All @@ -189,15 +192,22 @@ private void readRoomList() {
} }
} }
totalRoomTagSet.addAll(room.getTagSet()); totalRoomTagSet.addAll(room.getTagSet());
roomList.add(room); Set<Timeslot> unavailableTimeslotSet = new LinkedHashSet<>();
for (Timeslot timeslot : solution.getTimeslotList()) { for (Timeslot timeslot : solution.getTimeslotList()) {
String[] talkCodes = Arrays.stream(nextCell().getStringCellValue().split(", ")) Cell cell = nextCell();
.filter(code -> !code.isEmpty()).toArray(String[]::new); if (extractColor(cell, UNAVAILABLE_COLOR) == UNAVAILABLE_COLOR) {
unavailableTimeslotSet.add(timeslot);
}
String[] talkCodes = cell.getStringCellValue().split(", ");
Pair<Timeslot, Room> pair = Pair.of(timeslot, room); Pair<Timeslot, Room> pair = Pair.of(timeslot, room);
for (String talkCode : talkCodes) { for (String talkCode : talkCodes) {
talkCodeToTimeslotRoomMap.put(talkCode, pair); if (!talkCode.isEmpty()) {
talkCodeToTimeslotRoomMap.put(talkCode, pair);
}
} }
} }
room.setUnavailableTimeslotSet(unavailableTimeslotSet);
roomList.add(room);
} }
solution.setRoomList(roomList); solution.setRoomList(roomList);
} }
Expand Down Expand Up @@ -512,7 +522,13 @@ private void writeRoomList() {
nextCell().setCellValue(String.join(", ", room.getTagSet())); nextCell().setCellValue(String.join(", ", room.getTagSet()));
for (Timeslot timeslot : solution.getTimeslotList()) { for (Timeslot timeslot : solution.getTimeslotList()) {
List<Talk> talkList = timeslotRoomToTalkMap.get(Pair.of(timeslot, room)); List<Talk> talkList = timeslotRoomToTalkMap.get(Pair.of(timeslot, room));
nextCell().setCellValue(talkList == null ? "" Cell cell;
if (room.getUnavailableTimeslotSet().contains(timeslot)) {
cell = nextCell(unavailableStyle);
} else {
cell = nextCell();
}
cell.setCellValue(talkList == null ? ""
: talkList.stream().map(Talk::getCode).collect(Collectors.joining(", "))); : talkList.stream().map(Talk::getCode).collect(Collectors.joining(", ")));
} }
} }
Expand Down
Expand Up @@ -35,6 +35,13 @@ rule "Talk type of timeslot"
scoreHolder.addHardConstraintMatch(kcontext, -100); scoreHolder.addHardConstraintMatch(kcontext, -100);
end end


rule "Room unavailable timeslots"
when
Talk(hasUnavailableRoom())
then
scoreHolder.addHardConstraintMatch(kcontext, -1);
end

rule "Speaker unavailable timeslots" rule "Speaker unavailable timeslots"
when when
Talk(hasAnyUnavailableSpeaker()) Talk(hasAnyUnavailableSpeaker())
Expand Down

0 comments on commit 630bcf5

Please sign in to comment.