[英]Given a number N how many pairs of numbers have square sum less than or equal to N?
[英]How to produce random numbers so that their sum is equal to given number?
我想產生X個隨機數,每個隨機數的間隔均<0; Y>
<0; Y>
(給定每個數字的最大值Y
),但是存在限制,即這些數字的總和必須等於Z
實施例:5個隨機量的數字,每個最大6和的總和必須等於14,例如: 0, 2, 6, 4, 2
已經有可以執行類似操作的C / C ++函數嗎?
就我個人而言,我只能提出一些丑陋的if-else-constructs構想。
由於不需要統一的生成順序,因此這可能是以下解決方案之一:
#include <iostream>
#include <vector>
#include <cstdlib>
int irand(int min, int max) {
return ((double)rand() / ((double)RAND_MAX + 1.0)) * (max - min + 1) + min;
}
int main()
{
int COUNT = 5, // X
MAX_VAL = 6, // Y
MAX_SUM = 14; // Z
std::vector<int> buckets(COUNT, 0);
srand(time(0));
int remaining = MAX_SUM;
while (remaining > 0)
{
int rndBucketIdx = irand(0, COUNT-1);
if (buckets[rndBucketIdx] == MAX_VAL)
continue; // this bucket is already full
buckets[rndBucketIdx]++;
remaining--;
}
std::cout << "Printing sequence: ";
for (size_t i = 0; i < COUNT; ++i)
std::cout << buckets[i] << ' ';
}
這只是簡單地將總和除以一堆水桶,直到消失了:)
輸出示例: Printing sequence: 4 4 1 0 5
注意:當問題指定一個“ MAX SUM”參數時,即表示此解決方案是可以接受的,這意味着總和小於該數量是可以接受的。 現在根據OP的評論對問題進行了編輯,因為這意味着累計金額實際上必須達到該目標。 我不會更新此答案,但是很明顯,它可以在最后一級遞歸中舍棄較少的總數。
此解決方案對vector<vector<int>>
進行一次總體填充,其中所有可能的數字組合都可以解決輸入標准,然后每次需要新的解決方案時,它都會隨機選擇其中一個並將其洗牌成整數。隨機順序(從而選擇組合的排列)。
它有點重-也許不適合我開始寫后提到的實際使用; -P-但是它會產生加權平均分布 ,並且您可以輕松地做一些事情,例如確保組合不會再次返回,直到所有其他組合都已返回(帶有組合中索引的支持的隨機向量)。
#include <iostream>
#include <vector>
#include <algorithm>
using std::min;
using std::max;
using std::vector;
// print solutions...
void p(const vector<vector<int>>& vvi)
{
for (int i = 0; i < vvi.size(); ++i)
{
for (int j = 0; j < vvi[i].size(); ++j)
std::cout << vvi[i][j] << ' ';
std::cout << '\n';
}
}
// populate results with solutions...
void f(vector<vector<int>>& results, int n, int max_each, int max_total)
{
if (n == 0) return;
if (results.size() == 0)
{
for (int i = 0; i <= min(max_each, max_total); ++i)
results.push_back(vector<int>(2, i));
f(results, n - 1, max_each, max_total);
return;
}
vector<vector<int>> new_results;
for (int r = 0; r < results.size(); ++r)
{
int previous = *(results[r].rbegin() + 1);
int current_total = results[r].back();
int remaining = max_total - current_total;
for (int i = 0; i <= min(previous,min(max_each, remaining)); ++i)
{
vector<int> v = results[r];
v.back() = i;
v.push_back(current_total + i);
new_results.push_back(v);
}
}
results = new_results;
f(results, n - 1, max_each, max_total);
}
const vector<int>& once(vector<vector<int>>& solutions)
{
int which = std::rand() % solutions.size();
vector<int>& v = solutions[which];
std::random_shuffle(v.begin(), v.end() - 1);
return v;
}
int main()
{
vector<vector<int>> solutions;
f(solutions, 5, 6, 14);
std::cout << "All solution combinations...\n";
p(solutions);
std::cout << "------------------\n";
std::cout << "A few sample permutations...\n";
for (int n = 1; n <= 100; ++n)
{
const vector<int>& o = once(solutions);
for (int i = 0; i < o.size() - 1; ++i)
std::cout << o[i] << ' ';
std::cout << '\n';
}
}
#include<iostream>
#include <cstdlib> //rand ()
using namespace std;
void main()
{
int random ,x=5;
int max , totalMax=0 , sum=0;
cout<<"Enter the total maximum number : ";
cin>>totalMax;
cout<<"Enter the maximum number: ";
cin>>max;
srand(0);
for( int i=0; i<x ; i++)
{
random=rand()%max+1; //range from 0 to max
sum+=random;
if(sum>=totalMax)
{
sum-=random;
i--;
}
else
cout<<random<<' ';
}
cout<<endl<<"Reached total maximum number "<<totalMax<<endl;
}
我寫了這個簡單的代碼
我使用totalMax = 14和max = 3對其進行了測試,並且可以與我合作,希望它就是您所要求的
LiHo的答案看起來與我的第二個建議非常相似,因此我將其保留,但這是第一個建議的示例。 它可能會得到改善,但不應有任何可悲的錯誤。 這是現場樣本。
#include <algorithm>
#include <array>
#include <random>
std::random_device rd;
std::mt19937 gen(rd());
constexpr int MAX = 14;
constexpr int LINES = 5;
int sum{};
int maxNum = 6;
int minNum{};
std::array<int, LINES> nums;
for (int i = 0; i < LINES; ++i) {
maxNum = std::min(maxNum, MAX - sum);
minNum = std::min(maxNum, std::max(minNum, MAX - maxNum * (LINES - i)));
std::uniform_int_distribution<> dist(minNum, maxNum);
int num = dist(gen);
nums[i] = num;
sum += num;
}
std::shuffle(std::begin(nums), std::end(nums), gen);
每次創建該分配都有可能減慢它的速度(我不知道),但是范圍必須在構造函數中進行,我不是要說這些數字的分布情況如何。 但是,邏輯很簡單。 除此之外,它還使用了漂亮的,閃亮的C ++ 11 <random>
標頭。
我們只是確保沒有剩余數超過MAX
(14),並且在最后達到MAX
。 minNum
是奇數部分,這是由於它如何進行。 它從零開始,然后根據需要向上增加( std::max
的第二部分正在弄清楚如果剩下的6s會需要什么),但是我們不能讓它超過maxNum
。 我願意考慮一個更簡單的計算minNum
方法(如果存在)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.