Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/magento/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Prolog中的不同素数分区_Prolog_Computer Science_Primes_Clpfd - Fatal编程技术网

Prolog中的不同素数分区

Prolog中的不同素数分区,prolog,computer-science,primes,clpfd,Prolog,Computer Science,Primes,Clpfd,我需要列举所有将给定数字n划分为一个或多个不同素数之和的方法,a+b+…+我在序言中 例如: 给定一个整数n,程序应将适当的和写入标准输出。例如,如果n=20,程序可能会打印 2 + 5 + 13 2 + 7 + 11 3 + 17 7 + 13 n可以是任何数字,并且对运行时没有限制 以下是我所拥有的: partition(N, _, []) :- N = 0. partition(N, [], _) :- fail. partition(N, [IH|IT], [OH|OT]) :-

我需要列举所有将给定数字n划分为一个或多个不同素数之和的方法,a+b+…+我在序言中

例如:

给定一个整数n,程序应将适当的和写入标准输出。例如,如果n=20,程序可能会打印

2 + 5 + 13
2 + 7 + 11
3 + 17
7 + 13
n可以是任何数字,并且对运行时没有限制

以下是我所拥有的:

partition(N, _, []) :- N = 0.
partition(N, [], _) :- fail.

partition(N, [IH|IT], [OH|OT]) :-
    N =< 0, fail;
    N >= IH, M is N-IH, OH = IH,
    partition(M, [IH|IT], OT).

partition(N, [_|IT], Output) :-
    N =< 0, fail;
    partition(N, IT, Output).

partition(N, Output) :-
    generatePrime(N,L),
    partition(N, L, Output).

generatePrime(1, []) :- !.
generatePrime(N, X) :-
    not(isPrime(N)), !,
    Z is N-1,
    generatePrime(Z,X).
generatePrime(N, [N | X]) :-
    Z is N-1,
    generatePrime(Z,X).

isPrime(2).
isPrime(P) :-
    P > 2,
    isDivisible(P, P-1). 

isDivisible(P,X) :-
    X > 1,
    P mod X =\= 0,
    isDivisible(P, X-1).
isDivisible(_, X) :-
    1 is X.
