This notebook addresses a question (“[Ordering of resources for maximizing success[(https://math.stackexchange.com/questions/4271163/ordering-of-resources-for-maximizing-success)”) on Mathematics Stack Exchange. The problem is as follows. There are 32 workers and 16 tasks. Any worker can attempt any task. Success is random, with worker \(i\) having probability \(w_i\) of success on any task. Note that (a) the probability of success depends on the worker but is independent of the task and (b) success on any task does not alter the likelihood of success on the next task. If a worker fails on a task, the next worker attempts the task and the worker that failed becomes unavailable for any future tasks.

The objective is to sequence the workers so as to maximize the probability that all tasks are completed. In this notebook, we will set up a random problem and experiment with different sequences.

Setup

Our first step is to set up a test data set. We limit individual probabilities to below an arbitrary threshold to avoid getting overall success probabilities within rounding error of 1.0, but the conclusions remain the same even if we set the upper limit to 1.0.

set.seed(308)                    # seed the random number generator
nTasks <- 16                     # set the number of tasks
nWorkers <- 32                   # set the number of workers
w <- runif(nWorkers, min = 0, max = 0.7)   # generate worker success probabilities

Next, we set up a function that takes a permutation of the probability vector and returns the probability that all tasks are completed successfully. To avoid redundant computations and to provide additional evidence (for verification/debugging) of how a result was obtained, the function will return a matrix with one row for each worker slot (so that row one corresponds to the first worker in the permuted sequence) and one column for each task. The value in the cell \((i,j)\) of the matrix will be the probability that the last \(j\) tasks are completed given that the worker in schedule slot \(i\) is assigned to the next remaining task.

# Input: x is a permutation of the worker success probabilities
# Output: a matrix of partial probabilities
p.success <- function(x) {
  # Initialize the matrix.
  pSuccess <- matrix(nrow = nWorkers, ncol = nTasks)
  # For the last task (one remaining, so column 1 of the matrix), the probability of
  # success is one minus the probability that all remaining workers fail (product of
  # the complements of their success probabilities).
  for (n in 1:nWorkers) {
    pSuccess[n, 1] <- 1 - prod(1 - x[n:nWorkers])
  }
  # For more than one task remaining, the probability of finishing them is the
  # probability that the next available worker succeeds in the current task times
  # the probability that the remaining workers including that one finish the
  # remaining tasks, plus the probability that the next worker fails times the
  # probability that the remaining workers excluding the current one finish the
  # remaining tasks including the current one.
  for (t in 2:nTasks) {
    # If we are down to one worker, the probability of success is the probability
    # that worker finishes all remaining tasks.
    pSuccess[nWorkers, t] <- x[nWorkers]^t
    # Otherwise, the probability of success is the probability that the current
    # worker succeeds in the current task and the current and remaining workers
    # succeed in the remaining tasks plus the probability that the current worker
    # fails the current task and the remaining workers complete the current and
    # remaining tasks.
    for (n in (nWorkers - 1):1) {
      pSuccess[n, t] <- x[n] * pSuccess[n, t - 1] + (1 - x[n]) * pSuccess[n + 1, t]
    }
  }
  # Return the probability matrix.
  pSuccess
}

Results

For all experiments, the overall probability of success is the entry in row 1 (first worker is up) and column nTasks (all tasks yet to be done) of the matrix.

First, we try the workers in their original order.

result <- p.success(w)
cat("Original order probability of success = ", result[1, nTasks], ".\n")
Original order probability of success =  0.792882 .

Next, we try sorting the workers into ascending order of success probability (worst worker first).

result <- p.success(sort(w))
cat("In ascending probability order, probability of success = ", result[1, nTasks], ".\n")
In ascending probability order, probability of success =  0.792882 .

Now we try descending probability order (best worker first).

result <- p.success(sort(w, decreasing = T))
cat("In descending probability order, probability of success = ", result[1, nTasks], ".\n")
In descending probability order, probability of success =  0.792882 .

Last, we randomize the worker order.

result <- p.success(sample(w, nWorkers))
cat("In randomized order, probability of success = ", result[1, nTasks], ".\n")
In randomized order, probability of success =  0.792882 .

In repeated experiments, order of workers does not affect the overall success probability.

LS0tCnRpdGxlOiAiV29ya2VyIE9yZGVyIgphdXRob3I6IFBhdWwgQS4gUnViaW4gKHJ1YmluQG1zdS5lZHUpCmRhdGU6IE9jdG9iZXIgOSwgMjAyMQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpUaGlzIG5vdGVib29rIGFkZHJlc3NlcyBhIHF1ZXN0aW9uICgiW09yZGVyaW5nIG9mIHJlc291cmNlcyBmb3IgbWF4aW1pemluZyBzdWNjZXNzWyhodHRwczovL21hdGguc3RhY2tleGNoYW5nZS5jb20vcXVlc3Rpb25zLzQyNzExNjMvb3JkZXJpbmctb2YtcmVzb3VyY2VzLWZvci1tYXhpbWl6aW5nLXN1Y2Nlc3MpIikgb24gTWF0aGVtYXRpY3MgU3RhY2sgRXhjaGFuZ2UuIFRoZSBwcm9ibGVtIGlzIGFzIGZvbGxvd3MuIFRoZXJlIGFyZSAzMiB3b3JrZXJzIGFuZCAxNiB0YXNrcy4gQW55IHdvcmtlciBjYW4gYXR0ZW1wdCBhbnkgdGFzay4gU3VjY2VzcyBpcyByYW5kb20sIHdpdGggd29ya2VyICRpJCBoYXZpbmcgcHJvYmFiaWxpdHkgJHdfaSQgb2Ygc3VjY2VzcyBvbiBhbnkgdGFzay4gTm90ZSB0aGF0IChhKSB0aGUgcHJvYmFiaWxpdHkgb2Ygc3VjY2VzcyBkZXBlbmRzIG9uIHRoZSB3b3JrZXIgYnV0IGlzIGluZGVwZW5kZW50IG9mIHRoZSB0YXNrIGFuZCAoYikgc3VjY2VzcyBvbiBhbnkgdGFzayBkb2VzIG5vdCBhbHRlciB0aGUgbGlrZWxpaG9vZCBvZiBzdWNjZXNzIG9uIHRoZSBuZXh0IHRhc2suIElmIGEgd29ya2VyIGZhaWxzIG9uIGEgdGFzaywgdGhlIG5leHQgd29ya2VyIGF0dGVtcHRzIHRoZSB0YXNrIGFuZCB0aGUgd29ya2VyIHRoYXQgZmFpbGVkIGJlY29tZXMgdW5hdmFpbGFibGUgZm9yIGFueSBmdXR1cmUgdGFza3MuCgpUaGUgb2JqZWN0aXZlIGlzIHRvIHNlcXVlbmNlIHRoZSB3b3JrZXJzIHNvIGFzIHRvIG1heGltaXplIHRoZSBwcm9iYWJpbGl0eSB0aGF0IGFsbCB0YXNrcyBhcmUgY29tcGxldGVkLiBJbiB0aGlzIG5vdGVib29rLCB3ZSB3aWxsIHNldCB1cCBhIHJhbmRvbSBwcm9ibGVtIGFuZCBleHBlcmltZW50IHdpdGggZGlmZmVyZW50IHNlcXVlbmNlcy4KCiMgU2V0dXAKCk91ciBmaXJzdCBzdGVwIGlzIHRvIHNldCB1cCBhIHRlc3QgZGF0YSBzZXQuIFdlIGxpbWl0IGluZGl2aWR1YWwgcHJvYmFiaWxpdGllcyB0byBiZWxvdyBhbiBhcmJpdHJhcnkgdGhyZXNob2xkIHRvIGF2b2lkIGdldHRpbmcgb3ZlcmFsbCBzdWNjZXNzIHByb2JhYmlsaXRpZXMgd2l0aGluIHJvdW5kaW5nIGVycm9yIG9mIDEuMCwgYnV0IHRoZSBjb25jbHVzaW9ucyByZW1haW4gdGhlIHNhbWUgZXZlbiBpZiB3ZSBzZXQgdGhlIHVwcGVyIGxpbWl0IHRvIDEuMC4KCmBgYHtyfQpzZXQuc2VlZCgzMDgpICAgICAgICAgICAgICAgICAgICAjIHNlZWQgdGhlIHJhbmRvbSBudW1iZXIgZ2VuZXJhdG9yCm5UYXNrcyA8LSAxNiAgICAgICAgICAgICAgICAgICAgICMgc2V0IHRoZSBudW1iZXIgb2YgdGFza3MKbldvcmtlcnMgPC0gMzIgICAgICAgICAgICAgICAgICAgIyBzZXQgdGhlIG51bWJlciBvZiB3b3JrZXJzCncgPC0gcnVuaWYobldvcmtlcnMsIG1pbiA9IDAsIG1heCA9IDAuNykgICAjIGdlbmVyYXRlIHdvcmtlciBzdWNjZXNzIHByb2JhYmlsaXRpZXMKYGBgCgpOZXh0LCB3ZSBzZXQgdXAgYSBmdW5jdGlvbiB0aGF0IHRha2VzIGEgcGVybXV0YXRpb24gb2YgdGhlIHByb2JhYmlsaXR5IHZlY3RvciBhbmQgcmV0dXJucyB0aGUgcHJvYmFiaWxpdHkgdGhhdCBhbGwgdGFza3MgYXJlIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHkuIFRvIGF2b2lkIHJlZHVuZGFudCBjb21wdXRhdGlvbnMgYW5kIHRvIHByb3ZpZGUgYWRkaXRpb25hbCBldmlkZW5jZSAoZm9yIHZlcmlmaWNhdGlvbi9kZWJ1Z2dpbmcpIG9mIGhvdyBhIHJlc3VsdCB3YXMgb2J0YWluZWQsIHRoZSBmdW5jdGlvbiB3aWxsIHJldHVybiBhIG1hdHJpeCB3aXRoIG9uZSByb3cgZm9yIGVhY2ggd29ya2VyIHNsb3QgKHNvIHRoYXQgcm93IG9uZSBjb3JyZXNwb25kcyB0byB0aGUgZmlyc3Qgd29ya2VyIGluIHRoZSBwZXJtdXRlZCBzZXF1ZW5jZSkgYW5kIG9uZSBjb2x1bW4gZm9yIGVhY2ggdGFzay4gVGhlIHZhbHVlIGluIHRoZSBjZWxsICQoaSxqKSQgb2YgdGhlIG1hdHJpeCB3aWxsIGJlIHRoZSBwcm9iYWJpbGl0eSB0aGF0IHRoZSBsYXN0ICRqJCB0YXNrcyBhcmUgY29tcGxldGVkIGdpdmVuIHRoYXQgdGhlIHdvcmtlciBpbiBzY2hlZHVsZSBzbG90ICRpJCBpcyBhc3NpZ25lZCB0byB0aGUgbmV4dCByZW1haW5pbmcgdGFzay4KCmBgYHtyfQojIElucHV0OiB4IGlzIGEgcGVybXV0YXRpb24gb2YgdGhlIHdvcmtlciBzdWNjZXNzIHByb2JhYmlsaXRpZXMKIyBPdXRwdXQ6IGEgbWF0cml4IG9mIHBhcnRpYWwgcHJvYmFiaWxpdGllcwpwLnN1Y2Nlc3MgPC0gZnVuY3Rpb24oeCkgewogICMgSW5pdGlhbGl6ZSB0aGUgbWF0cml4LgogIHBTdWNjZXNzIDwtIG1hdHJpeChucm93ID0gbldvcmtlcnMsIG5jb2wgPSBuVGFza3MpCiAgIyBGb3IgdGhlIGxhc3QgdGFzayAob25lIHJlbWFpbmluZywgc28gY29sdW1uIDEgb2YgdGhlIG1hdHJpeCksIHRoZSBwcm9iYWJpbGl0eSBvZgogICMgc3VjY2VzcyBpcyBvbmUgbWludXMgdGhlIHByb2JhYmlsaXR5IHRoYXQgYWxsIHJlbWFpbmluZyB3b3JrZXJzIGZhaWwgKHByb2R1Y3Qgb2YKICAjIHRoZSBjb21wbGVtZW50cyBvZiB0aGVpciBzdWNjZXNzIHByb2JhYmlsaXRpZXMpLgogIGZvciAobiBpbiAxOm5Xb3JrZXJzKSB7CiAgICBwU3VjY2Vzc1tuLCAxXSA8LSAxIC0gcHJvZCgxIC0geFtuOm5Xb3JrZXJzXSkKICB9CiAgIyBGb3IgbW9yZSB0aGFuIG9uZSB0YXNrIHJlbWFpbmluZywgdGhlIHByb2JhYmlsaXR5IG9mIGZpbmlzaGluZyB0aGVtIGlzIHRoZQogICMgcHJvYmFiaWxpdHkgdGhhdCB0aGUgbmV4dCBhdmFpbGFibGUgd29ya2VyIHN1Y2NlZWRzIGluIHRoZSBjdXJyZW50IHRhc2sgdGltZXMKICAjIHRoZSBwcm9iYWJpbGl0eSB0aGF0IHRoZSByZW1haW5pbmcgd29ya2VycyBpbmNsdWRpbmcgdGhhdCBvbmUgZmluaXNoIHRoZQogICMgcmVtYWluaW5nIHRhc2tzLCBwbHVzIHRoZSBwcm9iYWJpbGl0eSB0aGF0IHRoZSBuZXh0IHdvcmtlciBmYWlscyB0aW1lcyB0aGUKICAjIHByb2JhYmlsaXR5IHRoYXQgdGhlIHJlbWFpbmluZyB3b3JrZXJzIGV4Y2x1ZGluZyB0aGUgY3VycmVudCBvbmUgZmluaXNoIHRoZQogICMgcmVtYWluaW5nIHRhc2tzIGluY2x1ZGluZyB0aGUgY3VycmVudCBvbmUuCiAgZm9yICh0IGluIDI6blRhc2tzKSB7CiAgICAjIElmIHdlIGFyZSBkb3duIHRvIG9uZSB3b3JrZXIsIHRoZSBwcm9iYWJpbGl0eSBvZiBzdWNjZXNzIGlzIHRoZSBwcm9iYWJpbGl0eQogICAgIyB0aGF0IHdvcmtlciBmaW5pc2hlcyBhbGwgcmVtYWluaW5nIHRhc2tzLgogICAgcFN1Y2Nlc3NbbldvcmtlcnMsIHRdIDwtIHhbbldvcmtlcnNdXnQKICAgICMgT3RoZXJ3aXNlLCB0aGUgcHJvYmFiaWxpdHkgb2Ygc3VjY2VzcyBpcyB0aGUgcHJvYmFiaWxpdHkgdGhhdCB0aGUgY3VycmVudAogICAgIyB3b3JrZXIgc3VjY2VlZHMgaW4gdGhlIGN1cnJlbnQgdGFzayBhbmQgdGhlIGN1cnJlbnQgYW5kIHJlbWFpbmluZyB3b3JrZXJzCiAgICAjIHN1Y2NlZWQgaW4gdGhlIHJlbWFpbmluZyB0YXNrcyBwbHVzIHRoZSBwcm9iYWJpbGl0eSB0aGF0IHRoZSBjdXJyZW50IHdvcmtlcgogICAgIyBmYWlscyB0aGUgY3VycmVudCB0YXNrIGFuZCB0aGUgcmVtYWluaW5nIHdvcmtlcnMgY29tcGxldGUgdGhlIGN1cnJlbnQgYW5kCiAgICAjIHJlbWFpbmluZyB0YXNrcy4KICAgIGZvciAobiBpbiAobldvcmtlcnMgLSAxKToxKSB7CiAgICAgIHBTdWNjZXNzW24sIHRdIDwtIHhbbl0gKiBwU3VjY2Vzc1tuLCB0IC0gMV0gKyAoMSAtIHhbbl0pICogcFN1Y2Nlc3NbbiArIDEsIHRdCiAgICB9CiAgfQogICMgUmV0dXJuIHRoZSBwcm9iYWJpbGl0eSBtYXRyaXguCiAgcFN1Y2Nlc3MKfQpgYGAKCiMgUmVzdWx0cwoKRm9yIGFsbCBleHBlcmltZW50cywgdGhlIG92ZXJhbGwgcHJvYmFiaWxpdHkgb2Ygc3VjY2VzcyBpcyB0aGUgZW50cnkgaW4gcm93IDEgKGZpcnN0IHdvcmtlciBpcyB1cCkgYW5kIGNvbHVtbiBgblRhc2tzYCAoYWxsIHRhc2tzIHlldCB0byBiZSBkb25lKSBvZiB0aGUgbWF0cml4LgoKRmlyc3QsIHdlIHRyeSB0aGUgd29ya2VycyBpbiB0aGVpciBvcmlnaW5hbCBvcmRlci4KCmBgYHtyfQpyZXN1bHQgPC0gcC5zdWNjZXNzKHcpCmNhdCgiT3JpZ2luYWwgb3JkZXIgcHJvYmFiaWxpdHkgb2Ygc3VjY2VzcyA9ICIsIHJlc3VsdFsxLCBuVGFza3NdLCAiLlxuIikKYGBgCk5leHQsIHdlIHRyeSBzb3J0aW5nIHRoZSB3b3JrZXJzIGludG8gYXNjZW5kaW5nIG9yZGVyIG9mIHN1Y2Nlc3MgcHJvYmFiaWxpdHkgKHdvcnN0IHdvcmtlciBmaXJzdCkuCgpgYGB7cn0KcmVzdWx0IDwtIHAuc3VjY2Vzcyhzb3J0KHcpKQpjYXQoIkluIGFzY2VuZGluZyBwcm9iYWJpbGl0eSBvcmRlciwgcHJvYmFiaWxpdHkgb2Ygc3VjY2VzcyA9ICIsIHJlc3VsdFsxLCBuVGFza3NdLCAiLlxuIikKYGBgCk5vdyB3ZSB0cnkgZGVzY2VuZGluZyBwcm9iYWJpbGl0eSBvcmRlciAoYmVzdCB3b3JrZXIgZmlyc3QpLgoKYGBge3J9CnJlc3VsdCA8LSBwLnN1Y2Nlc3Moc29ydCh3LCBkZWNyZWFzaW5nID0gVCkpCmNhdCgiSW4gZGVzY2VuZGluZyBwcm9iYWJpbGl0eSBvcmRlciwgcHJvYmFiaWxpdHkgb2Ygc3VjY2VzcyA9ICIsIHJlc3VsdFsxLCBuVGFza3NdLCAiLlxuIikKYGBgCgpMYXN0LCB3ZSByYW5kb21pemUgdGhlIHdvcmtlciBvcmRlci4KCmBgYHtyfQpyZXN1bHQgPC0gcC5zdWNjZXNzKHNhbXBsZSh3LCBuV29ya2VycykpCmNhdCgiSW4gcmFuZG9taXplZCBvcmRlciwgcHJvYmFiaWxpdHkgb2Ygc3VjY2VzcyA9ICIsIHJlc3VsdFsxLCBuVGFza3NdLCAiLlxuIikKYGBgCgpJbiByZXBlYXRlZCBleHBlcmltZW50cywgb3JkZXIgb2Ygd29ya2VycyBkb2VzIG5vdCBhZmZlY3QgdGhlIG92ZXJhbGwgc3VjY2VzcyBwcm9iYWJpbGl0eS4K