Changeset 16779 for trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp
- Timestamp:
- 04/12/19 13:45:11 (6 years ago)
- Location:
- trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1
- Files:
-
- 10 added
- 7 deleted
- 33 edited
- 3 copied
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/HeuristicLab.SimSharp-3.1.1/HeuristicLab.SimSharp-3.1.1.csproj
r16715 r16779 9 9 <AppDesignerFolder>Properties</AppDesignerFolder> 10 10 <RootNamespace>HeuristicLab.SimSharp</RootNamespace> 11 <AssemblyName>HeuristicLab.SimSharp-3. 0.11</AssemblyName>11 <AssemblyName>HeuristicLab.SimSharp-3.1.1</AssemblyName> 12 12 <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> 13 13 <FileAlignment>512</FileAlignment> … … 92 92 <Private>False</Private> 93 93 </ProjectReference> 94 <ProjectReference Include="..\SimSharp-3. 0.11\SimSharp-3.0.11.csproj">94 <ProjectReference Include="..\SimSharp-3.1.1\SimSharp-3.1.1.csproj"> 95 95 <Project>{9fe9c740-7859-4d01-ad07-7d4e15a6320b}</Project> 96 <Name>SimSharp-3. 0.11</Name>96 <Name>SimSharp-3.1.1</Name> 97 97 </ProjectReference> 98 98 </ItemGroup> 99 99 <ItemGroup> 100 <Content Include="SimSharp-3. 0.11 License.txt">100 <Content Include="SimSharp-3.1.1 License.txt"> 101 101 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> 102 102 </Content> -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/HeuristicLab.SimSharp-3.1.1/Plugin.cs.frame
r16565 r16779 23 23 24 24 namespace HeuristicLab.SimSharp { 25 [Plugin("HeuristicLab.SimSharp", "Transport plugin for the simulation framework Sim#", "3. 0.11.$WCREV$")]26 [PluginFile("HeuristicLab.SimSharp-3. 0.11.dll", PluginFileType.Assembly)]27 [PluginFile("SimSharp-3. 0.11.dll", PluginFileType.Assembly)]28 [PluginFile("SimSharp-3. 0.11 License.txt", PluginFileType.License)]25 [Plugin("HeuristicLab.SimSharp", "Transport plugin for the simulation framework Sim#", "3.1.1.$WCREV$")] 26 [PluginFile("HeuristicLab.SimSharp-3.1.1.dll", PluginFileType.Assembly)] 27 [PluginFile("SimSharp-3.1.1.dll", PluginFileType.Assembly)] 28 [PluginFile("SimSharp-3.1.1 License.txt", PluginFileType.License)] 29 29 public class HeuristicLabSimSharpPlugin : PluginBase { 30 30 } -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/HeuristicLab.SimSharp-3.1.1/Properties/AssemblyInfo.cs.frame
r15972 r16779 5 5 // set of attributes. Change these attribute values to modify the information 6 6 // associated with an assembly. 7 [assembly: AssemblyTitle("HeuristicLab.SimSharp -3.0.11")]7 [assembly: AssemblyTitle("HeuristicLab.SimSharp")] 8 8 [assembly: AssemblyDescription("Transport plugin for the simulation framework Sim#")] 9 9 [assembly: AssemblyConfiguration("")] 10 10 [assembly: AssemblyCompany("HEAL")] 11 11 [assembly: AssemblyProduct("HeuristicLab")] 12 [assembly: AssemblyCopyright("(c) 2002-201 8HEAL")]12 [assembly: AssemblyCopyright("(c) 2002-2019 HEAL")] 13 13 [assembly: AssemblyTrademark("")] 14 14 [assembly: AssemblyCulture("")] … … 32 32 // by using the '*' as shown below: 33 33 // [assembly: AssemblyVersion("1.0.*")] 34 [assembly: AssemblyVersion("3. 0.11.0")]35 [assembly: AssemblyFileVersion("3. 0.11.$WCREV$")]34 [assembly: AssemblyVersion("3.1.1.0")] 35 [assembly: AssemblyFileVersion("3.1.1.$WCREV$")] -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Analysis/ContinuousStatistics.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 21 21 namespace SimSharp { 22 22 public sealed class ContinuousStatistics { 23 private readonly Environmentenv;23 private readonly Simulation env; 24 24 25 25 public int Count { get; private set; } … … 41 41 42 42 43 public ContinuousStatistics( Environmentenv) {43 public ContinuousStatistics(Simulation env) { 44 44 this.env = env; 45 45 lastUpdateTime = env.NowD; -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Collections/EventQueue.cs
r15972 r16779 6 6 /// <summary> 7 7 /// An implementation of a min-Priority Queue using a heap. Has O(1) .Contains()! 8 /// See https:// bitbucket.org/BlueRaja/high-speed-priority-queue-for-c/wiki/Getting%20Started for more information8 /// See https://github.com/BlueRaja/High-Speed-Priority-Queue-for-C-Sharp/wiki/Getting-Started for more information 9 9 /// </summary> 10 10 /// <remarks> … … 48 48 /// Removes every node from the queue. O(n) (So, don't do this often!) 49 49 /// </summary> 50 #if AGGRESSIVE_INLINING 51 [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] 52 #endif 50 [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] 53 51 public void Clear() { 54 52 Array.Clear(_nodes, 1, _numNodes); … … 59 57 /// Returns (in O(1)!) whether the given node is in the queue. O(1) 60 58 /// </summary> 61 #if AGGRESSIVE_INLINING 62 [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] 63 #endif 59 [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] 64 60 public bool Contains(EventQueueNode node) { 65 61 return (_nodes[node.QueueIndex] == node); … … 69 65 /// Enqueue a node - .Priority must be set beforehand! O(log n) 70 66 /// </summary> 71 #if AGGRESSIVE_INLINING 72 [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] 73 #endif 67 [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] 74 68 public EventQueueNode Enqueue(DateTime primaryPriority, Event @event, int secondaryPriority = 0) { 75 69 var node = new EventQueueNode { … … 84 78 return node; 85 79 } 86 87 #if AGGRESSIVE_INLINING 88 [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] 89 #endif 80 81 [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] 90 82 private void Swap(EventQueueNode node1, EventQueueNode node2) { 91 83 //Swap the nodes … … 115 107 } 116 108 117 #if AGGRESSIVE_INLINING 118 [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] 119 #endif 109 110 [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] 120 111 private void CascadeDown(EventQueueNode node) { 121 112 //aka Heapify-down … … 170 161 /// Note that calling HasHigherPriority(node, node) (ie. both arguments the same node) will return false 171 162 /// </summary> 172 #if AGGRESSIVE_INLINING 173 [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] 174 #endif 163 164 [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] 175 165 private bool HasHigherPriority(EventQueueNode higher, EventQueueNode lower) { 176 166 return (higher.PrimaryPriority < lower.PrimaryPriority || … … 204 194 /// O(log n) 205 195 /// </summary> 206 #if AGGRESSIVE_INLINING 207 [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] 208 #endif 196 197 [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] 209 198 public void UpdatePriority(EventQueueNode node, DateTime primaryPriority, int secondaryPriority) { 210 199 node.PrimaryPriority = primaryPriority; -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/ActiveObject.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 18 18 19 19 namespace SimSharp { 20 public abstract class ActiveObject<T> where T : Environment{20 public abstract class ActiveObject<T> where T : Simulation { 21 21 protected T Environment { get; private set; } 22 22 -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Environment.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 23 23 namespace SimSharp { 24 24 /// <summary> 25 /// Environmentshold the event queues, schedule and process events.25 /// Simulation hold the event queues, schedule and process events. 26 26 /// </summary> 27 public class Environment { 27 /// <remarks> 28 /// This class is not thread-safe against manipulation of the event queue. If you supply a termination 29 /// event that is set outside the simulation, please use the <see cref="ThreadSafeSimulation"/> environment. 30 /// 31 /// For most purposes <see cref="Simulation"/> is however the better and faster choice. 32 /// </remarks> 33 public class Simulation { 28 34 private const int InitialMaxEvents = 1024; 29 private object locker = new object();30 35 31 36 /// <summary> … … 65 70 public int ProcessedEvents { get; protected set; } 66 71 67 public Environment() : this(new DateTime(1970, 1, 1)) { } 68 public Environment(TimeSpan? defaultStep) : this(new DateTime(1970, 1, 1), defaultStep) { } 69 public Environment(int randomSeed, TimeSpan? defaultStep = null) : this(new DateTime(1970, 1, 1), randomSeed, defaultStep) { } 70 public Environment(DateTime initialDateTime, TimeSpan? defaultStep = null) { 72 public Simulation() : this(new DateTime(1970, 1, 1)) { } 73 public Simulation(TimeSpan? defaultStep) : this(new DateTime(1970, 1, 1), defaultStep) { } 74 public Simulation(int randomSeed, TimeSpan? defaultStep = null) : this(new DateTime(1970, 1, 1), randomSeed, defaultStep) { } 75 public Simulation(DateTime initialDateTime, TimeSpan? defaultStep = null) : this(new PcgRandom(), initialDateTime, defaultStep) { } 76 public Simulation(DateTime initialDateTime, int randomSeed, TimeSpan? defaultStep = null) : this(new PcgRandom(randomSeed), initialDateTime, defaultStep) { } 77 public Simulation(IRandom random, DateTime initialDateTime, TimeSpan? defaultStep = null) { 71 78 DefaultTimeStepSeconds = (defaultStep ?? TimeSpan.FromSeconds(1)).Duration().TotalSeconds; 72 79 StartDate = initialDateTime; 73 80 Now = initialDateTime; 74 Random = new SystemRandom(); 75 ScheduleQ = new EventQueue(InitialMaxEvents); 76 Logger = Console.Out; 77 } 78 public Environment(DateTime initialDateTime, int randomSeed, TimeSpan? defaultStep = null) { 79 DefaultTimeStepSeconds = (defaultStep ?? TimeSpan.FromSeconds(1)).Duration().TotalSeconds; 80 StartDate = initialDateTime; 81 Now = initialDateTime; 82 Random = new SystemRandom(randomSeed); 81 Random = random; 83 82 ScheduleQ = new EventQueue(InitialMaxEvents); 84 83 Logger = Console.Out; … … 127 126 ProcessedEvents = 0; 128 127 Now = StartDate; 129 Random = new SystemRandom(randomSeed);128 Random = new PcgRandom(randomSeed); 130 129 ScheduleQ = new EventQueue(InitialMaxEvents); 130 useSpareNormal = false; 131 131 } 132 132 … … 139 139 /// </summary> 140 140 /// <param name="event">The event that should be scheduled.</param> 141 /// <param name="priority">The priority to rank events at the same time (smaller value = higher priority).</param> </param>141 /// <param name="priority">The priority to rank events at the same time (smaller value = higher priority).</param> 142 142 public virtual void Schedule(Event @event, int priority = 0) { 143 lock (locker) { 144 DoSchedule(Now, @event, priority); 145 } 143 DoSchedule(Now, @event, priority); 146 144 } 147 145 … … 158 156 if (delay < TimeSpan.Zero) 159 157 throw new ArgumentException("Negative delays are not allowed in Schedule(TimeSpan, Event)."); 160 lock (locker) { 161 var eventTime = Now + delay; 162 DoSchedule(eventTime, @event, priority); 163 } 158 var eventTime = Now + delay; 159 DoSchedule(eventTime, @event, priority); 164 160 } 165 161 … … 193 189 } 194 190 191 protected bool _stopRequested = false; 192 /// <summary> 193 /// Run until a certain event is processed. 194 /// </summary> 195 /// <remarks> 196 /// This simulation environment is not thread-safe, thus triggering this event outside the environment 197 /// leads to potential race conditions. Please use the <see cref="ThreadSafeSimulation"/> environment in case you 198 /// require this functionality. Note that the performance of <see cref="ThreadSafeSimulation"/> is lower due to locking. 199 /// 200 /// For real-time based termination, you can also call <see cref="StopAsync"/> which sets a flag indicating the simulation 201 /// to stop before processing the next event. 202 /// </remarks> 203 /// <param name="stopEvent">The event that stops the simulation.</param> 204 /// <returns></returns> 195 205 public virtual object Run(Event stopEvent = null) { 206 _stopRequested = false; 196 207 if (stopEvent != null) { 197 208 if (stopEvent.IsProcessed) return stopEvent.Value; … … 200 211 201 212 try { 202 var stop = ScheduleQ.Count == 0 ;213 var stop = ScheduleQ.Count == 0 || _stopRequested; 203 214 while (!stop) { 204 215 Step(); 205 216 ProcessedEvents++; 206 lock (locker) { 207 stop = ScheduleQ.Count == 0; 217 stop = ScheduleQ.Count == 0 || _stopRequested; 218 } 219 } catch (StopSimulationException e) { return e.Value; } 220 if (stopEvent == null) return null; 221 if (!stopEvent.IsTriggered) throw new InvalidOperationException("No scheduled events left but \"until\" event was not triggered."); 222 return stopEvent.Value; 223 } 224 225 public virtual void StopAsync() { 226 _stopRequested = true; 227 } 228 229 /// <summary> 230 /// Performs a single step of the simulation, i.e. process a single event 231 /// </summary> 232 /// <remarks> 233 /// This method is not thread-safe 234 /// </remarks> 235 public virtual void Step() { 236 Event evt; 237 var next = ScheduleQ.Dequeue(); 238 Now = next.PrimaryPriority; 239 evt = next.Event; 240 evt.Process(); 241 } 242 243 /// <summary> 244 /// Peeks at the time of the next event in terms of the defined step 245 /// </summary> 246 /// <remarks> 247 /// This method is not thread-safe 248 /// </remarks> 249 public virtual double PeekD() { 250 if (ScheduleQ.Count == 0) return double.MaxValue; 251 return (Peek() - StartDate).TotalSeconds / DefaultTimeStepSeconds; 252 } 253 254 /// <summary> 255 /// Peeks at the time of the next event 256 /// </summary> 257 /// <remarks> 258 /// This method is not thread-safe 259 /// </remarks> 260 public virtual DateTime Peek() { 261 return ScheduleQ.Count > 0 ? ScheduleQ.First.PrimaryPriority : DateTime.MaxValue; 262 } 263 264 protected virtual void StopSimulation(Event @event) { 265 throw new StopSimulationException(@event.Value); 266 } 267 268 public virtual void Log(string message, params object[] args) { 269 if (Logger != null) 270 Logger.WriteLine(message, args); 271 } 272 273 #region Random number distributions 274 public double RandUniform(IRandom random, double a, double b) { 275 return a + (b - a) * random.NextDouble(); 276 } 277 public double RandUniform(double a, double b) { 278 return RandUniform(Random, a, b); 279 } 280 281 public TimeSpan RandUniform(IRandom random, TimeSpan a, TimeSpan b) { 282 return TimeSpan.FromSeconds(RandUniform(random, a.TotalSeconds, b.TotalSeconds)); 283 } 284 public TimeSpan RandUniform(TimeSpan a, TimeSpan b) { 285 return RandUniform(Random, a, b); 286 } 287 public double RandTriangular(IRandom random, double low, double high) { 288 var u = random.NextDouble(); 289 if (u > 0.5) 290 return high + (low - high) * Math.Sqrt(((1.0 - u) / 2)); 291 return low + (high - low) * Math.Sqrt(u / 2); 292 } 293 public double RandTriangular(double low, double high) { 294 return RandTriangular(Random, low, high); 295 } 296 297 public TimeSpan RandTriangular(IRandom random, TimeSpan low, TimeSpan high) { 298 return TimeSpan.FromSeconds(RandTriangular(random, low.TotalSeconds, high.TotalSeconds)); 299 } 300 public TimeSpan RandTriangular(TimeSpan low, TimeSpan high) { 301 return RandTriangular(Random, low, high); 302 } 303 304 public double RandTriangular(IRandom random, double low, double high, double mode) { 305 var u = random.NextDouble(); 306 var c = (mode - low) / (high - low); 307 if (u > c) 308 return high + (low - high) * Math.Sqrt(((1.0 - u) * (1.0 - c))); 309 return low + (high - low) * Math.Sqrt(u * c); 310 } 311 public double RandTriangular(double low, double high, double mode) { 312 return RandTriangular(Random, low, high, mode); 313 } 314 315 public TimeSpan RandTriangular(IRandom random, TimeSpan low, TimeSpan high, TimeSpan mode) { 316 return TimeSpan.FromSeconds(RandTriangular(random, low.TotalSeconds, high.TotalSeconds, mode.TotalSeconds)); 317 } 318 public TimeSpan RandTriangular(TimeSpan low, TimeSpan high, TimeSpan mode) { 319 return RandTriangular(Random, low, high, mode); 320 } 321 322 /// <summary> 323 /// Returns a number that is exponentially distributed given a certain mean. 324 /// </summary> 325 /// <remarks> 326 /// Unlike in other APIs here the mean should be given and not the lambda parameter. 327 /// </remarks> 328 /// <param name="random">The random number generator to use.</param> 329 /// <param name="mean">The mean(!) of the distribution is 1 / lambda.</param> 330 /// <returns>A number that is exponentially distributed</returns> 331 public double RandExponential(IRandom random, double mean) { 332 return -Math.Log(1 - random.NextDouble()) * mean; 333 } 334 /// <summary> 335 /// Returns a number that is exponentially distributed given a certain mean. 336 /// </summary> 337 /// <remarks> 338 /// Unlike in other APIs here the mean should be given and not the lambda parameter. 339 /// </remarks> 340 /// <param name="mean">The mean(!) of the distribution is 1 / lambda.</param> 341 /// <returns>A number that is exponentially distributed</returns> 342 public double RandExponential(double mean) { 343 return RandExponential(Random, mean); 344 } 345 346 /// <summary> 347 /// Returns a timespan that is exponentially distributed given a certain mean. 348 /// </summary> 349 /// <remarks> 350 /// Unlike in other APIs here the mean should be given and not the lambda parameter. 351 /// </remarks> 352 /// <param name="random">The random number generator to use.</param> 353 /// <param name="mean">The mean(!) of the distribution is 1 / lambda.</param> 354 /// <returns>A number that is exponentially distributed</returns> 355 public TimeSpan RandExponential(IRandom random, TimeSpan mean) { 356 return TimeSpan.FromSeconds(RandExponential(random, mean.TotalSeconds)); 357 } 358 /// <summary> 359 /// Returns a timespan that is exponentially distributed given a certain mean. 360 /// </summary> 361 /// <remarks> 362 /// Unlike in other APIs here the mean should be given and not the lambda parameter. 363 /// </remarks> 364 /// <param name="mean">The mean(!) of the distribution is 1 / lambda.</param> 365 /// <returns>A number that is exponentially distributed</returns> 366 public TimeSpan RandExponential(TimeSpan mean) { 367 return RandExponential(Random, mean); 368 } 369 370 private bool useSpareNormal = false; 371 private double spareNormal = double.NaN; 372 /// <summary> 373 /// Uses the Marsaglia polar method to generate a random variable 374 /// from two uniform random distributed values. 375 /// </summary> 376 /// <remarks> 377 /// A spare random variable is generated from the second uniformly 378 /// distributed value. Thus, the two calls to the uniform random number 379 /// generator will be made only every second call. 380 /// </remarks> 381 /// <param name="random">The random number generator to use.</param> 382 /// <param name="mu">The mean of the normal distribution.</param> 383 /// <param name="sigma">The standard deviation of the normal distribution.</param> 384 /// <returns>A number that is normal distributed.</returns> 385 public virtual double RandNormal(IRandom random, double mu, double sigma) { 386 if (useSpareNormal) { 387 useSpareNormal = false; 388 return spareNormal * sigma + mu; 389 } else { 390 double u, v, s; 391 do { 392 u = random.NextDouble() * 2 - 1; 393 v = random.NextDouble() * 2 - 1; 394 s = u * u + v * v; 395 } while (s >= 1 || s == 0); 396 var mul = Math.Sqrt(-2.0 * Math.Log(s) / s); 397 spareNormal = v * mul; 398 useSpareNormal = true; 399 return mu + sigma * u * mul; 400 } 401 } 402 /// <summary> 403 /// Uses the Marsaglia polar method to generate a random variable 404 /// from two uniform random distributed values. 405 /// </summary> 406 /// <remarks> 407 /// A spare random variable is generated from the second uniformly 408 /// distributed value. Thus, the two calls to the uniform random number 409 /// generator will be made only every second call. 410 /// </remarks> 411 /// <param name="mu">The mean of the normal distribution.</param> 412 /// <param name="sigma">The standard deviation of the normal distribution.</param> 413 /// <returns>A number that is normal distributed.</returns> 414 public double RandNormal(double mu, double sigma) { 415 return RandNormal(Random, mu, sigma); 416 } 417 418 /// <summary> 419 /// Uses the Marsaglia polar method to generate a random variable 420 /// from two uniform random distributed values. 421 /// </summary> 422 /// <remarks> 423 /// A spare random variable is generated from the second uniformly 424 /// distributed value. Thus, the two calls to the uniform random number 425 /// generator will be made only every second call. 426 /// </remarks> 427 /// <param name="random">The random number generator to use.</param> 428 /// <param name="mu">The mean of the normal distribution.</param> 429 /// <param name="sigma">The standard deviation of the normal distribution.</param> 430 /// <returns>A number that is normal distributed.</returns> 431 public TimeSpan RandNormal(IRandom random, TimeSpan mu, TimeSpan sigma) { 432 return TimeSpan.FromSeconds(RandNormal(random, mu.TotalSeconds, sigma.TotalSeconds)); 433 } 434 /// <summary> 435 /// Uses the Marsaglia polar method to generate a random variable 436 /// from two uniform random distributed values. 437 /// </summary> 438 /// <remarks> 439 /// A spare random variable is generated from the second uniformly 440 /// distributed value. Thus, the two calls to the uniform random number 441 /// generator will be made only every second call. 442 /// </remarks> 443 /// <param name="mu">The mean of the normal distribution.</param> 444 /// <param name="sigma">The standard deviation of the normal distribution.</param> 445 /// <returns>A number that is normal distributed.</returns> 446 public TimeSpan RandNormal(TimeSpan mu, TimeSpan sigma) { 447 return RandNormal(Random, mu, sigma); 448 } 449 450 public double RandNormalPositive(IRandom random, double mu, double sigma) { 451 double val; 452 do { 453 val = RandNormal(random, mu, sigma); 454 } while (val <= 0); 455 return val; 456 } 457 public double RandNormalPositive(double mu, double sigma) { 458 return RandNormalPositive(Random, mu, sigma); 459 } 460 461 public TimeSpan RandNormalPositive(IRandom random, TimeSpan mu, TimeSpan sigma) { 462 return TimeSpan.FromSeconds(RandNormalPositive(random, mu.TotalSeconds, sigma.TotalSeconds)); 463 } 464 public TimeSpan RandNormalPositive(TimeSpan mu, TimeSpan sigma) { 465 return RandNormalPositive(Random, mu, sigma); 466 } 467 468 public double RandNormalNegative(IRandom random, double mu, double sigma) { 469 double val; 470 do { 471 val = RandNormal(random, mu, sigma); 472 } while (val >= 0); 473 return val; 474 } 475 public double RandNormalNegative(double mu, double sigma) { 476 return RandNormalNegative(Random, mu, sigma); 477 } 478 479 public TimeSpan RandNormalNegative(IRandom random, TimeSpan mu, TimeSpan sigma) { 480 return TimeSpan.FromSeconds(RandNormalNegative(random, mu.TotalSeconds, sigma.TotalSeconds)); 481 } 482 public TimeSpan RandNormalNegative(TimeSpan mu, TimeSpan sigma) { 483 return RandNormalNegative(Random, mu, sigma); 484 } 485 486 /// <summary> 487 /// Returns values from a log-normal distribution with the mean 488 /// exp(mu + sigma^2 / 2) 489 /// and the standard deviation 490 /// sqrt([exp(sigma^2)-1] * exp(2 * mu + sigma^2)) 491 /// </summary> 492 /// <param name="random">The random number generator to use.</param> 493 /// <param name="mu">The mu parameter of the log-normal distribution (not the mean).</param> 494 /// <param name="sigma">The sigma parameter of the log-normal distribution (not the standard deviation).</param> 495 /// <returns>A log-normal distributed random value.</returns> 496 public double RandLogNormal(IRandom random, double mu, double sigma) { 497 return Math.Exp(RandNormal(random, mu, sigma)); 498 } 499 /// <summary> 500 /// Returns values from a log-normal distribution with the mean 501 /// exp(mu + sigma^2 / 2) 502 /// and the standard deviation 503 /// sqrt([exp(sigma^2)-1] * exp(2 * mu + sigma^2)) 504 /// </summary> 505 /// <param name="mu">The mu parameter of the log-normal distribution (not the mean).</param> 506 /// <param name="sigma">The sigma parameter of the log-normal distribution (not the standard deviation).</param> 507 /// <returns>A log-normal distributed random value.</returns> 508 public double RandLogNormal(double mu, double sigma) { 509 return RandLogNormal(Random, mu, sigma); 510 } 511 512 /// <summary> 513 /// Returns values from a log-normal distribution with 514 /// the mean <paramref name="mean"/> and standard deviation <paramref name="stdev"/>. 515 /// </summary> 516 /// <param name="random">The random number generator to use.</param> 517 /// <param name="mean">The distribution mean.</param> 518 /// <param name="stdev">The distribution standard deviation.</param> 519 /// <returns>A log-normal distributed random value.</returns> 520 public double RandLogNormal2(IRandom random, double mean, double stdev) { 521 if (stdev == 0) return mean; 522 var alpha = Math.Sqrt(mean * stdev) / mean; 523 var sigma = Math.Sqrt(Math.Log(1 + (alpha * alpha))); 524 var mu = Math.Log(mean) - 0.5 * sigma * sigma; 525 return Math.Exp(RandNormal(random, mu, sigma)); 526 } 527 /// <summary> 528 /// Returns values from a log-normal distribution with 529 /// the mean <paramref name="mean"/> and standard deviation <paramref name="stdev"/>. 530 /// </summary> 531 /// <param name="mean">The distribution mean.</param> 532 /// <param name="stdev">The distribution standard deviation.</param> 533 /// <returns>A log-normal distributed random value.</returns> 534 public double RandLogNormal2(double mean, double stdev) { 535 return RandLogNormal2(Random, mean, stdev); 536 } 537 538 /// <summary> 539 /// Returns a timespan value from a log-normal distribution with the mean 540 /// exp(mu + sigma^2 / 2) 541 /// and the standard deviation 542 /// sqrt([exp(sigma^2)-1] * exp(2 * mu + sigma^2)) 543 /// </summary> 544 /// <param name="random">The random number generator to use.</param> 545 /// <param name="mu">The mu parameter of the log-normal distribution (not the mean).</param> 546 /// <param name="sigma">The sigma parameter of the log-normal distribution (not the standard deviation).</param> 547 /// <returns>A log-normal distributed random timespan.</returns> 548 public TimeSpan RandLogNormal(IRandom random, TimeSpan mu, TimeSpan sigma) { 549 return TimeSpan.FromSeconds(RandLogNormal(random, mu.TotalSeconds, sigma.TotalSeconds)); 550 } 551 /// <summary> 552 /// Returns a timespan value from a log-normal distribution with the mean 553 /// exp(mu + sigma^2 / 2) 554 /// and the standard deviation 555 /// sqrt([exp(sigma^2)-1] * exp(2 * mu + sigma^2)) 556 /// </summary> 557 /// <param name="mu">The mu parameter of the log-normal distribution (not the mean).</param> 558 /// <param name="sigma">The sigma parameter of the log-normal distribution (not the standard deviation).</param> 559 /// <returns>A log-normal distributed random timespan.</returns> 560 public TimeSpan RandLogNormal(TimeSpan mu, TimeSpan sigma) { 561 return RandLogNormal(Random, mu, sigma); 562 } 563 564 /// <summary> 565 /// Returns a timespan value from a log-normal distribution with 566 /// the mean <paramref name="mean"/> and standard deviation <paramref name="stdev"/>. 567 /// </summary> 568 /// <param name="random">The random number generator to use.</param> 569 /// <param name="mean">The distribution mean.</param> 570 /// <param name="stdev">The distribution standard deviation.</param> 571 /// <returns>A log-normal distributed random timespan.</returns> 572 public TimeSpan RandLogNormal2(IRandom random, TimeSpan mean, TimeSpan stdev) { 573 return TimeSpan.FromSeconds(RandLogNormal2(random, mean.TotalSeconds, stdev.TotalSeconds)); 574 } 575 /// <summary> 576 /// Returns a timespan value from a log-normal distribution with 577 /// the mean <paramref name="mean"/> and standard deviation <paramref name="stdev"/>. 578 /// </summary> 579 /// <param name="mean">The distribution mean.</param> 580 /// <param name="stdev">The distribution standard deviation.</param> 581 /// <returns>A log-normal distributed random timespan.</returns> 582 public TimeSpan RandLogNormal2(TimeSpan mean, TimeSpan stdev) { 583 return RandLogNormal2(Random, mean, stdev); 584 } 585 586 public double RandCauchy(IRandom random, double x0, double gamma) { 587 return x0 + gamma * Math.Tan(Math.PI * (random.NextDouble() - 0.5)); 588 } 589 public double RandCauchy(double x0, double gamma) { 590 return RandCauchy(Random, x0, gamma); 591 } 592 593 public TimeSpan RandCauchy(IRandom random, TimeSpan x0, TimeSpan gamma) { 594 return TimeSpan.FromSeconds(RandCauchy(random, x0.TotalSeconds, gamma.TotalSeconds)); 595 } 596 public TimeSpan RandCauchy(TimeSpan x0, TimeSpan gamma) { 597 return RandCauchy(Random, x0, gamma); 598 } 599 600 public double RandWeibull(IRandom random, double alpha, double beta) { 601 return alpha * Math.Pow(-Math.Log(1 - random.NextDouble()), 1 / beta); 602 } 603 public double RandWeibull(double alpha, double beta) { 604 return RandWeibull(Random, alpha, beta); 605 } 606 607 public TimeSpan RandWeibull(IRandom random, TimeSpan alpha, TimeSpan beta) { 608 return TimeSpan.FromSeconds(RandWeibull(random, alpha.TotalSeconds, beta.TotalSeconds)); 609 } 610 public TimeSpan RandWeibull(TimeSpan alpha, TimeSpan beta) { 611 return RandWeibull(Random, alpha, beta); 612 } 613 #endregion 614 615 #region Random timeouts 616 public Timeout TimeoutUniformD(IRandom random, double a, double b) { 617 return new Timeout(this, ToTimeSpan(RandUniform(random, a, b))); 618 } 619 public Timeout TimeoutUniformD(double a, double b) { 620 return TimeoutUniformD(Random, a, b); 621 } 622 623 public Timeout TimeoutUniform(IRandom random, TimeSpan a, TimeSpan b) { 624 return new Timeout(this, RandUniform(random, a, b)); 625 } 626 public Timeout TimeoutUniform(TimeSpan a, TimeSpan b) { 627 return TimeoutUniform(Random, a, b); 628 } 629 630 public Timeout TimeoutTriangularD(IRandom random, double low, double high) { 631 return new Timeout(this, ToTimeSpan(RandTriangular(random, low, high))); 632 } 633 public Timeout TimeoutTriangularD(double low, double high) { 634 return TimeoutTriangularD(Random, low, high); 635 } 636 637 public Timeout TimeoutTriangular(IRandom random, TimeSpan low, TimeSpan high) { 638 return new Timeout(this, RandTriangular(random, low, high)); 639 } 640 public Timeout TimeoutTriangular(TimeSpan low, TimeSpan high) { 641 return TimeoutTriangular(Random, low, high); 642 } 643 644 public Timeout TimeoutTriangularD(IRandom random, double low, double high, double mode) { 645 return new Timeout(this, ToTimeSpan(RandTriangular(random, low, high, mode))); 646 } 647 public Timeout TimeoutTriangularD(double low, double high, double mode) { 648 return TimeoutTriangularD(Random, low, high, mode); 649 } 650 651 public Timeout TimeoutTriangular(IRandom random, TimeSpan low, TimeSpan high, TimeSpan mode) { 652 return new Timeout(this, RandTriangular(random, low, high, mode)); 653 } 654 public Timeout TimeoutTriangular(TimeSpan low, TimeSpan high, TimeSpan mode) { 655 return TimeoutTriangular(Random, low, high, mode); 656 } 657 658 public Timeout TimeoutExponentialD(IRandom random, double mean) { 659 return new Timeout(this, ToTimeSpan(RandExponential(random, mean))); 660 } 661 public Timeout TimeoutExponentialD(double mean) { 662 return TimeoutExponentialD(Random, mean); 663 } 664 665 public Timeout TimeoutExponential(IRandom random, TimeSpan mean) { 666 return new Timeout(this, RandExponential(random, mean)); 667 } 668 public Timeout TimeoutExponential(TimeSpan mean) { 669 return TimeoutExponential(Random, mean); 670 } 671 672 public Timeout TimeoutNormalPositiveD(IRandom random, double mu, double sigma) { 673 return new Timeout(this, ToTimeSpan(RandNormalPositive(random, mu, sigma))); 674 } 675 public Timeout TimeoutNormalPositiveD(double mu, double sigma) { 676 return TimeoutNormalPositiveD(Random, mu, sigma); 677 } 678 679 public Timeout TimeoutNormalPositive(IRandom random, TimeSpan mu, TimeSpan sigma) { 680 return new Timeout(this, RandNormalPositive(random, mu, sigma)); 681 } 682 public Timeout TimeoutNormalPositive(TimeSpan mu, TimeSpan sigma) { 683 return TimeoutNormalPositive(Random, mu, sigma); 684 } 685 686 public Timeout TimeoutLogNormalD(IRandom random, double mu, double sigma) { 687 return new Timeout(this, ToTimeSpan(RandLogNormal(random, mu, sigma))); 688 } 689 public Timeout TimeoutLogNormalD(double mu, double sigma) { 690 return TimeoutLogNormalD(Random, mu, sigma); 691 } 692 693 public Timeout TimeoutLogNormal2D(IRandom random, double mean, double stdev) { 694 return new Timeout(this, ToTimeSpan(RandLogNormal2(random, mean, stdev))); 695 } 696 public Timeout TimeoutLogNormal2D(double mean, double stdev) { 697 return TimeoutLogNormal2D(Random, mean, stdev); 698 } 699 700 public Timeout TimeoutLogNormal(IRandom random, TimeSpan mu, TimeSpan sigma) { 701 return new Timeout(this, RandLogNormal(random, mu, sigma)); 702 } 703 public Timeout TimeoutLogNormal(TimeSpan mu, TimeSpan sigma) { 704 return TimeoutLogNormal(Random, mu, sigma); 705 } 706 707 public Timeout TimeoutLogNormal2(IRandom random, TimeSpan mean, TimeSpan stdev) { 708 return new Timeout(this, RandLogNormal2(random, mean, stdev)); 709 } 710 public Timeout TimeoutLogNormal2(TimeSpan mean, TimeSpan stdev) { 711 return TimeoutLogNormal2(Random, mean, stdev); 712 } 713 #endregion 714 } 715 716 /// <summary> 717 /// Provides a simulation environment that is thread-safe against manipulations of the event queue. 718 /// Its performance is somewhat lower than the non-thread-safe environment (cf. <see cref="Simulation"/>) 719 /// due to the locking involved. 720 /// </summary> 721 /// <remarks> 722 /// Please carefully consider if you must really schedule the stop event in a separate thread. You can also 723 /// call <see cref="Simulation.StopAsync"/> to request termination after the current event has been processed. 724 /// 725 /// The simulation will still run in only one thread and execute all events sequentially. 726 /// </remarks> 727 public class ThreadSafeSimulation : Simulation { 728 protected object _locker; 729 730 public ThreadSafeSimulation() : this(new DateTime(1970, 1, 1)) { } 731 public ThreadSafeSimulation(TimeSpan? defaultStep) : this(new DateTime(1970, 1, 1), defaultStep) { } 732 public ThreadSafeSimulation(DateTime initialDateTime, TimeSpan? defaultStep = null) : this(new PcgRandom(), initialDateTime, defaultStep) { } 733 public ThreadSafeSimulation(int randomSeed, TimeSpan? defaultStep = null) : this(new DateTime(1970, 1, 1), randomSeed, defaultStep) { } 734 public ThreadSafeSimulation(DateTime initialDateTime, int randomSeed, TimeSpan? defaultStep = null) : this(new PcgRandom(randomSeed), initialDateTime, defaultStep) { } 735 public ThreadSafeSimulation(IRandom random, DateTime initialDateTime, TimeSpan? defaultStep = null) : base(random, initialDateTime, defaultStep) { 736 _locker = new object(); 737 } 738 739 740 /// <summary> 741 /// Schedules an event to occur at the same simulation time as the call was made. 742 /// </summary> 743 /// <remarks> 744 /// This method is thread-safe against manipulations of the event queue 745 /// </remarks> 746 /// <param name="event">The event that should be scheduled.</param> 747 /// <param name="priority">The priority to rank events at the same time (smaller value = higher priority).</param> 748 public override void Schedule(Event @event, int priority = 0) { 749 lock (_locker) { 750 DoSchedule(Now, @event, priority); 751 } 752 } 753 754 /// <summary> 755 /// Schedules an event to occur after a certain (positive) delay. 756 /// </summary> 757 /// <remarks> 758 /// This method is thread-safe against manipulations of the event queue 759 /// </remarks> 760 /// <exception cref="ArgumentException"> 761 /// Thrown when <paramref name="delay"/> is negative. 762 /// </exception> 763 /// <param name="delay">The (positive) delay after which the event should be fired.</param> 764 /// <param name="event">The event that should be scheduled.</param> 765 /// <param name="priority">The priority to rank events at the same time (smaller value = higher priority).</param> 766 public override void Schedule(TimeSpan delay, Event @event, int priority = 0) { 767 if (delay < TimeSpan.Zero) 768 throw new ArgumentException("Negative delays are not allowed in Schedule(TimeSpan, Event)."); 769 lock (_locker) { 770 var eventTime = Now + delay; 771 DoSchedule(eventTime, @event, priority); 772 } 773 } 774 775 /// <summary> 776 /// Run until a certain event is processed. 777 /// </summary> 778 /// <remarks> 779 /// This method is thread-safe against manipulations of the event queue 780 /// </remarks> 781 /// <param name="stopEvent">The event that stops the simulation.</param> 782 /// <returns></returns> 783 public override object Run(Event stopEvent = null) { 784 _stopRequested = false; 785 if (stopEvent != null) { 786 if (stopEvent.IsProcessed) return stopEvent.Value; 787 stopEvent.AddCallback(StopSimulation); 788 } 789 790 try { 791 var stop = false; 792 lock (_locker) { 793 stop = ScheduleQ.Count == 0 || _stopRequested; 794 } 795 while (!stop) { 796 Step(); 797 ProcessedEvents++; 798 lock (_locker) { 799 stop = ScheduleQ.Count == 0 || _stopRequested; 208 800 } 209 801 } … … 214 806 } 215 807 216 public virtual void Step() { 808 /// <summary> 809 /// Performs a single step of the simulation, i.e. process a single event 810 /// </summary> 811 /// <remarks> 812 /// This method is thread-safe against manipulations of the event queue 813 /// </remarks> 814 public override void Step() { 217 815 Event evt; 218 lock ( locker) {816 lock (_locker) { 219 817 var next = ScheduleQ.Dequeue(); 220 818 Now = next.PrimaryPriority; … … 224 822 } 225 823 226 public virtual double PeekD() { 227 lock (locker) { 824 /// <summary> 825 /// Peeks at the time of the next event in terms of the defined step 826 /// </summary> 827 /// <remarks> 828 /// This method is thread-safe against manipulations of the event queue 829 /// </remarks> 830 public override double PeekD() { 831 lock (_locker) { 228 832 if (ScheduleQ.Count == 0) return double.MaxValue; 229 833 return (Peek() - StartDate).TotalSeconds / DefaultTimeStepSeconds; … … 231 835 } 232 836 233 public virtual DateTime Peek() { 234 lock (locker) { 837 /// <summary> 838 /// Peeks at the time of the next event 839 /// </summary> 840 /// <remarks> 841 /// This method is thread-safe against manipulations of the event queue 842 /// </remarks> 843 public override DateTime Peek() { 844 lock (_locker) { 235 845 return ScheduleQ.Count > 0 ? ScheduleQ.First.PrimaryPriority : DateTime.MaxValue; 236 846 } 237 847 } 238 239 protected virtual void StopSimulation(Event @event) { 240 throw new StopSimulationException(@event.Value); 241 } 242 243 public virtual void Log(string message, params object[] args) { 244 if (Logger != null) 245 Logger.WriteLine(message, args); 246 } 247 248 #region Random number distributions 848 } 849 850 /// <summary> 851 /// Environments hold the event queues, schedule and process events. 852 /// </summary> 853 [Obsolete("Use class Simulation or ThreadSafeSimulation instead. Due to name clashes with System.Environment the class SimSharp.Environment is being outphased.")] 854 public class Environment : ThreadSafeSimulation { 855 public Environment() 856 : base() { 857 Random = new SystemRandom(); 858 } 859 public Environment(TimeSpan? defaultStep) 860 : base(defaultStep) { 861 Random = new SystemRandom(); 862 } 863 public Environment(int randomSeed, TimeSpan? defaultStep = null) 864 : base(randomSeed, defaultStep) { 865 Random = new SystemRandom(randomSeed); 866 } 867 public Environment(DateTime initialDateTime, TimeSpan? defaultStep = null) 868 : base(initialDateTime, defaultStep) { 869 Random = new SystemRandom(); 870 } 871 public Environment(DateTime initialDateTime, int randomSeed, TimeSpan? defaultStep = null) 872 : base(initialDateTime, randomSeed, defaultStep) { 873 Random = new SystemRandom(randomSeed); 874 } 875 249 876 protected static readonly double NormalMagicConst = 4 * Math.Exp(-0.5) / Math.Sqrt(2.0); 250 251 public double RandUniform(double a, double b) { 252 return a + (b - a) * Random.NextDouble(); 253 } 254 255 public TimeSpan RandUniform(TimeSpan a, TimeSpan b) { 256 return TimeSpan.FromSeconds(RandUniform(a.TotalSeconds, b.TotalSeconds)); 257 } 258 259 public double RandTriangular(double low, double high) { 260 var u = Random.NextDouble(); 261 if (u > 0.5) 262 return high + (low - high) * Math.Sqrt(((1.0 - u) / 2)); 263 return low + (high - low) * Math.Sqrt(u / 2); 264 } 265 266 public TimeSpan RandTriangular(TimeSpan low, TimeSpan high) { 267 return TimeSpan.FromSeconds(RandTriangular(low.TotalSeconds, high.TotalSeconds)); 268 } 269 270 public double RandTriangular(double low, double high, double mode) { 271 var u = Random.NextDouble(); 272 var c = (mode - low) / (high - low); 273 if (u > c) 274 return high + (low - high) * Math.Sqrt(((1.0 - u) * (1.0 - c))); 275 return low + (high - low) * Math.Sqrt(u * c); 276 } 277 278 public TimeSpan RandTriangular(TimeSpan low, TimeSpan high, TimeSpan mode) { 279 return TimeSpan.FromSeconds(RandTriangular(low.TotalSeconds, high.TotalSeconds, mode.TotalSeconds)); 280 } 281 282 /// <summary> 283 /// Returns a number that is exponentially distributed given a certain mean. 284 /// </summary> 285 /// <remarks> 286 /// Unlike in other APIs here the mean should be given and not the lambda parameter. 287 /// </remarks> 288 /// <param name="mean">The mean(!) of the distribution is 1 / lambda.</param> 289 /// <returns>A number that is exponentially distributed</returns> 290 public double RandExponential(double mean) { 291 return -Math.Log(1 - Random.NextDouble()) * mean; 292 } 293 294 /// <summary> 295 /// Returns a timespan that is exponentially distributed given a certain mean. 296 /// </summary> 297 /// <remarks> 298 /// Unlike in other APIs here the mean should be given and not the lambda parameter. 299 /// </remarks> 300 /// <param name="mean">The mean(!) of the distribution is 1 / lambda.</param> 301 /// <returns>A number that is exponentially distributed</returns> 302 public TimeSpan RandExponential(TimeSpan mean) { 303 return TimeSpan.FromSeconds(RandExponential(mean.TotalSeconds)); 304 } 305 306 public double RandNormal(double mu, double sigma) { 877 public override double RandNormal(IRandom random, double mu, double sigma) { 307 878 double z, zz, u1, u2; 308 879 do { 309 u1 = Random.NextDouble();310 u2 = 1 - Random.NextDouble();880 u1 = random.NextDouble(); 881 u2 = 1 - random.NextDouble(); 311 882 z = NormalMagicConst * (u1 - 0.5) / u2; 312 883 zz = z * z / 4.0; … … 314 885 return mu + z * sigma; 315 886 } 316 317 public TimeSpan RandNormal(TimeSpan mu, TimeSpan sigma) {318 return TimeSpan.FromSeconds(RandNormal(mu.TotalSeconds, sigma.TotalSeconds));319 }320 321 public double RandNormalPositive(double mu, double sigma) {322 double val;323 do {324 val = RandNormal(mu, sigma);325 } while (val <= 0);326 return val;327 }328 329 public TimeSpan RandNormalPositive(TimeSpan mu, TimeSpan sigma) {330 return TimeSpan.FromSeconds(RandNormalPositive(mu.TotalSeconds, sigma.TotalSeconds));331 }332 333 public double RandNormalNegative(double mu, double sigma) {334 double val;335 do {336 val = RandNormal(mu, sigma);337 } while (val >= 0);338 return val;339 }340 341 public TimeSpan RandNormalNegative(TimeSpan mu, TimeSpan sigma) {342 return TimeSpan.FromSeconds(RandNormalNegative(mu.TotalSeconds, sigma.TotalSeconds));343 }344 345 public double RandLogNormal(double mu, double sigma) {346 return Math.Exp(RandNormal(mu, sigma));347 }348 349 public TimeSpan RandLogNormal(TimeSpan mu, TimeSpan sigma) {350 return TimeSpan.FromSeconds(RandLogNormal(mu.TotalSeconds, sigma.TotalSeconds));351 }352 353 public double RandCauchy(double x0, double gamma) {354 return x0 + gamma * Math.Tan(Math.PI * (Random.NextDouble() - 0.5));355 }356 357 public TimeSpan RandCauchy(TimeSpan x0, TimeSpan gamma) {358 return TimeSpan.FromSeconds(RandCauchy(x0.TotalSeconds, gamma.TotalSeconds));359 }360 361 public double RandWeibull(double alpha, double beta) {362 return alpha * Math.Pow(-Math.Log(1 - Random.NextDouble()), 1 / beta);363 }364 365 public TimeSpan RandWeibull(TimeSpan mu, TimeSpan sigma) {366 return TimeSpan.FromSeconds(RandWeibull(mu.TotalSeconds, sigma.TotalSeconds));367 }368 #endregion369 370 #region Random timeouts371 public Timeout TimeoutUniformD(double a, double b) {372 return new Timeout(this, ToTimeSpan(RandUniform(a, b)));373 }374 375 public Timeout TimeoutUniform(TimeSpan a, TimeSpan b) {376 return new Timeout(this, RandUniform(a, b));377 }378 379 public Timeout TimeoutTriangularD(double low, double high) {380 return new Timeout(this, ToTimeSpan(RandTriangular(low, high)));381 }382 383 public Timeout TimeoutTriangular(TimeSpan low, TimeSpan high) {384 return new Timeout(this, RandTriangular(low, high));385 }386 387 public Timeout TimeoutTriangularD(double low, double high, double mode) {388 return new Timeout(this, ToTimeSpan(RandTriangular(low, high, mode)));389 }390 391 public Timeout TimeoutTriangular(TimeSpan low, TimeSpan high, TimeSpan mode) {392 return new Timeout(this, RandTriangular(low, high, mode));393 }394 395 public Timeout TimeoutExponentialD(double mean) {396 return new Timeout(this, ToTimeSpan(RandExponential(mean)));397 }398 399 public Timeout TimeoutExponential(TimeSpan mean) {400 return new Timeout(this, RandExponential(mean));401 }402 403 public Timeout TimeoutNormalPositiveD(double mu, double sigma) {404 return new Timeout(this, ToTimeSpan(RandNormalPositive(mu, sigma)));405 }406 407 public Timeout TimeoutNormalPositive(TimeSpan mu, TimeSpan sigma) {408 return new Timeout(this, RandNormalPositive(mu, sigma));409 }410 411 public Timeout TimeoutLogNormalD(double mu, double sigma) {412 return new Timeout(this, ToTimeSpan(RandLogNormal(mu, sigma)));413 }414 415 public Timeout TimeoutLogNormal(TimeSpan mu, TimeSpan sigma) {416 return new Timeout(this, RandLogNormal(mu, sigma));417 }418 #endregion419 887 } 420 888 } -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Events/AllOf.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 21 21 namespace SimSharp { 22 22 public class AllOf : Condition { 23 public AllOf( Environmentenvironment, params Event[] events) : base(environment, events) { }24 public AllOf( Environmentenvironment, IEnumerable<Event> events) : base(environment, events) { }23 public AllOf(Simulation environment, params Event[] events) : base(environment, events) { } 24 public AllOf(Simulation environment, IEnumerable<Event> events) : base(environment, events) { } 25 25 26 26 protected override bool Evaluate() { -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Events/AnyOf.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 21 21 namespace SimSharp { 22 22 public class AnyOf : Condition { 23 public AnyOf( Environmentenvironment, params Event[] events) : base(environment, events) { }24 public AnyOf( Environmentenvironment, IEnumerable<Event> events) : base(environment, events) { }23 public AnyOf(Simulation environment, params Event[] events) : base(environment, events) { } 24 public AnyOf(Simulation environment, IEnumerable<Event> events) : base(environment, events) { } 25 25 26 26 protected override bool Evaluate() { -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Events/Condition.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 36 36 protected List<Event> FiredEvents { get; private set; } 37 37 38 protected Condition( Environmentenvironment, params Event[] events)38 protected Condition(Simulation environment, params Event[] events) 39 39 : this(environment, (IEnumerable<Event>)events) { } 40 protected Condition( Environmentenvironment, IEnumerable<Event> events)40 protected Condition(Simulation environment, IEnumerable<Event> events) 41 41 : base(environment) { 42 42 CallbackList.Add(CollectValues); -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Events/Event.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 36 36 /// </summary> 37 37 public class Event { 38 protected internal EnvironmentEnvironment { get; private set; }38 protected internal Simulation Environment { get; private set; } 39 39 protected List<Action<Event>> CallbackList { get; set; } 40 40 … … 73 73 public bool IsTriggered { get; protected set; } 74 74 75 public Event( Environmentenvironment) {75 public Event(Simulation environment) { 76 76 Environment = environment; 77 77 CallbackList = new List<Action<Event>>(); … … 186 186 if (IsProcessed) throw new InvalidOperationException("Event has already been processed."); 187 187 IsProcessed = true; 188 for each (var callback in CallbackList)189 callback(this);188 for (var i = 0; i < CallbackList.Count; i++) 189 CallbackList[i](this); 190 190 CallbackList = null; 191 191 } -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Events/Process.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 50 50 /// <param name="generator">The generator function of the process.</param> 51 51 /// <param name="priority">The priority if multiple processes are started at the same time.</param> 52 public Process( Environmentenvironment, IEnumerable<Event> generator, int priority = 0)52 public Process(Simulation environment, IEnumerable<Event> generator, int priority = 0) 53 53 : base(environment) { 54 54 this.generator = generator.GetEnumerator(); … … 128 128 Environment.ActiveProcess = null; 129 129 } 130 130 131 131 protected virtual bool ProceedToEvent() { 132 132 target = generator.Current; … … 156 156 157 157 private class Initialize : Event { 158 public Initialize( Environmentenvironment, Process process, int priority)158 public Initialize(Simulation environment, Process process, int priority) 159 159 : base(environment) { 160 160 CallbackList.Add(process.Resume); -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Events/Timeout.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 36 36 /// <param name="isOk">Whether the timeout should succeed or fail.</param> 37 37 /// <param name="priority">The priority to rank events at the same time (smaller value = higher priority).</param> 38 public Timeout( Environmentenvironment, TimeSpan delay, object value = null, bool isOk = true, int priority = 0)38 public Timeout(Simulation environment, TimeSpan delay, object value = null, bool isOk = true, int priority = 0) 39 39 : base(environment) { 40 40 IsOk = isOk; -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Exceptions/EmptyScheduleException.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Preempted.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Resources/Container.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 19 19 using System; 20 20 using System.Collections.Generic; 21 using System.Linq;22 21 23 22 namespace SimSharp { 23 /// <summary> 24 /// A container holds a variable amount of a single continuous entity, e.g. water, coal, grain, etc. 25 /// 26 /// Put and Get are in FIFO order only when they can be satisfied. 27 /// Any put or get that can be satisfied takes precedence. 28 /// Put events that attempt to add more to the Container than there is capacity for and 29 /// Get events that remove more than there is are backlogged. 30 /// </summary> 24 31 public class Container { 32 33 public double Capacity { get; protected set; } 34 25 35 public double Level { get; protected set; } 26 public double Capacity { get; protected set; } 27 protected EnvironmentEnvironment { get; private set; }36 37 protected Simulation Environment { get; private set; } 28 38 29 39 protected Queue<ContainerPut> PutQueue { get; private set; } 30 40 protected Queue<ContainerGet> GetQueue { get; private set; } 41 protected SimplePriorityQueue<Event, double> WhenAtLeastQueue { get; private set; } 42 protected SimplePriorityQueue<Event, double> WhenAtMostQueue { get; private set; } 43 protected List<Event> WhenChangeQueue { get; private set; } 31 44 32 public Container( Environmentenvironment, double capacity = double.MaxValue, double initial = 0) {45 public Container(Simulation environment, double capacity = double.MaxValue, double initial = 0) { 33 46 if (capacity <= 0) throw new ArgumentException("Capacity must be > 0", "capacity"); 34 47 if (initial < 0) throw new ArgumentException("Initial must be >= 0", "initial"); … … 39 52 PutQueue = new Queue<ContainerPut>(); 40 53 GetQueue = new Queue<ContainerGet>(); 54 WhenAtLeastQueue = new SimplePriorityQueue<Event, double>(); 55 WhenAtMostQueue = new SimplePriorityQueue<Event, double>(new ReverseComparer<double>()); 56 WhenChangeQueue = new List<Event>(); 41 57 } 42 58 … … 55 71 TriggerGet(); 56 72 return get; 73 } 74 75 public virtual Event WhenAtLeast(double level) { 76 var whenAtLeast = new Event(Environment); 77 WhenAtLeastQueue.Enqueue(whenAtLeast, level); 78 TriggerWhenAtLeast(); 79 return whenAtLeast; 80 } 81 82 public virtual Event WhenFull() { 83 return WhenAtLeast(Capacity); 84 } 85 86 public virtual Event WhenAtMost(double level) { 87 var whenAtMost = new Event(Environment); 88 WhenAtMostQueue.Enqueue(whenAtMost, level); 89 TriggerWhenAtMost(); 90 return whenAtMost; 91 } 92 93 public virtual Event WhenEmpty() { 94 return WhenAtMost(0); 95 } 96 97 public virtual Event WhenChange() { 98 var whenChange = new Event(Environment); 99 WhenChangeQueue.Add(whenChange); 100 return whenChange; 57 101 } 58 102 … … 77 121 if (put.IsTriggered) { 78 122 PutQueue.Dequeue(); 123 TriggerWhenAtLeast(); 124 TriggerWhenChange(); 79 125 } else break; 80 126 } … … 87 133 if (get.IsTriggered) { 88 134 GetQueue.Dequeue(); 135 TriggerWhenAtMost(); 136 TriggerWhenChange(); 89 137 } else break; 90 138 } 91 139 } 140 141 protected virtual void TriggerWhenAtLeast() { 142 while (WhenAtLeastQueue.Count > 0 && Level >= WhenAtLeastQueue.Peek) { 143 var whenAtLeast = WhenAtLeastQueue.Dequeue(); 144 whenAtLeast.Succeed(); 145 } 146 } 147 148 protected virtual void TriggerWhenAtMost() { 149 while (WhenAtMostQueue.Count > 0 && Level <= WhenAtMostQueue.Peek) { 150 var whenAtMost = WhenAtMostQueue.Dequeue(); 151 whenAtMost.Succeed(); 152 } 153 } 154 155 protected virtual void TriggerWhenChange() { 156 if (WhenChangeQueue.Count == 0) return; 157 foreach (var evt in WhenChangeQueue) 158 evt.Succeed(); 159 WhenChangeQueue.Clear(); 160 } 92 161 } 93 162 } -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Resources/Events/ContainerGet.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 23 23 public double Amount { get; protected set; } 24 24 public DateTime Time { get; private set; } 25 public Process Process { get; privateset; }25 public Process Owner { get; set; } 26 26 27 public ContainerGet( Environmentenvironment, Action<Event> callback, double amount)27 public ContainerGet(Simulation environment, Action<Event> callback, double amount) 28 28 : base(environment) { 29 29 if (amount <= 0) throw new ArgumentException("Amount must be > 0.", "amount"); … … 31 31 CallbackList.Add(callback); 32 32 Time = environment.Now; 33 Process= environment.ActiveProcess;33 Owner = environment.ActiveProcess; 34 34 } 35 35 } -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Resources/Events/ContainerPut.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 23 23 public double Amount { get; protected set; } 24 24 public DateTime Time { get; private set; } 25 public Process Process { get; privateset; }25 public Process Owner { get; set; } 26 26 27 public ContainerPut( Environmentenvironment, Action<Event> callback, double amount)27 public ContainerPut(Simulation environment, Action<Event> callback, double amount) 28 28 : base(environment) { 29 29 if (amount <= 0) throw new ArgumentException("Amount must be > 0.", "amount"); … … 31 31 CallbackList.Add(callback); 32 32 Time = environment.Now; 33 Process= environment.ActiveProcess;33 Owner = environment.ActiveProcess; 34 34 } 35 35 } -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Resources/Events/FilterStoreGet.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 23 23 public Func<object, bool> Filter { get; private set; } 24 24 25 public FilterStoreGet( Environmentenvironment, Action<Event> callback, Func<object, bool> filter)25 public FilterStoreGet(Simulation environment, Action<Event> callback, Func<object, bool> filter) 26 26 : base(environment, callback) { 27 27 Filter = filter; -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Resources/Events/PreemptiveRequest.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 20 20 21 21 namespace SimSharp { 22 public sealed class PreemptiveRequest : PriorityRequest { 22 public sealed class PreemptiveRequest : Request, IComparable<PreemptiveRequest>, IComparable { 23 public double Priority { get; private set; } 23 24 public bool Preempt { get; private set; } 25 public bool IsPreempted { get; internal set; } 24 26 25 public PreemptiveRequest(Environment environment, Action<Event> callback, Action<Event> disposeCallback, int priority = 1, bool preempt = false) 26 : base(environment, callback, disposeCallback, priority) { 27 public PreemptiveRequest(Simulation environment, Action<Event> callback, Action<Event> disposeCallback, double priority = 1, bool preempt = false) 28 : base(environment, callback, disposeCallback) { 29 Priority = priority; 27 30 Preempt = preempt; 31 } 32 33 public int CompareTo(PreemptiveRequest other) { 34 if (Priority > other.Priority) return 1; 35 else if (Priority < other.Priority) return -1; 36 if (Time > other.Time) return 1; 37 else if (Time < other.Time) return -1; 38 if (!Preempt && other.Preempt) return 1; 39 else if (Preempt && !other.Preempt) return -1; 40 return 0; 41 } 42 43 public int CompareTo(object obj) { 44 if (obj is PreemptiveRequest other) return CompareTo(other); 45 if (obj == null) return 1; 46 throw new ArgumentException("Can only compare to other objects of type PreemptiveRequest"); 28 47 } 29 48 } -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Resources/Events/Release.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 23 23 public Request Request { get; private set; } 24 24 25 public Release( Environmentenvironment, Request request, Action<Event> callback)25 public Release(Simulation environment, Request request, Action<Event> callback) 26 26 : base(environment) { 27 27 Request = request; -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Resources/Events/Request.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 23 23 private readonly Action<Event> disposeCallback; 24 24 public DateTime Time { get; private set; } 25 public Process Process { get; privateset; }25 public Process Owner { get; set; } 26 26 27 public Request( Environmentenvironment, Action<Event> callback, Action<Event> disposeCallback)27 public Request(Simulation environment, Action<Event> callback, Action<Event> disposeCallback) 28 28 : base(environment) { 29 29 CallbackList.Add(callback); 30 30 this.disposeCallback = disposeCallback; 31 31 Time = environment.Now; 32 Process= environment.ActiveProcess;32 Owner = environment.ActiveProcess; 33 33 } 34 34 -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Resources/Events/ResourcePoolRequest.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 23 23 public Func<object, bool> Filter { get; private set; } 24 24 25 public ResourcePoolRequest( Environmentenvironment, Action<Event> callback, Action<Event> disposeCallback, Func<object, bool> filter)25 public ResourcePoolRequest(Simulation environment, Action<Event> callback, Action<Event> disposeCallback, Func<object, bool> filter) 26 26 : base(environment, callback, disposeCallback) { 27 27 Filter = filter; -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Resources/Events/StoreGet.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 22 22 public class StoreGet : Event { 23 23 public DateTime Time { get; private set; } 24 public Process Process { get; privateset; }24 public Process Owner { get; set; } 25 25 26 public StoreGet( Environmentenvironment, Action<Event> callback)26 public StoreGet(Simulation environment, Action<Event> callback) 27 27 : base(environment) { 28 28 CallbackList.Add(callback); 29 29 Time = environment.Now; 30 Process= environment.ActiveProcess;30 Owner = environment.ActiveProcess; 31 31 } 32 32 } -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Resources/Events/StorePut.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 22 22 public class StorePut : Event { 23 23 public DateTime Time { get; private set; } 24 public Process Process { get; privateset; }24 public Process Owner { get; set; } 25 25 26 public StorePut( Environmentenvironment, Action<Event> callback, object value)26 public StorePut(Simulation environment, Action<Event> callback, object value) 27 27 : base(environment) { 28 28 if (value == null) throw new ArgumentNullException("value", "Value to put in a Store cannot be null."); … … 30 30 Value = value; 31 31 Time = environment.Now; 32 Process= environment.ActiveProcess;32 Owner = environment.ActiveProcess; 33 33 } 34 34 } -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Resources/FilterStore.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 22 22 23 23 namespace SimSharp { 24 /// <summary> 25 /// A filter store is similar to a <see cref="Store"/>. 26 /// However, in Get it is possible to specify the property of the item wished to retrieve. 27 /// 28 /// FilterStore holds a variable number of individual items. 29 /// Put are always performed in FIFO order. 30 /// Get are performed in FIFO order only when they match at least one item in the store. 31 /// </summary> 24 32 public class FilterStore { 33 protected static readonly Func<object, bool> TrueFunc = _ => true; 34 35 public int Capacity { get; protected set; } 36 25 37 public int Count { get { return Items.Count; } } 26 public int Capacity { get; protected set; } 27 protected EnvironmentEnvironment { get; private set; }38 39 protected Simulation Environment { get; private set; } 28 40 29 41 protected Queue<StorePut> PutQueue { get; private set; } 30 42 protected LinkedList<FilterStoreGet> GetQueue { get; private set; } 31 43 protected List<object> Items { get; private set; } 32 33 public FilterStore(Environment environment, int capacity = int.MaxValue) { 44 protected List<Event> WhenNewQueue { get; private set; } 45 protected List<Event> WhenAnyQueue { get; private set; } 46 protected List<Event> WhenFullQueue { get; private set; } 47 protected List<Event> WhenEmptyQueue { get; private set; } 48 protected List<Event> WhenChangeQueue { get; private set; } 49 50 public FilterStore(Simulation environment, int capacity = int.MaxValue) { 34 51 if (capacity <= 0) throw new ArgumentException("Capacity must be > 0", "capacity"); 35 52 Environment = environment; … … 38 55 GetQueue = new LinkedList<FilterStoreGet>(); 39 56 Items = new List<object>(); 40 } 41 public FilterStore(Environment environment, IEnumerable<object> items, int capacity = int.MaxValue) { 57 WhenNewQueue = new List<Event>(); 58 WhenAnyQueue = new List<Event>(); 59 WhenFullQueue = new List<Event>(); 60 WhenEmptyQueue = new List<Event>(); 61 WhenChangeQueue = new List<Event>(); 62 } 63 public FilterStore(Simulation environment, IEnumerable<object> items, int capacity = int.MaxValue) { 42 64 if (capacity <= 0) throw new ArgumentException("Capacity must be > 0", "capacity"); 43 65 Environment = environment; … … 46 68 GetQueue = new LinkedList<FilterStoreGet>(); 47 69 Items = new List<object>(items); 70 WhenNewQueue = new List<Event>(); 71 WhenAnyQueue = new List<Event>(); 72 WhenFullQueue = new List<Event>(); 73 WhenEmptyQueue = new List<Event>(); 74 WhenChangeQueue = new List<Event>(); 48 75 if (capacity < Items.Count) throw new ArgumentException("There are more initial items than there is capacity.", "items"); 49 76 } … … 61 88 62 89 public virtual FilterStoreGet Get(Func<object, bool> filter = null) { 63 if (filter == null) filter = _ => true; 64 var get = new FilterStoreGet(Environment, TriggerPut, filter); 90 var get = new FilterStoreGet(Environment, TriggerPut, filter ?? TrueFunc); 65 91 GetQueue.AddLast(get); 66 92 TriggerGet(); 67 93 return get; 94 } 95 96 public virtual Event WhenNew() { 97 var whenNew = new Event(Environment); 98 WhenNewQueue.Add(whenNew); 99 return whenNew; 100 } 101 102 public virtual Event WhenAny() { 103 var whenAny = new Event(Environment); 104 WhenAnyQueue.Add(whenAny); 105 TriggerWhenAny(); 106 return whenAny; 107 } 108 109 public virtual Event WhenFull() { 110 var whenFull = new Event(Environment); 111 WhenFullQueue.Add(whenFull); 112 TriggerWhenFull(); 113 return whenFull; 114 } 115 116 public virtual Event WhenEmpty() { 117 var whenEmpty = new Event(Environment); 118 WhenEmptyQueue.Add(whenEmpty); 119 TriggerWhenEmpty(); 120 return whenEmpty; 121 } 122 123 public virtual Event WhenChange() { 124 var whenChange = new Event(Environment); 125 WhenChangeQueue.Add(whenChange); 126 return whenChange; 68 127 } 69 128 … … 91 150 if (put.IsTriggered) { 92 151 PutQueue.Dequeue(); 152 TriggerWhenNew(); 153 TriggerWhenAny(); 154 TriggerWhenFull(); 155 TriggerWhenChange(); 93 156 } else break; 94 157 } … … 104 167 GetQueue.Remove(current); 105 168 current = next; 169 TriggerWhenEmpty(); 170 TriggerWhenChange(); 106 171 } else current = current.Next; 107 172 if (Items.Count == 0) break; 108 173 } 109 174 } 175 176 protected virtual void TriggerWhenNew() { 177 if (WhenNewQueue.Count == 0) return; 178 foreach (var evt in WhenNewQueue) 179 evt.Succeed(); 180 WhenNewQueue.Clear(); 181 } 182 183 protected virtual void TriggerWhenAny() { 184 if (Items.Count > 0) { 185 if (WhenAnyQueue.Count == 0) return; 186 foreach (var evt in WhenAnyQueue) 187 evt.Succeed(); 188 WhenAnyQueue.Clear(); 189 } 190 } 191 192 protected virtual void TriggerWhenFull() { 193 if (Count == Capacity) { 194 if (WhenFullQueue.Count == 0) return; 195 foreach (var evt in WhenFullQueue) 196 evt.Succeed(); 197 WhenFullQueue.Clear(); 198 } 199 } 200 201 protected virtual void TriggerWhenEmpty() { 202 if (Count == 0) { 203 if (WhenEmptyQueue.Count == 0) return; 204 foreach (var evt in WhenEmptyQueue) 205 evt.Succeed(); 206 WhenEmptyQueue.Clear(); 207 } 208 } 209 210 protected virtual void TriggerWhenChange() { 211 if (WhenChangeQueue.Count == 0) return; 212 foreach (var evt in WhenChangeQueue) 213 evt.Succeed(); 214 WhenChangeQueue.Clear(); 215 } 110 216 } 111 217 } -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Resources/PreemptiveResource.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 22 22 23 23 namespace SimSharp { 24 /// <summary> 25 /// A PreemptiveResource is similar to a <see cref="PriorityResource"/>. However, 26 /// it may be possible to interrupt a lower-priority user and hand over the resource. 27 /// 28 /// PreemptiveResource holds a fixed amount of anonymous entities. 29 /// Requests are processed in this order: priority, time, preemption, and finally FIFO. 30 /// Releases are processed in FIFO order (usually no simulation time passes for a Release). 31 /// </summary> 32 /// <remarks> 33 /// Working with PreemptiveResource, a process holding a request must always call 34 /// <see cref="Process.HandleFault"/> after yielding an event and handle a potential 35 /// interruption. 36 /// </remarks> 24 37 public class PreemptiveResource { 25 38 … … 30 43 public int Remaining { get { return Capacity - InUse; } } 31 44 32 protected EnvironmentEnvironment { get; private set; }33 34 protected S ortedList<int, LinkedList<PreemptiveRequest>> RequestQueue { get; private set; }45 protected Simulation Environment { get; private set; } 46 47 protected SimplePriorityQueue<PreemptiveRequest> RequestQueue { get; private set; } 35 48 protected Queue<Release> ReleaseQueue { get; private set; } 36 protected HashSet<Request> Users { get; private set; } 37 38 public PreemptiveResource(Environment environment, int capacity = 1) { 49 protected HashSet<PreemptiveRequest> Users { get; private set; } 50 protected List<Event> WhenAnyQueue { get; private set; } 51 protected List<Event> WhenFullQueue { get; private set; } 52 protected List<Event> WhenEmptyQueue { get; private set; } 53 protected List<Event> WhenChangeQueue { get; private set; } 54 55 public PreemptiveResource(Simulation environment, int capacity = 1) { 39 56 if (capacity <= 0) throw new ArgumentException("Capacity must be > 0.", "capacity"); 40 57 Environment = environment; 41 58 Capacity = capacity; 42 RequestQueue = new S ortedList<int, LinkedList<PreemptiveRequest>>();59 RequestQueue = new SimplePriorityQueue<PreemptiveRequest>(); 43 60 ReleaseQueue = new Queue<Release>(); 44 Users = new HashSet<Request>(); 45 } 46 47 public virtual PreemptiveRequest Request(int priority = 1, bool preempt = false) { 61 Users = new HashSet<PreemptiveRequest>(); 62 WhenAnyQueue = new List<Event>(); 63 WhenFullQueue = new List<Event>(); 64 WhenEmptyQueue = new List<Event>(); 65 WhenChangeQueue = new List<Event>(); 66 } 67 68 public virtual PreemptiveRequest Request(double priority = 1, bool preempt = false) { 48 69 var request = new PreemptiveRequest(Environment, TriggerRelease, DisposeCallback, priority, preempt); 49 if (!RequestQueue.ContainsKey(request.Priority)) 50 RequestQueue.Add(request.Priority, new LinkedList<PreemptiveRequest>()); 51 RequestQueue[request.Priority].AddLast(request); 70 RequestQueue.Enqueue(request); 52 71 TriggerRequest(); 53 72 return request; … … 61 80 } 62 81 82 public virtual Event WhenAny() { 83 var whenAny = new Event(Environment); 84 WhenAnyQueue.Add(whenAny); 85 TriggerWhenAny(); 86 return whenAny; 87 } 88 89 public virtual Event WhenFull() { 90 var whenFull = new Event(Environment); 91 WhenFullQueue.Add(whenFull); 92 TriggerWhenFull(); 93 return whenFull; 94 } 95 96 public virtual Event WhenEmpty() { 97 var whenEmpty = new Event(Environment); 98 WhenEmptyQueue.Add(whenEmpty); 99 TriggerWhenEmpty(); 100 return whenEmpty; 101 } 102 103 public virtual Event WhenChange() { 104 var whenChange = new Event(Environment); 105 WhenChangeQueue.Add(whenChange); 106 return whenChange; 107 } 108 63 109 protected void DisposeCallback(Event @event) { 64 110 var request = @event as PreemptiveRequest; … … 69 115 if (Users.Count >= Capacity && request.Preempt) { 70 116 // Check if we can preempt another process 71 var oldest = Users.OfType<PreemptiveRequest>().Select((r, i) => new { Request = r, Index = i }) 72 .OrderByDescending(x => x.Request.Priority) 73 .ThenByDescending(x => x.Request.Time) 74 .ThenByDescending(x => x.Request.Preempt) 75 .ThenByDescending(x => x.Index) 76 .First().Request; 77 if (oldest.Priority > request.Priority || (oldest.Priority == request.Priority 78 && (!oldest.Preempt && request.Preempt || (oldest.Preempt == request.Preempt 79 && oldest.Time > request.Time)))) { 80 Users.Remove(oldest); 81 oldest.Process.Interrupt(new Preempted(request.Process, oldest.Time)); 117 // MaxItems are the least important according to priorty, time, and preemption flag 118 var preempt = Users.MaxItems(x => x).Last(); 119 if (preempt.CompareTo(request) > 0) { 120 preempt.IsPreempted = true; 121 Users.Remove(preempt); 122 preempt.Owner?.Interrupt(new Preempted(request.Owner, preempt.Time)); 82 123 } 83 124 } … … 89 130 90 131 protected virtual void DoRelease(Release release) { 91 if (!Users.Remove(release.Request)) { 92 var preemptRequest = release.Request as PreemptiveRequest; 93 if (preemptRequest != null) { 94 var current = RequestQueue[preemptRequest.Priority].First; 95 while (current != null && current.Value != release.Request) 96 current = current.Next; 97 if (current != null) RequestQueue[preemptRequest.Priority].Remove(current); 98 } 99 } 132 var req = (PreemptiveRequest)release.Request; 133 if (!Users.Remove(req) && !req.IsPreempted) 134 throw new InvalidOperationException("Released request does not have a user."); 100 135 release.Succeed(); 101 136 } 102 137 103 138 protected virtual void TriggerRequest(Event @event = null) { 104 foreach (var entry in RequestQueue) { 105 var requests = entry.Value; 106 var current = requests.First; 107 while (current != null) { 108 var request = current.Value; 109 DoRequest(request); 110 if (request.IsTriggered) { 111 var next = current.Next; 112 requests.Remove(current); 113 current = next; 114 } else current = current.Next; 115 } 139 while (RequestQueue.Count > 0) { 140 var request = RequestQueue.First; 141 DoRequest(request); 142 if (request.IsTriggered) { 143 RequestQueue.Dequeue(); 144 TriggerWhenEmpty(); 145 TriggerWhenChange(); 146 } else break; 116 147 } 117 148 } … … 120 151 while (ReleaseQueue.Count > 0) { 121 152 var release = ReleaseQueue.Peek(); 122 DoRelease(release); 123 if (release.IsTriggered) { 153 if (release.Request.IsAlive) { 154 if (!RequestQueue.TryRemove((PreemptiveRequest)release.Request)) 155 throw new InvalidOperationException("Failed to cancel a request."); 156 release.Succeed(); 124 157 ReleaseQueue.Dequeue(); 125 } else break; 126 } 158 } else { 159 DoRelease(release); 160 if (release.IsTriggered) { 161 ReleaseQueue.Dequeue(); 162 TriggerWhenAny(); 163 TriggerWhenFull(); 164 TriggerWhenChange(); 165 } else break; 166 } 167 } 168 } 169 170 protected virtual void TriggerWhenAny() { 171 if (Remaining > 0) { 172 if (WhenAnyQueue.Count == 0) return; 173 foreach (var evt in WhenAnyQueue) 174 evt.Succeed(); 175 WhenAnyQueue.Clear(); 176 } 177 } 178 179 protected virtual void TriggerWhenFull() { 180 if (InUse == 0) { 181 if (WhenFullQueue.Count == 0) return; 182 foreach (var evt in WhenFullQueue) 183 evt.Succeed(); 184 WhenFullQueue.Clear(); 185 } 186 } 187 188 protected virtual void TriggerWhenEmpty() { 189 if (Remaining == 0) { 190 if (WhenEmptyQueue.Count == 0) return; 191 foreach (var evt in WhenEmptyQueue) 192 evt.Succeed(); 193 WhenEmptyQueue.Clear(); 194 } 195 } 196 197 protected virtual void TriggerWhenChange() { 198 if (WhenChangeQueue.Count == 0) return; 199 foreach (var evt in WhenChangeQueue) 200 evt.Succeed(); 201 WhenChangeQueue.Clear(); 127 202 } 128 203 } -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Resources/PriorityResource.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 21 21 22 22 namespace SimSharp { 23 /// <summary> 24 /// A PriorityResource is similar to a <see cref="Resource"/>. 25 /// However, it enables prioritizing requests. 26 /// 27 /// PriorityResource holds a fixed number of anonymous entities. 28 /// Requests are processed in order priority first, FIFO second. 29 /// Releases are processed in FIFO order (usually no simulation time passes for a Release). 30 /// </summary> 23 31 public class PriorityResource { 24 32 … … 29 37 public int Remaining { get { return Capacity - InUse; } } 30 38 31 protected EnvironmentEnvironment { get; private set; }39 protected Simulation Environment { get; private set; } 32 40 33 protected S ortedList<int, LinkedList<PriorityRequest>> RequestQueue { get; private set; }41 protected SimplePriorityQueue<Request, double> RequestQueue { get; private set; } 34 42 protected Queue<Release> ReleaseQueue { get; private set; } 35 43 protected HashSet<Request> Users { get; private set; } 44 protected List<Event> WhenAnyQueue { get; private set; } 45 protected List<Event> WhenFullQueue { get; private set; } 46 protected List<Event> WhenEmptyQueue { get; private set; } 47 protected List<Event> WhenChangeQueue { get; private set; } 36 48 37 public PriorityResource( Environmentenvironment, int capacity = 1) {49 public PriorityResource(Simulation environment, int capacity = 1) { 38 50 if (capacity <= 0) throw new ArgumentException("Capacity must be > 0.", "capacity"); 39 51 Environment = environment; 40 52 Capacity = capacity; 41 RequestQueue = new S ortedList<int, LinkedList<PriorityRequest>>();53 RequestQueue = new SimplePriorityQueue<Request, double>(); 42 54 ReleaseQueue = new Queue<Release>(); 43 55 Users = new HashSet<Request>(); 56 WhenAnyQueue = new List<Event>(); 57 WhenFullQueue = new List<Event>(); 58 WhenEmptyQueue = new List<Event>(); 59 WhenChangeQueue = new List<Event>(); 44 60 } 45 61 46 public virtual PriorityRequest Request(int priority = 1) { 47 var request = new PriorityRequest(Environment, TriggerRelease, DisposeCallback, priority); 48 if (!RequestQueue.ContainsKey(priority)) 49 RequestQueue.Add(priority, new LinkedList<PriorityRequest>()); 50 RequestQueue[priority].AddLast(request); 62 public virtual Request Request(double priority = 1) { 63 var request = new Request(Environment, TriggerRelease, DisposeCallback); 64 RequestQueue.Enqueue(request, priority); 51 65 TriggerRequest(); 52 66 return request; 53 67 } 54 68 55 public virtual Release Release( PriorityRequest request) {69 public virtual Release Release(Request request) { 56 70 var release = new Release(Environment, request, TriggerRequest); 57 71 ReleaseQueue.Enqueue(release); … … 60 74 } 61 75 76 public virtual Event WhenAny() { 77 var whenAny = new Event(Environment); 78 WhenAnyQueue.Add(whenAny); 79 TriggerWhenAny(); 80 return whenAny; 81 } 82 83 public virtual Event WhenFull() { 84 var whenFull = new Event(Environment); 85 WhenFullQueue.Add(whenFull); 86 TriggerWhenFull(); 87 return whenFull; 88 } 89 90 public virtual Event WhenEmpty() { 91 var whenEmpty = new Event(Environment); 92 WhenEmptyQueue.Add(whenEmpty); 93 TriggerWhenEmpty(); 94 return whenEmpty; 95 } 96 97 public virtual Event WhenChange() { 98 var whenChange = new Event(Environment); 99 WhenChangeQueue.Add(whenChange); 100 return whenChange; 101 } 102 62 103 protected void DisposeCallback(Event @event) { 63 var request = @event as PriorityRequest;104 var request = @event as Request; 64 105 if (request != null) Release(request); 65 106 } … … 73 114 74 115 protected virtual void DoRelease(Release release) { 75 if (!Users.Remove(release.Request)) { 76 var prioRequest = release.Request as PriorityRequest; 77 if (prioRequest != null) { 78 var current = RequestQueue[prioRequest.Priority].First; 79 while (current != null && current.Value != release.Request) 80 current = current.Next; 81 if (current != null) RequestQueue[prioRequest.Priority].Remove(current); 82 } 83 } 116 if (!Users.Remove(release.Request)) 117 throw new InvalidOperationException("Released request does not have a user."); 84 118 release.Succeed(); 85 119 } 86 120 87 121 protected virtual void TriggerRequest(Event @event = null) { 88 foreach (var entry in RequestQueue) { 89 var cascade = false; 90 var requests = entry.Value; 91 while (requests.Count > 0) { 92 var req = requests.First.Value; 93 DoRequest(req); 94 if (req.IsTriggered) { 95 requests.RemoveFirst(); 96 } else { 97 cascade = true; 98 break; 99 } 100 } 101 if (cascade) break; 122 while (RequestQueue.Count > 0) { 123 var request = RequestQueue.First; 124 DoRequest(request); 125 if (request.IsTriggered) { 126 RequestQueue.Dequeue(); 127 TriggerWhenEmpty(); 128 TriggerWhenChange(); 129 } else break; 102 130 } 103 131 } … … 106 134 while (ReleaseQueue.Count > 0) { 107 135 var release = ReleaseQueue.Peek(); 136 if (release.Request.IsAlive) { 137 if (!RequestQueue.TryRemove(release.Request)) 138 throw new InvalidOperationException("Failed to cancel a request."); 139 release.Succeed(); 140 ReleaseQueue.Dequeue(); 141 } 108 142 DoRelease(release); 109 143 if (release.IsTriggered) { 110 144 ReleaseQueue.Dequeue(); 145 TriggerWhenAny(); 146 TriggerWhenFull(); 147 TriggerWhenChange(); 111 148 } else break; 112 149 } 113 150 } 151 152 protected virtual void TriggerWhenAny() { 153 if (Remaining > 0) { 154 if (WhenAnyQueue.Count == 0) return; 155 foreach (var evt in WhenAnyQueue) 156 evt.Succeed(); 157 WhenAnyQueue.Clear(); 158 } 159 } 160 161 protected virtual void TriggerWhenFull() { 162 if (InUse == 0) { 163 if (WhenFullQueue.Count == 0) return; 164 foreach (var evt in WhenFullQueue) 165 evt.Succeed(); 166 WhenFullQueue.Clear(); 167 } 168 } 169 170 protected virtual void TriggerWhenEmpty() { 171 if (Remaining == 0) { 172 if (WhenEmptyQueue.Count == 0) return; 173 foreach (var evt in WhenEmptyQueue) 174 evt.Succeed(); 175 WhenEmptyQueue.Clear(); 176 } 177 } 178 179 protected virtual void TriggerWhenChange() { 180 if (WhenChangeQueue.Count == 0) return; 181 foreach (var evt in WhenChangeQueue) 182 evt.Succeed(); 183 WhenChangeQueue.Clear(); 184 } 114 185 } 115 186 } -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Resources/Resource.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 21 21 22 22 namespace SimSharp { 23 /// <summary> 24 /// A resource holds a fixed number of anonymous entities. 25 /// 26 /// Requests are processed in FIFO order. 27 /// Releases are processed in FIFO order (usually no simulation time passes for a Release). 28 /// </summary> 23 29 public class Resource { 24 30 … … 29 35 public int Remaining { get { return Capacity - InUse; } } 30 36 31 protected EnvironmentEnvironment { get; private set; }37 protected Simulation Environment { get; private set; } 32 38 33 39 protected LinkedList<Request> RequestQueue { get; private set; } 34 40 protected Queue<Release> ReleaseQueue { get; private set; } 35 41 protected HashSet<Request> Users { get; private set; } 42 protected List<Event> WhenAnyQueue { get; private set; } 43 protected List<Event> WhenFullQueue { get; private set; } 44 protected List<Event> WhenEmptyQueue { get; private set; } 45 protected List<Event> WhenChangeQueue { get; private set; } 36 46 37 public Resource( Environmentenvironment, int capacity = 1) {47 public Resource(Simulation environment, int capacity = 1) { 38 48 if (capacity <= 0) throw new ArgumentException("Capacity must > 0.", "capacity"); 39 49 Environment = environment; … … 42 52 ReleaseQueue = new Queue<Release>(); 43 53 Users = new HashSet<Request>(); 54 WhenAnyQueue = new List<Event>(); 55 WhenFullQueue = new List<Event>(); 56 WhenEmptyQueue = new List<Event>(); 57 WhenChangeQueue = new List<Event>(); 44 58 } 45 59 … … 56 70 TriggerRelease(); 57 71 return release; 72 } 73 74 public virtual Event WhenAny() { 75 var whenAny = new Event(Environment); 76 WhenAnyQueue.Add(whenAny); 77 TriggerWhenAny(); 78 return whenAny; 79 } 80 81 public virtual Event WhenFull() { 82 var whenFull = new Event(Environment); 83 WhenFullQueue.Add(whenFull); 84 TriggerWhenFull(); 85 return whenFull; 86 } 87 88 public virtual Event WhenEmpty() { 89 var whenEmpty = new Event(Environment); 90 WhenEmptyQueue.Add(whenEmpty); 91 TriggerWhenEmpty(); 92 return whenEmpty; 93 } 94 95 public virtual Event WhenChange() { 96 var whenChange = new Event(Environment); 97 WhenChangeQueue.Add(whenChange); 98 return whenChange; 58 99 } 59 100 … … 73 114 74 115 protected virtual void DoRelease(Release release) { 75 if (!Users.Remove(release.Request)) { 76 var current = RequestQueue.First; 77 while (current != null && current.Value != release.Request) 78 current = current.Next; 79 if (current != null) RequestQueue.Remove(current); 80 } 116 if (!Users.Remove(release.Request)) 117 throw new InvalidOperationException("Released request does not have a user."); 81 118 release.Succeed(); 82 119 } … … 88 125 if (request.IsTriggered) { 89 126 RequestQueue.RemoveFirst(); 127 TriggerWhenEmpty(); 128 TriggerWhenChange(); 90 129 } else break; 91 130 } … … 95 134 while (ReleaseQueue.Count > 0) { 96 135 var release = ReleaseQueue.Peek(); 97 DoRelease(release); 98 if (release.IsTriggered) { 136 if (release.Request.IsAlive) { 137 if (!RequestQueue.Remove(release.Request)) 138 throw new InvalidOperationException("Failed to cancel a request."); 139 release.Succeed(); 99 140 ReleaseQueue.Dequeue(); 100 } else break; 141 } else { 142 DoRelease(release); 143 if (release.IsTriggered) { 144 ReleaseQueue.Dequeue(); 145 TriggerWhenAny(); 146 TriggerWhenFull(); 147 TriggerWhenChange(); 148 } else break; 149 } 101 150 } 151 } 152 153 protected virtual void TriggerWhenAny() { 154 if (Remaining > 0) { 155 if (WhenAnyQueue.Count == 0) return; 156 foreach (var evt in WhenAnyQueue) 157 evt.Succeed(); 158 WhenAnyQueue.Clear(); 159 } 160 } 161 162 protected virtual void TriggerWhenFull() { 163 if (InUse == 0) { 164 if (WhenFullQueue.Count == 0) return; 165 foreach (var evt in WhenFullQueue) 166 evt.Succeed(); 167 WhenFullQueue.Clear(); 168 } 169 } 170 171 protected virtual void TriggerWhenEmpty() { 172 if (Remaining == 0) { 173 if (WhenEmptyQueue.Count == 0) return; 174 foreach (var evt in WhenEmptyQueue) 175 evt.Succeed(); 176 WhenEmptyQueue.Clear(); 177 } 178 } 179 180 protected virtual void TriggerWhenChange() { 181 if (WhenChangeQueue.Count == 0) return; 182 foreach (var evt in WhenChangeQueue) 183 evt.Succeed(); 184 WhenChangeQueue.Clear(); 102 185 } 103 186 } -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Resources/ResourcePool.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 22 22 23 23 namespace SimSharp { 24 /// <summary> 25 /// A ResourcePool is a crossover between a <see cref="Resource"/> and a <see cref="Store"/>. 26 /// There is a fixed number of non-anonymous resources. 27 /// 28 /// Requests are performed in FIFO order only when they match at least one resource in the pool. 29 /// Releases are processed in FIFO order (usually no simulation time passes for a Release). 30 /// </summary> 24 31 public class ResourcePool { 25 32 protected static readonly Func<object, bool> TrueFunc = _ => true; … … 31 38 public int Remaining { get { return Resources.Count; } } 32 39 33 protected EnvironmentEnvironment { get; private set; }40 protected Simulation Environment { get; private set; } 34 41 35 42 protected LinkedList<ResourcePoolRequest> RequestQueue { get; private set; } 36 43 protected Queue<Release> ReleaseQueue { get; private set; } 37 44 protected List<object> Resources { get; private set; } 45 protected List<Event> WhenAnyQueue { get; private set; } 46 protected List<Event> WhenFullQueue { get; private set; } 47 protected List<Event> WhenEmptyQueue { get; private set; } 48 protected List<Event> WhenChangeQueue { get; private set; } 38 49 39 public ResourcePool( Environmentenvironment, IEnumerable<object> resources) {50 public ResourcePool(Simulation environment, IEnumerable<object> resources) { 40 51 Environment = environment; 41 52 if (resources == null) throw new ArgumentNullException("resources"); … … 45 56 RequestQueue = new LinkedList<ResourcePoolRequest>(); 46 57 ReleaseQueue = new Queue<Release>(); 58 WhenAnyQueue = new List<Event>(); 59 WhenFullQueue = new List<Event>(); 60 WhenEmptyQueue = new List<Event>(); 61 WhenChangeQueue = new List<Event>(); 47 62 } 48 63 … … 63 78 TriggerRelease(); 64 79 return release; 80 } 81 82 public virtual Event WhenAny() { 83 var whenAny = new Event(Environment); 84 WhenAnyQueue.Add(whenAny); 85 TriggerWhenAny(); 86 return whenAny; 87 } 88 89 public virtual Event WhenFull() { 90 var whenFull = new Event(Environment); 91 WhenFullQueue.Add(whenFull); 92 TriggerWhenFull(); 93 return whenFull; 94 } 95 96 public virtual Event WhenEmpty() { 97 var whenEmpty = new Event(Environment); 98 WhenEmptyQueue.Add(whenEmpty); 99 TriggerWhenEmpty(); 100 return whenEmpty; 101 } 102 103 public virtual Event WhenChange() { 104 var whenChange = new Event(Environment); 105 WhenChangeQueue.Add(whenChange); 106 return whenChange; 65 107 } 66 108 … … 93 135 RequestQueue.Remove(current); 94 136 current = next; 137 TriggerWhenEmpty(); 138 TriggerWhenChange(); 95 139 } else current = current.Next; 96 140 if (Resources.Count == 0) break; … … 101 145 while (ReleaseQueue.Count > 0) { 102 146 var release = ReleaseQueue.Peek(); 103 DoRelease(release); 104 if (release.IsTriggered) { 147 if (release.Request.IsAlive) { 148 if (!RequestQueue.Remove((ResourcePoolRequest)release.Request)) 149 throw new InvalidOperationException("Failed to cancel a request."); 150 release.Succeed(); 105 151 ReleaseQueue.Dequeue(); 106 } else break; 152 } else { 153 DoRelease(release); 154 if (release.IsTriggered) { 155 ReleaseQueue.Dequeue(); 156 TriggerWhenAny(); 157 TriggerWhenFull(); 158 TriggerWhenChange(); 159 } else break; 160 } 107 161 } 162 } 163 164 protected virtual void TriggerWhenAny() { 165 if (Remaining > 0) { 166 if (WhenAnyQueue.Count == 0) return; 167 foreach (var evt in WhenAnyQueue) 168 evt.Succeed(); 169 WhenAnyQueue.Clear(); 170 } 171 } 172 173 protected virtual void TriggerWhenFull() { 174 if (InUse == 0) { 175 if (WhenFullQueue.Count == 0) return; 176 foreach (var evt in WhenFullQueue) 177 evt.Succeed(); 178 WhenFullQueue.Clear(); 179 } 180 } 181 182 protected virtual void TriggerWhenEmpty() { 183 if (Remaining == 0) { 184 if (WhenEmptyQueue.Count == 0) return; 185 foreach (var evt in WhenEmptyQueue) 186 evt.Succeed(); 187 WhenEmptyQueue.Clear(); 188 } 189 } 190 191 protected virtual void TriggerWhenChange() { 192 if (WhenChangeQueue.Count == 0) return; 193 foreach (var evt in WhenChangeQueue) 194 evt.Succeed(); 195 WhenChangeQueue.Clear(); 108 196 } 109 197 } -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Core/Resources/Store.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify … … 19 19 using System; 20 20 using System.Collections.Generic; 21 using System.Linq;22 21 23 22 namespace SimSharp { 23 /// <summary> 24 /// The store holds a variable number of individual items. 25 /// The items are removed from the store in FIFO order. 26 /// 27 /// Put are processed in FIFO order. 28 /// Get are processed in FIFO order. 29 /// </summary> 24 30 public class Store { 31 32 public int Capacity { get; protected set; } 33 25 34 public int Count { get { return Items.Count; } } 26 public int Capacity { get; protected set; } 27 protected EnvironmentEnvironment { get; private set; }35 36 protected Simulation Environment { get; private set; } 28 37 29 38 protected Queue<StorePut> PutQueue { get; private set; } 30 39 protected Queue<StoreGet> GetQueue { get; private set; } 31 protected List<object> Items { get; private set; } 32 33 public Store(Environment environment, int capacity = int.MaxValue) { 40 protected Queue<object> Items { get; private set; } 41 protected List<Event> WhenNewQueue { get; private set; } 42 protected List<Event> WhenAnyQueue { get; private set; } 43 protected List<Event> WhenFullQueue { get; private set; } 44 protected List<Event> WhenEmptyQueue { get; private set; } 45 protected List<Event> WhenChangeQueue { get; private set; } 46 47 public Store(Simulation environment, int capacity = int.MaxValue) { 34 48 if (capacity <= 0) throw new ArgumentException("Capacity must be > 0", "capacity"); 35 49 Environment = environment; … … 37 51 PutQueue = new Queue<StorePut>(); 38 52 GetQueue = new Queue<StoreGet>(); 39 Items = new List<object>(); 53 Items = new Queue<object>(); 54 WhenNewQueue = new List<Event>(); 55 WhenAnyQueue = new List<Event>(); 56 WhenFullQueue = new List<Event>(); 57 WhenEmptyQueue = new List<Event>(); 58 WhenChangeQueue = new List<Event>(); 59 } 60 public Store(Simulation environment, IEnumerable<object> items, int capacity = int.MaxValue) { 61 if (capacity <= 0) throw new ArgumentException("Capacity must be > 0", "capacity"); 62 Environment = environment; 63 Capacity = capacity; 64 PutQueue = new Queue<StorePut>(); 65 GetQueue = new Queue<StoreGet>(); 66 Items = new Queue<object>(items); 67 WhenNewQueue = new List<Event>(); 68 WhenAnyQueue = new List<Event>(); 69 WhenFullQueue = new List<Event>(); 70 WhenEmptyQueue = new List<Event>(); 71 WhenChangeQueue = new List<Event>(); 72 if (capacity < Items.Count) throw new ArgumentException("There are more initial items than there is capacity.", "items"); 40 73 } 41 74 … … 54 87 } 55 88 89 public virtual Event WhenNew() { 90 var whenNew = new Event(Environment); 91 WhenNewQueue.Add(whenNew); 92 return whenNew; 93 } 94 95 public virtual Event WhenAny() { 96 var whenAny = new Event(Environment); 97 WhenAnyQueue.Add(whenAny); 98 TriggerWhenAny(); 99 return whenAny; 100 } 101 102 public virtual Event WhenFull() { 103 var whenFull = new Event(Environment); 104 WhenFullQueue.Add(whenFull); 105 TriggerWhenFull(); 106 return whenFull; 107 } 108 109 public virtual Event WhenEmpty() { 110 var whenEmpty = new Event(Environment); 111 WhenEmptyQueue.Add(whenEmpty); 112 TriggerWhenEmpty(); 113 return whenEmpty; 114 } 115 116 public virtual Event WhenChange() { 117 var whenChange = new Event(Environment); 118 WhenChangeQueue.Add(whenChange); 119 return whenChange; 120 } 121 56 122 protected virtual void DoPut(StorePut put) { 57 123 if (Items.Count < Capacity) { 58 Items. Add(put.Value);124 Items.Enqueue(put.Value); 59 125 put.Succeed(); 60 126 } … … 63 129 protected virtual void DoGet(StoreGet get) { 64 130 if (Items.Count > 0) { 65 var item = Items.First(); 66 Items.RemoveAt(0); 131 var item = Items.Dequeue(); 67 132 get.Succeed(item); 68 133 } … … 75 140 if (put.IsTriggered) { 76 141 PutQueue.Dequeue(); 142 TriggerWhenNew(); 143 TriggerWhenAny(); 144 TriggerWhenFull(); 145 TriggerWhenChange(); 77 146 } else break; 78 147 } … … 85 154 if (get.IsTriggered) { 86 155 GetQueue.Dequeue(); 156 TriggerWhenEmpty(); 157 TriggerWhenChange(); 87 158 } else break; 88 159 } 160 } 161 162 protected virtual void TriggerWhenNew() { 163 if (WhenNewQueue.Count == 0) return; 164 foreach (var evt in WhenNewQueue) 165 evt.Succeed(); 166 WhenNewQueue.Clear(); 167 } 168 169 protected virtual void TriggerWhenAny() { 170 if (Count > 0) { 171 if (WhenAnyQueue.Count == 0) return; 172 foreach (var evt in WhenAnyQueue) 173 evt.Succeed(); 174 WhenAnyQueue.Clear(); 175 } 176 } 177 178 protected virtual void TriggerWhenFull() { 179 if (Count == Capacity) { 180 if (WhenFullQueue.Count == 0) return; 181 foreach (var evt in WhenFullQueue) 182 evt.Succeed(); 183 WhenFullQueue.Clear(); 184 } 185 } 186 187 protected virtual void TriggerWhenEmpty() { 188 if (Count == 0) { 189 if (WhenEmptyQueue.Count == 0) return; 190 foreach (var evt in WhenEmptyQueue) 191 evt.Succeed(); 192 WhenEmptyQueue.Clear(); 193 } 194 } 195 196 protected virtual void TriggerWhenChange() { 197 if (WhenChangeQueue.Count == 0) return; 198 foreach (var evt in WhenChangeQueue) 199 evt.Succeed(); 200 WhenChangeQueue.Clear(); 89 201 } 90 202 } -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Properties/AssemblyInfo.cs
r15972 r16779 28 28 [assembly: AssemblyCompany("HEAL")] 29 29 [assembly: AssemblyProduct("SimSharp")] 30 [assembly: AssemblyCopyright("(c) 2002-201 8HEAL")]30 [assembly: AssemblyCopyright("(c) 2002-2019 HEAL")] 31 31 [assembly: AssemblyTrademark("")] 32 32 [assembly: AssemblyCulture("")] … … 50 50 // by using the '*' as shown below: 51 51 // [assembly: AssemblyVersion("1.0.*")] 52 [assembly: AssemblyVersion("3. 0.11.0")]53 [assembly: AssemblyFileVersion("3. 0.11.0")]52 [assembly: AssemblyVersion("3.1.1.0")] 53 [assembly: AssemblyFileVersion("3.1.1.0")] -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Random/IRandom.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify -
trunk/HeuristicLab.ExtLibs/HeuristicLab.SimSharp/3.1.1/SimSharp-3.1.1/Random/SystemRandom.cs
r15972 r16779 1 1 #region License Information 2 2 /* SimSharp - A .NET port of SimPy, discrete event simulation framework 3 Copyright (C) 201 6Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 Copyright (C) 2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 5 5 This program is free software: you can redistribute it and/or modify
Note: See TracChangeset
for help on using the changeset viewer.