/*
* Copyright © 2010 by Ondrej Skalicka. All Rights Reserved
*/
package cz.cvut.felk.cig.jcop.problem;
import java.util.ArrayList;
import java.util.List;
/**
* Configuration is representation of one state in state space. It has configuration attributes, dimension and history
* of operations applied to this configuration.
*
* @author Ondrej Skalicka
*/
public class Configuration implements Comparable<Configuration> {
/**
* Dimension of this configuration, eg. number of configuration attributes.
*/
protected int dimension;
/**
* Configuration attributes.
*/
protected List<Integer> attributes;
/**
* Last element in operationHistory of this configuration.
*/
protected OperationHistory operationHistory;
/**
* Creates new Configuration with set attributes and operation history.
*
* @param attributes new attributes for Configuration. List is NOT copied so take care not to use it for more
* than one configuration or change it afterwards.
* @param operationHistory last item in configuration history.
*/
public Configuration(List<Integer> attributes, OperationHistory operationHistory) {
this.dimension = attributes.size();
this.attributes = attributes;
this.operationHistory = operationHistory;
}
/**
* Special constructor for creating first configuration (eg. starting configuration). DO NOT use in operations!
* <p/>
* Is equivalent to new Configuration(attributes, new OperationHistory(new NewConfigurationOperation(createText))).
*
* @param attributes new attributes for Configuration. List is NOT copied so take care not to use it for more than
* one configuration or change it afterwards.
* @param createText text for {@link NewConfigurationOperation} constructor
*/
public Configuration(List<Integer> attributes, String createText) {
this(attributes, new OperationHistory(new NewConfigurationOperation(createText)));
}
/**
* Creates new configuration with UnknownOperation in operation history.
*
* @param attributes new attributes for Configuration. List is NOT copied so take care not to use it for more than
* one configuration or change it afterwards.
*/
public Configuration(List<Integer> attributes) {
this(attributes, new OperationHistory(new UnknownOperation()));
}
/**
* Gets value of an attribute specified by index.
*
* @param index index of attribute
* @return value of attribute
* @throws IndexOutOfBoundsException if index < 0 or index >= dimension
*/
public Integer valueAt(int index) throws IndexOutOfBoundsException {
return attributes.get(index);
}
/**
* Returns configuration as list.
* <p/>
* Note that new list is created so it is safe to just edit some values and pass it to new configuration.
*
* @return copy of list
*/
public List<Integer> asList() {
return new ArrayList<Integer>(this.attributes);
}
public int[] asSimpleArray() {
int[] result = new int[this.attributes.size()];
for (int i=0; i<this.attributes.size(); i++) result[i] = this.attributes.get(i).intValue();
return result;
}
/**
* Fingerprint is somehow similar to hashCode in that way, that two configurations that are considered equal via
* CompareTo has the same fingerprint. However, contrast to hashCode, if two configurations has the same
* fingerprint, they are considered equal.
*
* @return Fingerprint of configuration
*/
public String fingerprint() {
StringBuffer fingerprint = new StringBuffer("");
for (int i = 0; i < this.dimension; ++i) {
if (i > 0) fingerprint.append("-");
fingerprint.append(attributes.get(i));
}
return fingerprint.toString();
}
/**
* Returns last element in operation history for this configuration.
*
* @return last operation history element
*/
public OperationHistory getOperationHistory() {
return operationHistory;
}
/**
* Size of configuration
*
* @return size of configuration
*/
public int size() {
return this.attributes.size();
}
public int compareTo(Configuration o) {
return o.fingerprint().compareTo(this.fingerprint());
}
public int getDimension() {
return dimension;
}
@Override
public String toString() {
if (this.operationHistory == null) {
return "Configuration{" +
"attributes=" + attributes +
"}}";
}
if (this.operationHistory.getCounter() > 10) return "Configuration{" +
"attributes=" + attributes +
", operationHistory={" + this.operationHistory.getCounter() +
" items}}";
return "Configuration{" +
"attributes=" + attributes +
", operationHistory={" + operationHistory +
"}}";
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Configuration)) return false;
Configuration that = (Configuration) o;
return dimension == that.dimension && attributes.equals(that.attributes);
}
@Override
public int hashCode() {
int result = dimension;
result = 31 * result + attributes.hashCode();
return result;
}
}