Полный NP означает что-то очень определенное, и необходимо быть осторожными, или Вы поймете определение превратно. Во-первых, проблемой NP является да/нет проблема, таким образом что
проблема А X Полна NP, если
, Если X полно NP и детерминированный, полиномиально-разовый алгоритм существует, который может решить все экземпляры X правильно (0% ложных положительных сторон, 0%-х ложных отрицательных сторон), тогда любая проблема в NP может быть решена в deterministic-polynomial-time (сокращением к X).
До сих пор, никто не придумал такой детерминированный полиномиально-разовый алгоритм, но никто не доказал, что каждый не существует (существует миллион маркеров для любого, кто может сделать также: P = проблема NP ). Это не означает, что Вы не можете решить конкретный экземпляр Полного NP (или NP-трудный) проблема. Это просто означает, что у Вас не может быть чего-то, что будет работать надежно над всеми экземплярами проблемы тем же путем, Вы могли надежно отсортировать список целых чисел. Вы могли бы очень хорошо быть в состоянии придумать алгоритм, который будет работать очень хорошо над всеми практическими экземплярами NP-трудной проблемы.
Один из способов использования сопрограмм в играх - это использование легких потоков в модели, подобной актору, как в Kamaelia .
Каждый объект в вашей игре будет Камаэлийская «составляющая». Компонент - это объект, который может приостановить выполнение, уступив, когда это разрешено. Эти компоненты также имеют систему обмена сообщениями, которая позволяет им безопасно обмениваться данными друг с другом в асинхронном режиме.
Все объекты будут одновременно делать свои собственные дела, с сообщениями, отправляемыми друг другу, когда происходят взаимодействия.
Так что на самом деле это не так. специфичны для игр, но что угодно, когда у вас есть множество взаимодействующих компонентов, действующих одновременно, может выиграть от сопрограмм.
Сопрограммы позволяют создавать большое количество очень легких «микропотоков» с совместной многозадачностью (т. Е. Микропотоки самовольно приостанавливаются, чтобы позволить другим микропотокам работать). Прочтите на эту тему статью Дейва Бизли
. Теперь очевидно, как такие микропотоки могут быть полезны для программирования игр. Представьте себе стратегию в реальном времени, в которой у вас есть десятки юнитов, у каждого из которых свой ум. Это может быть удобная абстракция для запуска ИИ каждого устройства в качестве микропотока в моделируемой многозадачной среде. Это всего лишь один пример, я уверен, что их гораздо больше.
Поиск в Google «программирование сопрограмм» дает интересные результаты.
Две ссылки, которые могут вас заинтересовать:
http://aigamedev.com/open/articles/coroutine-state-machine/
http: //www.dabeaz. com / coroutines / (ищите "задача" на этой странице и в PDF-файле)
Довольно часто возникает желание использовать сопрограммы для представления сценариев ИИ отдельных акторов. К сожалению, люди часто забывают, что сопрограммы имеют те же проблемы синхронизации и взаимного исключения, что и потоки, только на более высоком уровне. Таким образом, вам часто необходимо, во-первых, сделать все возможное для устранения локального состояния, а во-вторых, написать надежные способы обработки ошибок в сопрограмме, которые возникают, когда что-то, на что вы ссылались, перестает существовать.
Так что на практике они вполне приемлемы. трудно получить выгоду, поэтому такие языки, как UnrealScript, которые используют некоторое подобие сопрограмм, выталкивают большую часть полезной логики на атомарные события. Некоторые люди получают от них хорошую пользу, например. люди EVE Online, но им пришлось в значительной степени спроектировать всю свою систему вокруг этой концепции.
Наиболее ярким случаем сопрограмм являются, вероятно, старые графические приключенческие игры с указанием и щелчком, где они использовались для создания сценариев кат-сцен и других анимационных последовательностей в игре. Простой пример кода будет выглядеть так:
# script_file.scr
bob.walkto(jane)
bob.lookat(jane)
bob.say("How are you?")
wait(2)
jane.say("Fine")
...
Вся эта последовательность не может быть записана как обычный код, так как вы хотите увидеть, как Боб делает свою анимацию ходьбы после того, как вы вместо bob.walkto (jane)
перехода прямо на следующую строку. Однако для воспроизведения анимации ходьбы вам необходимо вернуть управление движку игры, и именно здесь в игру вступают сопрограммы.
Вся эта последовательность выполняется как сопрограмма, что означает, что у вас есть возможность приостанавливать и возобновлять ее по своему усмотрению. Команда типа bob.walkto (jane)
, таким образом, сообщает объекту боба на стороне двигателя его цель, а затем приостанавливает выполнение сопрограммы, ожидая пробуждения, когда Боб достигнет своей цели.
Что касается движка. может выглядеть так (псевдокод):
class Script:
def __init__(self, filename):
self.coroutine = Coroutine(filename)
self.is_wokenup = True
def wakeup(self):
self.is_wokenup = False;
def update():
if self.is_wokenup:
coroutine.run()
class Character:
def walkto(self, target, script):
self.script = script
self.target = target
def update(self):
if target:
move_one_step_closer_to(self.target)
if close_enough_to(self.target):
self.script.wakeup()
self.target = None
self.script = None
objects = [Character("bob"), Character("jane")]
scripts = [Script("script_file.scr")]
while True:
for obj in objects:
obj.update()
for scr in scripts:
scr.update()
Небольшое предупреждение, однако, хотя сопрограммы делают кодирование этих последовательностей очень простым, не все их реализации, которые вы найдете, будут построены с учетом сериализации, поэтому сохранение игры станет довольно проблемная проблема, если вы интенсивно используете сопрограммы.
Этот пример также является самым простым случаем сопрограммы в игре, сами сопрограммы также могут использоваться для множества других задач и алгоритмов.
это означает, что у вас есть возможность приостанавливать и возобновлять его по своему усмотрению. Команда типа bob.walkto (jane)
, таким образом, сообщает объекту боба на стороне двигателя его цель, а затем приостанавливает выполнение сопрограммы, ожидая пробуждения, когда Боб достигнет своей цели.
Что касается движка. может выглядеть так (псевдокод):
class Script:
def __init__(self, filename):
self.coroutine = Coroutine(filename)
self.is_wokenup = True
def wakeup(self):
self.is_wokenup = False;
def update():
if self.is_wokenup:
coroutine.run()
class Character:
def walkto(self, target, script):
self.script = script
self.target = target
def update(self):
if target:
move_one_step_closer_to(self.target)
if close_enough_to(self.target):
self.script.wakeup()
self.target = None
self.script = None
objects = [Character("bob"), Character("jane")]
scripts = [Script("script_file.scr")]
while True:
for obj in objects:
obj.update()
for scr in scripts:
scr.update()
Небольшое предупреждение, однако, хотя сопрограммы делают кодирование этих последовательностей очень простым, не все их реализации, которые вы найдете, будут построены с учетом сериализации, поэтому сохранение игры станет довольно проблемная проблема, если вы интенсивно используете сопрограммы.
Этот пример также является самым простым случаем сопрограммы в игре, сами сопрограммы также могут использоваться для множества других задач и алгоритмов.
это означает, что у вас есть возможность приостанавливать и возобновлять его по своему усмотрению. Команда типа bob.walkto (jane)
, таким образом, сообщает объекту боба на стороне двигателя его цель, а затем приостанавливает выполнение сопрограммы, ожидая пробуждения, когда Боб достигнет своей цели.
Что касается движка. может выглядеть так (псевдокод):
class Script:
def __init__(self, filename):
self.coroutine = Coroutine(filename)
self.is_wokenup = True
def wakeup(self):
self.is_wokenup = False;
def update():
if self.is_wokenup:
coroutine.run()
class Character:
def walkto(self, target, script):
self.script = script
self.target = target
def update(self):
if target:
move_one_step_closer_to(self.target)
if close_enough_to(self.target):
self.script.wakeup()
self.target = None
self.script = None
objects = [Character("bob"), Character("jane")]
scripts = [Script("script_file.scr")]
while True:
for obj in objects:
obj.update()
for scr in scripts:
scr.update()
Небольшое предупреждение, однако, хотя сопрограммы делают кодирование этих последовательностей очень простым, не все их реализации, которые вы найдете, будут построены с учетом сериализации, поэтому сохранение игры станет довольно проблемная проблема, если вы интенсивно используете сопрограммы.
Этот пример также является самым простым случаем сопрограммы в игре, сами сопрограммы также могут использоваться для множества других задач и алгоритмов.