Correlated stochatic factors in Simulation
Correlation between stochastic factors in mining simulation (and any discrete-event simulation) is very important because ignoring it can give misleading results.
For example:
Truck travel time and fuel consumption are correlated (longer trips → more fuel).
Ore grade and processing time may be correlated (lower grade → longer processing).
Weather events may simultaneously affect travel times and breakdowns.
Why Independence Is a Problem
If you draw travel time from lognormal and fuel consumption from another independent normal, the simulation might produce combinations that don’t make sense (e.g., extremely long trip but unusually low fuel usage).
You need correlated sampling.
Ways to Model Correlation
(1) Choose from historical pairs, i.e. Empirical Joint Distribution
If you have historical paired data, simply sample pairs from historical data (travel_time, fuel_usage).
(2) Regression-Based Modeling
Model one variable as a function of another plus noise.
Example: fuel usage depends on travel time.
travel_time = np.random.lognormal(mean=3, sigma=0.4, size=1000)
fuel_usage = 2.5 * travel_time + np.random.normal(0, 5, size=1000)
Or use season (weather time) as an input parameter for all the correlated factors.
(3) Multivariate Distributions (when both are normal), i.e combine two normals
If both variables are normal (or can be approximated), you can use multivariate normal.
But this assumes you know the covariance between the two.
mean = [10, 50] # mean travel time, fuel
cov = [[4, 3], # variance-covariance matrix
[3, 9]]
samples = np.random.multivariate_normal(mean, cov, size=1000)
travel_time, fuel_usage = samples[:,0], samples[:,1]
(4) Copulas (general-purpose method)
This is a fancy way. Do some reading first.
A copula lets you model dependency structure separately from marginal distributions.
step 1: fit marginal distributions (e.g., travel ~ lognormal, fuel ~ normal).
step 2: Fit correlation structure using a copula (often Gaussian copula).
step 3: Generate correlated samples.
But shis also assumes you know the correlation matrix
Python example (Gaussian copula via scipy + numpy):
import numpy as np
from scipy.stats import norm, lognorm
# Correlation matrix
rho = 0.7
cov = [[1, rho], [rho, 1]]
# Generate correlated normals
z = np.random.multivariate_normal([0, 0], cov, size=1000)
# Transform to uniforms
u = norm.cdf(z)
# Apply marginals
travel_time = lognorm(s=0.4, scale=np.exp(3)).ppf(u[:,0]) # lognormal
fuel_usage = norm(loc=50, scale=5).ppf(u[:,1]) # normal