générer une table de vérité donnée une entrée?

voix
2

Est-il un algorithme intelligent qui prend un certain nombre de probabilités et génère la table de vérité correspondant à l'intérieur d'un tableau multidimensionnel ou conteneur

ex:

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

Je peux le faire avec des boucles et des Ifs, mais je sais que mon chemin sera lent et prend du temps. Donc, je vous demande s'il y a une fonctionnalité avancée que je peux utiliser pour faire le plus efficace possible?

Créé 17/08/2010 à 17:18
source utilisateur
Dans d'autres langues...                            


5 réponses

voix
8

Si nous sommes autorisés à remplir le tableau avec tous les zéros pour commencer, il devrait être possible d'effectuer ensuite exactement 2^n - 1remplir pour régler les 1 bits que nous désirons. Cela peut ne pas être plus rapide que l' écriture d' une boucle manuelle bien, il est tout à fait non profilée .

EDIT: La ligne std::vector<std::vector<int> > output(n, std::vector<int>(1 << n));déclare un vecteur de vecteurs. Le vecteur externe est de longueur n, et l'une intérieure est 2^n(le nombre de résultats de vérité pour les n entrées) , mais je faire le calcul de la puissance à l'aide de décalage vers la gauche de sorte que le compilateur peut insérer une constante plutôt que d' un appel à, disons, pow. Dans le cas où n=3nous finissons avec un vecteur 3x8. J'organise de cette façon (plutôt que le 8x3 habituelle avec ligne que le premier indice) parce que nous allons tirer profit d'un modèle en colonnes dans les données de sortie. En utilisant les vectorconstructeurs de cette façon assure également que chaque élément du vecteur de vecteurs est initialisé à 0. Ainsi , nous avons seulement à vous soucier de la définition des valeurs que nous voulons 1 et laisser le reste seul.

Le deuxième ensemble de imbriqués forboucles est juste utilisé pour imprimer les données obtenues quand il est fait, rien de spécial.

La première série de boucles pour implémente l'algorithme réel. Nous profitons d'un motif en colonnes dans les données de sortie ici. Pour une table de vérité donnée, la colonne de gauche aura deux pièces: la première moitié est tout 0 et la seconde moitié est tout 1. Puisque nous zéros prérempli, un seul remplissage de la moitié de la hauteur de la colonne de départ à mi-chemin vers le bas appliquera tous les 1 nous avons besoin. La deuxième colonne aura des lignes 1/4 0, 1/4 1, 1/4 0, 1/4 1. Ainsi deux remplissages s'appliqueront toutes les 1 dont nous avons besoin. Nous le répétons jusqu'à ce que nous arrivons à la colonne de droite dans ce cas, toutes les autres lignes est 0 ou 1.

Nous commençons en disant « Je dois remplir la moitié des lignes à la fois » ( unsigned num_to_fill = 1U << (n - 1);). Ensuite , nous boucle sur chaque colonne. La première colonne commence à la position de remplir, et remplit que de nombreuses lignes avec 1. Ensuite , on incrémente la ligne et réduire la taille de remplissage de moitié (maintenant nous remplissons 1/4 des lignes à la fois, mais nous sauter alors en blanc rangées et remplir une seconde fois) pour la colonne suivante.

Par exemple:

#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;
}
Créé 17/08/2010 à 18:35
source utilisateur

voix
1

Vous pouvez diviser son problème en deux sections en remarquant chacune des lignes de la matrice représente un bit n nombre binaire où n est le nombre de probabilités [sic].

de sorte que vous devez:

  • itérer sur tous les numéros de n bits
  • convertir chaque numéro en ligne de votre conteneur 2d

modifier:

si vous êtes seulement préoccupés par l'exécution alors pour n constant que vous pouvez toujours Précalculer la table, mais il pensez que vous êtes coincé avec O (2 ^ n) pour la complexité lorsqu'il est calculé

Créé 17/08/2010 à 17:25
source utilisateur

voix
0

Karnaugh ou Quine-McCluskey

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

Cela devrait vous diriger dans la bonne direction pour réduire au minimum la table de vérité résultant.

Créé 17/08/2010 à 18:39
source utilisateur

voix
0

Pour des précisions sur la réponse de jk ... Si vous avez n valeurs booléennes (les « probabilités »?), Alors vous devez

  • créer un tableau de table de vérité qui est n par 2 ^ n
  • boucle i de 0 à (2 ^ n-1)
  • à l'intérieur de cette boucle, la boucle j de 0 à n-1
  • à l'intérieur de cette boucle, régler truthTable [i] [j] = j-ième bit du i (par exemple, (i >> j) et 1)
Créé 17/08/2010 à 17:55
source utilisateur

voix
0

Vous voulez écrire les nombres de 0 à 2 ^ N - 1 dans le système numérique binaire. Il n'y a rien à puce en elle. Il vous suffit de remplir toutes les cellules du tableau à deux dimensions. Vous ne pouvez pas le faire plus vite que cela.

Vous pouvez le faire sans itérer directement sur les chiffres. Notez que la colonne de droite répète 0 1, la colonne suivante répète 0 0 1 1, puis la suivante 0 0 0 0 1 1 1 1et ainsi de suite. Chaque colonne se répète 2 ^ columnIndex ( à partir de 0) zéros et de là alors.

Créé 17/08/2010 à 17:23
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more