Сгенерировать таблицу истинности в MatLab

Я хочу создать таблицу истинности в MatLab с i столбцами и i2 строками. Например, если i=2, то

T = 
[0  0] 
[1  0] 
[0  1] 
[1  1]

Код для этого уже создан здесь

Это часть более крупного проекта, для которого требуется i big. Эффективность вызывает беспокойство. Есть ли более эффективный код для создания таблицы истинности? Есть ли в MatLab встроенная функция для этого?

Редактировать: Извините за форматирование!


person Matthew Thirkettle    schedule 03.09.2015    source источник
comment
к сожалению, $$ для математических блоков здесь не работает. Обычно блоки кода заключаются в строку с обратными кавычками, и вы можете создавать блоки большего размера с помощью кнопки кода (у нее есть {}).   -  person scrappedcola    schedule 03.09.2015
comment
Благодарю вас! У меня все еще проблемы с форматированием матрицы.   -  person Matthew Thirkettle    schedule 03.09.2015
comment
@scrappedcola Или вы можете выделить блок кода и нажать ctrl-k   -  person beaker    schedule 04.09.2015


Ответы (3)


ndgrid очень ваш друг здесь:

function t = truthTable(n)
dims = repmat({[false, true]}, 1, n);
[grids{1:n}] = ndgrid(dims{:});
grids = cellfun(@(g)g(:), grids, 'UniformOutput',false);
t = [grids{:}];

Сначала вам нужно создать сетки для количества измерений в вашей таблице истинности. После того, как они у вас есть, вы можете разбить их на столбцы, чтобы получить нужные вам векторы столбцов, и вы можете горизонтально объединить эти векторы столбцов, чтобы получить свою таблицу истинности.

Я предполагаю, что производительность этого будет вполне конкурентоспособной.

>> truthTable(2)

ans =

     0     0
     1     0
     0     1
     1     1

>> truthTable(4)

ans =

     0     0     0     0
     1     0     0     0
     0     1     0     0
     1     1     0     0
     0     0     1     0
     1     0     1     0
     0     1     1     0
     1     1     1     0
     0     0     0     1
     1     0     0     1
     0     1     0     1
     1     1     0     1
     0     0     1     1
     1     0     1     1
     0     1     1     1
     1     1     1     1

>> 
>> timeit(@() truthTable(20))

ans =

        0.030922626777

EDIT: используйте изменение формы вместо разыменования столбца для дальнейшего повышения производительности.

function t = truthTable(n)
dims = repmat({[false, true]}, 1, n);
[grids{1:n}] = ndgrid(dims{:});
grids = cellfun(@(g) reshape(g,[],1), grids, 'UniformOutput',false);
t = [grids{:}];


>> timeit(@() truthTable(20))

ans =

        0.016237298777
person Andy Campbell    schedule 04.09.2015
comment
Спасибо. Исходный код Пола примерно в два раза быстрее вашего. (сек = 0,2796 по сравнению с сек = 0,5771 при n = 20). - person Matthew Thirkettle; 06.09.2015
comment
какой релиз используете? Используя R2015b, мой метод работает на порядок быстрее (n=20). Обновлен ответ, чтобы показать. - person Andy Campbell; 08.09.2015
comment
Похоже, что Pauls также быстрее в R2015b, но все же медленнее, чем при использовании ndgrid (около 0,157037 с). - person Andy Campbell; 08.09.2015
comment
Ах! Я использовал более старую версию Matlab. Ваше решение самое быстрое из трех на R2015b. @n=25, скорость s=10.2, 11.5, 1.8 (соответственно Пол, мензурка, твоя). - person Matthew Thirkettle; 08.09.2015

Что-то вроде этого?

n=2;
d=[0:2^n-1].';

T=dec2bin(d,n)

T =

00
01
10
11

dec2bin даст вам массив символов, который вы можете преобразовать в логический, если это необходимо. Также есть de2bi, который дает вам числовой массив напрямую, но вам нужна более новая версия Matlab, а порядок битов обратный.


Вот ускорение Луиса Мендо, которое воспроизводит dec2bin (n и d указаны выше):

T=rem(floor(d*pow2(1-n:0)),2);
person beaker    schedule 03.09.2015
comment
Я думаю, вам нужно изменить строку d на d=[0:2^n-1].'; Кроме того, хороший ответ! - person Luis Mendo; 04.09.2015
comment
Кроме того, dec2bin имеет много накладных расходов (проверка типов переменных и т. д.). Вы можете ускориться, используя T=rem(floor(d*pow2(1-n:0)),2);, что на самом деле делает dec2bin, не проверяя @MattT. - person Luis Mendo; 04.09.2015
comment
@LuisMendo Конечно, ты прав ... перевел мои условия задом наперед. - person beaker; 04.09.2015
comment
Это поднимает интересный вопрос, что n не может быть слишком большим, на самом деле оно должно быть меньше 31, иначе вы начнете выходить за пределы диапазона индекса. - person beaker; 04.09.2015
comment
Не говоря уже о памяти. Для n = 30 вы попытаетесь сгенерировать матрицу размером 30 ГБ. - person beaker; 04.09.2015
comment
Спасибо. Это похоже на ответ, оставленный в ссылка я написал выше. После 100 тестов при n=20 код Пола примерно в два раза быстрее, чем rem(floor(d*pow2(1-n:0)),2); (сек = 0,2796 против сек = 0,5969). - person Matthew Thirkettle; 06.09.2015
comment
Интересно. Мне нужно более внимательно посмотреть на связанный код. Я уверен, что @LuisMendo тоже будет заинтересован. - person beaker; 06.09.2015
comment
@beaker Действительно интересно. Представление Пола FEX основано на цикле. Это действительно быстрее? - person Luis Mendo; 06.09.2015
comment
@LuisMendo Я еще не рассчитал время, но его реализация устанавливает только значения 1, что исключает половину назначений. - person beaker; 06.09.2015

Я знаю, что этот вопрос уже давно мертв, но мне было интересно то же самое, и я нашел решение, которое мне очень нравится. Решил поделиться здесь:

fullfact(ones(1, i) + 1) - 1
person define cindy const    schedule 19.12.2017