14 июня 2011 г.

Удаление фиктивных переменных из таблицы значений булевой функции

 Немножко справки о фиктивных переменных:
// TODO: здесь будет инфа, обещаю. Как отсканю, выложу.

Сам код из Visual Studio с++ =>

// win32 console application: Discrete Math, program 2

#include <stdio.h>
#include <conio.h>
#include <iostream>

using namespace std;

int main ()
{
    setlocale (LC_ALL, "Russian");
   
    cout << endl << endl << endl << endl << endl << "                       Программа выявления и удаления фиктивных" << endl;
    cout << "                           переменных по таблице истинности" << endl;
    cout << "                       Author: Duseev Vagiz, first year IC TPU" << endl;
    cout << "                                    г. Томск, 2011" << endl << endl;
    getche();
    system("cls");

    cout << "Введите количество перееменных в формуле: ";

    int vars, strokes, comparablecurrentLinesAmount, currentLinesCompareLimit, jump, currentLine, i, j, k;
    bool equalColumns_true = false, columnsEquality_failed, lineOut_true;
   
    cin >> vars;
    strokes = 1 << vars;
    currentLinesCompareLimit = strokes;
    comparablecurrentLinesAmount = strokes;
    jump = strokes;

// Динамическое выделение памяти
    bool** tm_table = new bool *[strokes];
    for (i=0; i<strokes; i++)
        tm_table [i] = new bool [vars+1];

    int* variables = new int [vars+1];
   
// Заполнение таблицы истинности
    for (int i=0; i<strokes; i++)
        for (int j=0; j<vars; j++)
            tm_table[i][j] = (i >> (vars-j-1)) & 1;

    cout << endl << "Введите столбик из " << strokes << " значений функции: ";

    for (i=0; i<strokes; i++)
        cin >> tm_table [i][vars];

    for (i=0; i<vars+1; i++)
        variables [i] = i+1;
   
    getche();
    system("cls");
   
// Вывод таблицы истинности
    cout << endl << "Исходная таблица истинности:" << endl;
    for (i=0; i<vars; i++)
        cout << "x" << variables[i] << " ";
    cout << "f("; for (i=1; i<=vars;i++) if (i != vars) cout << "x" << i << ",";
    else cout << "x" << i << ")" << endl;

    for (i=0; i<strokes; i++)
    {
        for (j=0; j<vars+1; j++)
            cout << " " << tm_table [i][j] << " ";
        cout << endl;
    }
    cout << endl;

// Вывод отладочных данных
    //    cout << "strokes" << strokes << endl;
    //    cout << "vars" << vars << endl << endl;

// Распознавание фиктивной переменной
   
    for (j=0; j<vars; j++)
    // Пройтись по всем переменным
    {
        if (j == vars-1)
        {
            jump = 2; // Крайний случай проверки последнего столбца
            currentLinesCompareLimit = 1;
        }
        else
        {
            jump /= 2; // strokes/2 => jump/2 => jump/2 => ...
            currentLinesCompareLimit = jump; // strokes/2 => currentLinesCompareLimit/2 => currentLinesCompareLimit/2 => ...
        }

        //Отладочная информация, вывод
        //cout << endl << "*****Отладочная информация*****" << endl;
        //cout <<            "     Проверяемая переменная: " << j+1 << endl;
        //cout <<         "     currentLinesCompareLimit = " << currentLinesCompareLimit << endl;
        //cout <<         "     jump = " << jump << endl;

        columnsEquality_failed = false;
        currentLine = 0; // Каждую новую переменную сравниваем с 0 линии

        for (i=0; i < (1<<j); i++)
        // Количество итераций равно количеству сравнений для Xi
        {
            while (currentLine < currentLinesCompareLimit)
            // Одно сравнение в это цикле
            {
                if (tm_table[currentLine][vars] == tm_table[currentLine+currentLinesCompareLimit][vars])
                    equalColumns_true = true;
                else
                {
                    equalColumns_true = false;
                    columnsEquality_failed = true;
                    break;
                }

                currentLine++;
            }

            if (columnsEquality_failed)
                break;
           
            currentLinesCompareLimit += jump;
            currentLine += jump;

        }

        //cout <<         "     columnsEquality_failed = " << columnsEquality_failed << endl;
        //cout <<         "     equalColumns_true = " << equalColumns_true << endl;
        //cout <<         "*************Конец*************" << endl << endl;

        if (equalColumns_true)
        {
            cout << "x" << j+1 << " - фиктивная переменная" << endl;
            variables[j] = 0;
        }
    }

    getche();
    system("cls");

// Удаление фиктивных переменных. На самом деле, я их просто не вывожу.
    cout << endl << "Таблица истинности функции, из которой удалены фиктивные переменные:" << endl;
    for (i=0; i<vars; i++)
        if (variables[i] != 0)
            cout << "x" << i+1 << " ";


    int mark=0; k=1; for (i=0; i<vars; i++) if (variables[i] != 0) mark++;

    cout << "f(";
    for (i=0; i<vars;i++)
    // mark - количество существенных переменных
    // k - счётчик уже выведенных существенных переменных
    {
        if (variables[i] != 0)
        // переменная не фиктивна
            if (k != mark)
            // выведены не все переменные
            {
                cout << "x" << i+1 << ",";
                k++;
            }
            else
            // выведится последняя существенная переменная
                cout << "x" << i+1 << ")" << endl;
    }

    for (i=0; i<strokes; i++)
    // Вывод построчно.
    // Строки, где фикт. переменные равны 0 не выводить!
    {
        lineOut_true = true;

        // Проверка на возможность вывода строки
        for (k=0; k<vars; k++)
            if (variables[k] == 0)
                if (tm_table [i][k] == 0)
                {
                    lineOut_true = false;
                    break;
                }
       
        if (lineOut_true)
        {
            // Не выводить элемент строки, со значением фиктивной переменной!
            for (j=0; j<vars+1; j++)
                if (variables[j] != 0)
                    cout << " " << tm_table [i][j] << " ";       
            cout << endl;
        }
    }

    getche();
    system("cls");

    for (i=0; i<strokes; i++)delete tm_table [i];
        delete tm_table;
    delete variables;

    cout << "Спасибо за работу!";

    getche();
    return 0;
}

Примечание: Всё можно сделать без заморочек гораздо проще и легче, если пользоваться хотя бы 2-мя или 3-мя массивами и притом не делать их динамическими. Но *ть, так же не интересно!
 Как с ней работать:

Комментариев нет:

Отправить комментарий