LINUX.ORG.RU

Cannot allocate memory


0

2

Доброго времени суток всем!
Необходимо запрограммировать формулу
P = n!/(n^n * m_1! * m_2! * ... * m_n!), где m_1 + m_2 + ... m_n = n

В моем случае нужно расчитать для n = 24 (записывая возможные комбинации n_i и соответствующие значения P в текстовый файл)
применить стандартные типы с++ не получилось - выходит за границы Возможное решение - применение библиотеки gmp
вот что получилось:

#include <iostream>
#include <gmp.h>
#include <cstdlib>
#include <stdio.h>

using namespace std;
unsigned long int const n = 2;
FILE *comb, *prob;

void f(int level,unsigned long int sum[], unsigned long int m,unsigned long int mas[], unsigned long int l) 
{
	
	unsigned long int  ii[n];
	for (int j = 0; j < n; j++)
		{
			ii[j] = 0;
		}
	
	if(level < n-1)
        {for(ii[level] = n - sum[level]; ii[level] >= 0; ii[level]--)
		{
		   sum[level + 1] = ii[level] + sum[level];
		    mas[level] = ii[level];
		    f(level+1, sum, n, mas, n);
		  
		}
	}
    	else   
	    
	{
		mpf_t P, d1, d2;
		mpz_t N, div, factorial[n],znam, chisl;
		mpz_init(div);
		mpz_init(N);
		mpz_init(znam);
		mpz_init(chisl);
		mpf_init(P);
		mpf_init(d1);
		mpf_init(d2);
		mpz_fac_ui(chisl,n);  	 //числитель  = (n)!
		mpf_set_z(d1,chisl);	 // из int  в float
	
		mpz_set_ui(N,n);  	// запись в N = n 
		mpz_pow_ui(div,N,n);	 // n в степени  n
		mpz_set_ui(znam,1);	// знаменатель = 1
		mas[level] = n - sum[level]; // ??
		for (int j = 0; j < n; j++)
		mpz_init(factorial[j]);

		for (int i = 0; i < n; i++)
		mpz_fac_ui(factorial[i],mas[i]);	 // вычисляем факториалы в знаменателе
		
		for (int i = 0; i < n; i++)
		mpz_mul(znam, znam, factorial[i]);	 // перемножаем факториалы в знаменателе
	
		mpz_mul(znam,znam,div); 	// общий знаменатель (факториалы и степень)
		mpf_set_z(d2,znam);		 // из int  в float
		mpf_div(P,d1,d2);	 	// нахождение вероятности для данной комбинации
		mpf_out_str(prob,10,33,P); 	// запись в файл вероятности
		fwrite (" ; \n", sizeof(char),1, prob);
		/*for (int j = 0; j < n; j++)  	// запись в файл комбинаций
			{
				fwrite (&mas[j], 4, 1, prob);	
				fwrite (";", 1, 1, prob);
			} */
		fwrite ("\n", 2, 1, prob);
		mpf_clear(P);
		mpf_clear(d1);
		mpf_clear(d2);
		mpz_clear(N);
		mpz_clear(div);
		mpz_clear(znam);
		mpz_clear(chisl);
		for (int y = 0; y < n; y++)
		mpz_clear(factorial[y]);
	}
}

int main()
{
	prob = fopen("prob.txt","w");
	int level = 0;
	unsigned long int sum[n], mas[n];
	for (int k = 0; k < n; k++)
	{
		mas[k] = 0;
		sum[k] = 0;
	}
	f(level,sum,n,mas,n);
	fclose(prob); 			
return 0;

}

Компилируется без ошибок, но при запуске make-файла выводит Cannot allocate memory (size=486547464) и происходит аварийное завершение программы. Подскажите, в чем проблема?

Подскажите, в чем проблема?

в ДНК

anonymous ()

Пиши на C++, там хоть GMP можно по-человечески складывать и умножать ;-)

r2d2 ()
Ответ на: комментарий от nanoolinux

erlang не лучший инструмент для математических вычислений. И если мне не изменяет память, то факториала «из коробки» там нет.

beka ()

Предлагаю посмотреть на строку «for(ii[level] = n - sum[level]; ii[level] >= 0; ii[level]--)» и осознать, что ii - это массив _unsigned_ long.

lomereiter ()
Ответ на: комментарий от r2d2

Попробовала считать вашим способом, но все равно та же ошибка вылезает

Zarazka ()
Ответ на: комментарий от Jetty

Да пожалуйста...

24! * 64! = 78726794275565767407284888816115129288148513047496715163284838111705803966827982799926716268544000000000000000000

Я так долго задержался, потому что в столбик на бумажке умножал, если что...

DeVliegendeHollander ★★ ()
Ответ на: комментарий от Jetty

могу предоставить пару тетрадок

Общие, 96 листов.

и карандаши с резинками :)

Хорошо, но мало. Доллеров 50 хотя бы добавь. :)

DeVliegendeHollander ★★ ()

Возможное решение - применение библиотеки gmp

Мозг надо применять. За gmp незачет.

Reset ★★★★★ ()
Ответ на: комментарий от Jetty

23! * 22! * 21!*...*1!

Мелочи, смотри:

Prelude> let fact x = product [1..x]
Prelude> product $ map fact [1..23]
1891984688274192607739481159411532607771433686902374691017403396401535783431356418138933900060697141172863325793213721068660204501893619736331984249640376781921613013749596160000000000000000000000000000000000000000000000
Begemoth ★★★★★ ()
Ответ на: комментарий от beka

для математических вычислений

за то с большими числами работает.

факториала «из коробки» там нет.

при изучении пишется же.

nanoolinux ★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.