проблемы с вектором <double>f (long int N) - PullRequest
0 голосов
/ 16 декабря 2018

У меня есть следующий фрагмент кода, который не работает

const int N=45;
long int toc;
toc = pow(2, N) - 1;
vector<long double > E(toc);

Я думаю, что проблема в

vector<long double > E(toc);

Но я не могу понять, что не так.

Сообщение об ошибке «Ошибка отладки!»Программа: .. \ Curie-Weise.exe

abort () была вызвана

Код

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define _USE_MATH_DEFINES
#include <cmath>  
#include <conio.h>
#include <ctime>
#include <limits>
#include <iostream>
#include <fstream>
#include <complex>
#include <vector>
#include <random>
#include <bitset>
using namespace std;
//Function sum J_ij s_i s_j
double CountSumflip(const vector<vector<double>>& J, const vector<int>& 
spin)
{
double sumflip = 0;
int N = spin.size();
for (int i = 0; i < N; i++) {
    for (int j = i + 1; j < N; j++)
    {
        sumflip += J[i][j] * spin[i] * spin[j];
    }
}
return 2 * sumflip; //izza treugolnika
}

//Function M= sum s_i
int CountMflip(const vector<int>& spin) {

int Mflip = 0;
int N = spin.size();
for (int i = 0; i < N; i++) {
    Mflip += spin[i];
}
return Mflip;
}
//Function M= sum b_i s_i
int CountBM(const vector<int>& spin, const vector<int>& Be) {
int BM = 0;
int N = spin.size();
for (int i = 0; i < N; i++) {
    BM += Be[i] * spin[i];
}
return BM;
}

//------------------MAIN---------------------------------------------
//--------------------------------------------------------------------
int main(int argc, char *argv[])
{
int job_number = atoi(argv[1]);

const int N = 40;

std::default_random_engine generator;//Normal generator with 
int seed = 1000000 + 100 * M_PI *  job_number + job_number * job_number;
generator.seed(seed);
std::normal_distribution<double> distribution(0.0 /* mean */, 1.0 
/*stddev*/);

std::fstream sfs("perebor_" + std::to_string(job_number) + ".txt", 
std::ios_base::out);
std::fstream sfs2("minimacount_" + std::to_string(job_number) + ".txt", 
std::ios_base::out);
vector<vector<double>> J(N, vector<double>(N));

for (unsigned short int i = 0; i < N; ++i)
{
    J[i][i] = 0;
    for (unsigned short int j = i + 1; j < N; ++j)
    {
        J[i][j] = J[j][i] = distribution(generator);

    }
}

long int minimacount = 0;
for (unsigned short int i = 0; i < N; ++i)
{
    for (unsigned short int j = 0; j < N; ++j)
        std::cout << J[i][j] << " ";
    std::cout << std::endl;
}

//----------------Magnetic field generator ------------------------
vector<int> Be(N);
for (int i = 0; i < N; i++)
{
    Be[i] = 0;// rand() % 2 * 2 - 1;
}




long int num = 0; 
long int toc;
toc = pow(2, N) - 1;
cout <<"2^"<<N<<"= "<< toc << endl;


vector<long double > E(toc);
cout << "ups" << endl;
vector<double> Eflip(N);


for (num = 0; num <toc; num++)
{
    //if (num % 10000 == 0)
    //{
    //  cout << "%" << (num * 1.0 / toc) * 100 << endl;
    //}
    std::bitset<N> bitset = num;
    // 'to_string' вернет строку std::string формата '000...0111'
    //std::cout << "Binary : " << bitset.to_string<char, 
    std::char_traits<char>, std::allocator<char> >() << std::endl;
    //string s = bitset.to_string<char, std::char_traits<char>, 
    std::allocator<char> >();
    vector<int> spin(N);
    for (int i = 0; i < N; i++)
    {
        if (bitset[i])
        {
            spin[i] = 1;
        }
        else
        {
            spin[i] = -1;
        }
        //cout << "spin" << i << "= " << spin[i] << endl;
    }

    E[num] = -CountSumflip(J, spin) - CountBM(spin, Be);

    vector<int> spinflip(N);
    for (int i = 0; i < N; i++)
    {
        spinflip[i] = spin[i];
    }

    bool is_local = true;

    for (int i = 0; i < N; i++)
    {

        spinflip[i] = -1 * spin[i];
        Eflip[i]= -CountSumflip(J, spinflip) - CountBM(spinflip, Be);
        spinflip[i] = -1 * spin[i];
        if (Eflip[i] < E[num]) {
            is_local = false;
            break;
        }
    }

    if (is_local) {
        minimacount++;
    }
}

long double d = minimacount*1.0 / pow(2, N);
sfs2  << d << endl;




return 0;
}

