Thursday 25 October 2018

Data structure - Bubble sort & Big 0 Notation definition

Bubble Sort is a simple algorithm which is used to sort a given set of n elements provided in form of an array with n number of elements. 


Implementing Bubble Sort Algorithm

Following are the steps involved in bubble sort(for sorting a given array in ascending order):
  1. Starting with the first element(index = 0), compare the current element with the next element of the array.
  2. If the current element is greater than the next element of the array, swap them.
  3. If the current element is less than the next element, move to the next element. Repeat Step 1.
  4. In step 3, if If we have total n elements, then we need to repeat this process for n-1 times.
  5. If we did 1st iteration last index is found and fixed, 2nd iternation n-2 times, 3rd iteration n-3 times.
  6. Hence formula is (n-1) + (n-2) + (n-3) + ..... + 3 + 2 + 1

Let's consider an array with values {5, 1, 6, 2, 4, 3}
Below, we have a pictorial representation of how bubble sort will sort the given array.
Bubble sort algorithm
So as we can see in the representation above, after the first iteration, 6 is placed at the last index, which is the correct position for it.
Similarly after the second iteration, 5 will be at the second last index, and so on.
Time to write the code for bubble sort:
/ below we have a simple C program for bubble sort
#include <stdio.h>

void bubbleSort(int arr[], int n)
{
    int i, j, temp;
    for(i = 0; i < n; i++)
    {
        for(j = 0; j < n-i-1; j++)
        {
            if( arr[j] > arr[j+1])
            {
                // swap the elements
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            } 
        }
    }
    
    // print the sorted array
    printf("Sorted Array: ");
    for(i = 0; i < n; i++)
    {
        printf("%d  ", arr[i]);
    }
}

int main()
{
    int arr[100], i, n, step, temp;
    // ask user for number of elements to be sorted
    printf("Enter the number of elements to be sorted: ");
    scanf("%d", &n);
    // input elements if the array
    for(i = 0; i < n; i++)
    {
        printf("Enter element no. %d: ", i+1);
        scanf("%d", &arr[i]);
    }
    // call the function bubbleSort
    bubbleSort(arr, n);
    
    return 0;
}

Above algorithm is not efficient because as per the above logic, the outer for loop will keep on executing for 6 iterations even if the array gets sorted after the second iteration.
So, we can clearly optimize our algorithm.

Optimized Bubble Sort Algorithm

To optimize our bubble sort algorithm, we can introduce a flag to monitor whether elements are getting swapped inside the inner for loop.

If for a particular iteration, no swapping took place, it means the array has been sorted and we can jump out of the for loop, instead of executing all the iterations.

Let's consider an array with values {11, 17, 18, 26, 23}
Below, we have a pictorial representation of how the optimized bubble sort will sort the given array.
Optimized Bubble sort algorithm
As we can see, in the first iteration, swapping took place, hence we updated our flag value to 1, as a result, the execution enters the for loop again. 
But in the second iteration, no swapping will occur,
hence the value of flag will remain 0, and execution will break out of loop.
// below we have a simple C program for bubble sort
#include <stdio.h>

void bubbleSort(int arr[], int n)
{
    int i, j, temp;
    for(i = 0; i < n; i++)
    {
        for(j = 0; j < n-i-1; j++)
        {
            // introducing a flag to monitor swapping
            int flag = 0;
            if( arr[j] > arr[j+1])
            {
                // swap the elements
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
                // if swapping happens update flag to 1
                flag = 1;
            } 
        }
        // if value of flag is zero after all the iterations of inner loop
        // then break out
        if(!flag)
        {
            break;
        }
    }
    
    // print the sorted array
    printf("Sorted Array: ");
    for(i = 0; i < n; i++)
    {
        printf("%d  ", arr[i]);
    }
}

int main()
{
    int arr[100], i, n, step, temp;
    // ask user for number of elements to be sorted
    printf("Enter the number of elements to be sorted: ");
    scanf("%d", &n);
    // input elements if the array
    for(i = 0; i < n; i++)
    {
        printf("Enter element no. %d: ", i+1);
        scanf("%d", &arr[i]);
    }
    // call the function bubbleSort
    bubbleSort(arr, n);
    
    return 0;
}
In the above code, in the function bubbleSort, if for a single complete cycle of j iteration(inner forloop), no swapping takes place, then flag will remain 0 and then we will break out of the for loops, because the array has already been sorted.

