Vizeskannák szállítójaként mindig is lenyűgöztek a vizeskannák gyakorlati és elméleti vonatkozásai. Egy érdekes elméleti probléma, amelynek valós vonatkozásai vannak, a vizeskancsó probléma. Ebben a blogban végigvezetem Önt egy vizeskancsó problémamegoldó Java nyelven való megvalósításán.
A vizeskancsó probléma megértése
A vizeskancsó probléma klasszikus feladvány. Két (x) és (y) literes űrtartalmú kancsót kap, és egy (z) liter víz mérésére alkalmas. A végrehajtható műveletek a következők:
- Töltse meg teljesen egy kancsót.
- Ürítsen ki egy kancsót.
- Öntsön vizet egyik kancsóból a másikba, amíg vagy a forráskanna ki nem ürül, vagy a célkancsó megtelik.
A cél az, hogy megtaláljuk a műveletek sorozatát, aminek eredményeként (z) liter víz van az egyik kancsóban.
A Water Jug Problémamegoldó Java implementációja
Kezdjük egy osztály létrehozásával, amely a kancsók állapotát ábrázolja.
class JugState { int jug1; int kancsó2; public JugState(int kancsó1, int kancsó2) { this.kancsó1 = kancsó1; ez.kancsó2 = kancsó2; } @A nyilvános logikai érték felülírása egyenlő:(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) hamis értéket ad vissza; JugState jugState = (JugState) o; return jug1 == kancsó.kancsó1 && kancsó2 == kancsó.kancsó2; } @Override public int hashCode() { return 31 * kancsó1 + kancsó2; } @Override public String toString() { return "Jug1: " + kancsó1 + ", Jug2: " + kancsó2; } }
EzJugStateosztály az egyes kancsókban lévő víz aktuális mennyiségét jelenti. Felülírjuk aegyenlőéshashCodemetódusokat, hogy ezeket az állapotokat adatstruktúrákban felhasználhassuk, mint plHashSet.
Ezután megvalósítjuk a fő megoldó osztályt.
import java.util.*; public class WaterJugSolver { private int kapacitás1; privát int kapacitás2; privát int cél; public WaterJugSolver(int kapacitás1, int kapacitás2, int cél) { this.kapacitás1 = kapacitás1; ez.kapacitás2 = kapacitás2; this.target = cél; } public List<JugState> solve() { Queue<List<JugState>> queue = new LinkedList<>(); Set<JugState> látogatva = new HashSet<>(); JugState kezdetiState = new JugState(0, 0); List<JugState> kezdetiPath = new ArrayList<>(); kezdetiPath.add(kezdetiállapot); queue.add(initialPath); visited.add(initialState); while (!queue.isEmpty()) { List<JugState> currentPath = queue.poll(); JugState currentState = jelenlegiPath.get(currentPath.size() - 1); if (currentState.jug1 == target || currentState.jug2 == target) { return currentPath; } Lista<JugState> nextStates = getNextStates(currentState); for (JugState nextState : nextStates) { if (!visited.contains(nextState)) { List<JugState> newPath = new ArrayList<>(currentPath); newPath.add(nextState); queue.add(newPath); visited.add(nextState); } } } return null; } private List<JugState> getNextStates(JugState currentState) { Lista<JugState> nextStates = new ArrayList<>(); // 1. kancsó kitöltése nextStates.add(new JugState(kapacitás1, jelenlegiállapot.kancsó2)); // 2. kancsó kitöltése nextStates.add(new JugState(currentState.jug1, kapacitás2)); // Üres kancsó 1 nextStates.add(new JugState(0, currentState.jug2)); // Üres kancsó 2 nextStates.add(new JugState(currentState.jug1, 0)); // Öntés az 1. kancsóból a 2. kancsóba int pourAmount = Math.min(currentState.jug1, capacity2 - currentState.jug2); nextStates.add(new JugState(currentState.jug1 - pourAmount, currentState.jug2 + pourAmount)); // Öntés 2. kancsóból 1. kancsóba pourAmount = Math.min(currentState.jug2, capacity1 - currentState.jug1); nextStates.add(new JugState(currentState.jug1 + pourAmount, currentState.jug2 - pourAmount)); return nextStates; } public static void main(String[] args) { WaterJugSolver megoldó = new WaterJugSolver(3, 5, 4); Lista<JugState> megoldás = solver.solve(); if (megoldás != null) { for (JugState állapot : megoldás) { System.out.println(állapot); } } else { System.out.println("Nem található megoldás."); } } }
AWaterJugSolverosztályban a szélesség - első keresés (BFS) algoritmust használjuk a megoldás megtalálásához. Amegoldanimetódus inicializál egy sort az útvonalak tárolására és egy készletet a meglátogatott állapotok nyomon követésére. Kezdjük azzal a kezdeti állapottal, hogy mindkét kancsó üres.
AgetNextStatesmetódus az összes lehetséges következő állapotot generálja az aktuális állapotból a korábban említett hat művelet végrehajtásával.
Valós alkalmazások és vizeskancsóink
A vizeskancsó probléma egyszerű fejtörőnek tűnhet, de olyan területeken vannak alkalmazásai, mint az erőforrás-kezelés és az optimalizálás. Vizeskancsó-üzletágunk kontextusában ezen algoritmusok megértése segíthet olyan esetekben, mint a nagyméretű víztartályok hatékony megtöltése.
A vizeskannák széles választékát kínáljuk a különböző igények kielégítésére. A szabadtéri tevékenységekhez a miNagy kapacitású, rozsdamentes acél kültéri vízkancsónagyszerű választás. Jelentős mennyiségű vizet képes megtartani, így biztosítva a hidratáltságot a hosszú túrák vagy kempingezések során.
Ha hordozhatóbb lehetőségre van szüksége, akkor a miRozsdamentes acél 64oz hordozható kancsótökéletes. Könnyen hordozható, akár edzőterembe mész, akár ügyeletet futsz.
Azok számára, akiknek még több víztárolásra van szükségük, a miRozsdamentes acél 64oz 128oz gallon vizespalackbiztosítja a szükséges kapacitást.


Következtetés
A vizeskancsó problémamegoldó Java nyelven való megvalósítása nagyszerű módja annak, hogy megértsük az olyan algoritmusokat, mint a BFS, és hogyan alkalmazhatók a valós világ problémáira. Vizeskannák szállítójaként elkötelezettek vagyunk amellett, hogy kiváló minőségű termékeket biztosítsunk, amelyek megfelelnek az Ön víztárolási igényeinek.
Ha érdeklődik vizeskancsóink vásárlása iránt, vagy bármilyen kérdése van termékeinkkel kapcsolatban, javasoljuk, hogy lépjen kapcsolatba egy beszerzési megbeszéléssel. Azért vagyunk itt, hogy segítsünk megtalálni a tökéletes vizeskancsó megoldást az Ön igényeinek.
Hivatkozások
- Bevezetés az algoritmusokba – Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, Clifford Stein
- Adatstruktúrák és algoritmusok Java nyelven Robert Lafore
