Secretary Problem (A Optimal Stopping Problem)

The Secretary Problem also known as marriage problem, the sultan’s dowry problem, and the best choice problem is an example of Optimal Stopping Problem.

This problem can be stated in the following form: Imagine an administrator who wants to hire the best secretary out of n rankable applicants for a position. The applicants are interviewed one by one in random order. A decision about each particular applicant is to be made immediately after the interview. Once rejected, an applicant cannot be recalled. During the interview, the administrator can rank the applicant among all applicants interviewed so far but is unaware of the quality of yet unseen applicants. The question is about the optimal strategy (stopping rule) to maximize the probability of selecting the best applicant.

Optimal Stopping : In mathematics, the theory of optimal stopping or early stopping is concerned with the problem of choosing a time to take a particular action, in order to maximize an expected reward or minimize an expected cost.

If the decision to hire an applicant was to be taken in the end of interviewing all the n candidates, a simple solution is to use maximum selection algorithm of tracking the running maximum (and who achieved it) and selecting the overall maximum at the end. The difficult part of this problem is that the decision must be made immediately after interviewing a candidate.

1/e law of Optimal Strategy
According to this strategy, the optimal win probability is always at least 1/e.
The optimal stopping rule prescribes always rejecting the first n/e applicants that are interviewed (where e is the base of the natural logarithm and has the value 2.71828) and then stopping at the first applicant who is better than every applicant interviewed so far (or continuing to the last applicant if this never occurs). This strategy is called the 1/e stopping rule because the probability to select the best candidate is 1/e, in other words, this strategy selects the best candidate about 37% of time.

