Denkproblem: freie zeiträume

Alex Großmann

Erfahrenes Mitglied
Liebes Forum,

folgendes:

Ich habe eine CSV Datei welche so aufgebaut ist:
Tag;Zeit von; Zeit bis

Die CSV beinhaltet quasi Termine, bzw. wann ein Saal vergeben/vermietet wurde.
Ich will aber die freien Zeiträume zwischen den Terminen berechnen. Der Saal ist von 08:00 bis 20:00 Uhr geöffnet.

Das Problem, bzw. meines ist, das ich einfach nicht drauf komme wie ich:
1. die Tage unterscheide
2. unbedingt die Öffnungzeiten berücksichtige, sprich wenn der letzte Termin am Tage ist, dann nochmal die freie Zeit bis 20 Uhr zu berechnen....

Mein "Algorithmus" funktioniert hinten und vorn nicht, ich kann ihn auf Wunsch posten, aber ich wäre eher offener für neue Lösungsvorschläge/Ideen.

vielen dank und beste grüße


ps: ich arbeite mit opencsv und joda time
 
Hi,

folgende Datenstruktur würde ich grob verwenden:
Java:
Map< Day, List<TimeSpan> >
Wobei der Typ Day den Tag repräsentiert und der Typ TimeSpan eine Datenstruktur ist, welche die Zeit von und bis speichert (vllt. gibt es sowas in Joda Time).

Algorithmus
Pseudocode:
Java:
// data ist die oben angegebene Datenstruktur

Set<Day> days = data.keySet();
for (Day d : days) {
  Time startTime = new Time("8:00");

  List<TimeSpan> reservations = data.get(d);
  List<TimeSpan> freeTimes = new ArrayList<TimeSpan>();

  for (TimeSpan r : reservations) {
    if (!r.start.equals(startTime)) {
      freeTimes.add(new TimeSpan(startTime, r.start));
    }
    startTime = r.getEnd();
  }

  if (startTime.hour != "20") {
    freeTimes.add(new TimeSpan(startTime, new Time("20")));
  }
}
 
Zuletzt bearbeitet:
Das mit der Datenstruktur verstehe ich noch nicht.
In Joda gibts ja eine Period funktion, wäre dass, das Richtige?

Ansonsten schonmal vielen Dank für deinen Algorithmus, sieht sehr gut aus, Hut ab.
 
Zuletzt bearbeitet:
Das mit der Datenstruktur verstehe ich noch nicht.
In Joda gibts ja eine Period funktion, wäre dass, das Richtige?

Gerade nachgeschaut, ja, Period ist genau das, was ich meinte ;)

Java:
Map< Day, List<TimeSpan> >
Am Besten betrachtet man das von außen nach innen.

Map: Weist einzelnen Schlüsseln (Keys) Werte (Values) zu.
Z.B.:
Code:
"aaa" --> 9
"bbb" --> 10
Das wäre eine Map<String, Integer>-Struktur. Bei uns haben wir als Keys einen Datentyp, der den Tag speichert (DateTime in Joda müsste passen) und als zugehörige Werte haben wir eine Liste der reservierten Zeiten.

Kleines Beispiel mit erfundenen Daten:
Code:
09.08.13 --> Liste (13:00 - 15:00 reserviert, 16:00 - 18:00 reserviert)

12.09.14 --> Liste (13:30 - 16:23 reserviert, 16:00 - 19:42 reserviert)

Nachtrag
Mein Algorithmus kann nur dann funktionieren, wenn die Reservierungszeiten chronologisch per Tag sortiert sind!
 
Hallo,

ich könnte mir folgenden Ansatz vorstellen:

1. Du fügst die Zeitspanne von 8:00-20:00 für jeden Tag, den du betrachten möchtest, als freien Zeitraum in die Liste ein.
2. Du gehst die Datei Reservierung für Reservierung durch und betrachtest folgende Fälle:
a) Die Resverierung liegt in keinem der freien Zeiträume (sollte natürlich nicht vorkommen). --> Fehler
b) Die Reservierung hat den gleichen Start wie der freie Zeitraum --> Start des freien Zeitraumes in der Liste ist nun Ende der Reservierung.
c) Die Reservierung hat das gleiche ende wie der freie Zeitraum --> Ende des freien Zeitraumes in der Liste ist nun der Anfang der Reservierung.
d) Die Reservierung stimmt genau mit dem freien Zeitraum überein --> Freier Zeitraum wird aus der Liste gelöscht.
e) Die Reservierung liegt mitten im freien Zeitraum --> Es stehen nun 2 freie Zeiträume in der Liste. Einer von Anfang freier Zeitraum bis Anfang Reservierung und einer von Ende Reservierung bis Ende freier Zeitraum.
3. Am Ende kannst du dann die Liste ausgeben.

Der Vergleich der Zeiträume muss natürlich mit den vorhandenen Methoden geschehen.
 
Ist ja kein großes Problem.

Wie gesagt, du kannst "irgendwelche" Typen für meinen Pseudocode nehmen (es ging mehr um die Logik und das Verfahren).

Vielleicht sagt dir ein kleines Enum zu?
Java:
// Codeausschnitt von http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY 
}

Java:
Map< Day, List<TimeSpan> >

Und wenn du den String "Monday" hast und den Enum-Wert haben möchtest:
Java:
String str = "Monday";
Day day = Day.valueOf(str.toUpperCase());

Nachtrag Das letzte Codestück funktioniert natürlich nicht mit "Montag" ;)
 
Sooo, habs mal angepasst.
Leider verstehe ich die Ausgabe nicht... -.-

Java:
DateTime geeoffnetVon = new DateTime(2013, 1, 1, 8, 0);
DateTime geoeffnetBis = new DateTime(2013, 1, 1, 20, 0);
String tagMerker = "Montag";
List<DateTime> listPeriod = new ArrayList<>();


        HashMap<String, List<DateTime>> map = new HashMap();

 try {            
            CSVReader reader = new CSVReader(new FileReader(path));

            List content = reader.readAll();

            for (Object obj : content) {
                row = (String[]) obj;

                if (tagMerker.equals(row[0])) {
                    String[] timesplit = row[1].split(":");
                    DateTime time1 = new DateTime(2013, 1, 1, Integer.parseInt(timesplit[0]), Integer.parseInt(timesplit[1]));

                    timesplit = row[2].split(":");
                    DateTime time2 = new DateTime(2013, 1, 1, Integer.parseInt(timesplit[0]), Integer.parseInt(timesplit[1]));
                    
                    listPeriod.add(time1);
                    listPeriod.add(time2);

                } else {
                    map.put(tagMerker, listPeriod);
                    tagMerker = row[0];
                }
            }
        } catch (IOException ioE) {
        }

        Set<String> days = map.keySet();
        for (String d : days) {
            
            List<DateTime> reservations = map.get(d);
            List<Period> freeTimes = new ArrayList<Period>();

            for (DateTime r : reservations) {
                if (!r.isEqual(geeoffnetVon)) {
                    freeTimes.add(new Period(geeoffnetVon, r.toDateTime()));
                    geeoffnetVon = r.toDateTime();
                }
            }
            if (geeoffnetVon.isBefore(geoeffnetBis)) {
                freeTimes.add(new Period(geeoffnetVon, geoeffnetBis));
            }
            
        System.out.println(freeTimes.get(0).getHours()+ ":" + freeTimes.get(0).getMinutes());
        }

Ausgabe:
3:45
-6:-45
-6:-45
-6:-45

Die 3:45 stimmen! An diesem Tag geht um 11:45 der 1. Termin los. Aber was sollen die -6:45 dannach****
Vielleicht findet Ihr ja noch ein Fehler im Code, bin euch echt mega dankbar!!
 
Zurück