Flexibility.java 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. package holeg.model;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import java.util.function.Predicate;
  5. /**
  6. * Representative of a flexibility for a HolonElement.
  7. */
  8. public class Flexibility {
  9. /*
  10. * MODEL
  11. */
  12. /**
  13. * The Name of a Flexibility.
  14. */
  15. public String name;
  16. /**
  17. * How fast in TimeSteps the Flexibility can be activated.
  18. */
  19. public int speed;
  20. /**
  21. * How high the cost for a activation are.
  22. */
  23. public float cost;
  24. /**
  25. * SHould this Flexibility be Offered when is constrainList is fulfilled the flexibility can be
  26. * activated.
  27. */
  28. public boolean offered;
  29. /**
  30. * The List of Constrains the Flexibility
  31. */
  32. public List<Constrain> constrainList;
  33. /**
  34. * The owner of the Flexibility.
  35. */
  36. private transient HolonElement element;
  37. /**
  38. * The Duration in TimeSteps how long the Flexibility is activated.
  39. */
  40. private int duration;
  41. /** The Element this flexibility is assigned.*/
  42. /**
  43. * The Duration after a successful activation between the next possible activation.
  44. */
  45. private int cooldown;
  46. /*
  47. * STATE
  48. */
  49. private transient FlexState state = FlexState.OFFERED;
  50. private transient int timeStep;
  51. private transient int activationTime = -1;
  52. private transient int durationEndTime = -1;
  53. private transient int coolDownEndTime = -1;
  54. public Flexibility(HolonElement element) {
  55. this(0, 0.f, 1, 0, false, element);
  56. }
  57. public Flexibility(int speed, float cost, int duration, int cooldown, boolean offered,
  58. HolonElement element) {
  59. this.speed = speed;
  60. this.cost = cost;
  61. setDuration(duration);
  62. setCooldown(cooldown);
  63. this.offered = offered;
  64. this.element = element;
  65. constrainList = new ArrayList<Constrain>();
  66. }
  67. public HolonElement getElement() {
  68. return element;
  69. }
  70. public void setElement(HolonElement element) {
  71. this.element = element;
  72. }
  73. public int getDuration() {
  74. return duration;
  75. }
  76. /**
  77. * Minimum duration is 1 TimeStep.
  78. */
  79. public void setDuration(int duration) {
  80. this.duration = Math.max(1, duration);
  81. }
  82. public int getCooldown() {
  83. return cooldown;
  84. }
  85. /**
  86. * No negative cooldown TimeSteps.
  87. */
  88. public void setCooldown(int cooldown) {
  89. this.cooldown = Math.max(0, cooldown);
  90. }
  91. /**
  92. * returns the total energy Amount accumulated over the TimeSteps.
  93. */
  94. public float magnitude() {
  95. return ((float) duration) * element.getEnergy();
  96. }
  97. public float energyReleased() {
  98. return
  99. (constrainList.stream().map(Constrain::getName).anyMatch(name -> name.equals("onConstrain"))
  100. ? -1.0f : 1.0f) * element.getEnergy();
  101. }
  102. public boolean isPositive() {
  103. return energyReleased() >= 0;
  104. }
  105. public boolean isNegative() {
  106. return energyReleased() < 0;
  107. }
  108. public int getSpeed() {
  109. return speed;
  110. }
  111. public void setSpeed(int speed) {
  112. this.speed = speed;
  113. }
  114. @Override
  115. public String toString() {
  116. return "Flexibility: " + name + " from [HolonElement: " + element.getName() + "]";
  117. }
  118. void calculateState(int timestep) {
  119. this.timeStep = timestep;
  120. state = revalidateState();
  121. }
  122. public boolean order() {
  123. if (canOrder()) {
  124. state = FlexState.IN_USE;
  125. durationEndTime = timeStep + this.getDuration();
  126. coolDownEndTime = durationEndTime + this.getCooldown();
  127. activationTime = timeStep;
  128. return true;
  129. }
  130. return false;
  131. }
  132. public boolean cancel() {
  133. if (activationTime == timeStep) {
  134. reset();
  135. return true;
  136. }
  137. return false;
  138. }
  139. void reset() {
  140. durationEndTime = -1;
  141. coolDownEndTime = -1;
  142. state = revalidateState();
  143. }
  144. public boolean canActivate() {
  145. return remainingTimeTillActivation() == 0;
  146. }
  147. public boolean canOrder() {
  148. boolean flexIsOffered = state.equals(FlexState.OFFERED);
  149. return flexIsOffered && !element.isFlexActive();
  150. }
  151. public FlexState getState() {
  152. return state;
  153. }
  154. public int remainingTimeTillActivation() {
  155. return Math.max(0, coolDownEndTime - timeStep);
  156. }
  157. public int remainingDuration() {
  158. return Math.max(0, durationEndTime - timeStep);
  159. }
  160. /**
  161. * Checks if all assigned constrains are fulfilled. When no constrains assigned returns true.
  162. */
  163. private boolean fulfillsConstrains() {
  164. return constrainList.stream().map(Constrain::getConstrainFunction).reduce(Predicate::and)
  165. .orElse(f -> true).test(this);
  166. }
  167. private FlexState revalidateState() {
  168. if (canActivate()) {
  169. if (!this.fulfillsConstrains() || element.isFlexActive()) {
  170. return FlexState.UNAVAILABLE;
  171. } else if (this.offered) {
  172. return FlexState.OFFERED;
  173. }
  174. return FlexState.NOT_OFFERED;
  175. } else if (remainingDuration() == 0) {
  176. return FlexState.ON_COOLDOWN;
  177. } else {
  178. return FlexState.IN_USE;
  179. }
  180. }
  181. public enum FlexState {
  182. IN_USE, ON_COOLDOWN, OFFERED, NOT_OFFERED, UNAVAILABLE
  183. }
  184. }