分区(N,,[]):-N=0。 分区(N,[],\u1):-失败。 分区(N[IH|IT],[OH|OT]):- N=<0,失败; N>=IH,M是N-IH,OH=IH, 分区(M[IH | IT],OT)。 分区(N,[[u124; IT],输出):- N=<0,失败; 分区(N,IT,Output)。 分区(N,输出):- 生成时间(N,L), 分区(N,L,输出)。 GenerateTime(1,[]):-!。 GenerateTime(N,X):- 不是(iPrime(N))!, Z是N-1, 生成时间(Z,X)。 GenerateTime(N[N|X]):- Z是N-1, 生成时间(Z,X)。 iPrime(2)。 iPrime(P):- P>2, 可分(P,P-1)。 可分(P,X):- X>1, P mod X=\=0, 可分(P,X-1)。 可分(X,X):- 1是X。 目前,我尝试运行以下内容:

[?-分区(5,X)

我得到了[5]和[3,2]的重复提示。当我使用n=20这样的大数字时,还有另一类问题,因为我得到了类似[2,2,2,2,2,2,2,2]这样的重复素数提示

我对prolog非常陌生,我相信可能有一种更简单的方法来解决这个问题,但我不确定我在代码中遇到了什么问题。

你的不太了解

更大的问题是您调用分区/3的方式

partition(5, generatePrime(5,Y), X)
partition/3
希望第二个学期有一个列表,而不是
generateTime(5,Y)

我建议您添加一个
分区/2
,如下所示

partition(N, Output) :-
    generatePrime(N, L),
    partition(N, L, Output).
并调用此版本的
分区

partition(5, X)
还有其他错误,因为此调用返回相同响应的时间更长(返回,在
X
[5]
四次和
[3,2]
两次)

我会看一看,看我是否发现了问题

---编辑---

很抱歉,我在理解带有剪切(
)、
失败(
)和或(
)的序言代码时遇到了大问题

我想这是我的问题

我用以下方式修改了您的
分区/3

partition(0, _, []).

partition(N, [H | It], [H | Ot]) :-
   N >= H,
   M is N-H,
   partition(M, [H | It], Ot).

partition(N, [_ | It], O) :-
   N > 0, 
   partition(N, It, O).
这应该避免重复列表

如果您希望避免在同一列表中重复素数(如果您不接受8的
[3,3,2]
[2,2,2]
,因为素数重复),那么您应该避免在以下对
分区/3
的调用中重复使用
H
IH

我的意思是下面的条款

partition(N, [H | It], [H | Ot]) :-
   N >= H,
   M is N-H,
   partition(M, [H | It], Ot).
应该成为

partition(N, [H | It], [H | Ot]) :-
   N >= H,
   M is N-H,
   partition(M, It, Ot).

这是一个相对有效的答案,在SWI Prolog中使用

您需要
:-在程序开始时使用_模块(库(clpfd))。

主谓词:
partition/2
这个谓词可以用一种非常简单的方式来描述:

partition(N,Z) :-
    findall(P, (P in 2..N, prime(P)), L),
    findall(S, ordered_subset_sum(L, S, N), Z).
简而言之:在
[2,N]
中查找所有的
p
,使它们成为素数。我们将这些素数存储在列表
L

然后,我们使用谓词
ordered_subset_sum/3
检查对
L
的有序子集
S
求和是否会产生
N
。我们将有效子集存储在
Z
中,这是我们的输出

ordered\u subset\u sum/3
  • 基本情况:空列表只能生成空子集;空子集的元素之和为
    0

  • 第二条:我们将列表的开头
    H
    保留在子集中;因此,我们想要达到的
    N
    的总和减少
    H
    ,导致
    M
    。如果
    M
    为负数,那么我们已经知道子集不能和到
    N
    ,它太大了

  • 第三条:我们忽略列表的头部,允许生成子集

prime/1
如果愿意,您可以重用谓词
isPrime
,例如:

prime(N) :-
    indomain(N),
    isPrime(N).
但我建议使用一种更有效的素数检查算法。我建议使用下面的算法,它远不是最优的,但比你的算法效率更高。它检查你的数的素数分解是否只有一个元素(只有素数)。你也可以看一下


谢谢你的回答。我会相应地编辑这个问题。我还注意到,当我使用像20这样的数字时,我有你所说的重复答案,但也有像[2,2,2,2,2,2,2,2,2,2]这样不明显的素数答案。@Ganda-修改了我的anser以显示如何避免重复(列表中的素数列表)。
prime(N) :-
    indomain(N),
    isPrime(N).
prime(N) :-
    prime_decomposition(N,[_P]).

prime_decomposition(N, Z) :-
    N #> 0,
    indomain(N),
    prime_decomposition_ceiled_square_root(N,SN),
    prime_decomposition_1(N, SN, 2, [], Z).
 
prime_decomposition_1(1, _, _, L, L) :- !.
prime_decomposition_1(N, SN, D, L, LF) :-
    (   
        0 #= N mod D ->
        Q #= N // D,
        prime_decomposition_ceiled_square_root(Q,SQ),
        prime_decomposition_1(Q, SQ, D, [D |L], LF)
        ;
        D1 #= D+1,
        (    
            D1 #> SN ->
            LF = [N |L]
            ;
            prime_decomposition_2(N, SN, D1, L, LF)
        )
    ).
    
prime_decomposition_2(1, _, _, L, L) :- !.
prime_decomposition_2(N, SN, D, L, LF) :-
    (   
        0 #= N mod D ->
        Q #= N // D,
        prime_decomposition_ceiled_square_root(Q,SQ),
        prime_decomposition_2(Q, SQ, D, [D |L], LF);
        D1 #= D+2,
        (    
            D1 #> SN ->
            LF = [N |L]
            ;
            prime_decomposition_2(N, SN, D1, L, LF)
        )
    ).
    
prime_decomposition_ceiled_square_root(0, 0).
prime_decomposition_ceiled_square_root(N0, Root) :-
        N1 #= N0 - 1,
        Max in 0..N1,
        R0^2 #= Max,
        Root #= Root0 + 1,
        fd_sup(R0, Root0).