Мешанина какая-то.
Ну да, драйстоуны, ветстоуны, компиляторы, интерпретаторы, байткод, кэш, code bloat — все это прекрасные слова, но зачем вы все это свалили в одну кучу и приправили жиденькими, бесполезными рекомендациями?
Рекомендации должны быть предметными, а не «вообще».
— Важна производительность именно вычислительная? Тогда — компилируемые языки, многопоточность, распаралеливание, использование GPU (OpenCL, CUDA), распределенные вычисления. У вас из всего этого — только мутноватые рассуждения о производительности и издевательские рекомендации писать на ассемблере. Издевательские — потому что современные компиляторы генерируют код весьма высокого качества, а попытки оптимизировать его вручную обычно приводят к тому, что «оптимизированная» программа работает медленнее оригинала. Кроме того, писать на ассемблере под тот же ARM — занятие для истинных гурманов.
— Важен отклик пользовательского интерфейса программы? Тогда — правильное проектирование, обработка длительных операций в отдельном потоке, и пофиг на язык программирования. Время комфортного отклика на действия пользователя — ЕМНИП, что-то около 250 миллисекунд. На такую производительность вполне способны даже весьма медленные языки программирования.
— Важен малый объем программы? Тогда — использование «легких» фреймворков, языков программирования, выдающих компактный результирующий код, и т. п.Но лично мне проблема «жира» в программах кажется слегка надуманной: на десктопных компьютерах основное ОЗУ жрут картинки и иконки, а на всяческих маломощных контроллерах обычно выбор языка программирования невелик: или пишешь на том, что предоставил производитель контроллера, или не пишешь вообще.
Если оклад зависит от часов — люди будут спать, заниматься своими личными делами и т. п. на работе.
Если оклад фиксированный плюс штрафы/бонусы — то будет повышенная текучка. Это только в воспаленном мозгу директора, получающего фиксированный оклад, может возникнуть мысль, что штраф приведет к повышению качества работы. По факту штраф — это обида сотрудника на компанию, т.к. в большинстве случаев сотрудник себя виноватым не считает. Плюс снижается его уверенность в завтрашнем дне.
Если человек не может спланировать расходы из-за того, что его зарплата «болтается» туда-сюда из-за штрафов и бонусов — это минус. Допустим, к бонусам можно отнестись как к неожиданному приятному сюрпризу (при этом приязнь не переносится на компанию). Но вот штраф — однозначно трактуется как «меня тут не ценят». Как следствие — пара штрафов, и специалист уходит к конкурентам, которые не внедряют таких «прогрессивных схем оплаты».
И ещё, я предполагаю что там ошибка в утилите, потому как там в результате выводятся сектора через интервал, меньший чем размер области. Это подходит для обоих вариантов мегабайта. По крайней мере так происходит на больших значениях. 420 пробовал.
Вот, собственно, код, который вычисляет границы области:
// we have a span. Define its lower and higher boundaries.
qint64 const offset = ( badBlock * SECTORSIZE ) / minSpan;
qint64 const lowBlock = ( offset * minSpan ) / SECTORSIZE;
qint64 const uppBlock = lowBlock + minSpan / SECTORSIZE;
minSpan — это размер области в байтах, badBlock — номер сбойного сектора, SECTORSIZE = 512.
Итого теоретически имеем:
— lowBlock выравнивается на нижнюю границу области (в секторах).
— uppBlock — тупо прибавляем к lowBlock размер области в секторах.
Как оно могло выдать интервал, меньший размера области — не понимаю. :)
Действительно, я как-то упустил этот момент.
Просто для меня запуск утилит, напрямую работающих с устройствами через файлы в /dev/ — нечто само собой разумеющееся.
Добавлю к комментарию.
Не соглашусь. В IT далеко не все быстро меняется.
Основные технические принципы и решения живут десятилетиями и не меняются.
Основные платформы, языки программирования живут десятилетиями и тоже практически не меняются.
Революции в IT — редкость.
А вот когда в IT влезает политика и бизнес — тут-то и начинаются перемены. Вот только напоминают они мне заполошную беготню туда-обратно:
«Р-р-р-революционное решение! Переворот! Такого еще не было!»
(через год) «Новое рррреволюционное решение взамен устаревшему! Срочно бежим в другую сторону!»
(еще через год) «Мы бежали не туда, но теперь — все поменялось!»
Помнится, лет пять назад майкрософт усиленно крутил рекламу в духе «узнайте, почему сервер на виндовсе обойдется вам дешевле сервера на линуксе». Все, концепция поменялась, генеральная линия Партии совершила новый поворот, и мотор ревет?
Бес плавающей точки, демон летающей запятой, дух ныряющего баклана…
Это называется «длинная арифметика» и существует во множестве языков программирования (первый же пришедший в голову пример — язык python).
И астрономия тут вовсе ни при чем: числа вовсе не обязательно должны быть астрономически большими.
Графом называют множество узлов и связей между ними. Для типа «graf» узел существует только тогда, когда у него есть хотя бы одна связь.
Не-ет, любезный, графом называют дворянский титул выше баронского, а также лицо, носящее этот титул. Потому что в том написании, что вы даете, Graf — это титул, заимствованный из немецкого языка.
А то, о чем вы рассуждаете, называется graph — от греческого γραφω — пишу.
Как было сказано выше, для начала работы нашего демона, в соответствии с правилами работы подобных программ в Linux, его нужно отвязать от терминала, в котором его запустили для этого нужно воспользоваться функцией pcntl_fork(), она создаёт дочернюю копию текущего процесса и возвращает его числовой id в случае успеха. Ну и конечно прикончить родительский процесс.
Все это вовсе не обязательно.
Достаточно запустить скрипт в фоновом режиме с использованием nohup:
% nohup your_script.php &
А можно вообще не перенаправлять ничего. Просто запускаем скрипт в сессии screen.
Таким образом, операционная система будет знать что мы способны определять своё поведение и поместит pid нашего процесса в очередь для получения системных сигналов.
В какую еще очередь на получение системных сигналов? Нет никакой такой «очереди».
setsid() делает процесс лидером группы и отвязывает его от терминала (т.е. процессу перестают посылать сигнал SIGHUP при закрытии терминала).
Приступим, для начала необходимо определиться что что класс должен уметь делать.
Получать и обрабатывать сигналы операционной системы;
Уметь понимать запущен ли демон или нет;
Запускать задачу необходимую для демонизации;
Знать когда нужно остановиться;
Какой чудесный класс. Авто-, мото-, вело-, фото- гонщик, зритель и пловец.
Задачи управления демоном (запуск, снятие, проверка пид-файла) практически всегда выполняются внешними скриптами, лежащими в /etc/init.d. И раз уж вы пишете своего собственного демона, то без этих скриптов вам все равно не обойтись.
Обработка сигналов и собственно выполнение работы — это задача самого демона.
Здесь мы проверяем все возможные варианты событий, существует ли файл, если да то каким процессом создан, проверяем существует ли такой процесс, если процесс создавший файл не существует, так как процесс завершился неожиданно, пробуем удалить файл
Отнюдь не все возможные. Например, если в файл записать число 1 (пид процесса init), то ваш демон не запустится никогда.
Впрочем, это ладно, это стандартная практика.
А вот выходить без диагностики, если не удалось удалить файл — это как-то очень нехорошо. Собственно, а зачем вы вообще его удаляете? Ведь при несчастливом стечении обстоятельств может получиться так, что вторая копия вашего демона «успеет» запуститься как раз тогда, когда файл удален, но новый файл еще не создан. В результате обе копии решат, что они одни-единственные на свете, обе счастливо запишут свой пид в файл (одна поверх другой), и начнут оттаптывать друг другу пальцы.
Еще у вас нет никаких блокировок при записи пид-файла. Вы уверены, что file_put_contents() запишет все в файл атомарно, а file_get_contents() его так же атомарно прочтет? Я вот — нет.
// Собственно создаём демона, соответственно говорим ему куда записывать свой pid…
$daemon = new Daemon('/tmp/daemon.pid');
// Закрываем порочные связи со стандартным вводом-выводом…
fclose(STDIN);
fclose(STDOUT);
fclose(STDERR);
// Перенаправляем ввод-вывод туда куда нам надо или не надо…
$STDIN = fopen('/dev/null', 'r');
$STDOUT = fopen('/dev/null', 'wb');
$STDERR = fopen('/dev/null', 'wb');
Как я уже говорил, все это практически не нужно. Но если уж так чешутся руки написать свой демонайзер на РНР, то делайте это правильно:
1. Вместо fclose()/fopen() нужно использовать функцию dup2(), чтобы номера файловых дескрипторов остались гарантированно те же, что и при старте программы. На С это выглядит так:
int fd = open("/dev/null", O_RDWR, 0);
if (fd != -1) {
dup2(fd, STDIN_FILENO);
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
if (fd > 2) close(fd);
}
2. После всех прыжков с файловыми дескрипторами, терминальными сессиями и пид-файлами остался один, но очень важный шаг: сделать chdir("/").
Смысл этого шага — разблокировать текущий каталог после запуска демона. Скажем, если зайти на подмонтированную флэшку, а потом запустить вашего демона, лежащего, например, в /usr/bin, то флэшку после этого отмонтировать не получится: она останется в качестве текущего рабочего каталога у запущенного демона.
И да, с запятыми вам надо что-то делать. Примерно в половине фраз отсутствуют.
Во-первых, распространение рекламных и других опасных расширений это целая индустрия, у которой есть деньги, время и лучшие умы для поиска все новых способов обхода защиты.
Почему-то вспомнилось, как еще пару лет назад приходилось убирать галочку «а еще поставить Яндекс Бар» или «поставить Яндекс Браузер» чуть ли не во всех инсталляторах.
Во-вторых, меры, принимаемые как в Яндекс.Браузере, так и в других браузерах и каталогах, постепенно создают для мошенников неблагоприятные условия. Им приходится искать альтернативные каналы для подмены рекламы или воровства данных на компьютере пользователя.
Почему-то вспомнилась история о том, как яндекс-бар собирал историю посещений (включая закрытые страницы) и отсылал ее в Яндекс.
Почему принципиально скрещивание без знания внутреннего устройства?
Потому что тогда у нас собственно генетический алгоритм полностью изолирован от конкретных данных. Для «доказательства эволюции» — самый правильный подход.
Впрочем, это не так уж и принципиально. Просто универсальнее.
(в реальных организмах внутреннее устройство в виде деления на гены «известно»)
С некоторой натяжкой да. ЕМНИП, в местах, где возможен кроссинговер, есть довольно широкие «буферные зоны», не содержащие генов.
В компьютерной симуляции важны основные принципы (скрещивание, мутации, отбор). Многие присущие реальным организмам вещи (такие, как кроссинговер с учетом границ генов) в компьютерной симуляции малосущественны, т. к. ведут к увеличению времени работы или объемов потребляемой памяти, но при этом мало сказываются на конечном результате. Скажем, кроссинговер «посреди живого гена» по сути своей мало отличается от мутации в этом гене (а если ген у родителей одинаков, то вообще никак не проявится). Но для учета границ генов их придется как-то обозначать (+расход памяти), или вычислять (+расход времени), или завязывать всю реализацию под конкретное представление генов (потеря универсальности).
И почему случайные изменения параметров — не мутации?
В нашем конкретном случае на то есть несколько причин:
1. Это не совсем случайная мутация, а постепенное «гуляние» параметров. В реальном генетическом алгоритме одной случайной мутацией можно кардинально изменить ген, а в некоторых реализациях — вообще чуть ли не весь генотип сразу. Например, пропуск бита при копировании приведет к тому, что все гены, расположенные после мутации, изменятся. Здесь же все изменения постепенные.
2. Вероятность мутирования достаточно низка (в генетических алгоритмах задается отдельным параметром). Вероятность получить нежизнеспособный организм (в симуляции — неконкурентный) в результате мутации — весьма высока. Но можно получить и организм кардинально более «приспособленный». Смысл введения мутаций как раз в том, чтобы дать популяции возможность выйти из локального минимума (т. е. не дать популяции выродиться раньше времени). Здесь же «мутации», по сути, изменяют организм достаточно плавно, но при этом по всем параметрам сразу, поэтому нет смысла от них ждать каких-то «эволюционных скачков».
Ну и общее замечание по реализации: в генетическом алгоритме у потомка будет набор родительских генов (минус мутации, которые редкость). Здесь же у потомка весь генотип, по всем генам, всегда отличается от генотипа обоих родителей. То есть по сути — ничего общего с генетическими алгоритмами предложенная нам программа не имеет. Получился своеобразный поиск экстремума сложной функции методом случайных шагов.
Ценю вашу тягу к расстановке точек над Ё. Открываем священную книгу Тору на странице 1432 в очередной раз википедию, смотрим в текст:
Genetic algorithms use linear binary representations. The most standard one is an array of bits. Arrays of other types and structures can be used in essentially the same way. The main property that makes these genetic representations convenient is that their parts are easily aligned due to their fixed size. This facilitates simple crossover operation. Variable length representations were also explored in Genetic algorithms, but crossover implementation is more complex in this case.
В общем случае физическое представление генома (битовые строчки, байты, текст и т.п.) для работы генетического алгоритма не важно. Тем не менее, именно с битовых строчек генетические алгоритмы начались (см. работы Джона Холларда, которые я сам, впрочем, не читал).
Я когда-то довольно плотно игрался с генетическими алгоритмами. Они отлично работают в задачах, где куча параметров, неочевидно влияющих на результат (и где тупой перебор работал бы веками).
Мне всегда казалось, что основной их особенностью является оператор скрещивания, остальное непринципиально.
(заметим, что в реальных организмах скрещивание происходит как раз на уровне генов, а не нуклеотидов)
У вас в программе нет ни скрещивания как такового, ни, строго говоря, мутаций. Вместо скрещивания у вас усреднение признаков, вместо мутаций — случайные изменения признаков в пределах каких-то лимитов. То есть это — не генетический алгоритм, а нечто совсем другое. Зато у вас есть вещи, не относящиеся к генетике напрямую: беготня особей по полю — это всего лишь очень хитрый способ построения оценочной функции.
Вы меня простите, конечно, но с генетикой тут нет ничего общего. Это не генетический алгоритм.
Суть генетических алгоритмов в том, что генетическая информация хранится в родителях в виде битовой строчки. При скрещивании и мутировании тоже используется эта битовая строчка, безо всякого знания о ее внутреннем устройстве. Только потом получившийся код «парсится на гены» (т.е. разбирается на составляющие его поля) и используется при создании нового организма.
Может это другая проблема, а может проблема в какой-нибудь прослойке: в иксах, в DRI.
Грузишь линукс с драйвером nvidia — грабли. Причем грабли возникают даже в текстовом режиме(!) при использовании frame buffer.
Грузишь тот же линукс с драйвером… эээ… как его бишь? nouveaux? — все прекрасно работает, но ни CUDA, ни OpenCL не доступны (что естественно).
Насчёт nvidia не знаю ничего — на этих машинах иксы никогда не запускались.
Погодите-ка. Как это не запускались? Разве для того, чтобы заработала CUDA, не нужны запущенные иксы?
Для работы OpenCL, например, иксы должны быть запущены обязательно.
У НВидии на линуксе есть один застарелый и неприятный баг: когда система загружена (например, компиляция идет), экран частично или полностью перестает перерисовываться. Ну то есть вплоть до того, что вводишь в консоли ls, а результата не видишь. Но если сдвинуть окно — все моментально отрисовывается. Необновленное окно может висеть часами, т.е. это не задержка.
Багу уже много лет, его фиксили все — и нвидия, и разработчики гнома. Есть множество рецептов по его обходу, разной степени эзотеричности (от отключения power saving на видеокарте до каких-то непонятных ключиков в иксовых конфигах). Ни один не работает гарантированно. Обновление дров с сайта нвидии проблему не решает. Видеокарты, на которых баг вылазит — самые разные (от древней quadro до более-менее современных бюджетных). Линуксы, на которых баг вылазит, тоже разные: дебиан, ред хат энтерпрайзный, етц.
Так вот, интересно: починили уже или по-прежнему все очень печально?
Судя по логике авторов статей, клиенты просто могут написать что-то типа: «Я бы купил, но дорого и я хочу скидку 100500%».
Вот и я о том же: это какая-то высосанная из пальца ситуация. Автор письма тут выглядит как идиот, а необходимость подключать роботов для ответа на его письмо подразумевает, что таких идиотов много. Им что, клиенты не нужны?
Когда клиент просит скидку, мы будем реагировать примерно так:
картинко
Почему это работает? Мы сопереживаем (понимаем, что чувствует клиент), письмо личное (мы включили информацию о клиенте и его аккаунте) и мы увеличиваем ценность (во время консультации по телефону мы предлагаем увеличить известную ценность для клиента).
Вы прослушали версию эффективного менеджера.
А теперь послушайте версию здорового человека.
Судя по картинке, письмо не является ответом на письмо клиента (иначе в заголовке письма было бы Re:). Скорее всего, оно сформировано в ответ на какое-то действие клиента на сайте (кнопка «Хочу скидку»?). Вообще, ситуация, мне кажется, идиотская: если на сайте есть кнопка «хочу скидку!», то она должна работать, а не генерировать отписки. А если на сайте такой кнопки нет, то клиент, интересующийся скидками, скорее всего, хочет приобрести крупную партию товара (а возможно, и не одну). В ваших же интересах рассмотреть его просьбу глазами, чтобы не потерять ценного клиента.
Получив такую вот формальную отписку (явно заранее сочиненную, многословную, с орфографическими ошибками, да еще и с дурацкими смайликами), мои чувства будут ровно такими, как в следующем разделе: «Вы что там все, совсем охренели, что ли?»
Ну да, драйстоуны, ветстоуны, компиляторы, интерпретаторы, байткод, кэш, code bloat — все это прекрасные слова, но зачем вы все это свалили в одну кучу и приправили жиденькими, бесполезными рекомендациями?
Рекомендации должны быть предметными, а не «вообще».
— Важна производительность именно вычислительная? Тогда — компилируемые языки, многопоточность, распаралеливание, использование GPU (OpenCL, CUDA), распределенные вычисления. У вас из всего этого — только мутноватые рассуждения о производительности и издевательские рекомендации писать на ассемблере. Издевательские — потому что современные компиляторы генерируют код весьма высокого качества, а попытки оптимизировать его вручную обычно приводят к тому, что «оптимизированная» программа работает медленнее оригинала. Кроме того, писать на ассемблере под тот же ARM — занятие для истинных гурманов.
— Важен отклик пользовательского интерфейса программы? Тогда — правильное проектирование, обработка длительных операций в отдельном потоке, и пофиг на язык программирования. Время комфортного отклика на действия пользователя — ЕМНИП, что-то около 250 миллисекунд. На такую производительность вполне способны даже весьма медленные языки программирования.
— Важен малый объем программы? Тогда — использование «легких» фреймворков, языков программирования, выдающих компактный результирующий код, и т. п.Но лично мне проблема «жира» в программах кажется слегка надуманной: на десктопных компьютерах основное ОЗУ жрут картинки и иконки, а на всяческих маломощных контроллерах обычно выбор языка программирования невелик: или пишешь на том, что предоставил производитель контроллера, или не пишешь вообще.
Если оклад зависит от часов — люди будут спать, заниматься своими личными делами и т. п. на работе.
Если оклад фиксированный плюс штрафы/бонусы — то будет повышенная текучка. Это только в воспаленном мозгу директора, получающего фиксированный оклад, может возникнуть мысль, что штраф приведет к повышению качества работы. По факту штраф — это обида сотрудника на компанию, т.к. в большинстве случаев сотрудник себя виноватым не считает. Плюс снижается его уверенность в завтрашнем дне.
Если человек не может спланировать расходы из-за того, что его зарплата «болтается» туда-сюда из-за штрафов и бонусов — это минус. Допустим, к бонусам можно отнестись как к неожиданному приятному сюрпризу (при этом приязнь не переносится на компанию). Но вот штраф — однозначно трактуется как «меня тут не ценят». Как следствие — пара штрафов, и специалист уходит к конкурентам, которые не внедряют таких «прогрессивных схем оплаты».
Двоичных:
Вот, собственно, код, который вычисляет границы области:
minSpan — это размер области в байтах, badBlock — номер сбойного сектора, SECTORSIZE = 512.
Итого теоретически имеем:
— lowBlock выравнивается на нижнюю границу области (в секторах).
— uppBlock — тупо прибавляем к lowBlock размер области в секторах.
Как оно могло выдать интервал, меньший размера области — не понимаю. :)
Просто для меня запуск утилит, напрямую работающих с устройствами через файлы в /dev/ — нечто само собой разумеющееся.
Добавлю к комментарию.
Основные технические принципы и решения живут десятилетиями и не меняются.
Основные платформы, языки программирования живут десятилетиями и тоже практически не меняются.
Революции в IT — редкость.
А вот когда в IT влезает политика и бизнес — тут-то и начинаются перемены. Вот только напоминают они мне заполошную беготню туда-обратно:
«Р-р-р-революционное решение! Переворот! Такого еще не было!»
(через год) «Новое рррреволюционное решение взамен устаревшему! Срочно бежим в другую сторону!»
(еще через год) «Мы бежали не туда, но теперь — все поменялось!»
Бес плавающей точки, демон летающей запятой, дух ныряющего баклана…
Это называется «длинная арифметика» и существует во множестве языков программирования (первый же пришедший в голову пример — язык python).
И астрономия тут вовсе ни при чем: числа вовсе не обязательно должны быть астрономически большими.
Не-ет, любезный, графом называют дворянский титул выше баронского, а также лицо, носящее этот титул. Потому что в том написании, что вы даете, Graf — это титул, заимствованный из немецкого языка.
А то, о чем вы рассуждаете, называется graph — от греческого γραφω — пишу.
Все это вовсе не обязательно.
Достаточно запустить скрипт в фоновом режиме с использованием nohup:
% nohup your_script.php &
В дебиане и убунту есть специальный скрипт для запуска любой программы в виде демона: help.ubuntu.ru/wiki/start-stop-daemon
А можно вообще не перенаправлять ничего. Просто запускаем скрипт в сессии screen.
В какую еще очередь на получение системных сигналов? Нет никакой такой «очереди».
setsid() делает процесс лидером группы и отвязывает его от терминала (т.е. процессу перестают посылать сигнал SIGHUP при закрытии терминала).
Какой чудесный класс. Авто-, мото-, вело-, фото- гонщик, зритель и пловец.
Задачи управления демоном (запуск, снятие, проверка пид-файла) практически всегда выполняются внешними скриптами, лежащими в /etc/init.d. И раз уж вы пишете своего собственного демона, то без этих скриптов вам все равно не обойтись.
Обработка сигналов и собственно выполнение работы — это задача самого демона.
Отнюдь не все возможные. Например, если в файл записать число 1 (пид процесса init), то ваш демон не запустится никогда.
Впрочем, это ладно, это стандартная практика.
А вот выходить без диагностики, если не удалось удалить файл — это как-то очень нехорошо. Собственно, а зачем вы вообще его удаляете? Ведь при несчастливом стечении обстоятельств может получиться так, что вторая копия вашего демона «успеет» запуститься как раз тогда, когда файл удален, но новый файл еще не создан. В результате обе копии решат, что они одни-единственные на свете, обе счастливо запишут свой пид в файл (одна поверх другой), и начнут оттаптывать друг другу пальцы.
Еще у вас нет никаких блокировок при записи пид-файла. Вы уверены, что file_put_contents() запишет все в файл атомарно, а file_get_contents() его так же атомарно прочтет? Я вот — нет.
Как я уже говорил, все это практически не нужно. Но если уж так чешутся руки написать свой демонайзер на РНР, то делайте это правильно:
1. Вместо fclose()/fopen() нужно использовать функцию dup2(), чтобы номера файловых дескрипторов остались гарантированно те же, что и при старте программы. На С это выглядит так:
2. После всех прыжков с файловыми дескрипторами, терминальными сессиями и пид-файлами остался один, но очень важный шаг: сделать chdir("/").
Смысл этого шага — разблокировать текущий каталог после запуска демона. Скажем, если зайти на подмонтированную флэшку, а потом запустить вашего демона, лежащего, например, в /usr/bin, то флэшку после этого отмонтировать не получится: она останется в качестве текущего рабочего каталога у запущенного демона.
И да, с запятыми вам надо что-то делать. Примерно в половине фраз отсутствуют.
Почему-то вспомнилось, как еще пару лет назад приходилось убирать галочку «а еще поставить Яндекс Бар» или «поставить Яндекс Браузер» чуть ли не во всех инсталляторах.
Почему-то вспомнилась история о том, как яндекс-бар собирал историю посещений (включая закрытые страницы) и отсылал ее в Яндекс.
Наверное, это очень плохо, такие вещи помнить?
Потому что тогда у нас собственно генетический алгоритм полностью изолирован от конкретных данных. Для «доказательства эволюции» — самый правильный подход.
Впрочем, это не так уж и принципиально. Просто универсальнее.
С некоторой натяжкой да. ЕМНИП, в местах, где возможен кроссинговер, есть довольно широкие «буферные зоны», не содержащие генов.
В компьютерной симуляции важны основные принципы (скрещивание, мутации, отбор). Многие присущие реальным организмам вещи (такие, как кроссинговер с учетом границ генов) в компьютерной симуляции малосущественны, т. к. ведут к увеличению времени работы или объемов потребляемой памяти, но при этом мало сказываются на конечном результате. Скажем, кроссинговер «посреди живого гена» по сути своей мало отличается от мутации в этом гене (а если ген у родителей одинаков, то вообще никак не проявится). Но для учета границ генов их придется как-то обозначать (+расход памяти), или вычислять (+расход времени), или завязывать всю реализацию под конкретное представление генов (потеря универсальности).
В нашем конкретном случае на то есть несколько причин:
1. Это не совсем случайная мутация, а постепенное «гуляние» параметров. В реальном генетическом алгоритме одной случайной мутацией можно кардинально изменить ген, а в некоторых реализациях — вообще чуть ли не весь генотип сразу. Например, пропуск бита при копировании приведет к тому, что все гены, расположенные после мутации, изменятся. Здесь же все изменения постепенные.
2. Вероятность мутирования достаточно низка (в генетических алгоритмах задается отдельным параметром). Вероятность получить нежизнеспособный организм (в симуляции — неконкурентный) в результате мутации — весьма высока. Но можно получить и организм кардинально более «приспособленный». Смысл введения мутаций как раз в том, чтобы дать популяции возможность выйти из локального минимума (т. е. не дать популяции выродиться раньше времени). Здесь же «мутации», по сути, изменяют организм достаточно плавно, но при этом по всем параметрам сразу, поэтому нет смысла от них ждать каких-то «эволюционных скачков».
Ну и общее замечание по реализации: в генетическом алгоритме у потомка будет набор родительских генов (минус мутации, которые редкость). Здесь же у потомка весь генотип, по всем генам, всегда отличается от генотипа обоих родителей. То есть по сути — ничего общего с генетическими алгоритмами предложенная нам программа не имеет. Получился своеобразный поиск экстремума сложной функции методом случайных шагов.
священную книгу Тору на странице 1432в очередной раз википедию, смотрим в текст:В общем случае физическое представление генома (битовые строчки, байты, текст и т.п.) для работы генетического алгоритма не важно. Тем не менее, именно с битовых строчек генетические алгоритмы начались (см. работы Джона Холларда, которые я сам, впрочем, не читал).
Да, перепутал, прошу прощения.
Нигде. Какие, по-вашему, из этого следует сделать выводы?
Для компьютерной симуляции это малосущественно и в большинстве случаев такими тонкостями можно пренебречь.
ru.wikipedia.org/wiki/%D0%93%D0%B5%D0%BD%D0%B5%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC
Я когда-то довольно плотно игрался с генетическими алгоритмами. Они отлично работают в задачах, где куча параметров, неочевидно влияющих на результат (и где тупой перебор работал бы веками).
Скрещивание происходит вообще на уровне хромосом: ru.wikipedia.org/wiki/%D0%9A%D1%80%D0%BE%D1%81%D1%81%D0%B8%D0%BD%D0%B3%D0%BE%D0%B2%D0%B5%D1%80
Впрочем, все это лирика.
У вас в программе нет ни скрещивания как такового, ни, строго говоря, мутаций. Вместо скрещивания у вас усреднение признаков, вместо мутаций — случайные изменения признаков в пределах каких-то лимитов. То есть это — не генетический алгоритм, а нечто совсем другое. Зато у вас есть вещи, не относящиеся к генетике напрямую: беготня особей по полю — это всего лишь очень хитрый способ построения оценочной функции.
Какое-то странное правило. А если особи не столкнутся, они что — живут вечно?
Вы меня простите, конечно, но с генетикой тут нет ничего общего. Это не генетический алгоритм.
Суть генетических алгоритмов в том, что генетическая информация хранится в родителях в виде битовой строчки. При скрещивании и мутировании тоже используется эта битовая строчка, безо всякого знания о ее внутреннем устройстве. Только потом получившийся код «парсится на гены» (т.е. разбирается на составляющие его поля) и используется при создании нового организма.
Грузишь линукс с драйвером nvidia — грабли. Причем грабли возникают даже в текстовом режиме(!) при использовании frame buffer.
Грузишь тот же линукс с драйвером… эээ… как его бишь? nouveaux? — все прекрасно работает, но ни CUDA, ни OpenCL не доступны (что естественно).
Погодите-ка. Как это не запускались? Разве для того, чтобы заработала CUDA, не нужны запущенные иксы?
Для работы OpenCL, например, иксы должны быть запущены обязательно.
Кстати о прогрессе.
Багу уже много лет, его фиксили все — и нвидия, и разработчики гнома. Есть множество рецептов по его обходу, разной степени эзотеричности (от отключения power saving на видеокарте до каких-то непонятных ключиков в иксовых конфигах). Ни один не работает гарантированно. Обновление дров с сайта нвидии проблему не решает. Видеокарты, на которых баг вылазит — самые разные (от древней quadro до более-менее современных бюджетных). Линуксы, на которых баг вылазит, тоже разные: дебиан, ред хат энтерпрайзный, етц.
Так вот, интересно: починили уже или по-прежнему все очень печально?
Вот и я о том же: это какая-то высосанная из пальца ситуация. Автор письма тут выглядит как идиот, а необходимость подключать роботов для ответа на его письмо подразумевает, что таких идиотов много. Им что, клиенты не нужны?
Вы прослушали версию эффективного менеджера.
А теперь послушайте версию здорового человека.
Судя по картинке, письмо не является ответом на письмо клиента (иначе в заголовке письма было бы Re:). Скорее всего, оно сформировано в ответ на какое-то действие клиента на сайте (кнопка «Хочу скидку»?). Вообще, ситуация, мне кажется, идиотская: если на сайте есть кнопка «хочу скидку!», то она должна работать, а не генерировать отписки. А если на сайте такой кнопки нет, то клиент, интересующийся скидками, скорее всего, хочет приобрести крупную партию товара (а возможно, и не одну). В ваших же интересах рассмотреть его просьбу глазами, чтобы не потерять ценного клиента.
Получив такую вот формальную отписку (явно заранее сочиненную, многословную, с орфографическими ошибками, да еще и с дурацкими смайликами), мои чувства будут ровно такими, как в следующем разделе: «Вы что там все, совсем охренели, что ли?»