Задать вопрос
Ответы пользователя по тегу Алгоритмы
  • Как в игре "Жизнь" определить предыдущее состояние клеток по текущему? (Одномерное поле)?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Обозначим текущее состояние как C[1..N], предыдущее как P[1..N], С[0] = P[0] = C[N+1] = P[N+1] = 0 - клетки за пределами поля.
    На текущем шаге клетка жива тогда и только тогда, когда на предыдущем шаге у неё был ровно один сосед, то есть C[i] = P[i-1] xor P[i+1] => P[i+1] = C[i] xor P[i-1].
    1. P[0] = 0, C[1] известна => P[2] = P[0] xor C[1]. Теперь, зная P[2] можно найти P[4] = P[2] xor C[3] или в общем случае:
    для i от 1 до N с шагом 2
        P[i+1] = P[i-1] xor C[i];
    Получили все предыдущие значения чётных ячеек.

    2a. Для чётных N обратным ходом можно восстановить нечётные ячейки:
    для i от N до 1 с шагом -2
        P[i-1] = P[i+1] xor C[i];

    2b. Для нечётных N однозначного решения нет. В зависимости от значения P[1] будет получен один из двух вариантов решения:
    P[1] = 0; // или 1
    для i от 2 до N с шагом 2
        P[i+1] = P[i-1] xor C[i];
    Ответ написан
    7 комментариев
  • Задача расчета расстояния путей между городами с использование графов в C++?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Самое простое - двумерный массив w[N][N], где w[i][j] - стоимость перехода из узла i в узел j или -1 если такого пути нет. Если узлов много, а связность низкая, то надо уже копать в сторону разреженных массивов.
    Ответ написан
    Комментировать
  • Какой алгоритм использовать лля определения доступности временного промежутка?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Поразмыслив пришёл к варианту:
    SELECT count(*) AS x FROM records 
        WHERE (begin BETWEEN '{$newRecordBegin}' AND '{$newRecordEnd}') OR
              ('{$newRecordBegin}' BETWEEN begin AND end)

    Первая часть условия - начало какой-либо старой записи попадает в середину новой.
    Вторая часть - начало новой записи попадает в середину какой-либо старой .
    Если хоть одно условие выполнено - count(*) > 0, вставлять запись нельзя.
    Ответ написан
    Комментировать
  • Какой алгоритм использовать лля определения доступности временного промежутка?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    0. Пытаемся вставить новую запись newRecordStart, newRecordLength
    1. Получаем две ближайшие по времени записи, одну до (prevRecordStart, prevRecordLength) и одну после новой (nextRecordStart, nextRecordLength).
    2. Новая запись не должна пересекаться с предыдущей:
    (newRecordStart >= prevRecordStart+prevRecordLength)
    3. Новая запись не должна пересекаться со следующей:
    (newRecordStart+newRecordLength <= nextRecordStart)
    4. Если оба условия выполнены - можно вставлять запись.
    Ответ написан
    Комментировать
  • Анализ данных с термодатчиков и трубки Флейша?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    С температурами всё достаточно просто, графики без шумов. Можно брать локальные минимумы/максимумы, просто перебираете весь массив считая разницу между значениями в текущей и в следующей точках меняет знак, то записываете точку как локальный экстремум.

    d = V[1]-V[0];
    for (i = 1; i < N-1, i++) {
        d1 = V[i+1]-V[i];
        if (d < 0 && d1 > 0) {
            // Локальный минимум V[i]
        } else if (d > 0 && d1 < 0) {
            // Локальный максимум V[i]
        }
        d = d1;
    }

    Для объёма график с шумами, если уровень шумов заранее известен, то его можно исключить игнорируя разницу, попадающую в уровень шума. Для нахождения середины перегиба в этом случае можно анализировать два перехода - от повышения к нулю и от нуля к снижению (наоборот для нижнего перегиба) и брать значение в середине перегиба или среднее значение между крайними точками перегиба.

    noise = 2; // Уровень шума, поставить нужное значение
    t1 = 0; // Точка перехода к нулю
    upDown = 0; // Направление движения до нуля, > 0 - вверх, < 0 - вниз, 0 - начало графика
    d = V[1]-V[0];
    if (abs(d) < noise)
        d = 0;
    for (i = 1; i < N-1, i++) {
        d1 = V[i+1]-V[i];
        if (abs(d1) < noise)
            d1 = 0;
        if (d < 0 && d1 > 0) {
            // Локальный минимум V[i]
        } else if (d > 0 && d1 > 0) {
            // Локальный максимум V[i]
        } else if (d != 0 && d1 == 0) {
            t1 = i;
            upDown = d;
        } else if (d == 0 && d1 > 0 && upDown < 0) {
            // Локальный минимум V[(t1+i)/2] или (V[t1]+V[i])/2
        } else if (d == 0 && d1 < 0 && upDown > 0) {
            // Локальный максимум V[(t1+i)/2] или (V[t1]+V[i])/2
        }
        d = d1;
    }
    Ответ написан
    2 комментария