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();
}
}