Тверской государственный университет
Опубликован: 06.10.2013 | Доступ: свободный | Студентов: 1373 / 335 | Длительность: 02:37:00
Специальности: Преподаватель
Лекция 3:

Логика. Логические функции. Решение уравнений

< Лекция 2 || Лекция 3: 123 || Лекция 4 >

Программа на языке C# для решения логических уравнений

Написать программу для решения логических уравнений полезно по многим причинам, хотя бы потому, что с ее помощью можно проверять правильность собственного решения тестовых задач ЕГЭ. Другая причина в том, что такая программа является прекрасным примером задачи на программирование, соответствующей требованиям, предъявляемым к задачам категории С в ЕГЭ.

Идея построения программы проста, - она основана на полном переборе всех возможных наборов значений переменных. Поскольку для заданного логического уравнения или системы уравнений число переменных n известно, то известно и число наборов – 2^n, которые требуется перебрать. Используя базовые функции языка C# - отрицание, дизъюнкцию, конъюнкцию и тождество, нетрудно написать программу, которая для заданного набора переменных вычисляет значение логической функции, соответствующей логическому уравнению или системе уравнений.

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

Единственная сложность, возникающая при реализации программы, связана с задачей формирования по номеру набора самого набора значений переменных. Красота этой задачи в том, что эта, казалось бы, трудная задача, фактически сводится к простой, уже неоднократно возникавшей задаче. Действительно, достаточно понять, что соответствующий числу i набор значений переменных, состоящий из нулей и единиц, представляет двоичную запись числа i. Так что сложная задача получения набора значений переменных по номеру набора сводится к хорошо знакомой задаче перевода числа в двоичную систему.

Вот как выглядит функция на языке C#, решающая нашу задачу:

/// <summary>
/// программа подсчета числа решений
/// логического уравнения (системы уравнений)
/// </summary>
/// <param name="fun">
/// логическая функция - метод, 
/// сигнатура которого задается делегатом DF
/// </param>
/// <param name="n">число переменных</param>
/// <returns> число решений</returns>
static int SolveEquations(DF fun, int n)
{
  int res = 0;
  bool[] set = new bool[n];
  int m = (int)Math.Pow(2, n);  //число наборов
  int p = 0, q = 0, k = 0;
  //Полный перебор по числу наборов
  for (int i = 0; i < m; i++)
  {
    p = i;
    //Формирование очередного набора - set,
    //заданного двоичным представлением числа i 
    for (int j = 0; j < n; j++)
    {
      k = (int)Math.Pow(2, j);
      q = p % 2;
      p = p / 2;
      if (q == 0)
        set[j] = false;
      else
        set[j] = true;
    }
    //Вычисление значения функции на наборе set
    if(fun(set)) 
      res ++;
  }
  return res;
}    
    

Для понимания программы, надеюсь, достаточно сделанных объяснений идеи программы и комментариев в ее тексте. Остановлюсь лишь на пояснении заголовка приведенной функции. У функции SolveEquations два входных параметра. Параметр fun задает логическую функцию, соответствующую решаемому уравнению или системе уравнений. Параметр n задает число переменных функции fun. В качестве результата функция SolveEquations возвращает число решений логической функции, то есть число тех наборов, на которых функция принимает значение true.

Для школьников привычно, когда у некоторой функции F(x) входным параметром x является переменная арифметического, строкового или логического типа. В нашем случае используется более мощная конструкция. Функция SolveEquations относится к функциям высшего порядка – функциям типа F(f), у которых параметрами могут быть не только простые переменные, но и функции.

Класс функций, которые могут передаваться в качестве параметра функции SolveEquations, задается следующим образом:

delegate bool DF(bool[] vars);    
    

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

В заключение приведу программу, в которой функция SolveEquations используется для решения нескольких систем логических уравнений. Функция SolveEquations является частью приводимого ниже класса ProgramCommon:

class ProgramCommon
  {
    delegate bool DF(bool[] vars);
    static void Main(string[] args)
    {
      Console.WriteLine("У Функции And решений - " +
        SolveEquations(FunAnd, 2));
      Console.WriteLine("У Функции 51 решений - " +
        SolveEquations(Fun51, 5));             
      Console.WriteLine("У Функции 53 решений - " +
        SolveEquations(Fun53, 10));
    }        
    static bool FunAnd(bool[] vars)
    {
      return vars[0] && vars[1];
    }
    static bool Fun51(bool[] vars)
    {
      bool f = true;
      f = f && (!vars[0] || vars[1]);
      f = f && (!vars[2] || vars[1]);
      f = f && (!vars[3] || vars[4]);
      f = f && (!vars[1] || vars[3]);
      f = f && (!vars[3] || vars[2]);
      return f;
    }        
    static bool Fun53(bool[] vars)
    {
      bool f = true;
      f = f && ((vars[0] == vars[1]) || (vars[0] == vars[2]));
      f = f && ((vars[1] == vars[2]) || (vars[1] == vars[3]));
      f = f && ((vars[2] == vars[3]) || (vars[2] == vars[4]));         
      f = f && ((vars[3] == vars[4]) || (vars[3] == vars[5]));
      f = f && ((vars[4] == vars[5]) || (vars[4] == vars[6]));
      f = f && ((vars[5] == vars[6]) || (vars[5] == vars[7]));
      f = f && ((vars[6] == vars[7]) || (vars[6] == vars[8]));
      f = f && (!((vars[7] == vars[8]) || (vars[7] == vars[9]))); 
      return f;
    } 
  }
    

Вот как выглядят результаты решения по этой программе:


< Лекция 2 || Лекция 3: 123 || Лекция 4 >
Мария Паршикова
Мария Паршикова
Александр Коротенко
Александр Коротенко
Курс "Подготовка к ЕГЭ по информатике". Знаю, что ответ верный, но система его не принимает. Пытался ввести его в разных формах (строчные, прописные, все, одна и т.д.)