Complexity Analysis of Bubble Sort

In Bubble Sort, n-1 comparisons will be done in the 1st pass, n-2 in 2nd pass, n-3 in 3rd pass and so on. So the total number of comparisons will be,
(n-1) + (n-2) + (n-3) + ..... + 3 + 2 + 1 Sum = n(n-1)/2 i.e O(n2)
Hence the time complexity of Bubble Sort is O(n2).
The main advantage of Bubble Sort is the simplicity of the algorithm.
The space complexity for Bubble Sort is O(1), because only a single additional memory space is required i.e. for temp variable.
Also, the best case time complexity will be O(n), it is when the list is already sorted.
Following are the Time and Space complexity for the Bubble Sort algorithm.
  • Worst Case Time Complexity [ Big-O ]: O(n2)
  • Best Case Time Complexity [Big-omega]: O(n)
  • Average Time Complexity [Big-theta]: O(n2)
  • Space Complexity: O(1)

Others comment on Big 0, need to analyse, don't blindly take:

When calculating the Big-O complexity of an algorithm, the thing being shown is the factor that gives the largest contribution to the increase in execution time if the number of elements that you run the algorithm over increases.
If you have an algorithm with a complexity of (n^2 + n)/2 and you double the number of elements, then the constant 2 does not affect the increase in the execution time, the term n causes a doubling in the execution time and the term n^2 causes a four-fold increase in execution time.
As the n^2 term has the largest contribution, the Big-O complexity is O(n^2).

2nd person(ShadSterling) thought:

It's not that "(n² + n)/2 behaves like n² when n is large", it's that (n² + n)/2 grows like n² as n increases.
For example, as n increases from 1,000 to 1,000,000
(n² + n) / 2  increases from  500500 to  500000500000
(n²) / 2      increases from  500000 to  500000000000
(n²)          increases from 1000000 to 1000000000000
Similarly, as n increases from 1,000,000 to 1,000,000,000
(n² + n) / 2  increases from  500000500000 to  500000000500000000
(n²) / 2      increases from  500000000000 to  500000000000000000
(n²)          increases from 1000000000000 to 1000000000000000000
They grow similarly, which is what Big O Notation is about.
If you plot (n²+n)/2 and n²/2 on Wolfram Alpha, they are so similar that they're difficult to distinguish by n=100. If you plot all three on Wolfram Alpha, you see two lines separated by a constant factor of 2.

3rd Person thought:

use of an equal sign, which is not used here to denote the equality of functions.
As you know, this notation expresses an asymptotic comparisons of functions, and writing f = O(g)means that f(n) grows at most as fast as g(n) as n goes to infinity.
This is pretty much like saying that 2 = 5 mod 3 does not imply that 2 = 5 and if you are keen on algebra, you can actually understand the big O notation as an equality modulo something.

What is Big 0 from Rob Bell:



Big O notation is used in Computer Science to describe the performance or complexity of an algorithm. Big O specifically describes the worst-case scenario, and can be used to describe the execution time required or the space used (e.g. in memory or on disk) by an algorithm.
Anyone who's read Programming Pearls or any other Computer Science books and doesn’t have a grounding in Mathematics will have hit a wall when they reached chapters that mention O(N log N) or other seemingly crazy syntax. Hopefully this article will help you gain an understanding of the basics of Big O and Logarithms.
As a programmer first and a mathematician second (or maybe third or fourth) I found the best way to understand Big O thoroughly was to produce some examples in code. So, below are some common orders of growth along with descriptions and examples where possible.

O(1)

O(1) describes an algorithm that will always execute in the same time (or space) regardless of the size of the input data set.
bool IsFirstElementNull(IList<string> elements)
{
    return elements[0] == null;
}

O(N)

O(N) describes an algorithm whose performance will grow linearly and in direct proportion to the size of the input data set. The example below also demonstrates how Big O favours the worst-case performance scenario; a matching string could be found during any iteration of the for loop and the function would return early, but Big O notation will always assume the upper limit where the algorithm will perform the maximum number of iterations.
bool ContainsValue(IList<string> elements, string value)
{
    foreach (var element in elements)
    {
        if (element == value) return true;
    }

    return false;
}