1 Ответ

0 голосов
/ 16 декабря 2018

Чтобы объяснить комментарий Петерта:

const int N=45;
long int toc;
toc = pow(2, N) - 1;
vector<long double > E(toc);

Здесь toc составляет около 2 45 , что на самом деле огромное число, что-то выше 30e12, то есть 3 раза 10 13 (потому что 2 10 чуть больше тысячи, а 2 5 - больше 30, и вы можете вычислить это в своей голове, без какого-либо устройства или бумаги).

У вас недостаточно ресурсов для того, чтобы хранить столько цифр на вашем компьютере (long double занимает от 8 до 12 байт каждый), даже если каким-то чудом Гарри Поттера вы получили такой гигантский компьютер, так как заполняяlong double число может занять одну или несколько наносекунд, вам потребуется как минимум много часов (поскольку 30e12 наносекунд - это 30000 секунд, например, более 8 часов) процессорного времени, чтобы заполнить такую ​​гигантскую память (по крайней мере, 8 * 30e12)байт, например, 240 терабайт оперативной памяти; более 1000 евро за 128 Гбайт DRAM4 потребительского уровня, что будет означать 200 тыс. евро для 2000 модулей DDR4 SDRAM - ни одна материнская плата не справится с такой нагрузкой!).Помните о пределах вычислений и проблемах с вычислениями .

При кодировании учитывайте фактическую емкость вашего типичного компьютера и сделайте приблизительную оценку ресурсов(в памяти, на диске, во времени), необходимый вашей программе.Первые практические правила: ваш ноутбук или настольный компьютер имеют менее 128 ГБ ОЗУ (если вы не заплатили за это много; обычный высокопроизводительный ноутбук имеет 16 или 32 ГБ в 2018 году; с 3000 € до 5000 €Я мог бы купить в 2019 году настольный компьютер с 128 ГБ ОЗУ и 10 Терабайт SSD или диска), он имеет менее нескольких терабайт диска;он выполняет от 3 до 20 «элементарных операций» (я оставляю вас догадываться, какими могут быть эти машинные коды инструкции) каждую наносекунду.Весь день длится 86400 секунд (вы можете округлить его до 1e5).См. http://norvig.com/21-days.html для полезного понимания.Год - 31e6 секунд, век - более 3 миллиардов (3.1e9) секунд.

Для суперкомпьютеров вам нужно много платить за них (или получить какой-то исследовательский грант для доступа к ним).Просмотрите список TOP500 , чтобы получить представление об их возможностях.Сегодня это высокопараллельные компьютеры, и параллельные вычисления - сложный вопрос.

Когда вы что-то кодируете, вы должны сделать обоснованное предположение о ресурсах, необходимых для вашей программы.Таким образом, понимание сложности времени и других видов сложности вычислений (в частности сложность пространства ) на практике необходимо для кодирования (вам следует избегать комбинаторного взрыва ).Некоторые проблемы неразрешимы , другие неразрешимы (читайте о теории сложности вычислений , узнайте о проблеме коммивояжера ).Вы должны спросить себя, подходит ли ваша проблема (или ваш предполагаемый алгоритм) в такие области.

...