约束满足问题(Constraint Satisfaction Problem, CSP)的Java实现(四)地图填色问题Map coloring problem
对于如上所示的澳大利亚地图,我们只用红蓝绿三种颜色填色,要求相邻两省份颜色不能相同,使用CSP求解器求解。
问题的具体描述写在txt文件中,格式如下
Australia Map Coloring Problem from AIMA
WA NT Q NSW V SA T
WA NT SA
NT Q SA WA
Q NSW SA NT
NSW V SA Q
V SA NSW
SA WA NT Q NSW V
T
r g b
WA = r
SA != g
第一行为题目,第二行为变量,第三行开始第一个为当前变量,其他是和此变量相邻的变量。倒数第三行为domain,后面为单约束。
定义具体的地图填色约束如下所示
import java.util.List;
public class MapColorConstraint extends AbstractConstraint<String,String>{
public MapColorConstraint(List<String> variables){
variableList = variables;
}
boolean satisfied(AbstractAssignment<String,String> assignment){
String region1 = variableList.get(0);
String region2 = variableList.get(1);
if(!assignment.hasVariable(region1)||(!assignment.hasVariable(region2))){
return true;
}
else{
return !assignment.getDomain(region1).equals(assignment.getDomain(region2));
}
}
}
求解问题:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;
public class CSPTestClass {
public static void main(String[] args) throws Exception {
String fileName = "Map.txt";
File file = new File(fileName);
List<String> fileString = new ArrayList<>();
try {
Scanner sc = new Scanner(file);
while (sc.hasNextLine()) {
fileString.add(sc.nextLine());
}
sc.close();
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
if(fileString.size()==0){
System.out.println("NO DATA FOUND IN THE FILE!");
return;
}
List<String> variables = new ArrayList<>();
List<String> domains = new ArrayList<>();
Map<String, List<String>> variableDomains = new HashMap<>();
List<MapColorConstraint> mapColorConstraintList = new ArrayList<>();
boolean startGetOtherConstraints = false;
for(int i=1;i<fileString.size();i++){
if(i==1){
variables.addAll(Arrays.asList(fileString.get(i).split(" ")));
}
else if(!startGetOtherConstraints){
List<String> wordList = new ArrayList<>(Arrays.asList(fileString.get(i).split(" ")));
if(!variables.contains(wordList.get(0))){
startGetOtherConstraints = true;
domains.addAll(wordList);
for(String variable:variables){
variableDomains.put(variable, new ArrayList<>(domains));
}
}
if(!startGetOtherConstraints){
for(int j=1;j<wordList.size();j++){
mapColorConstraintList.add(new MapColorConstraint(Arrays.asList(wordList.get(0), wordList.get(j))));
}
}
}
else{
List<String> wordList = new ArrayList<>(Arrays.asList(fileString.get(i).split(" ")));
if(wordList.get(1).equals("=")){
variableDomains.get(wordList.get(0)).clear();
variableDomains.get(wordList.get(0)).add(wordList.get(2));
}
else{
variableDomains.get(wordList.get(0)).remove(wordList.get(2));
}
}
}
BaseCSP<String,String> csp = new BaseCSP<>(variables, variableDomains);
for(MapColorConstraint mapColorConstraint:mapColorConstraintList){
csp.addConstraint(mapColorConstraint);
}
AbstractAssignment<String, String> ass = csp.backTrackingSearch();
if(ass!=null){
ass.display();
}
else{
System.out.println("No solution!");
}
}
}