O(N2)

O(N2) represents an algorithm whose performance is directly proportional to the square of the size of the input data set. This is common with algorithms that involve nested iterations over the data set. Deeper nested iterations will result in O(N3), O(N4) etc.
bool ContainsDuplicates(IList<string> elements)
{
    for (var outer = 0; outer < elements.Count; outer++)
    {
        for (var inner = 0; inner < elements.Count; inner++)
        {
            // Don't compare with self
            if (outer == inner) continue;

            if (elements[outer] == elements[inner]) return true;
        }
    }

    return false;
}

O(2N)

O(2N) denotes an algorithm whose growth doubles with each additon to the input data set. The growth curve of an O(2N) function is exponential - starting off very shallow, then rising meteorically. An example of an O(2N) function is the recursive calculation of Fibonacci numbers:
int Fibonacci(int number)
{
    if (number <= 1) return number;

    return Fibonacci(number - 2) + Fibonacci(number - 1);
}

Logarithms

Logarithms are slightly trickier to explain so I'll use a common example:

Binary search is a technique used to search sorted data sets. It works by selecting the middle element of the data set, essentially the median, and compares it against a target value. If the values match it will return success. If the target value is higher than the value of the probe element it will take the upper half of the data set and perform the same operation against it. Likewise, if the target value is lower than the value of the probe element it will perform the operation against the lower half. It will continue to halve the data set with each iteration until the value has been found or until it can no longer split the data set.

This type of algorithm is described as O(log N). The iterative halving of data sets described in the binary search example produces a growth curve that peaks at the beginning and slowly flattens out as the size of the data sets increase e.g. an input data set containing 10 items takes one second to complete, a data set containing 100 items takes two seconds, and a data set containing 1000 items will take three seconds. Doubling the size of the input data set has little effect on its growth as after a single iteration of the algorithm the data set will be halved and therefore on a par with an input data set half the size. This makes algorithms like binary search extremely efficient when dealing with large data sets.
This article only covers the very basics or Big O and logarithms. For a more in-depth explanation take a look at their respective Wikipedia entries: Big O NotationLogarithms.




Reference:
    https://www.studytonight.com/data-structures/bubble-sort
    Others thoughts:
            https://softwareengineering.stackexchange.com/questions/279609/big-o-question-about-an-algorithm-with-n2-n-2-growth-rate
    Rob Bell:
        https://rob-bell.net/2009/06/a-beginners-guide-to-big-o-notation/    


Monday 15 October 2018

snmp traps vs notification and pdu

This table gives the difference between the SNMPv1 and SNMPv2 traps.
SNMPv1 Trap and SNMPv2 Notification, notification is advance

TrapNotification
1. Contains agent address.
1. Does not contain agent address.
2. It has information about specific trap and generic trap value.
2. It has Trap OID in the second varbind.
3. It does not have error index and status.
3. It has error index and status.
4. Does not support confirmed trap.
4. Supports Confirmed Notification (INFORM).

 
SNMPv2 PDUs fixed this by introducing the notion of an INFORM, which is nothing more than an acknowledged TRAP.


SNMP Protocol data units (PDUs) 



PDU Type may be get, get next, set, trap










TC means TEXTUAL-CONVENTION

CISCO-SMI contain the first starting OID for cisco assigned by IANA.
----------------------snip ---------------------------
cisco MODULE-IDENTITY
LAST-UPDATED "9704090000Z"
ORGANIZATION "Cisco Systems, Inc."
CONTACT-INFO
" Cisco Systems
Customer Service

Postal: 170 West Tasman Drive
San Jose, CA  95134
USA

   Tel: +1 800 553-NETS

E-mail: cs-snmp@cisco.com"
DESCRIPTION
"The Structure of Management Information for the
Cisco enterprise."
REVISION      "9704090000Z"
DESCRIPTION
"Added ciscoPartnerProducts to generate sysObjectID
for partner platforms"

REVISION      "9505160000Z"
DESCRIPTION
"New oid assignments for Cisco REPEATER MIB and others."
REVISION      "9404262000Z"
DESCRIPTION
"Initial version of this MIB module."
::= { enterprises 9 } -- assigned by IANA


