Das Programm YacsTester dient dazu, verschiedene Funktionalitäten von YACS zu testen und den Gebrauch des Frameworks zu demonstrieren. Auf das an dieser Stelle abgedruckte Programm-Listing wird in Kapitel 8 in Abschnitt 8.3 ff. zur Validierung des YACS-Frameworks anhand synthetischer Problemstellungen Bezug genommen.
Zum Programmablauf: Durch das Programm YacsTester wird im Konstruktor eine Initialisierung unterschiedlicher Constraint-Probleme vorgenommen und anschließend zwei Auswertevorgänge durchgeführt. Dazwischen werden Modifikationen an den bestehenden Constraint-Problemen vorgenommen. Die Ergebnisse der Auswertevorgänge werden jeweils ausgegeben.
import yacs.*; import yacs.domain.*; import yacs.exceptions.*; import yacs.net.*; import java.util.*; import org.apache.log4j.*; /** * <p>Klasse zum Testen verschiedener Funktionalitaeten von YACS.</p> * * <p>Copyright (C) 2005 Wolfgang Runte * <br><br> * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * <br><br> * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * <br><br> * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 * USA</p> * * @author Wolfgang Runte (woru@tzi.org) * @version YACS 0.1.1 */ public class YacsTester { // ********** private attributs ********** /** Logger aktivieren: */ private static Logger logger = Logger.getLogger("yacs"); /** Dateipfad zu den Constraint-Loesungsstrategien. */ private final String strategyPath = "yacs_strategies.xml"; /** Instanz des YACS Constraint-Managers. */ private final YacsConstraintManager ycm; // ********** public attributs ********** // ********** private methods ********** /** * Ein paar Testausgaben: Der Strategiename, das zugehoerigen Teilproblem, die * primitiven Constraint-Ausdruecke sowie die involvierten Variablen und deren * Domaenen. * @param strategyName String */ private void printTestValues(String strategyName) { try { // Constraint-Netz unter Angabe des Strategienamens vom YCM holen: ConstraintNet constraintNet = this.ycm.getConstraintNet(strategyName); // Liste der vorhandenen Variablen des Teilproblems holen: List variablesList = constraintNet.getVariables(); // Testausgaben: System.out.println("Strategie: '" + constraintNet.getStrategyName() + "'"); System.out.println("Expression: " + constraintNet.getSubproblem()); List exprList = constraintNet.getConstraints(); System.out.println("Primitive Constraints: (" + exprList.size() + ")"); for (int i = 0; i < exprList.size(); i++) { System.out.println(exprList.get(i)); } System.out.println("Variablen: " + constraintNet.getVariables()); System.out.println("Domaenen der Constraint-Variablen: (" + variablesList.size() + ")"); try { for (int i = 0; i < variablesList.size(); i++) { System.out.println(variablesList.get(i) + ": " + this.ycm. getVariableDomain((String)variablesList.get(i))); } } catch (VariableNotFoundException e) { e.printStackTrace(); } System.out.println("Constraint-Netz -> " + this.ycm.getConstraintNet(strategyName)); System.out.println("Inkonsistenz: " + this.ycm.isInconsistent(strategyName)); } catch (StrategyNotFoundException e) { e.printStackTrace(); } } /** * Constraints unter Angabe des Namens der zu verwendenen Strategie zum YACS * Constraint-Manager (YCM) hinzufuegen. * @param strategyName String * @param constraintArray String[] */ private void initConstraints(String strategyName, String[] constraintArray) { for (int i = 0; i < constraintArray.length; i++) { try { this.ycm.addConstraint(constraintArray[i], strategyName); } catch (ConstraintParserException e) { e.printStackTrace(); } catch (StrategyNotFoundException e) { e.printStackTrace(); } } } // ********** public methods ********** /** * NCSolverTest * @param init boolean */ public void NCSolverTest(boolean init) { List variablesList; // Name der Strategie: String strategyName = "low_consistency"; try { if (init) { System.out.println(); System.out.println("Einfaches Problem zum Testen von Knotenkonsistenz:"); System.out.println("=================================================="); // Constraints spezifizieren: String constraintArray[] = new String[4]; constraintArray[0] = "x < y;"; constraintArray[1] = "y < z;"; constraintArray[2] = "z <= 2;"; constraintArray[3] = "3 + y < 7;"; // Constraints zum YCM hinzufuegen: this.initConstraints(strategyName, constraintArray); // Liste der Variablen der Strategie bzw. des Constraint-Netzes holen: variablesList = this.ycm.getVariables(strategyName); // Wertebereiche der Constraint-Variablen setzen: try { for (int i = 0; i < variablesList.size(); i++) { this.ycm.setVariableDomain((String)variablesList.get(i), new NumericFDDomain(0, 9)); } } catch (VariableNotFoundException e) { e.printStackTrace(); } // Testausgaben: this.printTestValues(strategyName); } else { System.out.println(); System.out.println("Ergebnis fuer Knotenkonsistenz:"); System.out.println("==============================="); // Testausgaben: this.printTestValues(strategyName); // Ergebnis ausgeben: if (!this.ycm.hasFalseDomain(strategyName)) { System.out.println("\nErgebnis ist knotenkonsistent!"); } else { System.out.println("\nKnotenkonsistenz nicht herstellbar!"); } } } catch (StrategyNotFoundException e) { e.printStackTrace(); } } /** * AC3SolverTest * @param init boolean */ public void AC3SolverTest(boolean init) { List variablesList; // Name der Strategie: String strategyName = "medium_consistency"; try { if (init) { System.out.println(); System.out.println("Kartenfaerbeproblem fuer eine Australienkarte:"); System.out.println("=============================================="); // Constraints spezifizieren: String constraintArray[] = new String[9]; constraintArray[0] = "WA != NT;"; constraintArray[1] = "WA != SA;"; constraintArray[2] = "NT != SA;"; constraintArray[3] = "NT != Q;"; constraintArray[4] = "SA != Q;"; constraintArray[5] = "SA != NSW;"; constraintArray[6] = "SA != V;"; constraintArray[7] = "Q != NSW;"; constraintArray[8] = "T = T;"; // Constraints zum YCM hinzufuegen: this.initConstraints(strategyName, constraintArray); // Liste der Variablen der Strategie bzw. des Constraint-Netzes holen: variablesList = this.ycm.getVariables(strategyName); // Wertebereiche der Constraint-Variablen setzen: SymbolicFDDomain domain; try { for (int i = 0; i < variablesList.size(); i++) { domain = new SymbolicFDDomain(); domain.add(new SymbolicFDElement("rot")); domain.add(new SymbolicFDElement("gruen")); domain.add(new SymbolicFDElement("blau")); this.ycm.setVariableDomain((String)variablesList.get(i), domain); } // Die Einschraenkungen vornehmen, um auf Inkonsistenzen pruefen zu // koennen: this.ycm.setVariableDomain("WA", new SymbolicFDDomain("rot")); } catch (VariableNotFoundException e) { e.printStackTrace(); } // Testausgaben: this.printTestValues(strategyName); } else { System.out.println(); System.out.println("Ergebnis fuer Kartenfaerbeproblem:"); System.out.println("=================================="); // Testausgaben: this.printTestValues(strategyName); // Ergebnis ausgeben: if (!this.ycm.hasFalseDomain(strategyName)) { System.out.println("\nErgebnis ist kantenkonsistent!"); } else { System.out.println("\nKantenkonsistenz nicht herstellbar!"); } } } catch (StrategyNotFoundException e) { e.printStackTrace(); } } /** * SingleSolutionBTSolverTest * @param init boolean */ public void SingleSolutionBTSolverTest(boolean init) { List variablesList; // Name der Strategie: String strategyName = "simple_search"; try { if (init) { System.out.println(); System.out.println("Simple Search:"); System.out.println("=============="); // Constraints spezifizieren: String constraintArray[] = new String[2]; constraintArray[0] = "X < Y;"; constraintArray[1] = "Y < Z;"; // Constraints zum YCM hinzufuegen: this.initConstraints(strategyName, constraintArray); // Liste der Variablen der Strategie bzw. des Constraint-Netzes holen: variablesList = this.ycm.getVariables(strategyName); // Wertebereiche der Constraint-Variablen setzen: try { for (int i = 0; i < variablesList.size(); i++) { this.ycm.setVariableDomain((String)variablesList.get(i), new NumericFDDomain(1, 2)); } } catch (VariableNotFoundException e) { e.printStackTrace(); } // Testausgaben: this.printTestValues(strategyName); } else { System.out.println(); System.out.println("Ergebnis fuer Simple Search:"); System.out.println("============================"); // Testausgaben: this.printTestValues(strategyName); // Ergebnis ausgeben: try { if (this.ycm.hasSolutions(strategyName)) { System.out.println("\nLoesung(en):" + this.ycm.getSolutions(strategyName)); } else { System.out.println( "\nEs konnte keine Loesung fuer das Problem ermittelt werden."); } } catch (StrategyNotFoundException e) { e.printStackTrace(); } } } catch (StrategyNotFoundException e) { e.printStackTrace(); } } /** * BacktrackingSolverTest * @param init boolean */ public void BacktrackingSolverTest(boolean init) { List variablesList; // Name der Strategie: String strategyName = "search"; try { if (init) { System.out.println(); System.out.println("Smuggler's Knapsack (1):"); System.out.println("========================"); // Constraints spezifizieren: String constraintArray[] = new String[2]; constraintArray[0] = "4*W + 3*P + 2*C <= 9;"; constraintArray[1] = "15*W + 10*P + 7*C >=30;"; // Constraints zum YCM hinzufuegen: this.initConstraints(strategyName, constraintArray); // Liste der Variablen der Strategie bzw. des Constraint-Netzes holen: variablesList = this.ycm.getVariables(strategyName); // Wertebereiche der Constraint-Variablen setzen: try { for (int i = 0; i < variablesList.size(); i++) { this.ycm.setVariableDomain((String)variablesList.get(i), new NumericFDDomain(0, 9)); } } catch (VariableNotFoundException e) { e.printStackTrace(); } // Testausgaben: this.printTestValues(strategyName); } else { System.out.println(); System.out.println("Ergebnis fuer Smuggler's Knapsack (1):"); System.out.println("======================================"); // Testausgaben: this.printTestValues(strategyName); // Ergebnis ausgeben: try { if (this.ycm.hasSolutions(strategyName)) { System.out.println("\nLoesung(en):" + this.ycm.getSolutions(strategyName)); } else { System.out.println( "\nEs konnte keine Loesung fuer das Problem ermittelt werden."); } } catch (StrategyNotFoundException e) { e.printStackTrace(); } } } catch (StrategyNotFoundException e) { e.printStackTrace(); } } /** * MAC3SolverTest * @param init boolean */ public void MAC3SolverTest(boolean init) { List variablesList; // Name der Strategie: String strategyName = "search_with_look-ahead"; try { if (init) { System.out.println(); System.out.println("Smuggler's Knapsack (2):"); System.out.println("========================"); // Constraints spezifizieren: String constraintArray[] = new String[2]; constraintArray[0] = "4*W + 3*P + 2*C <= 9;"; constraintArray[1] = "15*W + 10*P + 7*C >=30;"; // Constraints zum YCM hinzufuegen: this.initConstraints(strategyName, constraintArray); // Liste der Variablen der Strategie bzw. des Constraint-Netzes holen: variablesList = this.ycm.getVariables(strategyName); // Wertebereiche der Constraint-Variablen setzen: try { for (int i = 0; i < variablesList.size(); i++) { this.ycm.setVariableDomain((String)variablesList.get(i), new NumericFDDomain(0, 9)); } } catch (VariableNotFoundException e) { e.printStackTrace(); } // Testausgaben: this.printTestValues(strategyName); } else { System.out.println(); System.out.println("Ergebnis fuer Smuggler's Knapsack (2):"); System.out.println("======================================="); // Testausgaben: this.printTestValues(strategyName); // Ergebnis ausgeben: try { if (this.ycm.hasSolutions(strategyName)) { System.out.println("\nLoesung(en):" + this.ycm.getSolutions(strategyName)); } else { System.out.println( "\nEs konnte keine Loesung fuer das Problem ermittelt werden."); } } catch (StrategyNotFoundException e) { e.printStackTrace(); } } } catch (StrategyNotFoundException e) { e.printStackTrace(); } } /** * HullConsistencySolverTest * @param init boolean */ public void HullConsistencySolverTest(boolean init) { List variablesList; // Name der Strategie: String strategyName = "interval_consistency"; try { if (init) { System.out.println(); System.out.println("Einfaches Problem zum Testen von Hull-Konsistenz:"); System.out.println("================================================="); // Constraints spezifizieren: String constraintArray[] = new String[2]; constraintArray[0] = "v1 + v2 = v3; v2 = v3 - v1; v1 = v3 - v2;"; constraintArray[1] = "v2 = v1; v1 = v2;"; // Constraints zum YCM hinzufuegen: this.initConstraints(strategyName, constraintArray); // Wertebereiche der Constraint-Variablen setzen: try { this.ycm.setVariableDomain("v1", new IntervalDomain(2, 12)); this.ycm.setVariableDomain("v2", new IntervalDomain(4, 9)); this.ycm.setVariableDomain("v3", new IntervalDomain(2, 8)); } catch (VariableNotFoundException e) { e.printStackTrace(); } // Testausgaben: this.printTestValues(strategyName); } else { System.out.println(); System.out.println("Ergebnis fuer Hull-Konsistenz:"); System.out.println("=============================="); // Testausgaben: this.printTestValues(strategyName); // Ergebnis ausgeben: if (!this.ycm.hasFalseDomain(strategyName)) { System.out.println("\nErgebnis ist konsistent!"); } else { System.out.println("\nKonsistenz nicht herstellbar!"); } } } catch (StrategyNotFoundException e) { e.printStackTrace(); } } /** * Konstruktor */ public YacsTester() { // Den YACS Constraint-Manager mit dem Pfad zu den // Constraint-Loesungsstrategien instantiieren: this.ycm = new YacsConstraintManagerImpl(this.strategyPath); // Loglevel setzen (moegliche Level: ALL, DEBUG, INFO, WARN, ERROR, FATAL): this.logger.setLevel(Level.OFF); // Testprobleme initialisieren: this.NCSolverTest(true); this.AC3SolverTest(true); this.SingleSolutionBTSolverTest(true); this.BacktrackingSolverTest(true); this.MAC3SolverTest(true); this.HullConsistencySolverTest(true); // Constraint-Loesungsprozess initiieren: System.out.println("\n"); System.out.println("**************************************"); System.out.println("* Starten der Constraint-Auswertung! *"); System.out.println("**************************************"); System.out.println(); this.ycm.evaluate(); // Ergebnisse ausgeben: this.NCSolverTest(false); this.AC3SolverTest(false); this.SingleSolutionBTSolverTest(false); this.BacktrackingSolverTest(false); this.MAC3SolverTest(false); this.HullConsistencySolverTest(false); // Einige Constraints hinzufuegen: System.out.println("\n"); System.out.println("Fuege zusaetzliche Constraints hinzu:"); System.out.println("====================================="); try { this.ycm.addConstraint("z > 2;", "low_consistency"); this.ycm.addConstraint("NSW != V;", "medium_consistency"); this.ycm.addConstraint("W > 1;", "search"); this.ycm.addConstraint("W > 1;", "search_with_look-ahead"); this.ycm.addConstraint("v1 = [5,5];", "interval_consistency"); } catch (ConstraintParserException e) { e.printStackTrace(); } catch (StrategyNotFoundException e) { e.printStackTrace(); } // Einige zusaetzliche Wertebereichseinschraenkungen vornehmen: System.out.println("\n"); System.out.println("Nehme Aenderungen an den Wertebereichen vor:"); System.out.println("============================================"); try { System.out.println("Variable: 'V' -> Wert: 'blau'"); this.ycm.setVariableDomain("V", new SymbolicFDDomain("blau")); System.out.println("Variable: 'W' -> Wert: '2'"); this.ycm.setVariableDomain("W", new NumericFDDomain(2)); System.out.println("Variable: 'Z' -> Wert: '1' bis '3'"); this.ycm.setVariableDomain("Z", new NumericFDDomain(1, 3)); } catch (VariableNotFoundException e) { e.printStackTrace(); } // Constraint-Loesungsprozess initiieren: System.out.println("\n"); System.out.println("**************************************************"); System.out.println("* Nochmaliges Starten der Constraint-Auswertung! *"); System.out.println("**************************************************"); System.out.println(); this.ycm.evaluate(); // Ergebnisse ausgeben: this.NCSolverTest(false); this.AC3SolverTest(false); this.SingleSolutionBTSolverTest(false); this.BacktrackingSolverTest(false); this.MAC3SolverTest(false); this.HullConsistencySolverTest(false); } public static void main(String[] args) { YacsTester yacsTester = new YacsTester(); } }