Having seen a lot of good explanations and some good ideas, I still think this can help you:
You can use any distribution function f around 0 and substitute the interval of interest of interest to your desired interval [1,100] : f → f .
Then pass C++ discrete_distribution with the results of f ' .
I have an example with a normal distribution below, but I can not get my result in this function: -S
#include <iostream> #include <random> #include <chrono> #include <cmath> using namespace std; double p1(double x, double mean, double sigma); // p(x|x_avg,sigma) double p2(int x, int x_min, int x_max, double x_avg, double z_min, double z_max); // transform ("stretch") it to the interval int plot_ps(int x_avg, int x_min, int x_max, double sigma); int main() { int x_min = 1; int x_max = 20; int x_avg = 6; double sigma = 5; /* int p[]={2,1,3,1,2,5,1,1,1,1}; default_random_engine generator (chrono::system_clock::now().time_since_epoch().count()); discrete_distribution<int> distribution {p*}; for (int i=0; i< 10; i++) cout << i << "\t" << distribution(generator) << endl; */ plot_ps(x_avg, x_min, x_max, sigma); return 0; //*/ } // Normal distribution function double p1(double x, double mean, double sigma) { return 1/(sigma*sqrt(2*M_PI)) * exp(-(x-mean)*(x-mean) / (2*sigma*sigma)); } // Transforms intervals to your wishes ;) // z_min and z_max are the desired values f'(x_min) and f'(x_max) double p2(int x, int x_min, int x_max, double x_avg, double z_min, double z_max) { double y; double sigma = 1.0; double y_min = -sigma*sqrt(-2*log(z_min)); double y_max = sigma*sqrt(-2*log(z_max)); if(x < x_avg) y = -(x-x_avg)/(x_avg-x_min)*y_min; else y = -(x-x_avg)/(x_avg-x_max)*y_max; return p1(y, 0.0, sigma); } //plots both distribution functions int plot_ps(int x_avg, int x_min, int x_max, double sigma) { double z = (1.0+x_max-x_min); // plot p1 for (int i=1; i<=20; i++) { cout << i << "\t" << string(int(p1(i, x_avg, sigma)*(sigma*sqrt(2*M_PI)*20.0)+0.5), '*') << endl; } cout << endl; // plot p2 for (int i=1; i<=20; i++) { cout << i << "\t" << string(int(p2(i, x_min, x_max, x_avg, 1.0/z, 1.0/z)*(20.0*sqrt(2*M_PI))+0.5), '*') << endl; } }
With the following result, if I let them build a graph:
1 ************ 2 *************** 3 ***************** 4 ****************** 5 ******************** 6 ******************** 7 ******************** 8 ****************** 9 ***************** 10 *************** 11 ************ 12 ********** 13 ******** 14 ****** 15 **** 16 *** 17 ** 18 * 19 * 20 1 * 2 *** 3 ******* 4 ************ 5 ****************** 6 ******************** 7 ******************** 8 ******************* 9 ***************** 10 **************** 11 ************** 12 ************ 13 ********* 14 ******** 15 ****** 16 **** 17 *** 18 ** 19 ** 20 *
So - if you could give this result discrete_distribution<int> distribution {} , you got everything you want ...