ciscoProducts OBJECT-IDENTITY
STATUS current
DESCRIPTION
"ciscoProducts is the root OBJECT IDENTIFIER from
which sysObjectID values are assigned.  Actual
values are defined in CISCO-PRODUCTS-MIB."
::= { cisco 1 }

local OBJECT-IDENTITY
STATUS current
DESCRIPTION
"Subtree beneath which pre-10.2 MIBS were built."
::= { cisco 2 }

temporary OBJECT-IDENTITY
STATUS current
DESCRIPTION
"Subtree beneath which pre-10.2 experiments were
placed."
::= { cisco 3 }
------------------------sniip---------------





TC MIB example 


----------------------- snip of TC MIB -----------------
CISCO-ENTITY-REDUNDANCY-TC-MIB DEFINITIONS ::= BEGIN

IMPORTS
     MODULE-IDENTITY            FROM SNMPv2-SMI
     TEXTUAL-CONVENTION         FROM SNMPv2-TC
     ciscoMgmt                  FROM CISCO-SMI
     ;

ciscoEntityRedunTcMIB MODULE-IDENTITY
    LAST-UPDATED    "200510010000Z"
    ORGANIZATION    "Cisco Systems, Inc."
    CONTACT-INFO
                    "Cisco Systems, Inc.
                     Customer Service
                     Postal: 170 W. Tasman Drive
                             San Jose, CA  95134-1706
                             USA
                     Tel: +1 800 553-NETS
                     Email: cs-ha@cisco.com"

    DESCRIPTION
        "This module defines the textual conventions used within
         Cisco Entity Redundancy MIBs.
         "
    REVISION      "200510010000Z"
    DESCRIPTION
         "The initial version of this MIB module."
    ::= { ciscoMgmt 494 }


-- Start of Textual Conventions
CeRedunType ::= TEXTUAL-CONVENTION
    STATUS       current
    DESCRIPTION
        "Defines the following group redundancy types:

         other(1)
           Indicates a type of redundancy which doesn't fall into
           any other listed category.

         yCable(2)
           A form of redundancy in which signals from a common line 
           are connected to ports on two redundant members using a 
           special Y-shaped splitter/combiner cable.  The receive 
           signals are split and fed to the receive ports on each 
           redundant member. The transmit signals are combined from 
           the transmit ports on each member. However, only the active
           redundant member transmits a signal, while the standby 
           member suppresses sending a signal into the Y-combiner.

         aps(3) 
           Automatic Protection Switching.  A form of redundancy 
           using redundant lines with one connected to the working 
           port on the primary member and the other connected to 
           the protection port on the secondary member.  APS 
           redundancy protects against line (or fiber) failures in 
           addition to protecting against port module hardware 
           failures.

         featureCard(4)
           The featureCard option is used when the module
           does not have external line interfaces. Examples are
           modules which provide packet processing, additional
           memory or even fans or power supplies.

         externalSwitch(5)
           A form of redundancy similar to yCable but using an
           external switch to select or direct the receive or 
           transmit signals from a common line to ports on 
           redundant members. Additional control (not provided in
           this general MIB) may be necessary in order to control
           and monitor the external switch.
         
         slotPair(6)
           Some platforms require the user to configure a slot-pair
           group in order to allow internal signals to be bridged to 
           redundant linecards in the slot-pair.  But redundancy groups
           would also need to be configured for contained entities, 
           such as ports. Switchovers should take place independently 
           for each contained entity (e.g. port).

           The slotPair groups support only basic group and member
           configuration including the primary/secondary designation.
           Switchovers may only be supported for the contained
           entity.  The primary/secondary roles of contained group 
           members must match the primary/secondary role of the 
           containing entity.
         
          cmts(7)
           redundancy is provided for Cable Modem Termination Systems.
        "
    SYNTAX      INTEGER {
                          other(1),
                          yCable(2),
                          aps(3),
                          featureCard(4),
                          externalSwitch(5),
                          slotPair(6),
                          cmts(7)
                        }


----------------------- snip of TC MIB -----------------


MIB example 

