【发布时间】:2016-09-26 20:13:56
【问题描述】:
标题说明了一切。我正在寻找计算两个多项式的 GCD。有什么方法可以在 Prolog 中完成吗?如果是这样,什么是一个好的起点?具体来说,我在如何使用 Prolog 实现多项式除法方面遇到了麻烦。
编辑以包含示例输入和输出:
示例输入:
?- GCD(x^2 + 7x + 6, x2 − 5x − 6, X).
示例输出:
X = x + 1.
解决方案
万一其他人需要这样做,这是我的最终解决方案:
tail([_|Tail], Tail).
head([Head | _], Head).
norm(Old, N, New) :-
length(Tail, N),
append(New, Tail, Old).
norm(Old, N, []) :-
length(Old, L),
N > L.
mult_GCD(List, GCD) :- length(List, L),
L > 2, tail(List, Tail),
mult_GCD(Tail, GCD).
mult_GCD([H | T], GCD) :-
length(T, L),
L == 1, head(T, N),
gcd(H, N, GCD).
lead(List, List) :-
length(List, L),
L == 1.
lead([0 | Tail], Out) :-
!, lead(Tail, Out).
lead([Head | Tail], [Head | Tail]) :- Head =\= 0.
poly_deg([], 0).
poly_deg(F, D) :-
lead(F, O),
length(O, N),
D is N - 1.
poly_red([0], [0]).
poly_red(Poly, Out) :-
mult_GCD(Poly, GCD),
scal_div(Poly, GCD, Out).
poly_sub(Poly,[],Poly) :- Poly = [_|_].
poly_sub([],Poly,Poly).
poly_sub([P1_head|P1_rest], [P2_head|P2_rest], [PSub_head|PSub_rest]) :-
PSub_head is P1_head-P2_head,
poly_sub(P1_rest, P2_rest, PSub_rest).
scal_prod([],_Sc,[]).
scal_prod([Poly_head|Poly_rest], Sc, [Prod_head|Prod_rest]) :-
Prod_head is Poly_head*Sc,
scal_prod(Poly_rest, Sc, Prod_rest).
scal_div([],_,[]).
scal_div([Poly_head|Poly_rest], Sc, [Prod_head|Prod_rest]) :-
Prod_head is Poly_head / Sc,
scal_div(Poly_rest, Sc, Prod_rest).
poly_div(Num, Den, OutBuild, Out) :-
poly_deg(Num, X),
poly_deg(Den, Y),
X < Y,
Out = OutBuild.
poly_div(INum, IDen, OutBuild, Out) :-
lead(INum, [NumHead | NumTail]), lead(IDen, [DenHead | DenTail]),
Q is NumHead / DenHead,
append(OutBuild, [Q], Out1),
append([DenHead], DenTail, DenNorm), append([NumHead], NumTail, Num),
scal_prod(DenNorm, Q, DenXQ),
poly_sub(Num, DenXQ, N),
poly_div(N, IDen, Out1, Out).
poly_mod(Num, Den, Out) :-
poly_deg(Num, X), poly_deg(Den, Y),
X < Y,
lead(Num, Out1),
poly_red(Out1, Out2),
lead(Out2, Out).
poly_mod(INum, IDen, Out) :-
lead(INum, [NumHead | NumTail]), lead(IDen, [DenHead | DenTail]),
Q is NumHead / DenHead,
append([DenHead], DenTail, DenNorm), append([NumHead], NumTail, Num),
scal_prod(DenNorm, Q, DenXQ),
poly_sub(Num, DenXQ, N),
poly_mod(N, IDen, Out).
poly_gcd(X, Y, X):- poly_deg(Y, O), O == 0, !.
poly_gcd(Y, X, X):- poly_deg(Y, O), O == 0, !.
poly_gcd(X, Y, D):- poly_deg(X, Xd), poly_deg(Y, Yd), Xd > Yd, !, poly_mod(X, Y, Z), poly_gcd(Y, Z, D).
poly_gcd(X, Y, D):- poly_mod(Y, X, Z), poly_gcd(X, Z, D).
gcd(X, Y, Z) :-
X < 0, X > Y, !,
X1 is X - Y,
gcd(-X, Y, Z).
gcd(X, Y, Z) :-
Y < 0, Y >= X, !,
Y1 is Y - X,
gcd(X, -Y, Z).
gcd(X, 0, X).
gcd(0, Y, Y).
gcd(X, Y, Z) :-
X > Y, Y > 0,
X1 is X - Y,
gcd(Y, X1, Z).
gcd(X, Y, Z) :-
X =< Y, X > 0,
Y1 is Y - X,
gcd(X, Y1, Z).
gcd(X, Y, Z) :-
X > Y, Y < 0,
X1 is X + Y,
gcd(Y, X1, Z).
gcd(X, Y, Z) :-
X =< Y, X < 0,
Y1 is Y + X,
gcd(X, Y1, Z).
【问题讨论】:
-
是的,它应该能够处理任何指数。这完全有可能在 Prolog 中不太可能,我只是希望真正擅长 Prolog 的人告诉我。
-
Prolog 是一种通用编程语言。如果你可以用电脑来做,你应该可以用 Prolog 来做。首先,尝试搜索并查找您的问题是否尚未解决。然后,如果没有,请找到一个满足您需要的算法,并尝试在 Prolog 中实现它。如果你遇到了你自己无法解决的问题,展示你的代码,解释问题,解释你自己无法解决的问题。我不打算投票结束这个问题,但它现在已经成熟了。
-
我的问题是我真的不知道如何开始。我有一个为整数计算 GCD 的版本,但我不知道从哪里开始多项式除法。这不是我第一次来这里,我知道在问之前先搜索一下,据我所知,网上确实没有关于这个话题的任何内容。
-
好吧,关于多项式 gcd 的维基百科页面有用于对多项式进行欧几里德除法的伪代码,并展示了如何使用它来查找多项式的 gcd。你试过阅读这篇文章吗?
-
是的,我已经阅读了这篇文章。不幸的是,它似乎假设多项式除法,这正是我遇到的麻烦。同样,我的问题是我不知道如何开始,如果我写了一些代码,我会发布它,但事实上,我什至想不出办法来解决这个问题。跨度>
标签: prolog polynomial-math greatest-common-divisor