Обобщающая последовательность Фибоначчи с помощью SICStus Prolog

Я пытаюсь найти решение для запроса по обобщенной последовательности Фибоначчи (GFS). Вопрос: есть ли GFS, у которых 885 в качестве 12-го числа? Начальные 2 числа могут быть ограничены от 1 до 10.

Я уже нашел решение найти N-е число в последовательности, начинающейся с (1, 1), в которой я явно определяю начальные числа. Вот что у меня есть для этого:

fib(1, 1).
fib(2, 1).

fib(N, X) :-
    N #> 1,
    Nmin1 #= N - 1,
    Nmin2 #= N - 2,
    fib(Nmin1, Xmin1),
    fib(Nmin2, Xmin2),
    X #= Xmin1 + Xmin2.

Для упомянутого запроса я подумал, что следующее поможет, в котором я повторно использую метод fib без явного определения начальных чисел, поскольку теперь это нужно делать динамически:

fib(N, X) :-
    N #> 1,
    Nmin1 #= N - 1,
    Nmin2 #= N - 2,
    fib(Nmin1, Xmin1),
    fib(Nmin2, Xmin2),
    X #= Xmin1 + Xmin2.

fib2 :-
    X1 in 1..10,
    X2 in 1..10,
    fib(1, X1),
    fib(2, X2),
    fib(12, 885).

... но это не похоже на работу.

Разве невозможно таким образом определить начальные числа, или я делаю что-то ужасно неправильно? Я не прошу решения, но любой совет, который мог бы помочь мне решить это, был бы очень признателен.

6 ответов

Под SWI-Прологом:

:- use_module(library(clpfd)).

fib(A,B,N,X):-
    N #> 0,
    N0 #= N-1,
    C #= A+B,
    fib(B,C,N0,X).
fib(A,B,0,A).

task(A,B):-
    A in 1..10,
    B in 1..10,
    fib(A,B,11,885).

Определите предикат gfs(X0, X1, N, F), где X0 и X1 - значения для базовых случаев 0 и 1.

Может быть, не решение в строгом смысле, но я поделюсь им, тем не менее. Вероятно, единственный выигрыш - показать, что для этого не нужен ни компьютер, ни калькулятор. Если вы знаете трюк, это можно сделать на медвежонке.

Если F_n - это n-й Термин обычной Фибо-последовательности, начиная с F_1 = F_2 = 1, то n-й Термин обобщенной последовательности будет G_n = F_ {n-2} * a + F_ {n- 1} * б. Определить F _ {- 1} = 1, F_0 = 0

(Действительно, по индукции

  • G_1 = F _ {- 1} * a + F_0 * b = 1 * a + 0 * b = a
  • G_2 = F_0 * a + F_1 * b = 0 * a + 1 * b = b
  • G_ {n + 1} = F_ {n-1}a + F_n b = (F_ {n-3} + F_ {n-2}) a + (F_ {n-2} + F_ {n-1}) * b = G_n + G_ {n-1}

)

Таким образом, G_12 = F_10 * a + F_11 * b = 55a + 89b.

Теперь вы можете либо искать решения уравнения 55a + 89b = 885 с вашим компьютером

ИЛИ ЖЕ

делай математику:

Остатки мод 11 ( пояснения):

55a + 89b = 0 + 88b + b = b; 885 = 880 + 5 = 80 * 11 + 5 = 5

Таким образом, b = 5 mod 11, но, поскольку 1 <= b <= 10, b действительно равно 5. 89 * 5 = 445 и 885-445 = 440. Теперь разделим на 55 и получим a=8.

Я бы сказал, что вы делаете что-то ужасно неправильно... Когда вы звоните fib(1, X1)переменная X1 - это число, которое выполняет функция fib вернет, в этом случае это будет 1, из-за базового случая fib(1, 1).,

Без базовых случаев, fib/2 не имеет решения; независимо от того, как вы называете это в fib2. Примечание: если вы используете рекурсию, вам нужен как минимум один базовый вариант.

Рассматривать fib(N,F1,F2) так что вы сможете заменить fib(Nmin1, Xmin1) а также fib(Nmin2, Xmin2) с простым fib(Nmin2, Xmin2, Xmin1),

Другие вопросы по тегам