约束满足问题(Constraint Satisfaction Problem, CSP)的Java实现(三)Inference and variables order
排序的接口定义
import java.util.List;
import java.util.Map;
public interface Oder<V,D> {
boolean oderUnassigned(List<V> unassigned,AbstractAssignment<V,D> assignment,
Map<V, List<D>> domains, Map<V, List<AbstractConstraint<V,D>>> constraints);
}
MRV实现
import java.util.*;
public class MRV<V,D> implements Oder<V,D>{
@Override
public boolean oderUnassigned(List<V> unassigned,AbstractAssignment<V,D> assignment, Map<V, List<D>> domains, Map<V, List<AbstractConstraint<V, D>>> constraints) {
if(unassigned.size()==0){
return false;
}
else if(unassigned.size()==1){
return true;
}
unassigned.sort(new Comparator<V>() {
@Override
public int compare(V o1, V o2) {
return domains.get(o1).size() - domains.get(o2).size();
}
});
if(domains.get(unassigned.get(0)).size()!=0){
return true;
}
else{
return false;
}
}
}
Degree Heuristic实现
import java.util.*;
public class DegreeHeuristic<V,D> implements Oder<V,D> {
@Override
public boolean oderUnassigned(List<V> unassigned, AbstractAssignment<V,D> assignment, Map<V, List<D>> domains, Map<V, List<AbstractConstraint<V, D>>> constraints) {
Map<V,Integer> degrees = new HashMap<>();
for(V v:unassigned){
degrees.put(v,0);
for(V u:unassigned){
if(!v.equals(u)){
List<AbstractConstraint<V,D>> targetConstraints = constraints.get(v);
if((targetConstraints!=null)&&(!targetConstraints.isEmpty())){
for(AbstractConstraint<V,D> constraint:constraints.get(v)){
if(constraint.variableList.contains(u)){
degrees.put(v,degrees.get(v)+1);
}
}
}
}
}
}
unassigned.sort(new Comparator<V>(){
@Override
public int compare(V o1, V o2) {
return degrees.get(o2)-degrees.get(o1);
}
});
return true;
}
}
Inference实现
接口:
import java.util.List;
import java.util.Map;
public interface Inference<V,D>{
boolean doInference(List<V> unassigned, AbstractAssignment<V,D> assignment,
Map<V, List<D>> domains, Map<V, List<AbstractConstraint<V,D>>> constraints);
}
AC-3:
import java.util.*;
public class AC3<V,D> implements Inference<V,D>{
@Override
public boolean doInference(List<V> unassigned, AbstractAssignment<V,D> assignment,
Map<V, List<D>> domains, Map<V, List<AbstractConstraint<V, D>>> constraints) {
Queue<List<V>> arcs = new LinkedList<>();
for(V v:unassigned){
if(constraints.get(v)!=null){
for(AbstractConstraint<V,D> constraint:constraints.get(v)){
for(V u:constraint.variableList){
if(!v.equals(u) && unassigned.contains(u)){
arcs.add(new ArrayList<>(Arrays.asList(v,u)));
}
}
}
}
}
while(!arcs.isEmpty()){
List<V> firstArc = arcs.poll();
if(revised(firstArc.get(0), firstArc.get(1), domains, assignment, constraints)){
if(domains.get(firstArc.get(0)).size()==0){
return false;
}
for(AbstractConstraint<V,D> constraint:constraints.get(firstArc.get(0))){
for(V tempV:constraint.variableList){
if(!tempV.equals(firstArc.get(0))){
arcs.add(new ArrayList<>(Arrays.asList(tempV, firstArc.get(0))));
}
}
}
}
}
return false;
}
boolean revised(V o1, V o2, Map<V, List<D>> domains, AbstractAssignment<V,D> assignment,
Map<V, List<AbstractConstraint<V, D>>> constraints){
boolean revised = false;
Map<V, List<D>> tempDomain = new HashMap<>();
for(Map.Entry<V,List<D>> entry:domains.entrySet()){
tempDomain.put(entry.getKey(),new ArrayList<>(entry.getValue()));
}
for(D d1:tempDomain.get(o1)){
boolean haveTheValue = false;
// AbstractAssignment<V,D> tempAssignment = new AbstractAssignment<>(assignment);
for(D d2:tempDomain.get(o2)){
AbstractAssignment<V,D> tempAssignment = new AbstractAssignment<>(assignment);
tempAssignment.put(o1,d1);
tempAssignment.put(o2,d2);
for(AbstractConstraint<V,D> constraint:constraints.get(o1)){
if(constraint.variableList.contains(o2)){
if(constraint.satisfied(tempAssignment)){
haveTheValue = true;
}
}
}
}
if(!haveTheValue){
domains.get(o1).remove(d1);
revised = true;
}
}
return revised;
}
}
具体实现
import java.util.List;
import java.util.Map;
public class SimpleCSP<V,D> extends ClassicCSP<V,D>{
public SimpleCSP(List<V> vars, Map<V, List<D>> doms) throws Exception {
super(vars, doms);
oderAlgorithmList.add(new MRV<>());
oderAlgorithmList.add(new DegreeHeuristic<>());
inferenceList.add(new AC3<>());
}
}