gpt4 book ai didi

c - 算法优化(质因数分解)

转载 作者:太空狗 更新时间:2023-10-29 17:05:08 27 4
gpt4 key购买 nike

在开始之前让我说:这不是家庭作业,只是简单、古老、有趣。

现在,我正试图想出一个算法来回答这个问题 1/x + 1/y = 1/n! .

正如您在上面的链接中看到的那样,作者只要求提示而不是实际答案,所以我也很乐意提出同样的要求。

我按照 one of the answers 的建议简化了表达式,直到 (x - n!)(y - n!) = (n!)^2 , 那时我明白了 (x,y) 对的组合数与 n!^2 的除数数相同(如果我在这里错了请纠正我)。

因此,正如 accepted answer 所建议的那样,我正在尝试计算每个组成 N!^2 的素数的所有因数的乘积。

我使用 trial division 在 C 中编写了一些代码分解 N!^2 和 Sieve of Eratosthenes得到所有素数直到 sqrt(N!^2)。

现在的问题是内存,我试过 N = 15,我的 Mac(四核 6GB 内存)差点没电了。问题是内存。所以我添加了一些 printf 并尝试使用 N=11:

Sieve of Eratosthenes took 13339.910000 ms and used 152 mb of memory
n= 11; n!^2 = 1593350922240000; d = 6885
[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,5,5,5,5,7,7,11,11]

这个列表是 N!^2 的所有质因数(当然除了 1 和 N!^2)。

我想要一些关于如何最小化内存消耗和可能的优化的提示。

下面的代码,这只是一个快速实验,所以我相信它可以优化。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <strings.h>
#include <sys/time.h>
#include <assert.h>

//Linked List
struct node {
struct node * next;
long val;
};

void addValue(struct node *list, long val) {
struct node *n = list;

if (n->val == -1) {
n->val = val;
return;
}

while (n->next) {
n = n->next;
}

struct node *newNode = malloc(sizeof(struct node));
newNode->val = val;
newNode->next = NULL;
n->next = newNode;
}

void freeLinkedList(struct node *list) {
struct node *c = list;
if (!c) return;
struct node *n = c->next;
free(c);
freeLinkedList(n);
}

void printList(struct node *list) {
struct node *n = list;
printf("[");
while (n) {
printf("%ld", n->val);
n = n->next;
if (n) {
printf(",");
}
}
printf("]\n");
}
//-----------


int fac(int n) {
if (n == 1) return 1;
return fac(n-1)*n;
}

//Sieve of Eratosthenes
int sieve_primes(long limit, long **list) {
struct timeval t1;
struct timeval t2;
double elapsedTime = 0;
gettimeofday(&t1, NULL);

assert(limit > 0);

//Create a list of consecutive integers from 2 to n: (2, 3, 4, ..., n).
long arrSize = limit-1;
long *arr = malloc(sizeof(long)*arrSize);

long c = 2;
for (long i = 0; i < arrSize; i++) {
arr[i] = c++;
}
assert(arr[arrSize-1] == limit);


for (long i = 0; i < arrSize; i++) {
//Let p be equal to the first number not crossed
long p = arr[i];
if (p == 0) continue;

//Starting from p, count up in increments of p and mark each of these numbers greater than p itself in the list.
for (long f = p+p; f < arrSize; f+=p) {
arr[f] = 0;
}
}

*list = arr;


gettimeofday(&t2, NULL);

elapsedTime = (t2.tv_sec - t1.tv_sec) * 1000.0; // sec to ms
elapsedTime += (t2.tv_usec - t1.tv_usec) / 1000.0; // us to ms
printf("Sieve of Eratosthenes took %f ms and used %lu mb of memory\n",elapsedTime, (arrSize * sizeof(int))/1024/1024);
return arrSize;
}

void trial_division(struct node* list, long n) { if (n == 1) {
addValue(list, 1);
return;
}
long *primes;
long primesSize = sieve_primes(sqrt(n), &primes);

struct timeval t1;
struct timeval t2;
double elapsedTime = 0;
gettimeofday(&t1, NULL);
for (long i = 0; i < primesSize; i++) {
long p = primes[i];
if (p == 0) continue;
if (p*p > n) break;
while (n % p == 0) {
addValue(list, p);
n/=p;
}
}
if (n > 1) {
addValue(list, n);
}
free(primes);
}

int main(int argc, char *argv[]) {
struct node *linkedList = malloc(sizeof(struct node));
linkedList->val = -1;
linkedList->next = NULL;


long n = 11;
long nF = fac(n);
long nF2 = nF*nF;
trial_division(linkedList, nF2);

long multOfAllPrimeFactors = 1;
struct node *c = linkedList;
while (c) {
long sumOfVal = 2;
long val = c->val;
c = c->next;
while(c) {
long val2 = c->val;
if (val == val2) {
sumOfVal++;
c = c->next;
} else break;
}
multOfAllPrimeFactors*=sumOfVal;
}

printf("n= %ld; n!^2 = %ld; d = %ld\n", n,nF2, multOfAllPrimeFactors);
printList(linkedList);

freeLinkedList(linkedList);

}

编辑:

作为示例,我将向您展示计算初始方程的所有可能正整数解的方法:

3!^2 = 36 = (3^2*2^2*1^0)

所以丢番图方程有 (1+2)(1+2)(1+0)=9 个可能的正整数解。如果计算负整数,则加倍。我正在使用 WolframAlpha可以肯定。

编辑 2:

我想我刚刚发现“阶乘是什么”,我得到了这个非常有趣的输出:

3! = [2,3]
3!^2 = [2,2,3,3]
3!^3 = [2,2,2,3,3,3]
3!^4 = [2,2,2,2,3,3,3,3]

谢谢:D

最佳答案

这里的技巧是准确识别阶乘 N! 是什么。它是从 1N 的所有数字的乘积。这已经是向前迈出的一大步。

所以您需要做的就是对从 1N 的每个数字进行质因数分解。

从这个意义上讲,您不需要筛选到 N!。相反,只需筛选到 sqrt(N)。剩下的就是合并所有主要因素。

关于c - 算法优化(质因数分解),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9523279/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com