├── LICENSE ├── README.md ├── app1 ├── b1.py ├── b10.py ├── b11.py ├── b12.py ├── b2.py ├── b3.py ├── b4.py ├── b5.py ├── b6.py ├── b7.py ├── b8.py ├── b9.py ├── plot_erlang_hist.py ├── plot_erlang_pdf.py └── plot_triangular_pdf.py ├── app2 ├── .idea │ ├── .name │ ├── OOF.iml │ ├── misc.xml │ ├── modules.xml │ ├── vcs.xml │ └── workspace.xml ├── SimpleProtocol.py ├── event.py ├── ex01.py ├── ex02.py ├── ex03.py ├── ex04.py ├── mm1.py ├── scheduler.py ├── simEntity.py ├── state.py └── stateMachine.py ├── ch03 ├── approx_prob_3_head_event.py ├── approx_prob_outcome.py ├── moving_avg_tossing_coin.py └── sim_throw_die.py ├── ch04 ├── hist_expov.py ├── plot_exponential.py ├── plot_normal.py ├── plot_triangular.py ├── plot_uniform.py ├── scipy_stats.py ├── sim_birth_death_process.py ├── sim_poisson_process.py └── two_state_disc_markov.py ├── ch05 ├── __pycache__ │ └── simLib.cpython-35.pyc ├── simLib.py ├── sim_mm1.py ├── sim_mm1_avg_num_pkts.py ├── sim_mm1_indep_replic.py ├── sim_mm1_prob_N.py ├── sim_mm1_resp_time.py └── welch.py ├── ch06 ├── funcs.py └── simple_arq.py ├── ch07 └── prog01.py ├── ch08 ├── __pycache__ │ └── normal.cpython-35.pyc ├── bernoulli.py ├── binomial.py ├── erlang.py ├── erlang_plot_hist.pdf ├── erlang_plot_hist.py ├── erlang_plot_pdf.pdf ├── erlang_plot_pdf.py ├── geometric.py ├── lognormal.py ├── normal.py ├── normal_convolution.py ├── normal_convolution_plot_hist.py ├── plot_lognormal.py ├── poisson.py ├── rej_alg_01.py └── rvg_pmf.py ├── ch09 ├── lag_plot_non_random.py ├── lag_plot_rng.py ├── spectral_test.py └── uniform_stat_test.py ├── ch10 ├── antithetic_01.py ├── antithetic_02.py ├── buffon.py ├── estimate_integral.py ├── estimate_pi.py ├── importance_sampling.py └── reliability.py ├── ch11 ├── compute_ci.py ├── plot_ci.py ├── single_server.py └── trunc_point.py └── ch12 ├── CN ├── stop_wait_arq.py └── switch.py ├── MC_All_Paths ├── all_paths_12_nodes.py ├── all_paths_16_nodes.py ├── all_paths_20_nodes.py ├── all_paths_5_nodes.py ├── all_paths_8_nodes.py └── mc.py └── Reliability ├── prog01.py ├── prog02.py ├── prog03_antithetic.py └── prog0x.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Yahya Osais 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Computer-Simulation-Book 2 | =========================== 3 | 4 | Yahya Osais, “Computer Simulation: A Foundational Approach using Python”, to be published by the CRC press in 2017. 5 | 6 | Python programs accompanying the book. -------------------------------------------------------------------------------- /app1/b1.py: -------------------------------------------------------------------------------- 1 | C:/> python 2 | Python 3.5.9 .... more information will be shown 3 | >>> 1 + 1 4 | 2 5 | >>> -------------------------------------------------------------------------------- /app1/b10.py: -------------------------------------------------------------------------------- 1 | def add(): 2 | print ( 'Add' ) 3 | 4 | def sub(): 5 | print ( 'Sub' ) 6 | 7 | a = [add, sub] 8 | 9 | for i in range(len(a)): 10 | a [i] ( ) # Add two parenthese and include arguments, 11 | # if any -------------------------------------------------------------------------------- /app1/b11.py: -------------------------------------------------------------------------------- 1 | def doIt (func, x, y): 2 | z = func (x, y) 3 | return z 4 | 5 | def add (arg1, arg2): 6 | return arg1 + arg2 7 | 8 | def sub (arg1, arg2): 9 | return arg1 - arg2 10 | 11 | print ('Addition:') 12 | print ( doIt (add, 2, 3) ) # Passing the name of the function 13 | # and its arguments 14 | 15 | print ('Subtraction:') 16 | print ( doIt (sub, 2, 3) ) -------------------------------------------------------------------------------- /app1/b12.py: -------------------------------------------------------------------------------- 1 | def Handle_Event_1(): 2 | print ( 'Event_1' ) 3 | 4 | def Handle_Event_2(): 5 | print ( 'Event_2' ) 6 | 7 | Event_List = [(1.3, Handle_Event_1), (3.3, Handle_Event_2), 8 | (4.5, Handle_Event_1)] 9 | 10 | for ev in Event_List: 11 | (time , event_handler) = ev 12 | event_handler ( ) # Add two parenthese and include 13 | # arguments, if any -------------------------------------------------------------------------------- /app1/b2.py: -------------------------------------------------------------------------------- 1 | C:/> python my_prog.py 2 | Enter the two numbers to add: 1 3 3 | Result = 4 4 | C:/> -------------------------------------------------------------------------------- /app1/b3.py: -------------------------------------------------------------------------------- 1 | from random import choice 2 | min = input('Enter smallest number: ') 3 | max = input('Enter largest number: ') 4 | n = input('How many numbers do you want to generate? ') 5 | numbers = range(min, max + 1) 6 | selection = [] 7 | for i in xrange(n): 8 | r = choice(numbers) 9 | selection.append(r) 10 | numbers.remove(r) 11 | print( 'Your numbers:', selection ) -------------------------------------------------------------------------------- /app1/b4.py: -------------------------------------------------------------------------------- 1 | >>> m = input('Enter the mean service time: ') 2 | Enter the mean service time: 5 # Enter number 5 3 | >>> m 4 | 5 5 | >>> print( 'You entered: ', m ) 6 | You entered: 5 -------------------------------------------------------------------------------- /app1/b5.py: -------------------------------------------------------------------------------- 1 | >>> a = [] # The empty list 2 | >>> a 3 | [] 4 | >>> b = [1, 2.3, 'Arrival', False] # Elements of different types 5 | >>> b[0] # Accessing the fist element in 6 | 1 # the list 7 | >>> b[2] # Accessing the third element 8 | 'Arrival' 9 | >>> b[0:2] # Extract a part of the list 10 | [1, 2.3] # Two is the size of the new list 11 | >>> c = [0] * 6 # Creating and initializing 12 | >>> c # a list of size 6 13 | [0, 0, 0, 0, 0, 0] 14 | >>> len(c) # Returns the size of a list 15 | 6 16 | >>> 'Arrival' in b # Check if an element is in the list 17 | True 18 | >>> d = b + b # Combining two lists into one list 19 | >>> d 20 | [1, 2.3, 'Arrival', False, 1, 2.3, 'Arrival', False] -------------------------------------------------------------------------------- /app1/b6.py: -------------------------------------------------------------------------------- 1 | >>> import random 2 | >>> random.random() # Returns a floating-point number in 3 | 0.8545672259166788 # the range (0,1) 4 | 5 | >>> random.randrange(1,6) # Returns an integer in the 6 | 4 # range [1, 6) 7 | 8 | >>> random.uniform(1, 3) # Returns a floating-point number 9 | 1.290486289287417 # in the range [1, 3) 10 | 11 | >>> random.normalvariate(1,0) # Returns a normal variate where 12 | 1.0 # mean = 1 and stdDev = 0 13 | 14 | >>> random.expovariate(3) # Returns an exponential variate 15 | 0.06953873605855697 # with mean 1/3 16 | 17 | >>> random.choice([1,2,3,4,5,6]) # Returns a random element from 18 | 5 # the input sequence 19 | 20 | >>> random.sample([1,2,3,4,5,6], 3) # Randomly choose three 21 | [6, 1, 2] # elements from the given 22 | # sequence -------------------------------------------------------------------------------- /app1/b7.py: -------------------------------------------------------------------------------- 1 | import queue 2 | from queue import Queue 3 | Event_List = queue.PriorityQueue() 4 | for item in ((10, 'Arrival'), (5, 'Departure'), (2, 'Fully_Charged')): 5 | Event_List.put(item) 6 | while not Event_List.empty(): 7 | print(Event_List.get()) -------------------------------------------------------------------------------- /app1/b8.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | from heapq import * 3 | Event_List =[] 4 | heappush(Event_List, (10, 'Arrival')) 5 | heappush(Event_List, (5, 'Departure')) 6 | heappush(Event_List, (2, 'Fully_Charged')) 7 | # Print the first item in the heap 8 | print ( heappop(Event_List) ) -------------------------------------------------------------------------------- /app1/b9.py: -------------------------------------------------------------------------------- 1 | # The first field is always the time 2 | e1 = (10, 'Arrival') 3 | e2 = (5, 'Departure') 4 | e3 = (2, 'Fully_Charged') 5 | Event_List = [] 6 | Event_List += [e1] 7 | Event_List += [e2] 8 | Event_List += [e3] 9 | Event_List.sort() 10 | print(Event_List) -------------------------------------------------------------------------------- /app1/plot_erlang_hist.py: -------------------------------------------------------------------------------- 1 | from random import * 2 | from math import * 3 | from matplotlib.pyplot import * 4 | from statistics import * 5 | 6 | def Erlang(): 7 | k = 10 8 | theta = 1.0 9 | y = 0 10 | for i in range(k): 11 | u = random() 12 | x = (-1 / theta) * log(u) # Exponential variate 13 | y = y + x 14 | 15 | return y 16 | 17 | N = 100000 18 | v = [] 19 | for i in range(N): 20 | v.append( Erlang() ) 21 | 22 | bins = 100 23 | 24 | w = [1 / len(v)] * len(v) 25 | 26 | hist(v, bins, weights = w) 27 | 28 | xlabel('Y') 29 | ylabel('P(y)') 30 | 31 | # Hide numbers along y-axis 32 | gca().axes.get_yaxis().set_ticklabels([]) 33 | # Remove ticks along y-axis 34 | gca().axes.yaxis.set_tick_params(width=0) 35 | 36 | savefig('erlang_plot_hist.pdf', format='pdf', bbox_inches='tight') 37 | 38 | print("Mean = ", mean(v)) -------------------------------------------------------------------------------- /app1/plot_erlang_pdf.py: -------------------------------------------------------------------------------- 1 | from random import * 2 | from math import * 3 | from matplotlib.pyplot import * 4 | from numpy import * 5 | 6 | def pdf(x): 7 | k = 10 8 | theta = 1.0 9 | return (x**(k-1) * theta**k * exp(-1 * theta * x)) / factorial(k-1) 10 | 11 | X = arange(0, 50, 0.1) 12 | Y = [] 13 | for x in X: 14 | Y.append( pdf(x) ) 15 | 16 | xlabel('Y') 17 | ylabel('P(y)') 18 | 19 | # Hide numbers along y-axis 20 | gca().axes.get_yaxis().set_ticklabels([]) 21 | # Remove ticks along y-axis 22 | gca().axes.yaxis.set_tick_params(width=0) 23 | 24 | plot(X, Y, linewidth=2) 25 | savefig('erlang_plot_pdf.pdf', format='pdf', bbox_inches='tight') 26 | 27 | # Compute the mean 28 | mean = 0 29 | for i in range( len(X) ): 30 | mean = mean + X[i] * Y[i] 31 | 32 | print("Mean = ", mean) -------------------------------------------------------------------------------- /app1/plot_triangular_pdf.py: -------------------------------------------------------------------------------- 1 | from random import * 2 | from math import * 3 | from matplotlib.pyplot import * 4 | from numpy import * 5 | 6 | def pdf(x, a, b, c): 7 | if x < a: 8 | return 0 9 | elif x >= a and x < c: 10 | return (2 * (x-a)) / ((b-a)*(c-a)) 11 | elif x == c: 12 | return 2 / (b-a) 13 | elif x > c and x <= b: 14 | return (2 * (b-x)) / ((b-a)*(b-c)) 15 | elif x > b: 16 | return 0 17 | else: 18 | print("Error") 19 | 20 | 21 | a = 1 22 | b = 10 23 | c = 7 24 | 25 | X = arange(0, b+1, 0.1) 26 | Y = [] 27 | 28 | xlabel('X', fontsize=15) 29 | ylabel('f(x)', fontsize=15) 30 | 31 | gca().axes.get_xaxis().set_ticks( np.arange(0, b+1, 1.0) ) 32 | 33 | for x in X: 34 | Y.append( pdf(x, a, b, c) ) 35 | 36 | plot(X, Y, linewidth=2) 37 | 38 | # Show figure on screen 39 | show() 40 | 41 | # Save figure to hard disk 42 | savefig('triangular_pdf.pdf', format='pdf', bbox_inches='tight') -------------------------------------------------------------------------------- /app2/.idea/.name: -------------------------------------------------------------------------------- 1 | OOF -------------------------------------------------------------------------------- /app2/.idea/OOF.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app2/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app2/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app2/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app2/.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 15 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 119 | 120 | 121 | 139 | 140 | 141 | 142 | true 143 | 144 | 145 | 146 | 147 | 148 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 183 | 184 | 185 | 186 | 189 | 190 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 226 | 227 | 228 | 229 | 230 | 243 | 244 | 257 | 258 | 275 | 276 | 277 | 278 | 279 | 280 | true 281 | 282 | 283 | 284 | 285 | 304 | 305 | 324 | 325 | 346 | 347 | 369 | 370 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 1443173683845 403 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 437 | 440 | 441 | 442 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | -------------------------------------------------------------------------------- /app2/SimpleProtocol.py: -------------------------------------------------------------------------------- 1 | from state import State 2 | from stateMachine import StateMachine 3 | from event import Event 4 | 5 | 6 | class Bad(State): 7 | def __init__(self): 8 | super(Bad, self).__init__() 9 | 10 | def action(self): 11 | print("Bad State") 12 | 13 | def next(self, event): 14 | if event.type == "B": 15 | return self 16 | else: 17 | return Good() 18 | 19 | 20 | class Good(State): 21 | def __init__(self): 22 | super(Good, self).__init__() 23 | 24 | def action(self): 25 | print("Good State") 26 | 27 | def next(self, event): 28 | if event.type == "G": 29 | return self 30 | else: 31 | return Bad() 32 | 33 | 34 | class Protocol(StateMachine): 35 | def __init__(self, _initialState): 36 | super(Protocol, self).__init__(_initialState) 37 | 38 | 39 | p = Protocol(Bad()) 40 | p.applyEvent(Event(None, None, "G", None)) 41 | p.applyEvent(Event(None, None, "G", None)) 42 | p.applyEvent(Event(None, None, "B", None)) -------------------------------------------------------------------------------- /app2/event.py: -------------------------------------------------------------------------------- 1 | class Event: 2 | def __init__(self, _src, _target, _type, _time): 3 | self.src = _src 4 | self.target = _target 5 | self.type = _type 6 | self.time = _time 7 | 8 | def __eq__(self, other): 9 | return self.__dict__ == other.__dict__ 10 | -------------------------------------------------------------------------------- /app2/ex01.py: -------------------------------------------------------------------------------- 1 | from scheduler import Scheduler 2 | from simEntity import SimEntity 3 | 4 | 5 | class Node(SimEntity): 6 | def __init__(self, _scheduler, _id): 7 | super(Node, self).__init__(_scheduler, _id) 8 | self.schedule(self, 'Self_Message', self.scheduler.time + 2.0) 9 | 10 | def evHandler(self, ev): 11 | print( ev.type + ' From ' + str(ev.src.id) + ' To ' + str(ev.target.id) + ' @ ' + str(ev.time) ) 12 | self.schedule(self, 'Hi', self.scheduler.time + 2.0) 13 | 14 | 15 | scheduler = Scheduler(3) 16 | 17 | Node(scheduler, 1) 18 | 19 | scheduler.run() -------------------------------------------------------------------------------- /app2/ex02.py: -------------------------------------------------------------------------------- 1 | from scheduler import Scheduler 2 | from simEntity import SimEntity 3 | 4 | class Node(SimEntity): 5 | 6 | def __init__(self, _scheduler, _id): 7 | super(Node, self).__init__(_scheduler) 8 | self.id = _id 9 | self.schedule(self, 'Initialize', self.scheduler.time + 2.0) 10 | 11 | def setNeighbor(self, n): 12 | self.neighbor = n 13 | 14 | def evHandler(self, ev): 15 | print( ev.type + ' From ' + str(ev.src.id) + ' To ' + str(ev.target.id) + ' @ ' + str(ev.time) ) 16 | self.schedule(self.neighbor, 'Hi', self.scheduler.time + 3.0) 17 | 18 | 19 | 20 | 21 | scheduler = Scheduler(4) 22 | 23 | n1 = Node(scheduler, 1) 24 | n2 = Node(scheduler, 2) 25 | 26 | n1.setNeighbor(n2) 27 | n2.setNeighbor(n1) 28 | 29 | scheduler.run() -------------------------------------------------------------------------------- /app2/ex03.py: -------------------------------------------------------------------------------- 1 | # Remove n1.setNeighbor(n2) && n2.setNeighbor(n1) 2 | # Use a link to connect the two nodes 3 | # A link has two ends: a & b 4 | 5 | from scheduler import Scheduler 6 | from simEntity import SimEntity 7 | 8 | class Node(SimEntity): 9 | 10 | def __init__(self, _scheduler, _id): 11 | super(Node, self).__init__(_scheduler, _id) 12 | self.schedule( self, 'Initialize', self.scheduler.time + 2.0 ) 13 | 14 | def setNeighbor(self, n): 15 | self.neighbor = n 16 | 17 | def evHandler(self, ev): 18 | print( ev.type + ' From ' + str(ev.src.id) + ' To ' + str(ev.target.id) + ' @ ' + str(ev.time) ) 19 | self.schedule( self.neighbor, 'Hi', self.scheduler.time + 3.0 ) 20 | 21 | 22 | class Link(SimEntity): 23 | 24 | def __init__(self, _scheduler, _id): 25 | super(Link, self).__init__(_scheduler, _id) 26 | 27 | def setNeighbors(self, _a, _b): 28 | self.a = _a 29 | self.b = _b 30 | 31 | def evHandler(self, ev): 32 | print( ev.type + ' From ' + str(ev.src.id) + ' To ' + str(ev.target.id) + ' @ ' + str(ev.time) ) 33 | if( ev.src.id == self.a.id ): 34 | self.schedule( self.b, 'Hi', self.scheduler.time + 3.0 ) 35 | else: 36 | self.schedule( self.a, 'Hi', self.scheduler.time + 3.0 ) 37 | 38 | 39 | 40 | scheduler = Scheduler(6) 41 | 42 | n1 = Node(scheduler, 1) 43 | n2 = Node(scheduler, 2) 44 | l = Link(scheduler, 3) 45 | 46 | n1.setNeighbor(l) 47 | n2.setNeighbor(l) 48 | l.setNeighbors(n1, n2) 49 | 50 | scheduler.run() -------------------------------------------------------------------------------- /app2/ex04.py: -------------------------------------------------------------------------------- 1 | from scheduler import Scheduler 2 | from simEntity import SimEntity 3 | from event import Event 4 | 5 | class Node(SimEntity): 6 | def __init__(self, _scheduler, _id): 7 | super(Node, self).__init__(_scheduler, _id) 8 | self.schedule(self, 'Self_Message', self.scheduler.time + 5.0) 9 | self.schedule(self, 'Self_Message', self.scheduler.time + 3.0) 10 | self.schedule(self, 'Self_Message', self.scheduler.time + 4.0) 11 | self.schedule(self, 'Self_Message', self.scheduler.time + 1.0) 12 | self.schedule(self, 'Self_Message', self.scheduler.time + 2.0) 13 | ev = Event(self, self, 'Self_Message', self.scheduler.time + 1.0) 14 | self.cancel(ev) 15 | 16 | def evHandler(self, ev): 17 | print( ev.type + ' From ' + str(ev.src.id) + ' To ' + str(ev.target.id) + ' @ ' + str(ev.time) ) 18 | 19 | 20 | 21 | scheduler = Scheduler(5) 22 | 23 | Node(scheduler, 1) 24 | 25 | scheduler.run() 26 | -------------------------------------------------------------------------------- /app2/mm1.py: -------------------------------------------------------------------------------- 1 | # IAT = Average Inter-Arrival Time 2 | # ST = Average Service Time 3 | # Size of packet is its service time (in time units not bits) 4 | # Station contains a queue (Q) and server (S) 5 | 6 | from scheduler import Scheduler 7 | from simEntity import SimEntity 8 | import random as rnd 9 | import queue 10 | 11 | class TrafficGen(SimEntity): 12 | 13 | def __init__(self, _scheduler, _station, _id, _IAT = 1.0, _ST = 1.0): 14 | super(TrafficGen, self).__init__(_scheduler, _id) 15 | self.station = _station 16 | self.IAT = _IAT 17 | self.ST = _ST 18 | self.schedule( self, 'Packet_Arrival', self.scheduler.time + rnd.expovariate(1.0/self.IAT) ) 19 | 20 | def evHandler(self, ev): 21 | # Handle arrival event 22 | pkt = Packet( rnd.expovariate(1.0/self.ST) ) 23 | pkt.Arrival_Time = self.scheduler.time 24 | self.schedule(self.station, pkt, self.scheduler.time) 25 | # Schedule next packet arrival 26 | self.schedule( self, 'Packet_Arrival', self.scheduler.time + rnd.expovariate(1.0/self.IAT) ) 27 | 28 | 29 | class Packet: 30 | def __init__(self, _size): 31 | self.size = _size 32 | self.Arrival_Time = 0.0 33 | self.Service_At = 0.0 34 | self.Departure_Time = 0.0 35 | 36 | # Total time spent in system 37 | def delay(self): 38 | return self.Departure_Time - self.Arrival_Time 39 | 40 | def info(self): 41 | print("Arrival_Time = %.2f, Service_At = %.2f, Service_Time = %.2f, Departure_Time = %.2f" % (self.Arrival_Time, self.Service_At, self.size, self.Departure_Time)) 42 | 43 | 44 | class Server(SimEntity): 45 | busy = False 46 | 47 | def __init__(self, _scheduler, _station, _id): 48 | super(Server, self).__init__(_scheduler, _id) 49 | self.station = _station 50 | 51 | def evHandler(self, ev): 52 | global Num_Pkts, Total_Delay 53 | 54 | if isinstance(ev.type, Packet): 55 | pkt = ev.type 56 | self.busy = True 57 | pkt.Service_At = self.scheduler.time 58 | pkt.Departure_Time = self.scheduler.time + pkt.size 59 | #pkt.info() 60 | Num_Pkts = Num_Pkts + 1 61 | Total_Delay = Total_Delay + pkt.delay() 62 | self.schedule(self, 'End_of_Service', self.scheduler.time + pkt.size) 63 | elif ev.type == 'End_of_Service': 64 | self.busy = False 65 | self.schedule(self.station, 'Server_Available', self.scheduler.time) 66 | else: 67 | print('Server is supposed to receive packets!') 68 | 69 | def isBusy(self): 70 | return self.busy 71 | 72 | 73 | class Station(SimEntity): 74 | 75 | def __init__(self, _scheduler, _id): 76 | super(Station, self).__init__(_scheduler, _id) 77 | self.Q = queue.Queue() 78 | self.S = Server(_scheduler, self, _id) 79 | 80 | def evHandler(self, ev): 81 | # Handle arriving packet 82 | if isinstance(ev.type, Packet): 83 | pkt = ev.type 84 | if not self.S.isBusy(): 85 | self.schedule(self.S, pkt, self.scheduler.time) 86 | else: 87 | self.Q.put(pkt) 88 | elif ev.type == 'Server_Available': 89 | if not self.Q.empty(): 90 | pkt = self.Q.get() 91 | self.schedule(self.S, pkt, self.scheduler.time) 92 | else: 93 | print('Station is supposed to receive packets only!') 94 | 95 | Num_Pkts = 0.0 96 | Total_Delay = 0.0 97 | 98 | scheduler = Scheduler(100000) 99 | station = Station(scheduler, 1) 100 | src = TrafficGen(scheduler, station, 2, 3.33, 2.5) 101 | scheduler.run() 102 | 103 | print('Avg Delay = %.2f' % (Total_Delay / Num_Pkts)) -------------------------------------------------------------------------------- /app2/scheduler.py: -------------------------------------------------------------------------------- 1 | # The variable self.count_events counts events generated. The number of events executed will also be equal to this 2 | # number. 3 | # 4 | # You insert event based on its time. If there are two events occurring at the same time, the second sorting 5 | # criterion is to use the id of the target. The third sorting criterion is to use the id of the source. 6 | 7 | from queue import PriorityQueue 8 | 9 | class Scheduler: 10 | 11 | def __init__(self, _Max_Num_Events): 12 | self.evList = PriorityQueue() 13 | self.time = 0.0 14 | self.count_events = 0 15 | self.Max_Num_Events = _Max_Num_Events 16 | 17 | def insert(self, ev): 18 | if ( self.count_events < self.Max_Num_Events ): 19 | self.count_events = self.count_events + 1 20 | self.evList.put( (ev.time, self.count_events, ev) ) 21 | 22 | def remove(self, ev): 23 | _evList = PriorityQueue() 24 | for i in range(self.evList.qsize()): 25 | tmp = self.evList.get() 26 | _ev = tmp[2] 27 | if not _ev == ev: 28 | _evList.put(tmp) 29 | self.evList = _evList 30 | 31 | def head(self): 32 | ev = self.evList.get() 33 | self.time = ev[2].time 34 | return ev[2] 35 | 36 | def run(self): 37 | count = 0 38 | while( not self.empty() ): 39 | ev = self.head() 40 | self.time = ev.time 41 | count += 1 42 | ev.target.evHandler(ev) 43 | 44 | def empty(self): 45 | return self.evList.empty() 46 | 47 | def reset(self): 48 | self.evList = None 49 | self.time = 0.0 50 | self.count_events = 0 51 | -------------------------------------------------------------------------------- /app2/simEntity.py: -------------------------------------------------------------------------------- 1 | from event import Event 2 | 3 | class SimEntity: 4 | 5 | def __init__(self, _scheduler, _id): 6 | self.scheduler = _scheduler 7 | self.id = _id 8 | 9 | def schedule(self, target, type, time): 10 | ev = Event(self, target, type, time) 11 | self.scheduler.insert(ev) 12 | 13 | def cancel(self, ev): 14 | self.scheduler.remove(ev) 15 | 16 | def evHandler(self, ev): 17 | pass 18 | -------------------------------------------------------------------------------- /app2/state.py: -------------------------------------------------------------------------------- 1 | class State: 2 | def action(self): 3 | pass 4 | 5 | def next(self, event): 6 | pass 7 | 8 | -------------------------------------------------------------------------------- /app2/stateMachine.py: -------------------------------------------------------------------------------- 1 | # http://python-3-patterns-idioms-test.readthedocs.org/en/latest/StateMachine.html#the-table 2 | 3 | 4 | class StateMachine: 5 | def __init__(self, initialState): 6 | self.currentState = initialState 7 | self.currentState.action() 8 | 9 | # Make transition 10 | def applyEvent(self, event): 11 | self.currentSate = self.currentState.next(event) 12 | self.currentSate.action() 13 | -------------------------------------------------------------------------------- /ch03/approx_prob_3_head_event.py: -------------------------------------------------------------------------------- 1 | import random as rnd 2 | n = 10000 3 | ne = 0 4 | z = 6 5 | for i in range(n): 6 | heads = 0 7 | for j in range(5): # Generate the next event 8 | # 1 if head; 0 if tail 9 | heads = heads + rnd.randint(0,1) 10 | if heads == 3: # Check if event has occurred 11 | ne = ne + 1 12 | prob = float(ne) / float(n) 13 | print(prob) 14 | 15 | -------------------------------------------------------------------------------- /ch03/approx_prob_outcome.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | 3 | n = 1000000 # No. of times experiment is performed 4 | ne = 0 # Count the occurrences of event 5 | 6 | for i in range(n): 7 | outcome = randint(1, 6) 8 | if(outcome == 3): # Check for event of interest 9 | ne += 1 # ne = ne + 1 10 | 11 | print("Prob = ", round(ne / n, 4)) # = 0.1667 -------------------------------------------------------------------------------- /ch03/moving_avg_tossing_coin.py: -------------------------------------------------------------------------------- 1 | ### Part 1: Performing the simulation experiment 2 | from random import choice 3 | from statistics import mean 4 | 5 | n = 1000 6 | observed = [] 7 | 8 | for i in range(n): 9 | outcome = choice(['Head', 'Tail']) 10 | if outcome == 'Head': 11 | observed.append(1) 12 | else: 13 | observed.append(0) 14 | 15 | print("Prob = ", round(mean(observed), 2)) 16 | 17 | ### Part 2: Computing the moving average 18 | from numpy import cumsum 19 | 20 | cum_observed = cumsum(observed) 21 | 22 | moving_avg = [] 23 | for i in range(len(cum_observed)): 24 | moving_avg.append( cum_observed[i] / (i+1) ) 25 | 26 | ### Part 3: Making the plot 27 | from matplotlib.pyplot import * 28 | from numpy import arange 29 | 30 | x = arange(0, len(moving_avg), 1) # x-axis 31 | p = [0.5 for i in range(len(moving_avg))] # Line 32 | 33 | xlabel('Iterations', size=20) 34 | ylabel('Probability', size=20) 35 | 36 | plot(x, moving_avg) 37 | plot(x, p, linewidth=2, color='black') 38 | 39 | show() -------------------------------------------------------------------------------- /ch03/sim_throw_die.py: -------------------------------------------------------------------------------- 1 | from random import randint 2 | 3 | print( randint(1,6) ) # outcome = 1 4 | print( randint(1,6) ) # outcome = 3 5 | print( randint(1,6) ) # outcome = 5 6 | -------------------------------------------------------------------------------- /ch04/hist_expov.py: -------------------------------------------------------------------------------- 1 | from random import expovariate 2 | from matplotlib.pyplot import hist, xlabel, ylabel, title, show, savefig 3 | 4 | # Generate the data set 5 | N = 10000 6 | data = [expovariate(1.5) for i in range(N)] 7 | 8 | # Decide number of bins 9 | num_bins = 50 10 | 11 | # Construct the histogram of the data 12 | # To generate PDF, use normed=True 13 | n, bins, patches = hist(data, num_bins, normed=True, facecolor='black', alpha=0.6) 14 | 15 | 16 | xlabel('$X$', size=18) 17 | ylabel('$f_X(x)$', size=18) 18 | title('Histogram of exponential data: $\mu$ = 1.5', size=15) 19 | 20 | # Show the figure or save it 21 | #show() 22 | savefig('hist_expov.pdf', format='pdf', bbox_inches='tight') -------------------------------------------------------------------------------- /ch04/plot_exponential.py: -------------------------------------------------------------------------------- 1 | from math import exp 2 | from numpy import * 3 | from matplotlib.pyplot import * 4 | 5 | # Parameters 6 | mu = 1.5 7 | 8 | # Plotting the PDF 9 | def pdf(x): 10 | return mu * exp(-mu * x) 11 | 12 | X = arange(0, 10, 0.1) 13 | Y = [] 14 | 15 | for x in X: 16 | Y.append(pdf(x)) 17 | 18 | matplotlib.rc('xtick', labelsize=18) 19 | matplotlib.rc('ytick', labelsize=18) 20 | plot(X, Y, Linewidth=2, color='black') 21 | xlabel('$X$', size=22) 22 | ylabel('$f_X(x)$', size=22) 23 | #show() 24 | savefig('exponential_pdf.pdf', format='pdf', bbox_inches='tight') 25 | 26 | # Clear the current figure 27 | clf() 28 | 29 | # Plotting the CDF 30 | def cdf(x): 31 | return 1 - exp(-mu * x) 32 | 33 | X = arange(0, 10, 0.1) 34 | Y = [] 35 | 36 | for x in X: 37 | Y.append(cdf(x)) 38 | 39 | matplotlib.rc('xtick', labelsize=18) 40 | matplotlib.rc('ytick', labelsize=18) 41 | plot(X, Y, Linewidth=2, color='black') 42 | xlabel('$X$', size=22) 43 | ylabel('$F_X(x)$', size=22) 44 | #show() 45 | savefig('exponential_cdf.pdf', format='pdf', bbox_inches='tight') -------------------------------------------------------------------------------- /ch04/plot_normal.py: -------------------------------------------------------------------------------- 1 | from math import exp, sqrt, pi 2 | from numpy import * 3 | from matplotlib.pyplot import * 4 | 5 | # Parameters 6 | mu = 30 7 | sigma = 10 8 | 9 | # Plotting the PDF 10 | def pdf(x): 11 | return (1 / (sigma * sqrt(2*pi)) ) * exp(-(x - mu)**2 / (2 * sigma**2)) 12 | 13 | X = arange(-100, 100, 0.1) 14 | Y = [] 15 | 16 | for x in X: 17 | Y.append(pdf(x)) 18 | 19 | matplotlib.rc('xtick', labelsize=18) 20 | matplotlib.rc('ytick', labelsize=18) 21 | plot(X, Y, Linewidth=2, color='black') 22 | xlabel('$X$', size=22) 23 | ylabel('$f_X(x)$', size=22) 24 | #show() 25 | savefig('normal_pdf.pdf', format='pdf', bbox_inches='tight') 26 | -------------------------------------------------------------------------------- /ch04/plot_triangular.py: -------------------------------------------------------------------------------- 1 | from random import * 2 | from math import * 3 | from matplotlib.pyplot import * 4 | from numpy import * 5 | 6 | # Parameters 7 | a = 1 8 | b = 10 9 | c = 7 10 | 11 | def cdf(x): 12 | if x <= a: 13 | return 0 14 | elif x > a and x <= c: 15 | return (x-a)**2 / ((b-a)*(c-a)) 16 | elif x > c and x < b: 17 | return 1 - ( (b-x)**2 / ((b-a)*(b-c)) ) 18 | elif x >= b: 19 | return 1 20 | else: 21 | print("Error") 22 | 23 | def pdf(x): 24 | if x < a: 25 | return 0 26 | elif x >= a and x < c: 27 | return (2 * (x-a)) / ((b-a)*(c-a)) 28 | elif x == c: 29 | return 2 / (b-a) 30 | elif x > c and x <= b: 31 | return (2 * (b-x)) / ((b-a)*(b-c)) 32 | elif x > b: 33 | return 0 34 | else: 35 | print("Error") 36 | 37 | 38 | X = arange(0, b+1, 0.1) 39 | Y = [] 40 | 41 | for x in X: 42 | Y.append(pdf(x)) 43 | 44 | matplotlib.rc('xtick', labelsize=18) 45 | matplotlib.rc('ytick', labelsize=18) 46 | plot(X, Y, Linewidth=2, color='black') 47 | xlabel('$X$', size=22) 48 | ylabel('$f_X(x)$', size=22) 49 | #show() 50 | savefig('triangular_pdf.pdf', format='pdf', bbox_inches='tight') 51 | 52 | # Clear the current figure 53 | clf() 54 | 55 | X = arange(0, b, 0.1) 56 | Y = [] 57 | 58 | for x in X: 59 | Y.append(cdf(x)) 60 | 61 | matplotlib.rc('xtick', labelsize=18) 62 | matplotlib.rc('ytick', labelsize=18) 63 | plot(X, Y, Linewidth=2, color='black') 64 | xlabel('$X$', size=22) 65 | ylabel('$F_X(x)$', size=22) 66 | #show() 67 | savefig('triangular_cdf.pdf', format='pdf', bbox_inches='tight') -------------------------------------------------------------------------------- /ch04/plot_uniform.py: -------------------------------------------------------------------------------- 1 | from numpy import * 2 | from matplotlib.pyplot import * 3 | 4 | # Parameters 5 | a = 3 6 | b = 10 7 | 8 | # Plotting the PDF 9 | def pdf(x): 10 | if x >= a and x <= b: 11 | return 1 / (b - a) 12 | else: 13 | return 0 14 | 15 | X = arange(0, b+3, 0.1) 16 | Y = [] 17 | 18 | for x in X: 19 | Y.append(pdf(x)) 20 | 21 | matplotlib.rc('xtick', labelsize=18) 22 | matplotlib.rc('ytick', labelsize=18) 23 | plot(X, Y, Linewidth=2, color='black') 24 | xlabel('$X$', size=22) 25 | ylabel('$f_X(x)$', size=22) 26 | #show() 27 | savefig('uniform_pdf.pdf', format='pdf', bbox_inches='tight') 28 | 29 | # Clear the current figure 30 | clf() 31 | 32 | # Plotting the CDF 33 | def cdf(x): 34 | if x < a: 35 | return 0 36 | elif x >= a and x < b: 37 | return (x - a) / (b - a) 38 | elif x >= b: 39 | return 1 40 | 41 | X = arange(0, b+3, 0.1) 42 | Y = [] 43 | 44 | for x in X: 45 | Y.append(cdf(x)) 46 | 47 | matplotlib.rc('xtick', labelsize=18) 48 | matplotlib.rc('ytick', labelsize=18) 49 | plot(X, Y, Linewidth=2, color='black') 50 | xlabel('$X$', size=22) 51 | ylabel('$F_X(x)$', size=22) 52 | #show() 53 | savefig('uniform_cdf.pdf', format='pdf', bbox_inches='tight') -------------------------------------------------------------------------------- /ch04/scipy_stats.py: -------------------------------------------------------------------------------- 1 | from scipy.stats import bernoulli, poisson, uniform, expon, erlang, norm, triang 2 | 3 | # Bernoulli 4 | p = 0.5 5 | x = 1 6 | # Generate a probability using the PMF 7 | print( bernoulli.pmf(x, p) ) # 0.5 8 | # Generate a probability using the CDF 9 | print( bernoulli.cdf(x, p) ) # 1.0 10 | # Generate three Bernoulli random numbers 11 | print( bernoulli.rvs(p, size = 3) ) # [0 1 0] 12 | 13 | # Poisson 14 | lmda = 2 15 | x = 5 16 | print( poisson.pmf(x, lmda) ) 17 | print( poisson.cdf(x, lmda) ) 18 | print( poisson.rvs(lmda, size = 3) ) 19 | 20 | # Uniform 21 | a = 3 22 | b = 10 23 | x = 10 24 | print( uniform.pdf(x, loc=a, scale=(b-a)) ) # = 1 / 7 25 | print( uniform.cdf(x, loc=a, scale=(b-a)) ) # = 1.0 26 | print( uniform.rvs(loc = 3, scale=(b-a), size = 3) ) 27 | 28 | # Exponential 29 | mu = 2 30 | x = 2 31 | print( expon.pdf(x, scale = (1 / mu)) ) 32 | print( expon.cdf(x, scale = (1 / mu)) ) 33 | print( expon.rvs( scale = (1 / mu), size = 3) ) 34 | 35 | # Triangular 36 | a = 1 37 | b = 10 38 | c = 7 39 | print( triang.rvs(c, loc = a, scale = (b - a), size = 3) ) -------------------------------------------------------------------------------- /ch04/sim_birth_death_process.py: -------------------------------------------------------------------------------- 1 | from random import expovariate 2 | from matplotlib.pyplot import * 3 | 4 | Avg_IAT = 2.0 5 | Avg_ST = 1.0 # Avg service time 6 | Sim_Time = 100 # Total simulation time 7 | N = 0 8 | clock = 0 # Simulation time 9 | X = [] # Times of events 10 | Y = [] # Values of N 11 | 12 | while clock <= Sim_Time: 13 | IAT = expovariate(1 / Avg_IAT) 14 | ST = expovariate(1 / Avg_ST) 15 | if IAT <= ST: 16 | N += 1 17 | clock = clock + IAT 18 | X.append(clock) 19 | Y.append(N) 20 | else: 21 | if N > 0: 22 | N -= 1 23 | clock = clock + ST 24 | X.append(clock) 25 | Y.append(N) 26 | 27 | step(X, Y, Linewidth=1.2, color='black') 28 | xlabel('Time', size=16) 29 | ylabel('N', size=16) 30 | xlim(0, 101) 31 | #show() 32 | savefig('sim_birth_death_process.pdf', format='pdf', bbox_inches='tight') -------------------------------------------------------------------------------- /ch04/sim_poisson_process.py: -------------------------------------------------------------------------------- 1 | from random import expovariate 2 | 3 | Avg_IAT = 2.0 # Average IAT 4 | Sim_Time = 100 # Total simulation time 5 | N = 0 # Count number of arrivals 6 | clock = 0 # Simulation time 7 | 8 | while clock <= Sim_Time: 9 | N = N + 1 10 | # Advance simulation clock 11 | clock = clock + expovariate(1/Avg_IAT) 12 | 13 | print('Total Number of Arrivals = ', N) -------------------------------------------------------------------------------- /ch04/two_state_disc_markov.py: -------------------------------------------------------------------------------- 1 | from random import random 2 | 3 | n = 10 4 | S = [] 5 | 6 | S.append('G') # Initial state 7 | 8 | for i in range(n): 9 | u = random() 10 | if S[i] == 'G': 11 | if u < 0.5: 12 | S.append('G') 13 | else: 14 | S.append('B') 15 | elif S[i] == 'B': 16 | if u < 0.7: 17 | S.append('G') 18 | else: 19 | S.append('B') 20 | 21 | print('Sample Path: ', S) -------------------------------------------------------------------------------- /ch05/__pycache__/simLib.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yosais/Computer-Simulation-Book/87b2d83eded02f69cd7b8d839adfa554b25ae19d/ch05/__pycache__/simLib.cpython-35.pyc -------------------------------------------------------------------------------- /ch05/simLib.py: -------------------------------------------------------------------------------- 1 | # A user-defined simulation library 2 | 3 | from random import expovariate 4 | from statistics import mean 5 | from math import inf as Infinity 6 | 7 | # Simulation of mm1 queueing system 8 | # This function returns the average delay 9 | def mm1(lamda, mu, Num_Pkts): 10 | count = 0 # Count number of simulated packets 11 | clock = 0 12 | N = 0 # State Variable; number of packets in system 13 | 14 | Arr_Time = expovariate(lamda) 15 | Dep_Time = Infinity 16 | 17 | # Output Variables 18 | Arr_Time_Data = [] # Collect arrival times 19 | Dep_Time_Data = [] # Collect departure times 20 | Delay_Data = [] # Collect delays of individual packets 21 | 22 | while count < Num_Pkts: 23 | if Arr_Time < Dep_Time: # Arrival Event 24 | clock = Arr_Time 25 | Arr_Time_Data.append(clock) 26 | N = N + 1.0 27 | Arr_Time = clock + expovariate(lamda) 28 | if N == 1: 29 | Dep_Time = clock + expovariate(mu) 30 | else: # Departure Event 31 | clock = Dep_Time 32 | Dep_Time_Data.append(clock) 33 | N = N - 1.0 34 | count = count + 1 # Packet Simulated 35 | if N > 0: 36 | Dep_Time = clock + expovariate(mu) 37 | else: 38 | Dep_Time = Infinity 39 | 40 | for i in range(Num_Pkts): 41 | d = Dep_Time_Data[i] - Arr_Time_Data[i] 42 | Delay_Data.append(d) 43 | 44 | return mean(Delay_Data) 45 | 46 | # Simulation of mm1 queueing system 47 | # This function returns the output variable Delay 48 | # Delay contains delays of individual packets 49 | def out_var_mm1(lamda, mu, Num_Pkts): 50 | count = 0 # Count number of simulated packets 51 | clock = 0 52 | N = 0 # State Variable; number of packets in system 53 | 54 | Arr_Time = expovariate(lamda) 55 | Dep_Time = Infinity 56 | 57 | # Output Variables 58 | Arr_Time_Data = [] # Collect arrival times 59 | Dep_Time_Data = [] # Collect departure times 60 | Delay_Data = [] # Collect delays of individual packets 61 | 62 | while count < Num_Pkts: 63 | if Arr_Time < Dep_Time: # Arrival Event 64 | clock = Arr_Time 65 | Arr_Time_Data.append(clock) 66 | N = N + 1.0 67 | Arr_Time = clock + expovariate(lamda) 68 | if N == 1: 69 | Dep_Time = clock + expovariate(mu) 70 | else: # Departure Event 71 | clock = Dep_Time 72 | Dep_Time_Data.append(clock) 73 | N = N - 1.0 74 | count = count + 1 # Packet Simulated 75 | if N > 0: 76 | Dep_Time = clock + expovariate(mu) 77 | else: 78 | Dep_Time = Infinity 79 | 80 | for i in range(Num_Pkts): 81 | d = Dep_Time_Data[i] - Arr_Time_Data[i] 82 | Delay_Data.append(d) 83 | 84 | return Delay_Data 85 | 86 | # Simulation of mm1 queueing system 87 | # This function returns the moving (cumulative) average of the output variable Delay 88 | def out_var_cum_mm1(lamda, mu, Num_Pkts): 89 | Delay = out_var_mm1(lamda, mu, Num_Pkts) 90 | Delay_Cum = [] 91 | for i in range(Num_Pkts): 92 | Delay_Cum.append( sum(Delay[0:i+1]) / (i+1) ) 93 | 94 | return Delay_Cum -------------------------------------------------------------------------------- /ch05/sim_mm1.py: -------------------------------------------------------------------------------- 1 | from random import expovariate 2 | from math import inf as Infinity 3 | 4 | Avg_IAT = 2.0 # Average Inter-Arrival Time 5 | Avg_ST = 1.0 # Average Service Time 6 | Tot_Sim_Time = 100.0 # Total Simulation Time 7 | clock = 0.0 # Current Simulation Time 8 | 9 | N = 0 # State variable; number of customers in the system 10 | 11 | # Time of the next arrival event 12 | Arr_Time = expovariate(1.0/Avg_IAT) 13 | # Time of the next departure event 14 | Dep_Time = Infinity 15 | 16 | while clock <= Tot_Sim_Time: 17 | if Arr_Time < Dep_Time: # Arrival Event 18 | clock = Arr_Time 19 | N = N + 1.0 20 | Arr_Time = clock + expovariate(1.0/Avg_IAT) 21 | if N == 1: 22 | Dep_Time = clock + expovariate(1.0/Avg_ST) 23 | else: # Departure Event 24 | clock = Dep_Time 25 | N = N - 1.0 26 | if N > 0: 27 | Dep_Time = clock + expovariate(1.0/Avg_ST) 28 | else: 29 | Dep_Time = Infinity 30 | -------------------------------------------------------------------------------- /ch05/sim_mm1_avg_num_pkts.py: -------------------------------------------------------------------------------- 1 | from random import expovariate 2 | from statistics import mean 3 | from math import inf as Infinity 4 | 5 | # Parameters 6 | lamda = 1.3 7 | mu = 2.0 8 | Num_Pkts = 1000000 9 | count = 0 10 | clock = 0 11 | N = 0 12 | 13 | Arr_Time = expovariate(lamda) 14 | Dep_Time = Infinity 15 | 16 | Prev_Event_Time = 0.0 # Time of last event 17 | Area = [] # Output variable 18 | 19 | while count < Num_Pkts: 20 | if Arr_Time < Dep_Time: 21 | clock = Arr_Time 22 | # Area of rectangle 23 | Area.append((clock - Prev_Event_Time) * N) 24 | Prev_Event_Time = clock 25 | N = N + 1.0 26 | Arr_Time = clock + expovariate(lamda) 27 | if N == 1: 28 | Dep_Time = clock + expovariate(mu) 29 | else: 30 | clock = Dep_Time 31 | # Area of rectangle 32 | Area.append((clock - Prev_Event_Time) * N) 33 | Prev_Event_Time = clock 34 | N = N - 1.0 35 | count = count + 1 36 | if N > 0: 37 | Dep_Time = clock + expovariate(mu) 38 | else: 39 | Dep_Time = Infinity 40 | 41 | print( "E[ N(t) ] = ", round(sum(Area) / clock, 4) ) -------------------------------------------------------------------------------- /ch05/sim_mm1_indep_replic.py: -------------------------------------------------------------------------------- 1 | # simLib is your simulation library, which you will reuse 2 | # in your homeworks and projects. 3 | # It is available in the github repository 4 | 5 | from simLib import mm1 6 | from random import seed 7 | from statistics import mean 8 | 9 | lamda = 1.3 10 | mu = 2 11 | n = 100000 # Number of packets to be simulated 12 | 13 | Num_Repl = 50 # Number of replications (repetitions) 14 | Delay = [] # Data set 15 | 16 | for i in range(Num_Repl): 17 | seed() # Reseed RNG 18 | d = mm1(lamda, mu, n) 19 | Delay.append(d) 20 | 21 | # Estimate of performance measure 22 | print("Average Delay = " , round( mean(Delay), 4) ) -------------------------------------------------------------------------------- /ch05/sim_mm1_prob_N.py: -------------------------------------------------------------------------------- 1 | from random import expovariate 2 | from statistics import mean 3 | from math import inf as Infinity 4 | 5 | # Parameters 6 | lamda = 1.3 7 | mu = 2.0 8 | Num_Pkts = 1000000 9 | count = 0 10 | clock = 0 11 | N = 0 12 | 13 | Arr_Time = expovariate(lamda) 14 | Dep_Time = Infinity 15 | Prev_Event_Time = 0.0 16 | 17 | Data = {} # Dictionary 18 | 19 | while count < Num_Pkts: 20 | if Arr_Time < Dep_Time: 21 | clock = Arr_Time 22 | # Length of time interval 23 | delta = clock - Prev_Event_Time 24 | if N in Data: Data[N] += delta 25 | else: Data[N] = delta 26 | Prev_Event_Time = clock 27 | N = N + 1.0 28 | Arr_Time = clock + expovariate(lamda) 29 | if N == 1: 30 | Dep_Time = clock + expovariate(mu) 31 | else: 32 | clock = Dep_Time 33 | # Length of time interval 34 | delta = clock - Prev_Event_Time 35 | if N in Data: Data[N] += delta 36 | else: Data[N] = delta 37 | Prev_Event_Time = clock 38 | N = N - 1.0 39 | count = count + 1 40 | if N > 0: 41 | Dep_Time = clock + expovariate(mu) 42 | else: 43 | Dep_Time = Infinity 44 | 45 | # Compute probabilities 46 | for (key, value) in Data.items(): 47 | Data[key] = value / clock 48 | 49 | # Check total probability is 1.0 50 | print("Sum of Prob's = ", sum( Data.values() ) ) 51 | 52 | # Check expectation 53 | mean = 0.0 54 | for (key, value) in Data.items(): 55 | mean = mean + key * value 56 | 57 | print("E[N] = ", mean) -------------------------------------------------------------------------------- /ch05/sim_mm1_resp_time.py: -------------------------------------------------------------------------------- 1 | from random import expovariate 2 | from statistics import mean 3 | from math import inf as Infinity 4 | 5 | # Parameters 6 | lamda = 1.3 # Arrival rate (Lambda) 7 | mu = 2.0 # Departure rate (Mu) 8 | Num_Pkts = 100000 # Number of Packets to be simulated 9 | count = 0 # Count number of simulated packets 10 | clock = 0 11 | N = 0 # State Variable; number of packets in system 12 | 13 | Arr_Time = expovariate(lamda) 14 | Dep_Time = Infinity 15 | 16 | # Output Variables 17 | Arr_Time_Data = [] # Collect arrival times 18 | Dep_Time_Data = [] # Collect departure times 19 | Delay_Data = [] # Collect delays of individual packets 20 | 21 | while count < Num_Pkts: 22 | if Arr_Time < Dep_Time: # Arrival Event 23 | clock = Arr_Time 24 | Arr_Time_Data.append(clock) 25 | N = N + 1.0 26 | Arr_Time = clock + expovariate(lamda) 27 | if N == 1: 28 | Dep_Time = clock + expovariate(mu) 29 | else: # Departure Event 30 | clock = Dep_Time 31 | Dep_Time_Data.append(clock) 32 | N = N - 1.0 33 | count = count + 1 # Packet Simulated 34 | if N > 0: 35 | Dep_Time = clock + expovariate(mu) 36 | else: 37 | Dep_Time = Infinity 38 | 39 | for i in range(Num_Pkts): 40 | d = Dep_Time_Data[i] - Arr_Time_Data[i] 41 | Delay_Data.append(d) 42 | 43 | print( "Average Delay = ", round( mean(Delay_Data), 4) ) -------------------------------------------------------------------------------- /ch05/welch.py: -------------------------------------------------------------------------------- 1 | from simLib import out_var_cum_mm1 2 | from random import seed 3 | from matplotlib.pyplot import * 4 | import numpy as np 5 | 6 | lamda = 1.3 7 | mu = 2 8 | 9 | n = 10000 # Number of packets to be simulated 10 | R = 5 # Number of replications (repetitions) 11 | 12 | Y = np.zeros( shape = (R, n) ) # Output variable Delay 13 | 14 | # 1. Generate sample paths 15 | for i in range(R): 16 | seed() 17 | Y[i] = out_var_cum_mm1(lamda, mu, n) 18 | 19 | # 2. Compute the mean 20 | Z = [] 21 | for i in range(n): 22 | Z.append( sum(Y[:, i]) / R ) 23 | 24 | # Plot Y and Z 25 | plot(Y[0], "k--", label="Y[0]") 26 | plot(Y[1], "k--", label="Y[1]") 27 | plot(Y[2], "k--", label="Y[2]") 28 | plot(Y[3], "k--", label="Y[3]") 29 | plot(Y[4], "k--", label="Y[4]") 30 | plot(Z, "k", linewidth=2, label="Z") 31 | 32 | xlabel("$n$", size=16) 33 | ylabel("$W_{cum}$", size=16) 34 | legend(loc='upper right', shadow=True) 35 | show() -------------------------------------------------------------------------------- /ch06/funcs.py: -------------------------------------------------------------------------------- 1 | import bisect 2 | evList = [] 3 | def insert(ev): 4 | bisect.insort_right(evList, ev) 5 | def cancel(ev): 6 | evList.remove(ev) 7 | def run(): 8 | while evList: 9 | ev = evList.pop(0) 10 | clock = ev[0] 11 | ev[2](clock, param) 12 | -------------------------------------------------------------------------------- /ch06/simple_arq.py: -------------------------------------------------------------------------------- 1 | import random as rnd 2 | import queue 3 | import statistics as stat 4 | import bisect 5 | 6 | # Define a dictionary to hold the simulation parameters 7 | param = {'Timeout_Duration': 1, 8 | 'P' : 0.5, # Frame Error Rate (FER) 9 | 'Frame_Trans_Time': 1, # Frame transmission time 10 | 'Num_Frames': 1 11 | } 12 | 13 | #-------------- Global Variables -------------- 14 | Frames_Received = 0.0 15 | Count_Frames = 0.0 16 | clock = 0.0 17 | #---------------------------------------------- 18 | 19 | evList = [] 20 | 21 | cur_timeout_event = None 22 | 23 | def insert(ev): 24 | bisect.insort_right(evList, ev) 25 | 26 | def cancel(ev): 27 | evList.remove(ev) 28 | 29 | def run(): 30 | global evList 31 | while evList: 32 | ev = evList.pop(0) 33 | clock = ev[0] 34 | ev[2](clock, param) 35 | #-------------- Event Generators -------------- 36 | # REG for the start event 37 | def start_event (clock, param): 38 | ev = (clock, "start", start_event_handler) 39 | return ev 40 | 41 | 42 | # REG for the frame transmission event 43 | def frame_trans_event (clock, param): 44 | global Count_Frames 45 | if(Count_Frames < param['Num_Frames']): 46 | Count_Frames += 1 47 | ev = (clock, "transmission", frame_trans_event_handler) 48 | return ev 49 | 50 | # REG for the timeout event 51 | def timeout_event (clock, param): 52 | t = param['Timeout_Duration'] 53 | ev = (clock+t, "timeout", timeout_event_handler) 54 | return ev 55 | 56 | # REG for the frame reception event 57 | def frame_reception_event (clock, param): 58 | t = param['Frame_Trans_Time'] 59 | ev = (clock+t, "reception", frame_reception_event_handler) 60 | return ev 61 | 62 | # REG for the acknowledgement event 63 | def ack_event (clock, param): 64 | ev = (clock, "ack", ack_reception_event_handler) 65 | return ev 66 | 67 | #-------------- Event Handlers -------------- 68 | # Event handler for the sender start event 69 | def start_event_handler (clock, param): 70 | global Count_Frames, Frames_Received 71 | Count_Frames = 0.0 72 | Frames_Received = 0.0 73 | 74 | # Schedule the first frame transmission event 75 | schedule_event( frame_trans_event (clock, param) ) 76 | 77 | # Event handler for the frame transmission event 78 | def frame_trans_event_handler (clock, param): 79 | global cur_timeout_event 80 | schedule_event( frame_reception_event (clock, param) ) 81 | cur_timeout_event = timeout_event (clock, param) 82 | schedule_event( cur_timeout_event ) 83 | 84 | # Event handler for the frame reception event 85 | def frame_reception_event_handler (clock, param): 86 | global Frames_Received, cur_timeout_event 87 | if rnd.random() > param['P']: 88 | # Frame is OK 89 | Frames_Received += 1 90 | schedule_event( ack_event (clock, param) ) 91 | # Cancel the pending timeout event 92 | cancel(cur_timeout_event) 93 | 94 | # Event handler for the ack event 95 | def ack_reception_event_handler (clock, param): 96 | schedule_event( frame_trans_event (clock, param) ) 97 | 98 | # Event handler for the timeout event 99 | def timeout_event_handler (clock, param): 100 | global Count_Frames 101 | # Re-transmit the frame again 102 | Count_Frames = Count_Frames - 1; 103 | schedule_event( frame_trans_event (clock, param) ) 104 | 105 | #------------------------------------------------------- 106 | # Insert an event into the event list 107 | def schedule_event(ev): 108 | global evList 109 | if ev != None: 110 | insert(ev) 111 | 112 | #------------------------------------------------------- 113 | # Schedule the first frame transmission event 114 | schedule_event( start_event (clock, param) ) 115 | 116 | # Simulation Loop 117 | run() -------------------------------------------------------------------------------- /ch07/prog01.py: -------------------------------------------------------------------------------- 1 | import random as rnd 2 | import queue 3 | import statistics as stat 4 | # Compute the theoretical value using the calcualtor at 5 | # http://www.supositorio.com/rcalc/rcalclite.htm 6 | # Define a dictionary to hold the simulation parameters 7 | param = {'_lambda': 0.2, 8 | '_mu': 0.3, 9 | # Total number of arrival events 10 | 'Num_Arrival_Ev': 100000 11 | } 12 | # Define a dictionary to hold the state variables 13 | state_var = {'q_length': 0, 14 | 'server_busy': False 15 | } 16 | # Define a dictionary to hold the output variables 17 | out_var = { 'arrs': [], 18 | 'deps': [], 19 | 'Count_Arrival_Ev': 0 20 | } 21 | # Define the global event list 22 | evList = queue.PriorityQueue() 23 | # REG for the arrival event 24 | def get_next_arrival_event (clock, param): 25 | out_var['Count_Arrival_Ev'] += 1 26 | iat = rnd.expovariate(param['_lambda']) 27 | ev = (clock+iat, "arrival", arrival_event_handler) 28 | return ev 29 | # REG for the departure event 30 | def get_next_departure_event (clock, param): 31 | st = rnd.expovariate(param['_mu']) 32 | ev = (clock+st, "departure", departure_event_handler) 33 | return ev 34 | # Event handler for the arrival event 35 | def arrival_event_handler (clock, state_var, out_var, param): 36 | state_var['q_length'] += 1 37 | out_var['arrs'].append(clock) # Record arrival time 38 | if state_var['server_busy'] == False: 39 | state_var['server_busy'] = True 40 | schedule_event(get_next_departure_event(clock, param)) 41 | if out_var['Count_Arrival_Ev'] < param['Num_Arrival_Ev']: 42 | schedule_event(get_next_arrival_event(clock, param)) 43 | # Event handler for the departure event 44 | def departure_event_handler (clock, state_var, out_var, param): 45 | state_var['q_length'] -= 1 46 | out_var['deps'].append(clock) # Record departure time 47 | if state_var['q_length'] == 0: 48 | state_var['server_busy'] = False 49 | else: 50 | state_var['server_busy'] = True 51 | schedule_event(get_next_departure_event(clock, param)) 52 | # Insert an event into the event list 53 | def schedule_event(ev): 54 | global evList 55 | evList.put(ev) 56 | # Main simulation function 57 | def sim(state_var, out_var, param): 58 | global evList 59 | clock = 0 60 | evList = queue.PriorityQueue() 61 | # Reset state and output variables 62 | state_var['q_length'] = 0 63 | state_var['server_busy'] = False 64 | out_var['arrs'] = [] 65 | out_var['deps'] = [] 66 | out_var['Count_Arrival_Ev'] = 0 67 | # Initialize (seed) the RNG 68 | #rnd.seed(10) 69 | # Insert initial event 70 | ev = get_next_arrival_event(clock, param) 71 | schedule_event(ev) 72 | # Start simulation 73 | while not evList.empty(): 74 | ev = evList.get() 75 | clock = ev[0] 76 | if ev[1] == "arrival": 77 | ev[2](clock, state_var, out_var, param) 78 | else: 79 | ev[2](clock, state_var, out_var, param) 80 | def main(): 81 | sim(state_var, out_var, param) 82 | # Print statistics 83 | d = list(map(lambda x,y: x-y, 84 | out_var['deps'], out_var['arrs'])) 85 | print ("Avg Delay = ", stat.mean(d)) 86 | if __name__ == '__main__': 87 | main() -------------------------------------------------------------------------------- /ch08/__pycache__/normal.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yosais/Computer-Simulation-Book/87b2d83eded02f69cd7b8d839adfa554b25ae19d/ch08/__pycache__/normal.cpython-35.pyc -------------------------------------------------------------------------------- /ch08/bernoulli.py: -------------------------------------------------------------------------------- 1 | import random as rnd 2 | p = 0.5 # Probability of success 3 | u = rnd.random() 4 | if 0 <= u <= p: 5 | print( '1' ) # Sueccess 6 | else: 7 | print( '0' ) # Failure -------------------------------------------------------------------------------- /ch08/binomial.py: -------------------------------------------------------------------------------- 1 | import random as rnd 2 | p = 0.3 # Probability of success 3 | n = 10 # Number of trials 4 | count = 0 # Count number of successes 5 | def Bernoulli(p): # Bernoulli RVG Function 6 | u = rnd.random() 7 | if 0 <= u < p: 8 | return 1 9 | else: 10 | return 0 11 | for i in range(n): 12 | count = count + Bernoulli(p) 13 | print( 'v = ' , count ) -------------------------------------------------------------------------------- /ch08/erlang.py: -------------------------------------------------------------------------------- 1 | from random import * 2 | from math import * 3 | 4 | k = 10 5 | theta = 1.5 6 | 7 | y = 0 8 | 9 | for i in range(k): 10 | u = random() 11 | x = (-1 / theta) * log(1-u) # Exponential variate 12 | y = y + x 13 | 14 | print("Y", y) -------------------------------------------------------------------------------- /ch08/erlang_plot_hist.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yosais/Computer-Simulation-Book/87b2d83eded02f69cd7b8d839adfa554b25ae19d/ch08/erlang_plot_hist.pdf -------------------------------------------------------------------------------- /ch08/erlang_plot_hist.py: -------------------------------------------------------------------------------- 1 | from random import * 2 | from math import * 3 | from matplotlib.pyplot import * 4 | from statistics import * 5 | 6 | def Erlang(): 7 | k = 10 8 | theta = 1.0 9 | y = 0 10 | for i in range(k): 11 | u = random() 12 | x = (-1 / theta) * log(u) # Exponential variate 13 | y = y + x 14 | 15 | return y 16 | 17 | N = 100000 18 | v = [] 19 | for i in range(N): 20 | v.append( Erlang() ) 21 | 22 | bins = 100 23 | 24 | w = [1 / len(v)] * len(v) 25 | 26 | hist(v, bins, weights = w) 27 | 28 | xlabel('Y') 29 | ylabel('P(y)') 30 | 31 | # Hide numbers along y-axis 32 | gca().axes.get_yaxis().set_ticklabels([]) 33 | # Remove ticks along y-axis 34 | gca().axes.yaxis.set_tick_params(width=0) 35 | 36 | savefig('erlang_plot_hist.pdf', format='pdf', bbox_inches='tight') 37 | 38 | print("Mean = ", mean(v)) -------------------------------------------------------------------------------- /ch08/erlang_plot_pdf.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yosais/Computer-Simulation-Book/87b2d83eded02f69cd7b8d839adfa554b25ae19d/ch08/erlang_plot_pdf.pdf -------------------------------------------------------------------------------- /ch08/erlang_plot_pdf.py: -------------------------------------------------------------------------------- 1 | from random import * 2 | from math import * 3 | from matplotlib.pyplot import * 4 | from numpy import * 5 | 6 | def pdf(x): 7 | k = 10 8 | theta = 1.0 9 | return (x**(k-1) * theta**k * exp(-1 * theta * x)) / factorial(k-1) 10 | 11 | X = arange(0, 50, 0.1) 12 | Y = [] 13 | for x in X: 14 | Y.append( pdf(x) ) 15 | 16 | xlabel('Y') 17 | ylabel('P(y)') 18 | 19 | # Hide numbers along y-axis 20 | gca().axes.get_yaxis().set_ticklabels([]) 21 | # Remove ticks along y-axis 22 | gca().axes.yaxis.set_tick_params(width=0) 23 | 24 | plot(X, Y, linewidth=2) 25 | savefig('erlang_plot_pdf.pdf', format='pdf', bbox_inches='tight') 26 | 27 | # Compute the mean 28 | mean = 0 29 | for i in range( len(X) ): 30 | mean = mean + X[i] * Y[i] 31 | 32 | print("Mean = ", mean) -------------------------------------------------------------------------------- /ch08/geometric.py: -------------------------------------------------------------------------------- 1 | import random as rnd 2 | p = 0.6 # Probability of success 3 | # Number of Bernoulli trials Needed Before the First Success 4 | count = 0 5 | def Bernoulli(p): 6 | u = rnd.random() 7 | if 0 <= u < p: 8 | return 1 9 | else: 10 | return 0 11 | while(Bernoulli(p) == 0): 12 | count = count + 1 13 | print( 'v = ' , count ) -------------------------------------------------------------------------------- /ch08/lognormal.py: -------------------------------------------------------------------------------- 1 | import random as rnd 2 | import math 3 | # Import file containing the normal function 4 | from normal import * 5 | 6 | def lognormal(mean, sigma): 7 | u1, u2 = rnd.random(), rnd.random() 8 | z1, z2 = normal(u1, u2) 9 | # Generate random variate from a non-standard normal distribution 10 | v = mean + sigma * z1 11 | return math.exp(v) -------------------------------------------------------------------------------- /ch08/normal.py: -------------------------------------------------------------------------------- 1 | # mean = 0 & standard deviaiton = 1 2 | from math import sqrt, log, sin, cos, pi 3 | from random import random 4 | def normal(u1,u2): 5 | z1 = sqrt( -2 * log(u1) ) * cos ( 2 * pi * u2 ) 6 | z2 = sqrt( -2 * log(u1) ) * sin (2 * pi * u2 ) 7 | return z1 , z2 8 | u1 = random() 9 | u2 = random() 10 | z = normal(u1,u2) 11 | print ('z1 = ' , z[0] , 'z2 = ', z[1]) -------------------------------------------------------------------------------- /ch08/normal_convolution.py: -------------------------------------------------------------------------------- 1 | from random import * 2 | 3 | z = -6 4 | for i in range(12): 5 | u = random() 6 | z = z + u 7 | 8 | print("Z = ", z) -------------------------------------------------------------------------------- /ch08/normal_convolution_plot_hist.py: -------------------------------------------------------------------------------- 1 | from random import * 2 | from matplotlib.pyplot import * 3 | from statistics import * 4 | 5 | def Normal(): 6 | z = -6 7 | for i in range(12): 8 | u = random() 9 | z = z + u 10 | return z 11 | 12 | N = 100000 13 | v = [] 14 | for i in range(N): 15 | v.append( Normal() ) 16 | 17 | bins = 100 18 | 19 | w = [1 / len(v)] * len(v) 20 | 21 | hist(v, bins, weights = w) 22 | 23 | xlabel('Y') 24 | ylabel('P(y)') 25 | 26 | # Hide numbers along y-axis 27 | gca().axes.get_yaxis().set_ticklabels([]) 28 | # Remove ticks along y-axis 29 | gca().axes.yaxis.set_tick_params(width=0) 30 | 31 | savefig('normal_convolution_plot_hist.pdf', format='pdf', bbox_inches='tight') 32 | 33 | print("Mean = ", mean(v)) -------------------------------------------------------------------------------- /ch08/plot_lognormal.py: -------------------------------------------------------------------------------- 1 | import random as rnd 2 | import math 3 | import matplotlib.pyplot as plt 4 | 5 | def normal(u1,u2): 6 | z1 = sqrt( -2 * log(u1) ) * cos ( 2 * pi * u2 ) 7 | return z1 8 | 9 | def lognormal(mean, sigma): 10 | u1, u2 = rnd.random(), rnd.random() 11 | tmp = normal(u1,u2) 12 | v = mean + sigma * tmp 13 | return math.exp(v) 14 | 15 | v = [] 16 | mean, sigma = 3, 1 17 | 18 | for i in range(1000): 19 | v.append(lognormal(mean, sigma)) 20 | 21 | count, bins, ignored = plt.hist(v, 100, normed = True, align = 'mid') 22 | plt.show() -------------------------------------------------------------------------------- /ch08/poisson.py: -------------------------------------------------------------------------------- 1 | import random as rnd 2 | import math 3 | lmda = 10 # Arrival Rate 4 | count = 0 # Number of Arrivals 5 | b = math.exp(-lmda) 6 | u = rnd.random() 7 | while u >= b: 8 | count = count + 1 9 | u = u * rnd.random() 10 | print ('v = ' , count) -------------------------------------------------------------------------------- /ch08/rej_alg_01.py: -------------------------------------------------------------------------------- 1 | import random as rnd 2 | import math as M 3 | def f(x): 4 | return 0.2 * M.exp(-(x - 0.2)**2.0) + 5 | 0.8 * M.exp(-(x - 2.0)**2.0 / 0.2) 6 | def g(x): 7 | return 1 # Uniform PDF 8 | Stop = False 9 | while not Stop: 10 | x = rnd.uniform(0, 4) # Generate x 11 | u = rnd.random() # y = u * g(x) 12 | if u <= f(x) / g(x): # y <= f(x) 13 | print x 14 | Stop = True -------------------------------------------------------------------------------- /ch08/rvg_pmf.py: -------------------------------------------------------------------------------- 1 | import random as rnd 2 | p = [0.1, 0.2, 0.4, 0.1, 0.2] 3 | u = rnd.random() 4 | if (0 <= u < p[0]): 5 | v = 0 6 | elif (p[0] <= u < sum(p[0:2])): 7 | v = 1 8 | elif (sum(p[0:2]) <= u < sum(p[0:3])): 9 | v = 2 10 | elif (sum(p[0:3]) <= u < sum(p[0:4])): 11 | v = 3 12 | else: 13 | v = 4 14 | print ('u = ' , u , ' , v = ' , v) -------------------------------------------------------------------------------- /ch09/lag_plot_non_random.py: -------------------------------------------------------------------------------- 1 | # The generated random sequence will fill the 2D space in a uniform fashion 2 | import numpy as np 3 | import pandas 4 | from pandas.tools.plotting import lag_plot 5 | import matplotlib.pyplot as plt 6 | s = pandas.Series(0.1 * np.random.rand(1000) + 0.9 * np.sin(np.linspace(-99 * np.pi, 99 * np.pi, num=1000))) 7 | plt.figure() 8 | lag_plot(s, marker='o', color='grey') 9 | plt.xlabel('s[i]') 10 | plt.ylabel('s[i+1]') 11 | plt.show() -------------------------------------------------------------------------------- /ch09/lag_plot_rng.py: -------------------------------------------------------------------------------- 1 | import random as rnd 2 | import pandas 3 | from pandas.tools.plotting import lag_plot 4 | import matplotlib.pyplot as plt 5 | s = pandas.Series([rnd.random() for i in range(10000)]) 6 | plt.figure() 7 | lag_plot(s, marker='o', color='grey') 8 | plt.xlabel('Random Number - s[i]') 9 | plt.ylabel('Lag1(Random Number) - s[i+1]') 10 | plt.show() -------------------------------------------------------------------------------- /ch09/spectral_test.py: -------------------------------------------------------------------------------- 1 | import math 2 | import matplotlib.pyplot as plt 3 | from mpl_toolkits.mplot3d import Axes3D 4 | a = 65539 5 | M = math.pow(2, 31) 6 | seed = 123456 7 | X = [] 8 | Y = [] 9 | Z = [] 10 | for i in range(10000): 11 | num1 = math.fmod(a * seed, M) 12 | num2 = math.fmod(a * num1, M) 13 | num3 = math.fmod(a * num2, M) 14 | seed = num2 15 | X.append(num1) 16 | Y.append(num2) 17 | Z.append(num3) 18 | fig = plt.figure() 19 | ax = fig.add_subplot(111, projection='3d') 20 | ax.scatter(X, Y, Z, c='b', marker='o') 21 | # Remove axis ticks for readability 22 | ax.set_xticks([]) 23 | ax.set_yticks([]) 24 | ax.set_zticks([]) 25 | ax.set_xlabel('X') 26 | ax.set_ylabel('Y') 27 | ax.set_zlabel('Z') 28 | plt.show() -------------------------------------------------------------------------------- /ch09/uniform_stat_test.py: -------------------------------------------------------------------------------- 1 | from random import * 2 | from statistics import * 3 | 4 | N = 10000 5 | data = [random() for i in range(N)] 6 | 7 | corr = 0 8 | for i in range(N-1): 9 | corr = corr + data[i]*data[i+1] 10 | corr = corr / N 11 | 12 | print("Mean = ", mean(data)) 13 | print("Variance = ", variance(data)) 14 | print("Autocorrelation = ", corr) -------------------------------------------------------------------------------- /ch10/antithetic_01.py: -------------------------------------------------------------------------------- 1 | from random import * 2 | from statistics import * 3 | 4 | n = 1000 5 | a = 2 6 | b = 48 7 | 8 | s = [] # Samples generated using the crude Monte Carlo method 9 | s_ = [] # Samples generated using the antithetic method 10 | 11 | for i in range(n): 12 | v = uniform(a, b) 13 | s.append(v) 14 | v_ = a + b - v 15 | s_.append( (v + v_) / 2 ) 16 | 17 | print('Mean(s) = ', round(mean(s), 4)) # 24.975 18 | print('Var(s) = ', round(variance(s), 4)) # 180.4049 19 | print('Mean(s_) = ', round(mean(s_), 4)) # 25.0 20 | print('Var(s_) = ', round(variance(s_), 4)) # 0.0 -------------------------------------------------------------------------------- /ch10/antithetic_02.py: -------------------------------------------------------------------------------- 1 | from random import * 2 | from statistics import * 3 | from math import * 4 | 5 | n = 10000 6 | 7 | Z = [] 8 | Z_ = [] 9 | 10 | for i in range(n): 11 | u = random() 12 | u_ = 1 - u 13 | Z.append( exp(u**2) ) 14 | Z_.append( ( exp(u**2) + exp(u_**2) ) / 2) 15 | 16 | print("Mean(Z) = ",round(mean(Z), 4)) # 1.4592 17 | print("Var(Z) = ",round(variance(Z), 4)) # 0.2241 18 | print("Mean(Z_) = ",round(mean(Z_), 4)) # 1.4631 19 | print("Var(Z_) = ",round(variance(Z_), 4)) # 0.0281 20 | -------------------------------------------------------------------------------- /ch10/buffon.py: -------------------------------------------------------------------------------- 1 | from random import * 2 | from math import * 3 | l = 1 4 | d = 1 5 | n = 1000000 6 | count = 0 7 | for i in range(n): 8 | a = uniform(0, d/2) 9 | phi = uniform(0, pi) 10 | b = (l/2)*sin(phi) 11 | if b >= a: 12 | count = count + 1 13 | print('P = ', round(count/n, 3)) 14 | print('Exact = ', round((2*l)/(pi*d), 3)) 15 | -------------------------------------------------------------------------------- /ch10/estimate_integral.py: -------------------------------------------------------------------------------- 1 | from random import * 2 | from statistics import * 3 | 4 | # Specify parameters 5 | a = 1 6 | b = 8 7 | N = 100000 8 | 9 | # Integrand 10 | def f(x): 11 | return x**2 12 | 13 | # Find value of c 14 | c = f(b) 15 | 16 | # Area of rectangle 17 | A_J = (b-a) * c 18 | 19 | Z = [0]*N 20 | for i in range(N): 21 | x = uniform(a, b) 22 | y = uniform(0, c) 23 | if y <= f(x): 24 | Z[i] = 1 25 | 26 | A_I = mean(Z) * A_J 27 | 28 | print("A_I = ", round(A_I, 2)) # = 169.57 (170.33) 29 | print("Variance = ", round(variance(Z), 4)) # = 0.2352 -------------------------------------------------------------------------------- /ch10/estimate_pi.py: -------------------------------------------------------------------------------- 1 | from random import * 2 | from statistics import * 3 | 4 | N = 100000 5 | 6 | Z = [] 7 | for i in range(N): 8 | x = uniform(-1, 1) 9 | y = uniform(-1, 1) 10 | if x**2 + y**2 <= 1: 11 | Z.append(1) 12 | else: 13 | Z.append(0) 14 | 15 | print ("Pi = ", 4.0 * round(mean(Z), 4)) # = 3.1452 16 | print ("Variance = ", round(variance(Z), 4)) # = 0.1681 -------------------------------------------------------------------------------- /ch10/importance_sampling.py: -------------------------------------------------------------------------------- 1 | from random import * 2 | N = 100000 3 | E_g = 0 4 | def g(x): 5 | return 8*x 6 | for i in range(N): 7 | x = random() # Sample from p(x) 8 | y = normalvariate(0, 10) # Sample from q(x) 9 | w = x/y # Importance weight for current sample 10 | E_g = E_g + g(y) * w 11 | print("E[g(x)] = ", round(E_g / N, 2)) # Answer = 4.0 -------------------------------------------------------------------------------- /ch10/reliability.py: -------------------------------------------------------------------------------- 1 | from random import * 2 | 3 | Num_Trials = 100000 4 | count = 0 5 | p = 0.7 #Probability a block is working 6 | 7 | def Phi(X): 8 | if sum(X) == 3: 9 | return 1 10 | else: 11 | return 0 12 | 13 | for i in range(Num_Trials): 14 | X = [] 15 | for j in range(3): 16 | if random() <= p: X.append(1) 17 | else: X.append(0) 18 | count = count + Phi(X) 19 | 20 | print('Rel_sys = ', round(count / Num_Trials, 3)) -------------------------------------------------------------------------------- /ch11/compute_ci.py: -------------------------------------------------------------------------------- 1 | import statistics as stat 2 | import math 3 | sample_set = [3.2, 3, 2.8, 2.9, 3.1] 4 | n = 5 5 | mean = stat.mean(sample_set) 6 | std_dev = stat.stdev(sample_set) 7 | t = 2.776 8 | ci1 = mean - t * (std_dev/math.sqrt(n)) 9 | ci2 = mean + t * (std_dev/math.sqrt(n)) 10 | print("Confidence Interval: ", round(ci1, 2), round(ci2, 2)) -------------------------------------------------------------------------------- /ch11/plot_ci.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as plt 3 | x = [1, 2, 3, 4, 5, 6, 7] 4 | y = [17, 7, 14, 18, 12, 22, 13] 5 | plt.figure() 6 | plt.plot([0, 7], [15, 15], 'k-', lw=2) # Population Mean = 15 7 | plt.errorbar(x, y, yerr=4, fmt='.') 8 | plt.xlabel("Confidence Intervals") 9 | plt.ylabel("Sample Means") 10 | plt.show() -------------------------------------------------------------------------------- /ch11/single_server.py: -------------------------------------------------------------------------------- 1 | import random as rnd 2 | import statistics as stat 3 | import matplotlib.pyplot as plt 4 | import numpy as np 5 | import math 6 | 7 | Avg_IAT = 1.0 # Average Inter-Arrival Time 8 | Avg_ST = 0.5 # Average Service Time 9 | Num_Sim_Pkts = 1000 # Number of Simulated Packets 10 | Infinity = math.inf # A very large Number 11 | 12 | N = 0.0 # Number of customers in the system 13 | clock = 0.0 # Current Simulation Time 14 | count = 0 # Count Packets 15 | R = 10 # Number of simulation runs (i.e., replications) 16 | 17 | Arr_Time = 0.0 # Time of the next arrival event 18 | Dep_Time = Infinity # Time of the next departure event 19 | 20 | Arr_Time_Out_Var = [] # Output variable for collecting arrival times 21 | Dep_Time_Out_Var = [] # Output variable for collecting departure times 22 | 23 | Delay = np.zeros( (R, Num_Sim_Pkts) ) 24 | 25 | for r in range(R): 26 | while count < Num_Sim_Pkts: 27 | if Arr_Time < Dep_Time: # Arrival Event 28 | clock = Arr_Time 29 | Arr_Time_Out_Var.append(clock) 30 | N = N + 1.0 31 | Arr_Time = clock + rnd.expovariate(1.0/Avg_IAT) 32 | if N == 1: 33 | Dep_Time = clock + rnd.expovariate(1.0/Avg_ST) 34 | else: # Departure Event 35 | clock = Dep_Time 36 | Dep_Time_Out_Var.append(clock) 37 | N = N - 1.0 38 | count = count + 1 # Packet Simulated 39 | if N > 0: 40 | Dep_Time = clock + rnd.expovariate(1.0/Avg_ST) 41 | else: 42 | Dep_Time = Infinity 43 | 44 | for i in range(Num_Sim_Pkts): 45 | d = Dep_Time_Out_Var[i] - Arr_Time_Out_Var[i] 46 | Delay[r, i] = d 47 | 48 | # Initialize for next simulation run 49 | Arr_Time = 0.0 50 | Dep_Time = Infinity 51 | N = 0.0 52 | clock = 0.0 53 | count = 0 54 | Arr_Time_Out_Var = [] 55 | Dep_Time_Out_Var = [] 56 | #------------------------------------------------------------ 57 | # Ensemble Average 58 | Mean = [] 59 | for i in range(Num_Sim_Pkts): 60 | Mean.append(sum(Delay[:,i]) / R) 61 | 62 | # Cumulative Ensemble Average 63 | Cum_Ens_Avg = [] 64 | for i in range(Num_Sim_Pkts): 65 | s = i + 1 # Slice 66 | Cum_Ens_Avg.append( sum(Mean[0:s]) / s ) 67 | 68 | # Cumulative Delay from a Single Simulation Run 69 | Cum_Delay = [] 70 | for i in range(Num_Sim_Pkts): 71 | s = i + 1 # Slice 72 | Cum_Delay.append( sum(Delay[0,0:s]) / s ) 73 | #----------------------------------------------------------- 74 | x = [i for i in range(1, Num_Sim_Pkts+1)] 75 | #plt.plot(x, Delay[0,:]) 76 | plt.plot(x, Cum_Delay, label="Cum_Delay") 77 | #plt.plot(x, Cum_Ens_Avg, label="Cum_Ens_Avg") 78 | plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3, 79 | ncol=2, mode="expand", borderaxespad=0.) 80 | plt.show() -------------------------------------------------------------------------------- /ch11/trunc_point.py: -------------------------------------------------------------------------------- 1 | import random as rnd 2 | import statistics as stat 3 | import matplotlib.pyplot as plt 4 | import numpy as np 5 | import math 6 | 7 | Avg_IAT = 1.0 # Average Inter-Arrival Time 8 | Avg_ST = 0.5 # Average Service Time 9 | Num_Sim_Pkts = 10000 # Number of Simulated Packets 10 | Infinity = math.inf # A very large Number 11 | 12 | N = 0.0 # Number of customers in the system 13 | clock = 0.0 # Current Simulation Time 14 | count = 0 # Count Packets 15 | R = 5 # Number of simulation runs (i.e., replications) 16 | 17 | Arr_Time = 0.0 # Time of the next arrival event 18 | Dep_Time = Infinity # Time of the next departure event 19 | 20 | Arr_Time_Out_Var = [] # Output variable for collecting arrival times 21 | Dep_Time_Out_Var = [] # Output variable for collecting departure times 22 | 23 | Delay = np.zeros( (R, Num_Sim_Pkts) ) 24 | 25 | for r in range(R): 26 | while count < Num_Sim_Pkts: 27 | if Arr_Time < Dep_Time: # Arrival Event 28 | clock = Arr_Time 29 | Arr_Time_Out_Var.append(clock) 30 | N = N + 1.0 31 | Arr_Time = clock + rnd.expovariate(1.0/Avg_IAT) 32 | if N == 1: 33 | Dep_Time = clock + rnd.expovariate(1.0/Avg_ST) 34 | else: # Departure Event 35 | clock = Dep_Time 36 | Dep_Time_Out_Var.append(clock) 37 | N = N - 1.0 38 | count = count + 1 # Packet Simulated 39 | if N > 0: 40 | Dep_Time = clock + rnd.expovariate(1.0/Avg_ST) 41 | else: 42 | Dep_Time = Infinity 43 | 44 | for i in range(Num_Sim_Pkts): 45 | d = Dep_Time_Out_Var[i] - Arr_Time_Out_Var[i] 46 | Delay[r, i] = d 47 | 48 | # Initialize for next simulation run 49 | Arr_Time = 0.0 50 | Dep_Time = Infinity 51 | N = 0.0 52 | clock = 0.0 53 | count = 0 54 | Arr_Time_Out_Var = [] 55 | Dep_Time_Out_Var = [] 56 | #------------------------------------------------------------ 57 | # Average 58 | Z = [] 59 | 60 | for i in range(Num_Sim_Pkts): 61 | Z.append( sum(Delay[:,i]) / R ) 62 | #----------------------------------------------------------- 63 | # Moving Average 64 | H = [] 65 | 66 | H.append(Z[0]) 67 | 68 | for i in range(Num_Sim_Pkts): 69 | j = i + 1 70 | H.append( sum(Z[0:j]) / j ) 71 | #----------------------------------------------------------- 72 | # Statistics 73 | print('Mean of the Untruncated Sequence: ', stat.mean(H)) 74 | print('Mean of the Truncated Sequence: ', stat.mean(H[4000:6000])) 75 | #----------------------------------------------------------- 76 | x1 = [i for i in range(len(H))] 77 | plt.plot(x1, H, label="H") 78 | plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3, ncol=2, mode="expand", borderaxespad=0.) 79 | plt.show() -------------------------------------------------------------------------------- /ch12/CN/stop_wait_arq.py: -------------------------------------------------------------------------------- 1 | import random as rnd 2 | import queue 3 | import statistics as stat 4 | 5 | # Define a dictionary to hold the simulation parameters 6 | param = {'Timeout_Duration': 1, 7 | 'P' : 0.2, # Frame Error Rate (FER) 8 | 'Frame_Trans_Time': 1, # Frame transmission time 9 | 'Num_Frames': 3 10 | } 11 | 12 | #-------------- Global Variables -------------- 13 | Frames_Received = 0.0 14 | Count_Frames = 0.0 15 | clock = 0.0 16 | evList = queue.PriorityQueue() 17 | 18 | #-------------- Event Generators -------------- 19 | # REG for the sender start event 20 | def sender_start_event (clock, param): 21 | ev = (clock, "sender_start", sender_start_event_handler) 22 | return ev 23 | 24 | # REG for the receiver start event 25 | def receiver_start_event (clock, param): 26 | ev = (clock, "receiver_start", 27 | receiver_start_event_handler) 28 | return ev 29 | 30 | # REG for the frame transmission event 31 | def frame_trans_event (clock, param): 32 | global Count_Frames 33 | if(Count_Frames < param['Num_Frames']): 34 | Count_Frames += 1 35 | ev = (clock, "transmission", 36 | frame_trans_event_handler) 37 | return ev 38 | 39 | # REG for the timeout event 40 | def timeout_event (clock, param): 41 | t = param['Timeout_Duration'] 42 | ev = (clock+t, "timeout", timeout_event_handler) 43 | return ev 44 | 45 | # REG for the frame reception event 46 | def frame_reception_event (clock, param): 47 | t = param['Frame_Trans_Time'] 48 | ev = (clock+t, "reception", 49 | frame_reception_event_handler) 50 | return ev 51 | 52 | # REG for the acknowledgement event 53 | def ack_event (clock, param): 54 | ev = (clock, "ack", ack_reception_event_handler) 55 | return ev 56 | 57 | #-------------- Event Handlers -------------- 58 | # Event handler for the sender start event 59 | def sender_start_event_handler (clock, param): 60 | global Count_Frames 61 | Count_Frames = 0.0 62 | # Schedule the first frame transmission event 63 | schedule_event( frame_trans_event (clock, param) ) 64 | 65 | # Event handler for the receiver start event 66 | def receiver_start_event_handler (clock, param): 67 | global Frames_Received 68 | Frames_Received = 0.0 69 | 70 | # Event handler for the frame transmission event 71 | def frame_trans_event_handler (clock, param): 72 | # Generate a frame reception event if frame is going 73 | # to be succefully received 74 | if rnd.random() <= param['P']: 75 | # Frame is damaged. Generate a timeout event 76 | schedule_event( timeout_event (clock, param) ) 77 | else: 78 | # Frame is successfully delivered 79 | schedule_event( 80 | frame_reception_event (clock, param) ) 81 | 82 | # Event handler for the frame reception event 83 | def frame_reception_event_handler (clock, param): 84 | global Frames_Received 85 | Frames_Received += 1 86 | schedule_event( ack_event (clock, param) ) 87 | 88 | # Event handler for the ack event 89 | def ack_reception_event_handler (clock, param): 90 | schedule_event( frame_trans_event (clock, param) ) 91 | 92 | # Event handler for the timeout event 93 | def timeout_event_handler (clock, param): 94 | global Count_Frames 95 | # Re-transmit the frame again 96 | Count_Frames = Count_Frames - 1; 97 | schedule_event( frame_trans_event (clock, param) ) 98 | 99 | # Insert an event into the event list 100 | def schedule_event(ev): 101 | global evList 102 | if ev != None: 103 | evList.put(ev) 104 | 105 | #----- Start Simulation ----- 106 | 107 | # 1. Initialize sender and receiver 108 | schedule_event( sender_start_event (clock, param) ) 109 | schedule_event( receiver_start_event (clock, param) ) 110 | 111 | # 2. Run the simulation loop 112 | while not evList.empty(): 113 | ev = evList.get() 114 | print(ev) 115 | clock = ev[0] 116 | ev[2](clock, param) -------------------------------------------------------------------------------- /ch12/CN/switch.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yosais/Computer-Simulation-Book/87b2d83eded02f69cd7b8d839adfa554b25ae19d/ch12/CN/switch.py -------------------------------------------------------------------------------- /ch12/MC_All_Paths/all_paths_12_nodes.py: -------------------------------------------------------------------------------- 1 | import timeit 2 | 3 | def find_all_paths(graph, start, end, path=[]): 4 | path = path + [start] 5 | if start == end: 6 | return [path] 7 | # if start not in graph: 8 | # return [] 9 | paths = [] 10 | for node in graph[start]: 11 | if node not in path: 12 | newpaths = find_all_paths(graph, node, end, path) 13 | for newpath in newpaths: 14 | paths.append(newpath) 15 | return paths 16 | 17 | 18 | graph = { 19 | "1": ("2","3","4","5","6","7","9","10","11","12"), 20 | "2": ("1","3","4","5","6","7","8","9","10","11","12"), 21 | "3": ("1","2","4","5","6","7","8","9","11","12"), 22 | "4": ("1","2","3","5","6","7","8","9","10","12"), 23 | "5": ("1","2","3","6","7","8","10","11","12"), 24 | "6": ("1","2","3","4","5","7","8","9","10","11"), 25 | "7": ("1","2","3","4","5","6","8","9","10","11","12"), 26 | "8": ("1","2","3","4","5","6","7","9","10","11","12"), 27 | "9": ("1","2","3","4","5","6","7","8","10","11","12"), 28 | "10": ("1","2","3","4","5","6","7","8","9","11"), 29 | "11": ("1","2","3","4","5","6","7","8","9","10","12"), 30 | "12": ("1","2","3","4","5","6","7","8","9","10","11"), 31 | } 32 | 33 | start = timeit.default_timer() 34 | 35 | paths = find_all_paths(graph, "1", "12") 36 | 37 | stop = timeit.default_timer() 38 | 39 | print("Number of Paths = ", len(paths)) 40 | 41 | print("Runtime = ", round(stop - start, 2), " seconds") 42 | -------------------------------------------------------------------------------- /ch12/MC_All_Paths/all_paths_16_nodes.py: -------------------------------------------------------------------------------- 1 | def find_all_paths(graph, start, end, path=[]): 2 | path = path + [start] 3 | if start == end: 4 | return [path] 5 | # if start not in graph: 6 | # return [] 7 | paths = [] 8 | for node in graph[start]: 9 | if node not in path: 10 | newpaths = find_all_paths(graph, node, end, path) 11 | for newpath in newpaths: 12 | paths.append(newpath) 13 | return paths 14 | 15 | 16 | graph = { 17 | "1": ("2", "3", "6", "9"), 18 | "2": ("3", "4", "8", "9", "12", "14", "15", "16"), 19 | "3": ("1", "10", "11", "16"), 20 | "4": ("1", "2", "5", "6", "7", "8", "10", "11", "13", "16"), 21 | "5": ("2", "7", "10", "11", "15"), 22 | "6": ("1", "9", "12"), 23 | "7": ("4", "6", "9", "14", "16"), 24 | "8": ("1", "9", "10", "11", "14"), 25 | "9": ("1", "2", "5", "11", "14"), 26 | "10": ("1", "2", "5", "6", "9", "13", "15"), 27 | "11": ("3", "4", "5", "6", "8", "11", "13", "14", "16"), 28 | "12": ("3", "10", "16"), 29 | "13": ("1", "2", "5", "6", "14"), 30 | "14": ("3", "5", "6", "7", "9", "12", "15"), 31 | "15": ("1", "12", "13", "16"), 32 | "16": ("1", "2", "4", "8", "11"), 33 | } 34 | 35 | paths = find_all_paths(graph, "1", "16") 36 | 37 | print("Number of Paths = ", len(paths)) 38 | -------------------------------------------------------------------------------- /ch12/MC_All_Paths/all_paths_20_nodes.py: -------------------------------------------------------------------------------- 1 | def find_all_paths(graph, start, end, path=[]): 2 | path = path + [start] 3 | if start == end: 4 | return [path] 5 | # if start not in graph: 6 | # return [] 7 | paths = [] 8 | for node in graph[start]: 9 | if node not in path: 10 | newpaths = find_all_paths(graph, node, end, path) 11 | for newpath in newpaths: 12 | paths.append(newpath) 13 | return paths 14 | 15 | 16 | graph = { 17 | "1": ("2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "19"), 18 | "2": ("1", "3", "4", "6", "7", "8", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"), 19 | "3": ("1", "2", "5", "7", "8", "9", "11", "12", "13", "14", "15", "16", "17", "19", "20"), 20 | "4": ("1", "2", "5", "6", "7", "8", "10", "11", "12", "14", "15", "17", "18", "19", "20"), 21 | "5": ("1", "3", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"), 22 | "6": ("1", "2", "4", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"), 23 | "7": ("1", "2", "3", "4", "6", "8", "9", "10", "11", "12", "13", "16", "17", "18", "19", "20"), 24 | "8": ("1", "2", "3", "4", "5", "6", "7", "9", "10", "11", "12", "13", "14", "15", "17", "18", "19", "20"), 25 | "9": ("1", "3", "5", "6", "7", "8", "10", "11", "12", "13", "14", "15", "16", "17", "19", "20"), 26 | "10": ("1", "2", "4", "5", "6", "7", "8", "9", "11", "12", "13", "16", "17", "18", "19", "20"), 27 | "11": ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "13", "15", "16", "17", "18", "20"), 28 | "12": ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "14", "15", "16", "18", "19", "20"), 29 | "13": ("1", "2", "3", "5", "6", "7", "8", "9", "10", "11", "14", "15", "16", "17", "18", "19"), 30 | "14": ("1", "2", "3", "4", "5", "6", "8", "9", "12", "13", "15", "16", "17", "18", "19"), 31 | "15": ("1", "2", "3", "4", "5", "6", "8", "9", "11", "12", "13", "14", "16", "17", "18", "19"), 32 | "16": ("1", "2", "3", "5", "6", "7", "9", "10", "11", "12", "13", "14", "15", "17", "18", "19"), 33 | "17": ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "13", "14", "15", "16", "18", "19", "20"), 34 | "18": ("2", "3", "5", "6", "7", "8", "10", "11", "12", "13", "14", "15", "16", "17", "19", "20"), 35 | "19": ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "12", "13", "14", "15", "16", "17", "18", "20"), 36 | "20": ("1", "5", "6", "7", "8", "9", "10", "11", "12", "17", "18", "19"), 37 | } 38 | 39 | paths = find_all_paths(graph, "1", "20") 40 | 41 | print("Number of Paths = ", len(paths)) 42 | -------------------------------------------------------------------------------- /ch12/MC_All_Paths/all_paths_5_nodes.py: -------------------------------------------------------------------------------- 1 | def find_all_paths(graph, start, end, path=[]): 2 | path = path + [start] 3 | if start == end: 4 | return [path] 5 | # if start not in graph: 6 | # return [] 7 | paths = [] 8 | for node in graph[start]: 9 | if node not in path: 10 | newpaths = find_all_paths(graph, node, end, path) 11 | for newpath in newpaths: 12 | paths.append(newpath) 13 | return paths 14 | 15 | 16 | graph = { 17 | "1": ("2", "4"), 18 | "2": ("1", "4", "5"), 19 | "3": ("4", "5"), 20 | "4": ("1", "2", "3"), 21 | "5": ("2", "3"), 22 | } 23 | 24 | paths = find_all_paths(graph, "1", "5") 25 | 26 | print("Number of Paths = ", len(paths)) 27 | 28 | for path in paths: 29 | print(path) 30 | -------------------------------------------------------------------------------- /ch12/MC_All_Paths/all_paths_8_nodes.py: -------------------------------------------------------------------------------- 1 | def find_all_paths(graph, start, end, path=[]): 2 | path = path + [start] 3 | if start == end: 4 | return [path] 5 | # if start not in graph: 6 | # return [] 7 | paths = [] 8 | for node in graph[start]: 9 | if node not in path: 10 | newpaths = find_all_paths(graph, node, end, path) 11 | for newpath in newpaths: 12 | paths.append(newpath) 13 | return paths 14 | 15 | 16 | graph = { 17 | "1": ("2", "3", "4", "6", "7", "8"), 18 | "2": ("1", "5", "6", "7"), 19 | "3": ("1", "4", "5", "6", "7", "8"), 20 | "4": ("1", "3", "5", "6", "7", "8"), 21 | "5": ("2", "3", "4", "6"), 22 | "6": ("1", "2", "3", "4", "5", "7", "8"), 23 | "7": ("1", "2", "3", "4", "6", "8"), 24 | "8": ("1", "3", "4", "6", "7"), 25 | } 26 | 27 | paths = find_all_paths(graph, "1", "8") 28 | 29 | print("Number of Paths = ", len(paths)) 30 | 31 | -------------------------------------------------------------------------------- /ch12/MC_All_Paths/mc.py: -------------------------------------------------------------------------------- 1 | from copy import deepcopy 2 | import random as rnd 3 | 4 | def update_adj_matrix(AdjMat, current): 5 | for node in AdjMat: 6 | neighbors = AdjMat[node] 7 | new_neighbors = () 8 | for n in neighbors: 9 | if n != current: 10 | new_neighbors = new_neighbors + (n,) 11 | AdjMat[node] = new_neighbors 12 | return AdjMat 13 | 14 | 15 | def monte_carlo(source, destination, AdjMat, N): 16 | paths = [] 17 | for i in range(N): 18 | # Clone the AdjMat 19 | _AdjMat = deepcopy(AdjMat) 20 | 21 | x = [source] 22 | g = 1 23 | current = source 24 | 25 | # Remove current from being a potential next node 26 | update_adj_matrix(_AdjMat, current) 27 | 28 | while current != destination: 29 | # Get set of possible next nodes 30 | V = _AdjMat[current] 31 | 32 | # Check if V is empty 33 | if len(V) == 0: break 34 | 35 | # Choose next node 36 | next = rnd.choice(V) 37 | x.append(next) 38 | 39 | # Step 5 40 | current = next 41 | update_adj_matrix(_AdjMat, current) 42 | g = g / len(V) 43 | 44 | # Store the path and its g 45 | if x[ len(x)-1 ] == destination: 46 | paths.append((x, g)) 47 | 48 | return paths 49 | 50 | 51 | graph = { 52 | "1": ("2", "3", "4", "6", "7", "8"), 53 | "2": ("1", "5", "6", "7"), 54 | "3": ("1", "4", "5", "6", "7", "8"), 55 | "4": ("1", "3", "5", "6", "7", "8"), 56 | "5": ("2", "3", "4", "6"), 57 | "6": ("1", "2", "3", "4", "5", "7", "8"), 58 | "7": ("1", "2", "3", "4", "6", "8"), 59 | "8": ("1", "3", "4", "6", "7"), 60 | } 61 | 62 | 63 | paths = monte_carlo("1", "8", graph, 10) 64 | 65 | estimate = 0 66 | for (path, g) in paths: 67 | estimate = estimate + 1/g 68 | print(path, " -> ", g) 69 | 70 | estimate = estimate / len(paths) 71 | 72 | print("\nEstimate = ", round(estimate, 2)) -------------------------------------------------------------------------------- /ch12/Reliability/prog01.py: -------------------------------------------------------------------------------- 1 | q = 0.5 2 | Unreliability = q**4 + 4 * (1-q) * q**3 + 4 * (1-q)**2 * q**2 3 | print("Unreliability = ", round(Unreliability, 10)) -------------------------------------------------------------------------------- /ch12/Reliability/prog02.py: -------------------------------------------------------------------------------- 1 | from random import * 2 | from statistics import * 3 | 4 | q = 0.5 # Prob. of link failure 5 | N = 100000 # Number of trials 6 | L = 4 # Number of links 7 | 8 | # Check if network is connected 9 | def Phi(s): 10 | if s[0] == 0 and s[1] == 0 or s[0] == 0 and s[2] == 0 or \ 11 | s[1] == 0 and s[3] == 0 or s[2] == 0 and s[3] == 0: 12 | return 1 13 | else: 14 | return 0 15 | 16 | # Crude Monte Carlo simulation 17 | rv = [] # Realization of a Bernoulli random variable 18 | for i in range(N): 19 | s = [0]*L 20 | for j in range(L): 21 | if random() > q: 22 | s[j] = 1 23 | rv.append(Phi(s)) 24 | 25 | # Result 26 | print("Unreliability = ", round(mean(rv), 4)) 27 | print("Variance = ", round(variance(rv), 4)) -------------------------------------------------------------------------------- /ch12/Reliability/prog03_antithetic.py: -------------------------------------------------------------------------------- 1 | from random import * 2 | from statistics import * 3 | 4 | q = 0.5 # Prob. of link failure 5 | N = 100000 # Number of trials 6 | L = 4 # Number of links 7 | 8 | # Check if network is connected 9 | def Phi(s): 10 | if s[0] == 0 and s[1] == 0 or s[0] == 0 and s[2] == 0 or \ 11 | s[1] == 0 and s[3] == 0 or s[2] == 0 and s[3] == 0: 12 | return 1 13 | else: 14 | return 0 15 | 16 | # Antithetic Monte Carlo simulation 17 | rv = [] # Realization of a Bernoulli random variable 18 | for i in range(N): 19 | s1 = [0]*L 20 | s2 = [0]*L 21 | for j in range(L): 22 | u = random() 23 | if u > q: s1[j] = 1 24 | if (1 - u) > q: s2[j] = 1 25 | 26 | val = (Phi(s1) + Phi(s2) ) / 2 27 | rv.append(val) 28 | 29 | # Result 30 | print("Unreliability = ", round(mean(rv), 4)) 31 | print("Variance = ", round(variance(rv), 4)) -------------------------------------------------------------------------------- /ch12/Reliability/prog0x.py: -------------------------------------------------------------------------------- 1 | from random import * 2 | from statistics import * 3 | from math import * 4 | 5 | q = 0.0001 # Prob. of link failure 6 | L = 4 # Number of links 7 | N = 100000 # Number of trials in each replication 8 | M = 35 # Number of replications 9 | 10 | # Check if network is connected 11 | def Phi(s): 12 | if s[0] == 0 and s[1] == 0 or s[0] == 0 and s[2] == 0 or \ 13 | s[1] == 0 and s[3] == 0 or s[2] == 0 and s[3] == 0: 14 | return 1 15 | else: 16 | return 0 17 | 18 | u = [] 19 | for k in range(M): 20 | # Crude Monte Carlo simulation 21 | count = 0 22 | for i in range(N): 23 | s = [0]*L 24 | for j in range(L): 25 | if random() > q: 26 | s[j] = 1 27 | if Phi(s) == 1: 28 | count = count + 1 29 | u.append(count/N) 30 | 31 | # Compute half width confidence interval 32 | mean = mean(u) 33 | std_dev = stdev(u) 34 | t = 1.96 35 | 36 | ci = t * (std_dev / sqrt(M)) 37 | 38 | print("Mean = ", mean) 39 | print("CI = ", ci / float(mean) ) --------------------------------------------------------------------------------