----------------------- snip of MIB -----------------
CISCO-ENTITY-REDUNDANCY-MIB DEFINITIONS ::= BEGIN

IMPORTS
     MODULE-IDENTITY, 
     NOTIFICATION-TYPE,
     OBJECT-TYPE,
     Gauge32, 
     Counter64, 
     Unsigned32,
     Integer32
                                    FROM SNMPv2-SMI
     RowStatus,
     TimeStamp,
     TruthValue,
     StorageType,
     AutonomousType
                                    FROM SNMPv2-TC
     SnmpAdminString
                                    FROM SNMP-FRAMEWORK-MIB
     PhysicalIndex
                                    FROM ENTITY-MIB
     InetAddressType,
     InetAddress
                                    FROM INET-ADDRESS-MIB
     MODULE-COMPLIANCE, 
     OBJECT-GROUP, 
     NOTIFICATION-GROUP
                                    FROM SNMPv2-CONF
     CeRedunType,
     CeRedunScope,
     CeRedunArch,
     CeRedunSwitchCommand,
     CeRedunMode,
     CeRedunMbrStatus,
     CeRedunStateCategories,
     CeRedunReasonCategories
                                    FROM CISCO-ENTITY-REDUNDANCY-TC-MIB
     ciscoMgmt                    
                                    FROM CISCO-SMI
     ;

ciscoEntityRedunMIB MODULE-IDENTITY
    LAST-UPDATED    "200510010000Z"
    ORGANIZATION    "Cisco Systems, Inc."
    CONTACT-INFO
                    "Cisco Systems, Inc.
                     Customer Service
                     Postal: 170 W. Tasman Drive
                             San Jose, CA  95134-1706
                             USA
                     Tel: +1 800 553-NETS
                     Email: cs-ha@cisco.com"

    DESCRIPTION
        "This management information module supports 
         configuration, control and monitoring of redundancy 
         protection for various kinds of components on 
         Cisco managed devices. 

         It is meant to be generic enough to handle basic 
         redundancy control and monitoring for many types of 
         redundant member components and redundancy architectures
         as long as there is an Entity MIB entPhysicalIndex and 
         entPhysicalVendorType assigned to each member component.

         It is designed so that the tables can be augmented in
         other extension MIBS which build upon this MIB by 
         adding additional objects that may be specific to a 
         particular type of redundancy or member component.

         This MIB can also be used in cases where some types of
         redundancy groups and members don't require explicit 
         user configuration. One example may be redundant fan
         assemblies. In those cases, the managed system should 
         internally assign group and member indexes, so that 
         it can provide read-only access to the group and member 
         tables. This allows MIB monitoring for these types of 
         redundant entities.
        "
    REVISION      "200510010000Z"
    DESCRIPTION
         "The initial version of this MIB module."
    ::= { ciscoMgmt 498 }

ciscoEntityRedunMIBNotifs OBJECT IDENTIFIER
    ::= { ciscoEntityRedunMIB 0 }

ciscoEntityRedunMIBObjects OBJECT IDENTIFIER
    ::= { ciscoEntityRedunMIB 1 }

ciscoEntityRedunMIBConform OBJECT IDENTIFIER
    ::= { ciscoEntityRedunMIB 2 }

--
-- Redundancy Group Tables
--
-- These tables allow managed systems to report information about 
-- the types of redundancy groups available on the reporting system.
-- They also allow configuration and monitoring of objects which
-- apply to each redundancy group.
--
ceRedunGroup   OBJECT IDENTIFIER ::= {ciscoEntityRedunMIBObjects 1 }

-- Redundancy Group Types Table
ceRedunGroupTypesTable OBJECT-TYPE
    SYNTAX      SEQUENCE OF CeRedunGroupTypesEntry
    MAX-ACCESS  not-accessible
    STATUS      current
    DESCRIPTION
        "This table lists the basic types of redundancy groups 
         supported on the managed device along with additional 
         information about each group type.
        "
    ::= {ceRedunGroup 1 }

ceRedunGroupTypesEntry OBJECT-TYPE
    SYNTAX      CeRedunGroupTypesEntry
    MAX-ACCESS   not-accessible
    STATUS       current
    DESCRIPTION
        "A conceptual row in the ceRedunGroupTypesTable."
    INDEX { ceRedunGroupTypeIndex }
    ::= {ceRedunGroupTypesTable 1 }

