[c++]验证3n+1

[环境:Windows8.1 + Dev-c++5.11]

3n+1猜想即为卡拉兹(Callatz)猜想:

3x+1 ······ ①

x / 2  ······ ②

一个方程组, 对于任意正整数 x

如果它是奇数则执行①;

如果它是偶数则执行②;

我们编写一个程序验证一定范围以内的 n 成立。

枚举从 1 到 MAX_N 逐一验证。

#include <cstdio>
#include <vector>
#include <algorithm>
#include <conio.h>
#define MAX_STEP 1e6
using namespace std;

int main() {
	unsigned long long i = 1, limit, price;
	bool flag = 0;
	vector<unsigned long long> nerror;
	printf("limit number: ");
	scanf("%lld", &limit);
	price = limit / 100;
	FILE *ferr = fopen("3n+1_error.log", "w");
	
	printf("Checking 3n+1 from 1 to %lld... 00%%", limit);
	
	for (; i <= limit; ++i) {
		unsigned long long num = i, step = 0;
		while (num != 1) {
			if (num % 2) num = num * 3 + 1;
			else num /= 2;
			if (num < i) {
				if (!flag) break;
			}
			if (step++ > MAX_STEP) {
				nerror.push_back(i);
				fprintf(ferr,
					"[Error] number %lld isn't correct! (now is %lld)\n",
					i,
					num);
				flag = 1;
				break;
			}
		}
		printf("\b\b\b%02d%%", (int)(i / price));
	}
	printf("\b\b\b\bdone.\n");
	if (flag) printf("\n\nBut there is some error. see \"3n+1_error.log\"\n");
	getch();
	return 0;
}

效率较低:

发现CPU占用率并不高, 许多CPU资源被白白浪费了:

线程可以提高占用率,加快验证速度:

#include <thread>
#include <cstdio>
#include <vector>
#include <conio.h>
#define MAX_STEP 10000000
#define MAX_THREAD 10
using namespace std;

FILE *ferr = fopen("3n+1_error+.log", "w");
unsigned long long cnt = 1;
int end_sign = 0;
bool flag = 0;

void check(unsigned long long start, unsigned long long end) {
	unsigned long long i = start;
	for (; i <= end; ++i) {
		unsigned long long num = i, step = 0;
		while ((num != 1)) {
			if (num % 2) num = num * 3 + 1;
			else num /= 2;
			if (num < i) {
				if (!flag) break;
			}
			if (step++ > MAX_STEP) {
				fprintf(ferr,
					"[Error] number %d isn't correct! (now is %d)\n",
					i,
					num);
				flag = 1;
				break;
			}
		}
		++cnt;
	}
	++end_sign;
}

int main() {
	unsigned long long limit, price, each;
	
	printf("limit number: ");
	scanf("%lld", &limit);
	each = limit / MAX_THREAD + 1;
	price = limit / 100;
	
	printf("Checking 3n+1 from 1 to %lld... 00%%", limit);
	
	thread t1(check, each * 0 + 1, each * 1);
	thread t2(check, each * 1, each * 2);
	thread t3(check, each * 2, each * 3);
	thread t4(check, each * 3, each * 4);
	thread t5(check, each * 4, each * 5);
	thread t6(check, each * 5, each * 6);
	thread t7(check, each * 6, each * 7);
	thread t8(check, each * 7, each * 8);
	thread t9(check, each * 8, each * 9);
	thread t10(check, each * 9, each * 10);
	
	for (;end_sign < MAX_THREAD;) {
		printf("\b\b\b%02d%%", (cnt / price));
	}
	
	printf("\b\b\b\bdone.\n");
	if (flag) printf("\n\nBut there is some error. see \"3n+1_error+.log\"\n");
	getch();
	t1.join();
	t2.join();
	t3.join();
	t4.join();
	t5.join();
	t6.join();
	t7.join();
	t8.join();
	t9.join();
	t10.join();
	return 0;
}

编译时可能要加上编译选项 -std=c++11 

dev-c++ 可以在 工具 -> 编译选项 -> 编译时加入以下命令 添加

效率提高不少:

大家有兴趣可以验证一下,目前验证到最高应该是 7*10^1^1 

猜你喜欢

转载自blog.csdn.net/szdytom/article/details/82919446