Что ж Вы сразу не признались, что ведете учет в системе, которая была разработана 15 лет назад (хорошо еще не под DOS-ом). Она же даже с Microsoft SQL Server 2008 R2 не работает без бубна — подмены dll 1C.
Интересно было бы сравнить современные решения от 1С (Управление торговлей 8, 1С: Консолидация) и OLAP на SQL Server через Pivot Table в Excel по скорости формирования отчетов, удобству настройки измерений, затратам на внедрение.
А что если после границы Вселенной она начинает повторяться? Скажем, мы улетели вправо, а прилетим слева. Такую бесконечность можно реализовать конечным числом материи.
А если вы вообще про ИИ в играх, то уже давно есть боты для шашек и шахмат, которые делают неслучайные действия.
Это Вы выражаетесь очень мыслекорректно к ботам для шашек и шахмат. А можно ли эти действия назвать разумными? У каждого хода, если он делается разумным существом, должна быть цель. А сейчас мы имеем соперника в виде ИИ, который делает оптимизированный перебор ходов + имеет базу данных позиций, заложенную разработчиком. Это не цель, это способ имитации что у ИИ есть цель в его действиях.
Разумные существа были бы кстати везде — и в стрелялках, и в гонках, и в настольных играх.
Опять же, придираясь к заголовку, я ожидал в этой статье увидеть цель ИИ, ее обоснованный выбор и способ достижения цели.
Например: «не врезаться самому», «подрезать противника». В текущий момент времени одна из целей будет активной. Могут даже образовываться подцели. Например, ИИ про себя думает «я сейчас догоняю противника, чтобы на повороте его подрезать». Но способ выбора не должен быть рандомный. Вы же, когда играете в эту игру, принимаете решения пусть и быстро, но обоснованно? В идеале — на основе опыта. То есть если в прошлой игре ИИ принял решение «подрезать» и врезался сам, он должен извлечь опыт и в аналогичной ситуации остаться на цели «не врезаться». Можно ли как-то реализовать такое принятие решений?
Причем РЕШЕНИЕ [decision, model solution] — это
1. Выбор одной или нескольких альтернатив из множества возможных.
2. Процесс (алгоритм) осуществления такого выбора.
а в реализации
Math.random(); и «вместо случайной желаемой точки, я искал точку впереди врагов, чтобы перекрыть им путь»
Простите, но это не решение, а имитация (подражание) принятия решения.
Здесь же не нужно разговаривать на языке и анализировать речь, управлять конечностями в 3D чтобы ловить предметы и сохранять равновесие, распознавать образы при разном освещении, удаленности и наклоне.
Неужели даже для такой простой игры нельзя реализовать «сильный» ИИ?
Вопрос, наверное, не к автору, а вообще к разработчикам игр. Дайте нам умного соперника!
Это может быть наилучшим решением. Но какой же тоскливый стиль программирования фреймворками.
1. Либо в посте описывается «Я знаю как решить мою проблему при помощи фреймворка F» (о данном посте).
2. Либо «Я придумал как решить мою задачу примитивными средствами»
На что сразу же получаем коммент:
— А вы знаете о существовании фреймворка F?
Сжатое время разработки толкает к собиранию программы из готовых «кирпичиков». Но их очень и очень много, поэтому нужно знать все виды кирпичей фреймворки и быть в курсе, не подох ли очередной «кирпичный завод».
На этот раз Доуэль пришел в сознание, но все было по-другому. Он не чувствовал тела и это ощущение было ему знакомо. Но сейчас он был во мраке. Темнота окружала профессора, и это была абсолютная темнота, как будто он лишился зрения. Звуков также не было. Ни работы аппарата, ни шагов. Полная тишина.
— Где я? Что со мной произошло?
Но лишь беспорядочные образы возникали и снова исчезали. Мысли профессора оборвались от электрического разряда, но он не потерял нить рассуждений.
— Неужели к моей голове подключили электроды? А есть ли у меня голова?
Профессор не чувствовал языка и не мог пошевелить губами.
— Я мыслю, следовательно я существую?
От следующего разряда профессор потерял сознание.
Хороший подход в плане того, что все наименования будут одинаково отформатированы. Скажите, пожалуйста, пользователи запускают генерацию когда вводят накладные или заранее? И еще вопросы: генерится только текст или еще поля для отбора (к примеру нужно найти все шурупы диаметром 3 мм и длиной от 16 до 20 мм); рассматривался ли вариант вести учет в разрезе характеристик, когда в таблице наименований товаров будет только Шуруп, а длина, диаметр и т.д — в других таблицах?
А Вы смотрели ссылку на IOT от GlukKazan выше? Эта информация по Index-Organized Tables выложена на сайте Oracle, и там, насколько позволяют понять статью мои знания английского, весьма позитивный тон. Несмотря на некоторые издержки, в целом происходит именно ускорение доступа, как это ни странно. Примеры, почему это так, приведены прямо в статье.
Даже автор топика в своем «третьем моменте» упоминает, правда с опечаткой, про INDEX ORGANISED TABLES в списке средств ускорения доступа к данным.
Но вопрос даже не в том, какие таблицы лучше. Oracle дает возможность выбора, как будут храниться наши данные. Не заточен ли описанный в топике механизм логов для старых способов хранения данных и насколько он актуален для IOT и версионных данных?
Быстрый ли будет поиск, попробую описать без ссылок на другие источники. Вероятно, Вы согласитесь, что поиск по ключу в любом индексе выполняется быстро. А теперь представьте индекс, у которого ключ состоит из одного поля в виде целого числа. Поиск будет практически мгновенным!
Два слова об организации индексов вообще. Индекс состоит из иерархии страниц. На каждой странице содержатся элементы. В каждом элементе индекса присутствует ключ и ссылка. В верхнем элементе (узле) ссылка указывает на страницу ниже. В самом нижнем элементе (листе) ссылка в классическом варианте содержит физический адрес записи.
Теперь берем наш индекс с ключом по целому числу, и меняем структуру листа (самого нижнего элемента). Уберем ссылку на запись, и вместо нее мы будем хранить непосредственно сами данные. Это и будет таблица, организованная по индексу — стандартная вещь в Oracle.
Во вторичных индексах ссылками теперь будут не физические адреса, а целые числа — идентификаторы записей. Поиск по вторичному индексу будет дополняться поиском по нашей таблице-индексу. Но в ней поиск будет очень быстрым, т.к. мы изменили структуру только листа, а на верхних уровнях в узлах останутся пары ключ-ссылка. Из-за такого маленького размера узла их количество на странице будет большим, и таблица-дерево будет низким, но широким.
Можно прикинуть на примере.
Пусть размер страницы — 4 Кбайт, а размер записи (листового элемента) — 200 байт.
Количество записей на странице = 4096 / 200 = 20. То есть в дереве с одним уровнем можно будет разместить 20 записей.
Размер узла = 8 байт на идентификатор + 8 байт на ссылку = 16 байт;
Количество узлов на странице верхнего уровня = 4096 / 16 = 256, округлим до 200.
В дереве с двумя уровнями будет 200 * 20 = 4000 записей.
Чтобы разместить 32 000 000 000 записей, понадобится 5 уровней. То есть по ссылке из вторичного индекса мы приходим в корневую страницу, а из нее спускаемся по ссылкам 4 раза и получаем наши данные.
Это немного дольше, чем хранить во вторичном индексе сразу физический адрес записи. Но нужно учесть, что корневая страница таблицы-индекса и большое количество верхних страниц попадут в кэш и переход по ссылкам будет производиться в памяти.
Сортировка по идентификатору не обязательно требует постоянной физической перестановки записей. Пусть у нас идентификатором будет 64-разрядное целое. СУБД для новой записи инкрементирует это значение, поэтому любую новую запись достаточно разместить в конце таблицы, чтобы сохранить сортировку. Нет проблем и в модификации. Идентификатор — это суррогатный ключ (его значение не зависит от других полей). Поэтому запись остается со своим идентификатором при любых изменениях значений остальных полей. Только при физическом удалении записи нужно «сомкнуть ряды»: оставшиеся на странице элементы переместить ближе к началу, что является обычной операцией в индексах.
Теперь давайте вернемся к началу и соберем всё вместе. Если у записей будут идентификаторы, в элементах индексов можно будет ссылаться на эти идентификаторы, а не на физическое расположение записей. Это дает возможность сохранять блоки с записями в другое место, не перестраивая индексы. Если использовать эту возможность, и сохранять новые версии блоков на новое место, мы получаем версионность данных. Причем без логов.
В файле будет существовать некоторое количество блоков со старыми версиями наряду с новыми версиями этих же данных. Первое преимущество в отсутствии блокировок при чтении. Читающие транзакции начинают читать определенную версию и им глубоко безразлично, что пишущая транзакция сохраняет новые блоки.
Второе преимущество будет когда пишущая транзакция оборвется если «выдернуть сервер из розетки». Проблема будет только у этой конкретной транзакции. Все остальные данные останутся на своих местах. И я не очень понял как при наличии этих технологий (IOT и версионность блоков) процедура сохранения измененных данных такая сложная и длительная — со всеми этими обязательными копированиями в логи.
Записи придется физически упорядочить по идентификатору. А чтобы быстро находить нужную запись, таблица станет древовидной структурой, как индекс. Ведь это всё реализовано — кластерный первичный ключ, Index-Organized Tables из сообщения GlukKazan выше.
По фрагментации — пусть версии будут не у строк и не у записей, а у блоков. Все равно СУБД пишет на диск блоками.
Чтобы индексы лишний раз не обновлялись, можно в элементе индекса хранить не физический адрес записи, а ее уникальный идентификатор. К сожалению, это уже куда-то в сторону от обычных реляционных баз.
Апдейт создаст новую версию строки. Вот, к примеру, у нас есть запись ИВАНОВ. Мы ее исправляем на ПЕТРОВ. До начала редактирования с диска в память считывается ИВАНОВ, затем в оперативной памяти он меняется на ПЕТРОВ и эта строка пишется на диск. Я предлагаю всего лишь писать новую версию не затирая старую. Некоторое время в базе будут обе версии (и ИВАНОВ и ПЕТРОВ), пока все старые читающие транзакции не завершатся. Ну а потом новые пишущие транзакции затрут Иванова и останется только Петров.
Это ж сколько работы для СУБД (переходя в режим зануды). Предлагаю улучшение — писать новые данные не поверх старых, а где-то в другом месте в файл данных. Тогда не надо старые данные гонять в UNDO-файл, да и читающие транзакции не будут лазить в UNDO-файл за своим снимком данных. Получится такая вот естественная версионность.
Интересно было бы сравнить современные решения от 1С (Управление торговлей 8, 1С: Консолидация) и OLAP на SQL Server через Pivot Table в Excel по скорости формирования отчетов, удобству настройки измерений, затратам на внедрение.
Это Вы выражаетесь очень мыслекорректно к ботам для шашек и шахмат. А можно ли эти действия назвать разумными? У каждого хода, если он делается разумным существом, должна быть цель. А сейчас мы имеем соперника в виде ИИ, который делает оптимизированный перебор ходов + имеет базу данных позиций, заложенную разработчиком. Это не цель, это способ имитации что у ИИ есть цель в его действиях.
Опять же, придираясь к заголовку, я ожидал в этой статье увидеть цель ИИ, ее обоснованный выбор и способ достижения цели.
Например: «не врезаться самому», «подрезать противника». В текущий момент времени одна из целей будет активной. Могут даже образовываться подцели. Например, ИИ про себя думает «я сейчас догоняю противника, чтобы на повороте его подрезать». Но способ выбора не должен быть рандомный. Вы же, когда играете в эту игру, принимаете решения пусть и быстро, но обоснованно? В идеале — на основе опыта. То есть если в прошлой игре ИИ принял решение «подрезать» и врезался сам, он должен извлечь опыт и в аналогичной ситуации остаться на цели «не врезаться». Можно ли как-то реализовать такое принятие решений?
Причем РЕШЕНИЕ [decision, model solution] — это
1. Выбор одной или нескольких альтернатив из множества возможных.
2. Процесс (алгоритм) осуществления такого выбора.
а в реализации
Простите, но это не решение, а имитация (подражание) принятия решения.
Здесь же не нужно разговаривать на языке и анализировать речь, управлять конечностями в 3D чтобы ловить предметы и сохранять равновесие, распознавать образы при разном освещении, удаленности и наклоне.
Неужели даже для такой простой игры нельзя реализовать «сильный» ИИ?
Вопрос, наверное, не к автору, а вообще к разработчикам игр. Дайте нам умного соперника!
1. Либо в посте описывается «Я знаю как решить мою проблему при помощи фреймворка F» (о данном посте).
2. Либо «Я придумал как решить мою задачу примитивными средствами»
На что сразу же получаем коммент:
— А вы знаете о существовании фреймворка F?
Сжатое время разработки толкает к собиранию программы из готовых «кирпичиков». Но их очень и очень много, поэтому нужно знать все
виды кирпичейфреймворки и быть в курсе, не подох ли очередной «кирпичный завод».— Где я? Что со мной произошло?
Но лишь беспорядочные образы возникали и снова исчезали. Мысли профессора оборвались от электрического разряда, но он не потерял нить рассуждений.
— Неужели к моей голове подключили электроды? А есть ли у меня голова?
Профессор не чувствовал языка и не мог пошевелить губами.
— Я мыслю, следовательно я существую?
От следующего разряда профессор потерял сознание.
Даже автор топика в своем «третьем моменте» упоминает, правда с опечаткой, про INDEX ORGANISED TABLES в списке средств ускорения доступа к данным.
Но вопрос даже не в том, какие таблицы лучше. Oracle дает возможность выбора, как будут храниться наши данные. Не заточен ли описанный в топике механизм логов для старых способов хранения данных и насколько он актуален для IOT и версионных данных?
Два слова об организации индексов вообще. Индекс состоит из иерархии страниц. На каждой странице содержатся элементы. В каждом элементе индекса присутствует ключ и ссылка. В верхнем элементе (узле) ссылка указывает на страницу ниже. В самом нижнем элементе (листе) ссылка в классическом варианте содержит физический адрес записи.
Теперь берем наш индекс с ключом по целому числу, и меняем структуру листа (самого нижнего элемента). Уберем ссылку на запись, и вместо нее мы будем хранить непосредственно сами данные. Это и будет таблица, организованная по индексу — стандартная вещь в Oracle.
Во вторичных индексах ссылками теперь будут не физические адреса, а целые числа — идентификаторы записей. Поиск по вторичному индексу будет дополняться поиском по нашей таблице-индексу. Но в ней поиск будет очень быстрым, т.к. мы изменили структуру только листа, а на верхних уровнях в узлах останутся пары ключ-ссылка. Из-за такого маленького размера узла их количество на странице будет большим, и таблица-дерево будет низким, но широким.
Можно прикинуть на примере.
Пусть размер страницы — 4 Кбайт, а размер записи (листового элемента) — 200 байт.
Количество записей на странице = 4096 / 200 = 20. То есть в дереве с одним уровнем можно будет разместить 20 записей.
Размер узла = 8 байт на идентификатор + 8 байт на ссылку = 16 байт;
Количество узлов на странице верхнего уровня = 4096 / 16 = 256, округлим до 200.
В дереве с двумя уровнями будет 200 * 20 = 4000 записей.
Чтобы разместить 32 000 000 000 записей, понадобится 5 уровней. То есть по ссылке из вторичного индекса мы приходим в корневую страницу, а из нее спускаемся по ссылкам 4 раза и получаем наши данные.
Это немного дольше, чем хранить во вторичном индексе сразу физический адрес записи. Но нужно учесть, что корневая страница таблицы-индекса и большое количество верхних страниц попадут в кэш и переход по ссылкам будет производиться в памяти.
Теперь давайте вернемся к началу и соберем всё вместе. Если у записей будут идентификаторы, в элементах индексов можно будет ссылаться на эти идентификаторы, а не на физическое расположение записей. Это дает возможность сохранять блоки с записями в другое место, не перестраивая индексы. Если использовать эту возможность, и сохранять новые версии блоков на новое место, мы получаем версионность данных. Причем без логов.
В файле будет существовать некоторое количество блоков со старыми версиями наряду с новыми версиями этих же данных. Первое преимущество в отсутствии блокировок при чтении. Читающие транзакции начинают читать определенную версию и им глубоко безразлично, что пишущая транзакция сохраняет новые блоки.
Второе преимущество будет когда пишущая транзакция оборвется если «выдернуть сервер из розетки». Проблема будет только у этой конкретной транзакции. Все остальные данные останутся на своих местах. И я не очень понял как при наличии этих технологий (IOT и версионность блоков) процедура сохранения измененных данных такая сложная и длительная — со всеми этими обязательными копированиями в логи.
Чтобы индексы лишний раз не обновлялись, можно в элементе индекса хранить не физический адрес записи, а ее уникальный идентификатор. К сожалению, это уже куда-то в сторону от обычных реляционных баз.
То есть перед записью новых данных сначала происходит обязательное копирование старых данных в другой файл?