как реализовать недетерминированный конечный автомат?

210
24 апреля 2018, 02:40

Задание: написать функцию, которая выполняет один цикл работы недетермированного конечного автомата и процедуру распознавания слов недетерминированным конечным автоматом.

Есть псевдокод, который определяет, допускает ли НКА данное слово или нет.

Не понимаю, как его применить к представленной схеме на рисунке.

  1. R-множество достижимых состояний,
  2. w-слово,
  3. T-множество допускающих состояний автомата,
  4. δ — функция переходов,
  5. Σ — алфавит,
  6. Q — множество состояний автомата,
  7. s — начальное состояние автомата.

var states = { 
    q0:{ 
        name: 'q0', 
        isFinish: false, 
        next: { 
            'a': 'q3', 
            'a': 'q6', 
            'a': 'q5' 
        } 
    }, 
 
    q1: { 
        name: 'q1', 
        isFinish: false, 
        next: { 
            'a': 'q5', 
            'a': 'q6' 
        } 
    }, 
 
    q3: { 
      name: 'q3', 
      isFinish: true, 
      next: { 
          'b':'q4' 
      } 
    }, 
 
    q4: { 
        name: 'q4', 
        isFinish: true, 
        next: { 
            'b': 'q4' 
        } 
    }, 
 
    q5: { 
        name: 'q5', 
        isFinish: false, 
        next: { 
            'b': 'q1' 
        } 
    } 
};
<input type="button" value="Запустить КА" onclick="start()">

Answer 1

С недетерминированным автоматом, все несколько сложнее.

Фактически, автомат может находиться сразу в нескольких состояниях, поэтому нужно проверять сразу все возможный переходы.

Если немного расписать указанный псевдокод, получится так:

  1. Устанавливаем начальное состояние
  2. Для каждого символа из строки
    1. Устанавливаем доступные состояния в пустое множество
    2. Идем по всем переходам из предыдущего состояния
    3. Если переход возможен сохраняем доступное состояние
  3. Проверяем что конечное множество переходов пересекается со множеством конечных состояний.

Под этот алгоритм нужно немного изменить хранение состояний: теперь вместо одного значения по ключу в объекте next, будет хранится массив.

q0:{
    name: 'q0',
    isFinish: false,
    next: {'a': ['q3', 'q6', 'q5']}
}

Для работы с множествами можно воспользоваться Set

Функция перехода может выглядеть следующим образом:

function step(nexts, symbol) {
  return [
    ...new Set( // отбираем только уникальные имена состояния
      [].concat( // собираем все в один большой список
        ...nexts.filter(c => c[symbol]) // отбираем состояния куда можем перейти по символу
        .map(c => c[symbol]) // получаем списки возможных переходов
      )
    )
  ].map(c => states[c]) // по имени состояний получаем сами состояния
}

На входе получаем список всех возможных переходов, на выходе - список возможных переходов по указанному символу.

После прохождения всей цепочки смотрим список состояний в которых мы можем находиться, и если есть хотя бы одно конечное состояние - цепочка распознана.

Пример реализации:

var states = { 
  q0: { 
    name: 'q0', 
    isFinish: false, 
    next: { 
      'a': ['q3', 'q6', 'q5'] 
    } 
  }, 
 
  q1: { 
    name: 'q1', 
    isFinish: false, 
    next: { 
      'a': ['q5', 'q6'] 
    } 
  }, 
 
  q3: { 
    name: 'q3', 
    isFinish: true, 
    next: { 
      'b': ['q4'] 
    } 
  }, 
 
  q4: { 
    name: 'q4', 
    isFinish: true, 
    next: { 
      'b': ['q4'] 
    } 
  }, 
 
  q5: { 
    name: 'q5', 
    isFinish: false, 
    next: { 
      'b': ['q1'] 
    } 
  }, 
  q6: { 
    name: 'q6', 
    isFinish: true, 
    next: {} 
  } 
}; 
 
function step(nexts, symbol) { 
  return [ 
    ...new Set( // отбираем только уникальные имена состояния 
      [].concat( // собираем все в один большой список 
        ...nexts.filter(c => c[symbol]) // отбираем состояния куда можем перейти по символу 
        .map(c => c[symbol]) // получаем списки возможных переходов 
      ) 
    ) 
  ].map(c => states[c]) // по имени состояний получаем сами состояния 
} 
 
function start(w) { 
  var current = [states.q0]; 
  for (var i = 0; i < w.length; i++) { 
    current = step(current.map(c => c.next), w[i]); 
  } 
  var terminated = current.filter(c => c.isFinish); // получаем список конечных состояний из текущего списка, если есть хотя бы одно конечное состояние - цепочка распознаная 
  console.log(terminated.length > 0); 
}
<input type="button" value="Запустить КА" onclick="start('ababa')">

READ ALSO
Как можно определить на какую букву заканчивается слово?

Как можно определить на какую букву заканчивается слово?

У меня есть бот для вкМне нужно сделать так, чтобы бот мог читать последнюю букву слова которое пришлет человек

147
Как сделать кнопку &ldquo;лайк&rdquo; в Fancybox?

Как сделать кнопку “лайк” в Fancybox?

Суть вот в чем - нужно при открытии картинки в лайтбоксе отображение кнопки "Лайк", которая присутствует на каждом изображении на странице

159
оживить скрипт в IE

оживить скрипт в IE

Доброго дня! Скрипт работает везде, кроме IEПомогите разобраться

170
Скрыть элементы

Скрыть элементы

Есть код такого плана, в поле "Тип вмешательства" при выборе ККГ должны открывать допполя, при выборе другого значения, скрываться, но что-то...

208