Wie löst man diese Java-Aufgabe?
Guten Tag liebe Gutefrage-Community,
ich verzweifle schon seit einiger Zeit wegen dieser Aufgabe, ich weiß einfach nicht, was ich zutun habe.
Mir wurde gesagt, dass ich einen sog. Dijsktra-Algorithmus verwenden kann, aber ich hab auch einfach keine Ahnung wie ich das mache.
Hoffentlich könnt ihr mit weiterhelfen:
#Wanderer Streckenberechnung
Ein Wanderer geht jedes Mal in seinem Urlaub eine Wanderstrecke mit mehren potentiellen Stops in Herbergen innerhalb von drei Tagen ab. Dabei möchte er natürlich die maximale Strecke die an einem Tag zurückgelegt werden muss möglichst gering halten, allerdings muss er auch dreimal anhalten um die Nacht in einer Herberge(STOP) zu verbringen.
Aufgabe: Schreibe für den Wanderer ein Programm, das aus einer beliebigen Anzahl Stops, sowie der Distanz zwischen den Stops, eine Route mit der kürzesten maximalen Strecke die an einem Tag zurückgelegt werden muss, berechnet.
Beispiel:
##INPUT:
STOPS: 8
DISTANZEN: 25,5,2,1,15,3,1,20,5
25KM 5KM 2KM 1KM 15KM 3KM 1KM 20KM 5
ANFANG----->STOP_1----->STOP_2----->STOP_3----->STOP_4----->STOP_5----->STOP_6----->STOP_7----->STOP_8----->ENDE
##OUTPUT
Beste Route
Tag1: STOP1, STOP2, STOP3, STOP4 (33KM)
Tag2: STOP5, STOP6, STOP7 (19KM)
Tag3: STOP8, ENDE (25KM)
3 Antworten
Wenn ich dein Beispiel im Kopf durchgehe, komme ich auf diese Beste Route:
Tag 1: Stop 1 (25 Km)
Tag 2: Stops 2-6 (26 Km)
Tag 3: Rest (26 Km)
Der Dijkstra-Algorithmus hat damit eigentlich nichts zu tun. Der wäre eher dafür da, wenn man z.B. Querfeldein von Stop 1 zu Stop 6 laufen könnte und das dann nicht 26, sondern z.B. nur 20 Km wären.
Ich würde erstmal berechnen, wie weit die Strecken pro Tag im Durchschnitt sein müssten (insgesamt 77 km, durch 3 = 25,666 km) und dann für jeden Tag versuchen, möglichst nah an den Durchschnitt ranzukommen. Das wird bei einigen Sonderfällen (zwei sehr lange Abschnitte direkt hintereinander) zwar auch nicht 100%ig funktionieren, aber das wäre schon mal ein Anfang.
import java.util.*;
public class Wanderer {
public static void main(String[] args) {
// Teilstrecken berechnen
var sections = getSections(List.of(25,5,2,1,15,3,1,20,5), 3);
// und ausgeben
for (int tag = 1; tag <= sections.size(); tag++) {
System.out.printf("Tag %d: %s (%d km)%n", tag, sections.get(tag-1), sections.get(tag-1).stream().mapToInt(Integer::intValue).sum());
}
}
private static List<List<Integer>> getSections(List<Integer> distances, int sectionCount) {
List<List<Integer>> result = new LinkedList<>();
// Entfernungen in eine LinkedList packen, damit man einfach
// die Werte, die schon verarbeitet wurden, rausnehmen kann
LinkedList<Integer> dist = new LinkedList<>(distances);
// Tagesdurchschnitt berechnen
double avgDistance = dist.stream().mapToInt(Integer::intValue).sum() / (double) sectionCount;
// Listen für alle außer dem letzten Tag erzeugen und an das Ergebnis anfügen
int currentStop = dist.pollFirst();
for (int tag = 1; tag < sectionCount; tag++) {
LinkedList<Integer> todayStops = new LinkedList<>();
while (todayStops.stream().mapToInt(Integer::intValue).sum() + (currentStop / 2.0) < avgDistance) {
todayStops.add(currentStop);
currentStop = dist.pollFirst();
}
result.add(todayStops);
}
// alle verbliebenen Strecken als lezten Tag anfügen
dist.push(currentStop);
result.add(dist);
return result;
}
}
Bitteschön, gerne 😊
Ist auch erstmal nur ein Beispiel. Es ist gut, wenn du daraus deine eigene Variante baust, weil du dann logischerweise viel mehr lernst, als wenn du meinen Code nur kopierst. Viele benutzen z.B. auch Schleifen anstatt Streams. Bei diesem Beispiel hätte es sich z.B. auch gelohnt, eine Funktion zu bauen, die die Summe aus einer List<Integer> bilden kann.
Das ist keine „Java-Aufgabe“, sondern eine in algorithmischem Denken. Der Dijkstra wird dir dabei nicht direkt helfen, auch wenn er als Inspiration nützlich sein kann.
Mal es dir auf einem Blatt Papier auf und überleg dir, wie du ohne Computer vorgehen würdest. Oft hilft es, bewusst schlechte Lösungen anzusehen oder sich Sonderfälle anzusehen (was wäre, wenn die Abstände gleich wären, etwa jeden km einer? Was, wenn du die Strecke nur in 2 Teilstrecken zerlegen musst?)
Ad-Hoc habe ich diese Seite gefunden, wo auch Java-Beispiele angegeben sind, damit alle Routen berechnet werden können.
https://www.happycoders.eu/de/algorithmen/dijkstra-algorithmus-java/
Ich bezweifle sehr, dass jemand hier sich hinsetzt und Deine Hausaufgabe schreibt...
Ich habe mir auch schon gedacht, dass das eigentlich nichts mit dem Dijsktra-Algorithmus zutun hat.
Hättest du vielleicht einen Ansatz in Java, wie man dabei vorgeht (mit der /3 Rechnung und dann so nah wie möglich an der Zahl dran sein)?
Wäre echt hilfreich, weil ich bin ein Java-Noob.