001    /*
002     * Created on Sep 21, 2004
003     *
004     */
005    package aima.search.csp;
006    
007    import java.util.ArrayList;
008    import java.util.Hashtable;
009    import java.util.Iterator;
010    import java.util.List;
011    
012    /**
013     * @author Ravi Mohan
014     * 
015     */
016    
017    public class Assignment {
018            Hashtable<String, Object> variablesToValues;
019    
020            List<String> variables;
021    
022            public Assignment() {
023                    this(new ArrayList<String>());
024            }
025    
026            public Assignment(List<String> variables) {
027                    variablesToValues = new Hashtable<String, Object>();
028                    this.variables = variables;
029            }
030    
031            public void setAssignment(String variable, Object value) {
032                    variablesToValues.put(variable, value);
033            }
034    
035            public Object getAssignment(String variable) {
036                    return variablesToValues.get(variable);
037            }
038    
039            public boolean isComplete() {
040    
041                    return everyVariableIsAKeyAndHasAValue();
042            }
043    
044            private boolean everyVariableIsAKeyAndHasAValue() {
045    
046                    Iterator iter = variables.iterator();
047                    while (iter.hasNext()) {
048                            String variable = (String) iter.next();
049                            if (!variablesToValues.keySet().contains(variable)) {
050                                    return false;
051                            } else {
052                                    if (variablesToValues.get(variable) == null) {
053                                            return false;
054                                    }
055                            }
056                    }
057                    return true;
058            }
059    
060            public void remove(String variable) {
061                    if (variablesToValues.keySet().contains(variable)) {
062                            variablesToValues.remove(variable);
063                    }
064            }
065    
066            public String selectFirstUnassignedVariable() {
067                    Iterator iter = variables.iterator();
068                    while (iter.hasNext()) {
069                            String variable = (String) iter.next();
070                            if (!(variablesToValues.keySet().contains(variable))) {
071                                    return variable;
072                            }
073                    }
074                    return null;
075    
076            }
077    
078            public boolean hasAssignmentFor(String variable) {
079                    return variablesToValues.keySet().contains(variable);
080            }
081    
082            @Override
083            public String toString() {
084    
085                    return variablesToValues.toString();
086            }
087    
088            public Assignment copy() {
089                    Assignment copy = new Assignment();
090                    for (int i = 0; i < variables.size(); i++) {
091                            copy.variables.add(variables.get(i));
092                    }
093                    Iterator<String> iter = variablesToValues.keySet().iterator();
094                    while (iter.hasNext()) {
095                            String key = iter.next();
096                            copy.variablesToValues.put(key, variablesToValues.get(key));
097                    }
098                    return copy;
099            }
100    
101            public int getNumberOfConflictsFor(String conflictedVariable, Object value,
102                            Constraint constraint) {
103                    Assignment duplicate = copy();
104                    duplicate.setAssignment(conflictedVariable, value);
105                    return duplicate.getConflictedVariables(constraint).size();
106            }
107    
108            public List<String> getConflictedVariables(Constraint constraint) {
109                    List<String> conflictedVariables = new ArrayList<String>();
110                    List<String> variables = getVariables();
111                    for (String variable : variables) {
112                            Object value = getAssignment(variable);
113                            if (!(constraint.isSatisfiedWith(this, variable, value))) {
114                                    conflictedVariables.add(variable);
115                            }
116                    }
117                    return conflictedVariables;
118            }
119    
120            public Object getMinimumConflictingValueFor(String conflictedVariable,
121                            List domain, Constraint constraint) {
122                    int minConflict = Integer.MAX_VALUE;
123                    Object minConflictValue = null;
124    
125                    for (int i = 0; i < domain.size(); i++) {
126                            Object value = domain.get(i);
127                            if (getNumberOfConflictsFor(conflictedVariable, value, constraint) < minConflict) {
128                                    minConflict = getNumberOfConflictsFor(conflictedVariable,
129                                                    value, constraint);
130                                    minConflictValue = value;
131                            }
132                    }
133                    return minConflictValue;
134            }
135    
136            public boolean satisfies(Constraint constraint) {
137                    if (isComplete()) {
138                            for (int j = 0; j < getVariables().size(); j++) {
139                                    String variable = getVariables().get(j);
140                                    Object value = getAssignment(variable);
141                                    if (!(constraint.isSatisfiedWith(this, variable, value))) {
142                                            return false;
143                                    }
144                            }
145                            return true;
146                    } else {
147                            return false;
148                    }
149            }
150    
151            public List<String> getVariables() {
152                    return variables;
153            }
154    }