If you think carefully, it might seem obvious that one cannot select the first candidate because the first candidate has no one to compare with. A better strategy is to choose a few candidates as a sample to set the benchmark for remaining candidates. So the sample will be rejected and will only be used for setting benchmark.

  • If a sample is too small, we don’t get information enough for setting the benchmark for remaining candidates.
  • If a sample is too large, though we get plenty of information but we have also burned too many of the potential candidates. This leaves us with very few candidates to choose from, and hence making the strategy a poor one.
  • The best strategy is to choose the perfect or optimal sample size (ideal sample size) which can be done using 1/e law that is rejecting n/e candidates (this n/e is the sample size).
  • The optimal sample size and Probability of success for different values of n are :
    Optimal Sample size k = n / e
    Probability of success is given by :

    where x = k / n

    The probability of selecting the best applicant in the classical secretary problem converges toward 1/e = 0.368 (approx)

    Program to Test Secertary Problem :
    Note* : The Optimal Strategy doesn’t always find the best candidate but selects the almost best candidates most of the times.

    C++

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // C++ Program to test 1/e law for Secretary Problem :
    #include <iostream>
    #include <time.h>
    #define e 2.71828
    using namespace std;
      
    // To find closest integer of num.
    int roundNo(float num)
    {
        return num < 0 ? num - 0.5 : num + 0.5;
    }
      
    // Finds best candidate using n/e rule. candidate[]
    // represents talents of n candidates.
    void printBestCandidate(int candidate[], int n)
    {
        // Calculating sample size for benchmarking.
        int sample_size = roundNo(n/e);
        cout << "\n\nSample size is " << sample_size << endl;
      
        // Finding best candidate in sample size
        int best = 0; 
        for (int i = 1; i < sample_size; i++)
            if (candidate[i] > candidate[best])
                best = i;
      
        // Finding the first best candidate that is  
        // better than benchmark set.
        for (int i = sample_size; i < n; i++)
            if (candidate[i] >= candidate[best]) {
                best = i;
                break;
            }
      
        if (best >= sample_size)
            cout << endl << "Best candidate found is "
                << best + 1 << " with talent " 
                << candidate[best] << endl;
        else
            cout << "Couldn't find a best candidate\n";
    }
      
    int main()
    {
        int n = 8;
      
        // n = 8 candidates and candidate array contains
        // talents of n candidate where the largest 
        // number means highest talented candidate.
        int candidate[n];
      
        // generating random numbers between 1 to 8 
        // for talent of candidate
        srand(time(0));    
        for (int i = 0; i < n; i++)
            candidate[i] = 1 + rand() % 8;
      
        cout << "Candidate : ";
        for (int i = 0; i < n; i++)
            cout << i + 1 << " ";
        cout << endl;
        cout << "  Talents : ";
        for (int i = 0; i < n; i++)
            cout << candidate[i] << " ";
          
        printBestCandidate(candidate, n);
      
        return 0;
    }

    chevron_right

    
    

    Python3

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    # Python3 Program to test 1/e law for
    # Secretary Problem
    import random
    import math
      
    e = 2.71828;
      
    # To find closest integer of num.
    def roundNo(num):
        if(num < 0): 
            return (num - 0.5)
        else
            return (num + 0.5);
      
    # Finds best candidate using n/e rule. 
    # candidate[] represents talents of n candidates.
    def printBestCandidate(candidate, n):
          
        # Calculating sample size for benchmarking.
        sample_size = roundNo(n / e);
        print("\n\nSample size is"
               math.floor(sample_size));
      
        # Finding best candidate in sample size
        best = 0
        for i in range(1, int(sample_size)):
            if (candidate[i] > candidate[best]):
                best = i;
      
        # Finding the first best candidate that 
        # is better than benchmark set.
        for i in range(int(sample_size), n):
            if (candidate[i] >= candidate[best]):
                best = i;
                break;
      
        if (best >= int(sample_size)):
            print("\nBest candidate found is"
                         math.floor(best + 1), 
                  "with talent", math.floor(candidate[best]));
        else:
            print("Couldn't find a best candidate");
      
    # Driver code
    n = 8;
      
    # n = 8 candidates and candidate 
    # array contains talents of n 
    # candidate where the largest 
    # number means highest talented 
    # candidate.
    candidate = [0] * (n);
      
    # generating random numbers between 1 to 8 
    # for talent of candidate
    for i in range(n):
        candidate[i] = 1 + random.randint(1, 8);
    print("Candidate : ", end = "");
      
    for i in range(n):
        print((i + 1), end = " ");
    print("\nTalents : ", end = "");
      
    for i in range(n):
        print(candidate[i], end = " ");
       
    printBestCandidate(candidate, n);
      
    # This code is contributed by mits

    chevron_right

    
    

    PHP

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    <?php
    // PHP Program to test 1/e 
    // law for Secretary Problem :
      
    $e = 2.71828;
      
    // To find closest 
    // integer of num.
    function roundNo($num)
    {
        return $num < 0 ? 
             $num - 0.5 : $num + 0.5;
    }
      
    // Finds best candidate using 
    // n/e rule. candidate[] 
    // represents talents of n candidates.
    function printBestCandidate($candidate, $n)
    {
        global $e;
          
        // Calculating sample size 
        // for benchmarking.
        $sample_size = roundNo($n / $e);
        echo "\n\nSample size is "
               floor($sample_size) . "\n";
      
        // Finding best candidate
        // in sample size
        $best = 0; 
        for ($i = 1; $i < $sample_size; $i++)
            if ($candidate[$i] > 
                $candidate[$best])
                $best = $i;
      
        // Finding the first best 
        // candidate that is better
        // than benchmark set.
        for ($i = $sample_size; $i < $n; $i++)
            if ($candidate[$i] >= 
                $candidate[$best])
            {
                $best = $i;
                break;
            }
      
        if ($best >= $sample_size)
            echo "\nBest candidate found is "
                             floor($best + 1) . 
                              " with talent "
                     floor($candidate[$best]) . "\n";
        else
            echo "Couldn't find a best candidate\n";
    }
      
    // Driver code
    $n = 8;
      
    // n = 8 candidates and candidate 
    // array contains talents of n 
    // candidate where the largest 
    // number means highest talented 
    // candidate.
    $candidate = array_fill(0, $n, 0);
      
    // generating random numbers 
    // between 1 to 8 for talent
    // of candidate
    for ($i = 0; $i < $n; $i++)
        $candidate[$i] = 1 + rand(1, 8);
    echo "Candidate : ";
      
    for ($i = 0; $i < $n; $i++)
        echo ($i + 1) . " ";
    echo "\n Talents : ";
      
    for ($i = 0; $i < $n; $i++)
        echo $candidate[$i] . " ";
      
    printBestCandidate($candidate, $n);
      
    // This code is contributed by mits
    ?>

    chevron_right

    
    


    Output:

    Candidates : 1 2 3 4 5 6 7 8 
      Talents  : 5 3 8 6 5 7 8 6 
    
    Sample size is 3
    
    Best candidate found is 7 with talent 8
    

    Alternate Optimal Strategy : This strategy instead of choosing the sample size as n/e, it selects square root of n as the optimal sample size (i.e. sqrt(n)).

    This article is contributed by Shubham Rana. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

    Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.



    My Personal Notes arrow_drop_up



    Article Tags :
    Practice Tags :


    Be the First to upvote.


    Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.