Пролог: Как выбрать наибольшее значение из набора случайных чисел - PullRequest
0 голосов
/ 15 марта 2011

ОК, вопрос немного сформулирован, но я хочу выбрать N чисел от 0 до MAX, используя rand_int, и выбрать наибольшее значение.

Вот как я пытаюсь это сделать, но по какой-то причине это не работает:

rand_val(Count, Rng, Res) :-
    Count > 0,
    Count is Count - 1,
    rand_int(Rng, X),
    Res is max(X, Res),
    rand_val(Count, Rng, Res).

?- rand_val(2,100,Res).
-> no.

Я новичок в Прологе (изучаю его всего несколько часов), поэтому, наверное, просто неправильно что-то понял.

Ответы [ 2 ]

2 голосов
/ 15 марта 2011

Мой Пролог ржавый, поэтому я, возможно, что-то упустил, однако очевидная проблема в вашем коде такова: Count is Count - 1.

То, что вы написали, является уравнением (как в математике) x = x - 1. Очевидно, что это уравнение не имеет решений. Вот что двигатель Prolog подразумевает под своим «Нет». Вы можете попробовать переписать его как NextCount is Count - 1 (и позже использовать NextCount вместо Count).

2 голосов
/ 15 марта 2011

Ваша проблема в том, что вы не можете создать экземпляр переменной, для которой уже создан другой термин.Таким образом, если Count уже создан (скажем, с помощью 2), вы не можете сделать Count is Count - 1.

Оператору is / 2 требуется, чтобы левая переменная не была создана (или была создана с фактическим значением выражения)и правильное выражение для полной оценки.То же самое относится и к рекурсивному вызову.После создания экземпляра Res для целого числа вы не можете изменить его значение на другое целое число.

Вот еще одна реализация:

rand_val(Count, Rng, Res):-
  rand_val(Count, Rng, -1, Res).

rand_val(0, _, Value, Value):-
  !,
  Value >= 0.
rand_val(Count, Rng, MValue, Value) :-
  succ(NCount, Count),
  X is random(Rng), %rand_int(Rng, X),
  NValue is max(X, MValue),
  rand_val(NCount, Rng, NValue, Value).

Первое замечание, что я написал два предиката rand_val / 3 и rand_val / 4,Первый - тот, с подписью которого вы хотите.У последнего есть еще один аргумент, который будет содержать максимальное значение, найденное в тот момент.

Первый предикат просто вызывает rand_val / 4, присваивая значение -1 как максимальное найденное значение.

ТеперьПервое предложение rand_val / 4 проверяет, равен ли его входной аргумент «Count» 0. В этом случае он запрещает возврат (используя вырез) и проверяет, является ли Value допустимым значением.Если это <0, то это потому, что вы вызвали rand_val / 3 с Count = 0, поэтому он действительно никогда не выдавал случайное число. </p>

Если это> 0, он просто объединяет третий и четвертый аргумент (обратите внимание, чточетвертый аргумент - это значение, которое вы ожидаете получить на выходе).

Теперь перейдем ко второму предложению: сначала выполняется succ (NCount, Count), где NCount - новая переменная.Он будет создан с предшественником Count (Count-1).

Затем мы вычисляем случайное число.Я использую пролог SWI, поэтому я называю random (Max), чтобы получить случайное число.Это создает новую переменную X вместе с ней.

В этот момент у нас есть выбор наибольшего значения между промежуточным результатом (MValue) и X.

Наконец, мы делаем рекурсивный шаг, теперь вызываемrand_val / 4 с новыми вычисленными значениями NCount и NValue.

Обратите внимание, что переменная Value создается, когда мы возвращаемся из рекурсии (она становится связанной в первом предложении rand_val / 4).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...