сгенерировать таблицу истинности с учетом ввода? - PullRequest
2 голосов
/ 17 августа 2010

Есть ли интеллектуальный алгоритм, который принимает ряд вероятностей и генерирует соответствующую таблицу истинности внутри многомерного массива или контейнера

Пример:

n = 3
N : [0 0 0
     0 0 1
     0 1 0 
     ...
     1 1 1] 

Я могу сделать это сдля циклов и если, но я знаю, что мой путь будет медленным и трудоемким.Итак, я спрашиваю, есть ли расширенная функция, которую я могу использовать, чтобы сделать это максимально эффективным?

Ответы [ 5 ]

8 голосов
/ 17 августа 2010

Если нам разрешено заполнять таблицу всеми нулями, чтобы начать, то должна быть возможность выполнить точно 2^n - 1 заполнение, чтобы установить желаемые 1 биты. Это не может быть быстрее, чем написание ручного цикла, хотя оно полностью непрофильно.

EDIT: Линия std::vector<std::vector<int> > output(n, std::vector<int>(1 << n)); объявляет вектор векторов. Внешний вектор имеет длину n, а внутренний - 2^n (число результатов истинности для n входов), но я делаю вычисление мощности, используя сдвиг влево, чтобы компилятор мог вставить константу вместо вызова, скажем, pow. В случае, когда n=3, мы получаем вектор 3х8. Я организовал это таким образом (вместо обычного 8x3 со строкой в ​​качестве первого индекса), потому что мы собираемся использовать шаблон на основе столбцов в выходных данных. Таким образом, использование конструкторов vector также гарантирует, что каждый элемент вектора векторов инициализируется равным 0. Таким образом, нам остается только беспокоиться о том, чтобы установить значения, которые мы хотим, равными 1, и оставить остальные в покое.

Второй набор вложенных циклов for просто используется для распечатки результирующих данных, когда все готово, ничего особенного.

Первый набор циклов for реализует реальный алгоритм. Мы используем преимущества шаблона на основе столбцов в выходных данных здесь. Для данной таблицы истинности самый левый столбец будет состоять из двух частей: первая половина - все 0, а вторая половина - все 1. Так как мы предварительно заполнили нули, то будет применена одна заливка половины высоты столбца, начиная с половины. все 1, нам нужно. Во втором столбце будут строки 1/4-й 0, 1/4-й 1, 1/4-й 0, 1/4-й 1. Таким образом, два заполнения будут применять все 1, которые нам нужны. Мы повторяем это до тех пор, пока не доберемся до самого правого столбца, в этом случае каждая вторая строка будет 0 или 1.

Мы начинаем говорить: «Мне нужно заполнить половину строк одновременно» (unsigned num_to_fill = 1U << (n - 1);). Затем мы зациклились на каждом столбце. Первый столбец начинается с позиции, которую нужно заполнить, и заполняет столько строк на 1. Затем мы увеличиваем строку и уменьшаем размер заливки наполовину (теперь мы заполняем 1/4 строки сразу, но затем пропускаем пустое место). строк и заполните второй раз) для следующего столбца.

Например:

#include <iostream>
#include <vector>

int main()
{
    const unsigned n = 3;
    std::vector<std::vector<int> > output(n, std::vector<int>(1 << n));

    unsigned num_to_fill = 1U << (n - 1);
    for(unsigned col = 0; col < n; ++col, num_to_fill >>= 1U)
    {
        for(unsigned row = num_to_fill; row < (1U << n); row += (num_to_fill * 2))
        {
            std::fill_n(&output[col][row], num_to_fill, 1);
        }
    }

    // These loops just print out the results, nothing more.
    for(unsigned x = 0; x < (1 << n); ++x)
    {
        for(unsigned y = 0; y < n; ++y)
        {
            std::cout << output[y][x] << " ";
        }
        std::cout << std::endl;
    }

    return 0;
}
1 голос
/ 17 августа 2010

Вы можете разбить его задачу на два раздела, заметив, что каждая из строк в матрице представляет собой n-битное двоичное число, где n - это число вероятностей [sic].

, поэтому вам необходимо:

  • итерация по всем n-битным числам
  • преобразование каждого числа в строку вашего 2d-контейнера

edit:

, если вы толькоЕсли вы беспокоитесь о времени выполнения, то для константы n вы всегда можете предварительно вычислить таблицу, но она думает, что вы застряли со сложностью O (2 ^ n), когда она вычисляется

0 голосов
/ 17 августа 2010

Карта Карно или Куайн-МакКласки

http://en.wikipedia.org/wiki/Karnaugh_map http://en.wikipedia.org/wiki/Quine%E2%80%93McCluskey_algorithm

Это должно направить вас в правильном направлении для минимизации итоговой таблицы истинности.

0 голосов
/ 17 августа 2010

Чтобы уточнить ответ jk ... Если у вас есть n логических значений ("вероятностей"?), Тогда вам нужно

  • создать массив таблицы истинности, который n на 2 ^ n
  • цикл i от 0 до (2 ^ n-1)
  • внутри этого цикла, цикл j от 0 до n-1
  • внутри цикла ТО, установить trueTable [i] [j] = j-й бит i (например, (i >> j) & 1)
0 голосов
/ 17 августа 2010

Вы хотите записать числа от 0 до 2 ^ N - 1 в двоичной системе счисления.В этом нет ничего умного.Вам просто нужно заполнить каждую ячейку двумерного массива.Вы не можете сделать это быстрее, чем это.

Вы можете сделать это без итерации непосредственно по числам.Обратите внимание, что самый правый столбец повторяет 0 1, затем следующий столбец повторяет 0 0 1 1, затем следующий 0 0 0 0 1 1 1 1 и так далее.Каждый столбец повторяет 2 ^ columnIndex (начиная с 0) нулей, а затем единиц.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...