CeRedunGroupTypesEntry ::= SEQUENCE {
    ceRedunGroupTypeIndex              Unsigned32,
    ceRedunGroupTypeName               SnmpAdminString,
    ceRedunGroupCounts                 Gauge32,
    ceRedunNextUnusedGroupIndex        Unsigned32,
    ceRedunMaxMbrsInGroup              Unsigned32,
    ceRedunUsesGroupName               TruthValue,
    ceRedunGroupDefinitionChanged      TimeStamp
}

ceRedunGroupTypeIndex OBJECT-TYPE
    SYNTAX      Unsigned32
    MAX-ACCESS  not-accessible
    STATUS      current
    DESCRIPTION
        "An index assigned for each type of redundancy group supported 
         on a managed system that requires its own table listing 
         entPhysicalVendorTypes allowed as members for its groups.

         For instance, port groups have a different set of allowed
         entPhysicalVendorTypes than linecard groups. So each should 
         have a separate ceRedunGroupTypeIndex. 

         For this example, a command line interface may differentiate
         by using separate keywords (port-group versus linecard-group) 
         rather than exposing the ceRedunGroupTypeIndex to a user.
        "
    ::= { ceRedunGroupTypesEntry 1 }

ceRedunGroupTypeName OBJECT-TYPE
    SYNTAX      SnmpAdminString
    MAX-ACCESS  read-only
    STATUS      current
    DESCRIPTION
        "The textual name of the redundancy group type.  The value
         of this object should be the name of the redundancy group 
         type assigned by the local device as it would appear
         for display commands entered at the device's `console'.
         Examples are port-group, linecard-group, fan-group, etc.
        "
    ::= { ceRedunGroupTypesEntry 2 }

ceRedunGroupCounts OBJECT-TYPE
    SYNTAX      Gauge32
    MAX-ACCESS  read-only
    STATUS      current
    DESCRIPTION
        "The current count of redundancy groups for a specific 
         ceRedunGroupTypeIndex. This count indicates the number 
         of rows in the ceRedunGroupTable for a specific 
         ceRedunGroupTypeIndex.
        "
    ::= { ceRedunGroupTypesEntry 3 }

ceRedunNextUnusedGroupIndex OBJECT-TYPE
    SYNTAX      Unsigned32
    MAX-ACCESS  read-only
    STATUS      current
    DESCRIPTION
        "The next unused group index available for configuring 
         a new redundancy group for this group type.

         In order to avoid unnecessary collisions between competing 
         management stations, `adjacent' retrievals of this object 
         should give different index values. 
         
         But in order to prevent leaks of unused indexes, it is 
         acceptable to cycle through and report unused indexes again 
         if all of the indexes have already been retrieved previously, 
         yet some remain unused.  So the retrieval of an index 
         should not be considered a permanent longterm reservation.

         If there are no more unused group indexes available, the 
         managed system should return 0. 
         
         Note: 0 may be an acceptable group index on some 
         managed systems.
        "
    ::= { ceRedunGroupTypesEntry 4 }

ceRedunMaxMbrsInGroup OBJECT-TYPE
    SYNTAX      Unsigned32
    MAX-ACCESS  read-only
    STATUS      current
    DESCRIPTION
        "The maximum number of primary plus secondary members allowed
         in a group for a specific ceRedunGroupTypeIndex. If only
         1:1 or 1+1 is supported, this should be 2.

         If the maximum number is unknown or not determinable, the 
         managed system should return 0.
        "
    ::= { ceRedunGroupTypesEntry 5 }

ceRedunUsesGroupName OBJECT-TYPE
    SYNTAX      TruthValue
    MAX-ACCESS  read-only
    STATUS      current
    DESCRIPTION
        "Boolean to indicate whether this type of redundancy group 
         uses the ceRedunGroupString object as a group name 
         identifier. If it is reported as 'true', the 
         ceRedunGroupString name must contain no internal spaces.

         If it's reported as 'false', the ceRedunGroupString object
         is just used as an optional description for the group
         rather than as the group name. 
        "
    ::= { ceRedunGroupTypesEntry 6 }

----------------------- snip of MIB -----------------