Flexibility.java 5.3 KB

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