package nl.fontys.sofa.limo.domain.component.event.distribution;
import com.google.gson.annotations.Expose;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.Embedded;
import nl.fontys.sofa.limo.domain.component.event.distribution.input.InputValue;
/**
* A distribution that can be used for an event to generate a probability of
* that event happening during a simulation iteration.
*
* @author Dominik Kaisers {@literal <d.kaisers@student.fontys.nl>}
*/
public abstract class Distribution implements Serializable {
@Embedded
@Expose protected Map<String, InputValue> inputValues;
@Expose protected transient String description;
/**
* FOR CACHING ONLY!
*/
private transient Double probabilityCache;
/**
* Construct a new distribution.
*
* @param inputValues Input values.
*/
public Distribution(InputValue... inputValues) {
this.inputValues = new HashMap<>();
if (inputValues != null) {
for (InputValue iv : inputValues) {
this.inputValues.put(iv.getName(), iv);
}
}
}
/**
* FOR ORIENTDB USE ONLY! USE OTHER METHODS TO GET INFORMATION!
*
* @return Input values.
*/
public Map<String, InputValue> getInputValues() {
return inputValues;
}
/**
* FOR ORIENTDB USE ONLY! USE OTHER METHODS TO PUT IN VALUES!
*
* @param inputValues Input values.
*/
public void setInputValues(Map<String, InputValue> inputValues) {
this.inputValues = inputValues;
this.probabilityCache = null;
}
/**
* Gets the input type for a given input value.
*
* @param name Name of input value.
* @return Type of input value. NULL if not known.
*/
public Class<Number> getType(String name) {
if (!this.inputValues.containsKey(name)) {
return null;
}
return this.inputValues.get(name).getType();
}
/**
* Gets the value for a given input value.
*
* @param name Name of input value.
* @return Value of input value. NULL if not known.
*/
public Number getValue(String name) {
if (!this.inputValues.containsKey(name)) {
return null;
}
return this.inputValues.get(name).getValue();
}
/**
* Gets the available input values for the distribution type.
*
* @return Names of all available input values.
*/
public List<String> getNames() {
return new ArrayList<>(this.inputValues.keySet());
}
/**
* Sets the value for the input value with the given name. Unknown input
* values are ignored.
*
* @param name Name of input value to set.
* @param value New value of input value.
*/
public void setInputValue(String name, Number value) {
if (!this.inputValues.containsKey(name)) {
return;
}
this.inputValues.get(name).setValue(value);
this.probabilityCache = null;
}
/**
* Sets the values for the input values with the given names. Unknown input
* values are ignored.
*
* @param inputValues Map of input value names and their new values.
*/
public void setInputValueMap(Map<String, Number> inputValues) {
for (Map.Entry<String, Number> entry : inputValues.entrySet()) {
setInputValue(entry.getKey(), entry.getValue());
}
}
/**
* Gets the probability for the set distribution type and its parameters.
* Result is cached as long as the parameters do not change.
*
* @return (Cached) proability result.
*/
public double getProbability() {
if (this.probabilityCache == null) {
this.probabilityCache = calculateProbability();
}
return this.probabilityCache;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
/**
* Calculate the specific distribution probability and save it to the cache.
*
* @return the probability.
*/
protected abstract double calculateProbability();
}