如何科學地造數據

若是想要出一套信息學競賽模擬題, 或者要對拍以驗證本身程序的正確性,數據生成器是必不可少的。c++

隨機數

數據的隨機性很重要。 只有足夠隨機的數據才能夠均勻地覆蓋到各類狀況。算法

可是<cstdlib>裏的rand()不是很好用:dom

  1. 它在不一樣平臺上表現不一樣
  2. 它的線性遞推算法隨機性較弱。

c++11或以上的c++版本,能夠使用更好的mt19937隨機化工具。函數

要: #include<random>工具

它基於梅森素數,週期很是長,隨機性也有保證。 只是稍慢一點。spa

咱們能夠這樣定義一個基於mt19937的隨機函數c++11

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
mt19937_64 rng2(chrono::steady_clock::now().time_since_epoch().count());

rng的做用和rand()相同, 不過須要注意:code

  1. rng()\(\in [0, 2^{32})\)
  2. rng2()\(\in [0, 2^{64})\)

chrono::steady_clock::now().time_since_epoch().count()表示當前時間。 它是隨機種子。class

限定範圍的隨機數

//這樣來生成一個 1 ~ n 的隨機數
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
#define ll long long 
ll rd(ll x) {
    return rng() % x + 1;
}

如何造和圖論有關的數據?

生成一張隨機的樹的方法

for(int i = 2; i <= n; i++) {
        int u = rd(i-1);
        printf("%d %d\n", u, i); //(u, i) 爲一條邊的兩個端點
    }

生成一張隨機聯通圖的方法

set<pair<int, int> >  st;
    
    for(int i = 2; i <= n; i++) {
        int u = rd(i-1);
        st.insert(make_pair(u, i));
    }//先生成它的生成樹
    while(st.size() < m) {
        int u = rd(n), v = rd(n);
        if(u > v) swap(u, v);
        pair<int, int> pii = make_pair(u, v);
        if(u == v || st.find(pii) != st.end()) continue;
        st.insert(pii);
    }
    //這張圖無重邊和自環
相關文章
相關標籤/搜索