Tablica o znanym rozmiarze i znanej sumie losowych liczb z podanego zakresu

0

Hej, szukam sposobu na wygenerowanie tablicy losowych powtarzających się liczb całkowitych o podanym rozmiarze i podanej sumie elementów. Dodatkowo zakres tych liczb też ma być podany.

Na przykładzie:

suma liczb = 50
liczba elementów = 6
minimalna liczba = 6
maksymalna liczba = 12
tablica = [7, 7, 12, 11, 6, 7]
suma liczb = 10
liczba elementów = 5
minimalna liczba = 2
maksymalna liczba = 2
tablica = [2, 2, 2, 2, 2]

Mam też zamiar zrobić rzucanie wyjątku jeśli warunki nie pozwolą wygenerować tablicy tj. np:

suma liczb = 100
liczba elementów = 5
minimalna liczba = 2
maksymalna liczba = 4
tablica = [x, x, x, x, x]

Póki co jedynym moim pomysłem jest wypełnienie tablicy randomami z zakresu tyle razy, aż suma będzie się zgadzać, no ale sami widzicie jak mało optymalne i eleganckie to rozwiązanie.

Może szukać czegoś związanego z problemem plecakowym?

2
#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;

bool generate(vector<int> &tb,int count,int vmin,int vmax,int vsum)
{
   static ostream_iterator<int> sout(cout," ");
   tb.resize(count);
   if(count*vmin>vsum) return false;
   if(count*vmax<vsum) return false;
   while(count-->0)
   {
      int tmax=min(vmax,vsum-count*vmin);
      int tmin=max(vmin,vsum-count*vmax);
      int xval=tmin+rand()%(tmax-tmin+1);
      tb[count]=xval;
      vsum-=xval;
   }
   copy_n(begin(tb),tb.size(),sout);
   cout<<endl;
   return true;
}

int main()
{
   srand(time(0));
   vector<int> tb;
   cout<<"6,6,12,50"<<endl;
   for(int i=0;i<5;++i) generate(tb,6,6,12,50);
   return 0;
}
0
_13th_Dragon napisał(a):
#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;

bool generate(vector<int> &tb,int count,int vmin,int vmax,int vsum)
{
   static ostream_iterator<int> sout(cout," ");
   tb.resize(count);
   if(count*vmin>vsum) return false;
   if(count*vmax<vsum) return false;
   while(count-->0)
   {
      int tmax=min(vmax,vsum-count*vmin);
      int tmin=max(vmin,vsum-count*vmax);
      int xval=tmin+rand()%(tmax-tmin+1);
      tb[count]=xval;
      vsum-=xval;
   }
   copy_n(begin(tb),tb.size(),sout);
   cout<<endl;
   return true;
}

int main()
{
   srand(time(0));
   vector<int> tb;
   cout<<"6,6,12,50"<<endl;
   for(int i=0;i<5;++i) generate(tb,6,6,12,50);
   return 0;
}

Dzięki wielkie!
O to mi chodziło, świetnie działa i mogę dalej ruszyć z projektem :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1