vector <double> f(long int N)的问题

时间:2018-12-16 10:33:51

标签: c++ vector long-integer

我有以下不起作用的代码

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 :(得分:4)

解释PeterT的评论:

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 TB的RAM; 128G的消费级DRAM4售价超过1000欧元,这意味着2000 DDR4 SDRAM modules售价为200千欧元-没有主板能处理那么多!)。请注意limits of computationtranscomputational problems

进行编码时,请记住典型计算机的实际容量,并对程序所需的资源(内存,磁盘,时间)进行估算。第一个经验法则是:您的便携式计算机或台式计算机的RAM少于128GB(除非您为此付出了很多;典型的highend laptop在2018年具有16GB或32GB);我可以购买3000至5000欧元在2019年的台式机上,它具有128 GB的RAM和10 TB的SSD或磁盘),其磁盘空间不到几TB。每纳秒执行约3到20个“基本运算”(我让您猜测这些machine code指令的含义)。一整天的时间为86400秒(您可以将其舍入为1e5)。有关有用的见解,请参见http://norvig.com/21-days.html。一年是31e6秒,一个世纪是30亿(3.1e9)秒。

对于超级计算机,您需要为它们支付很多钱(或获得一些研究经费才能访问它们)。查看TOP500 list,以了解其功能。如今,它们是高度并行的计算机,parallel computing是一件困难的事情。

编写代码时,应该对程序所需的资源做出有根据的猜测。因此,在实践中,理解time complexity和其他类型的computational complexity(尤其是space complexity)对于编码至关重要(应避免使用combinatorial explosion)。有些问题是undecidable,有些问题是棘手的(阅读有关computation complexity theory的知识,了解有关travelling salesman problem的知识)。您需要问问自己自己的问题(或假装的算法)是否适合此类领域。