Отправляет email-рассылки с помощью сервиса Sendsay

Всё о работе в Интернет

  Все выпуски  

Занятие 34.


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

Поклянёмся с вами в том, что никогда не забудем о важности математических знаний для выработки умений и навыков профессионального программирования! Не так давно мне поведали, что особей, способных только лишь программировать составленные кем-то алгоритмы, в среде профессионалов нежно называют “быдлокодерами”.

РЕШЕНИЕ НЕРАВЕНСТВ И СИСТЕМ

1. Решение задачи “Неравенство”.

Задача V.2.8. “Неравенство”. Заданы коэффициенты неравенства a * x > b. Построить подпрограмму решения неравенства.

Математические предпосылки решения неравенства таковы:

-       если коэффициент a > 0, то решением неравенства будет выражение x > b / a; например, неравенство * x > 3 имеет решение x > 1.5;

-       если коэффициент a < 0, то решением неравенства будет выражение x < b / a; например, неравенство –2 * x > 3 имеет решение x < –1.5;

-       если коэффициент a = 0, а коэффициент b < 0, то решением неравенства может быть любое значение x; например, неравенство * x > –5 справедливо при произвольном x;

-       если коэффициент a = 0, а коэффициент b >= 0, то неравенство не имеет решений; например, неравенство 0  x > 5 не может быть справедливым ни при каком x.

Таким образом, подпрограмма решения неравенства должна иметь два результата. Основной результат – граничное значение для x, которое может быть вычислено не при любых значениях коэффициентов неравенства. Дополнительный результат – флажок z, который для всех случаев должен идентифицировать характер результата решения. Это достигается присвоением ему значений соответствующих кодов, в том числе:

-       код z = 1; решение следует записать в виде x > c, где с = b / a – граничное значение;

-       код z = 2; решение следует записать в виде x < c, где с = b / a – граничное значение;

-       код z = 3; следует сообщить, что решением может быть произвольное значение x;

-       код z = 4; следует сообщить, что решения отсутствуют.

Оптимальный порядок следования ветвей оператора ветвления совпадает со схемой математического решения.

Решение рассмотренной задачи оформлено в виде процедуры Inequality, которая включена в модуль Problem http://a-morgun.narod.ru/a08-01/a0008-0001-0002.html:

Procedure Inequality ( a,b: Real; Var c: Real; Var z: Byte);
Begin
   If a>0 Then Begin c:=b/a; z:=1 End Else
      If a<0 Then Begin c:=b/a; z:=2 End Else
         If b<0 Then z:=3 Else z:=4
End;

Соответствующая программа имеет вид:

{$B+,D+,E+,I+,L+,N+,Q+,R+,X-}
Program V_02_08;
   Uses Problem;
   Var a,b,c: Real; z: Byte;
Begin
   Write('
Введите коэффициенты неравенства a,b: ');
   ReadLn(a,b);
   Inequality(a,b,c,z);
   Case z Of
      1: WriteLn('
Решение: x > ',c:0:4);
      2: WriteLn('
Решение: x < ',c:0:4);
      3: WriteLn('
Решение произвольно');
      4: WriteLn('
Решение отсутствует');
   End
End.

2. Решение задачи “Система”.

Задача V.2.7. “Система”. Заданы коэффициенты и свободные члены системы двух линейных уравнений с двумя неизвестными


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

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

Вычислить определитель второго порядка очень легко. Для этого нужно найти разность произведений его диагональных элементов. Например, значение определителя Δ можно вычислить по формуле Δ = a1 * b2 – a2 * b1.    

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

-       Определитель в знаменателе отличен от нуля. Тогда система уравнений имеет единственное решение, определяемое по формулам Крамера.

-       Определитель в знаменателе равен нулю. Оба определителя в числителях также равны нулю. Система уравнений имеет бесчисленное множество решений.

-       Определитель в знаменателе равен нулю. Хотя бы один из определителей в числителе отличен от нуля. Система уравнений не имеет решений.

Эти выводы справедливы при условии, что не все коэффициенты системы a1b1a2b2 равны нулю одновременно. Это ограничение значений исходных данных указано непосредственно в условии задачи.

Таким образом, подпрограмма решения системы двух линейных уравнений с двумя неизвестными имеет три результата. Основные результаты – значения неизвестных x и y, которые могут быть вычислены не при любых значениях коэффициентов и свободных членов системы. Дополнительный результат – флажок z, который во всех случаях должен идентифицировать характер результата решения. Это достигается присвоением ему значений соответствующих кодов (1 – единственное решение, 2 – множество решений, 3 – отсутствие решений).

Наиболее целесообразно порядок следования ветвей оператора ветвления выбрать таким:

-       проверка условия V <> 0, где V – значение определителя в знаменателе; в случае его истинности может быть получено единственное решение системы; в дальнейшем условие V = 0 можно не проверять;

-       проверка на равенство нулю определителей в обоих числителях; в случае положительного ответа имеем бесчисленное множество решений;

-       во всех остальных случаях система решений не имеет, что соответствует альтернативной ветви оператора ветвления. 

После вычисления каждого из определителей в процедуре присутствуют операторы вида x := Int ( x * 1E10 ) / 1E10. Они используются для уборки “мусора”. В данном случае это необходимо, чтобы правильно вычислять определители тогда, когда они должны иметь нулевые значения.

В необходимости этого убеждает пример системы уравнений . Эта система имеет бесчисленное множество решений, поскольку все её определители равны нулю, в чём несложно убедиться вручную. А теперь проконтролируем значения выражений a1*b2–a2*b1, c1*b2–c2*b1 и a1*c2–a2*c1, составив для этого простенькую программку. При этом получаем результаты 3.637978807110–12, 1.818989403510–12 и –7.275957614210–12 соответственно.

Отличия определителей от нуля, возникшие по причине приближённого характера машинных вычислений, весьма незначительны. Но даже столь небольшие отличия приводят к неправильному определению характера результата решения и к получению несуществующих решений системы уравнений. Благодаря же применению операторов вида x := Int ( x * 1E10 ) / 1E10 определители получают правильные нулевые значения.

Решение рассмотренной задачи оформлено в виде процедуры System_Equation, которая включена в модуль Problem http://a-morgun.narod.ru/a08-01/a0008-0001-0002.html:  

Procedure System_Equation(a1,b1,c1,a2,b2,c2:Real; Var x,y:Real; Var z:Byte);
  
Var V,Vx,Vy: Real;
Begin
  
V := a1*b2-a2*b1; V := Int ( V*1E10 ) / 1E10;
  
Vx := c1*b2-c2*b1; Vx := Int ( Vx*1E10 ) / 1E10;
  
Vy := a1*c2-a2*c1; Vy := Int ( Vy*1E10 ) / 1E10;
  
If V<>0 Then Begin x := Vx/V; y := Vy/V; z := 1 End
     
Else If (Vx=0) And (Vy=0) Then z:=2 Else z:=3
End;

Уважаемые подписчики! Вы уже, наверное, обратили внимание на то, что теперь мы значительно меньше уделяем внимания алгоритмическому языку, нежели ранее? Прислушайтесь к себе и вы поймёте, что, как средство алгоритмизации ветвлений, АЯ вам уже не нужен. Некоторые даже могут сказать, что он им был не нужен изначально. Это нормально, поскольку человек, не являющийся педагогом-профессионалом, чаще всего не отдаёт себе отчёт в том, откуда, каким путём и благодаря чему у него появились те или иные знания.

Уважаемые подписчики! При необходимости задать вопрос, проконсультироваться, уточнить или обсудить что-либо обращайтесь через Гостевую книгу моего персонального сайта http://a-morgun.narod.ru. При этом настоятельно рекомендую пользоваться браузером Internet Explorer.

С уважением, Александр.

A-morgun.narod.ru/image/i001_z034.jpg


В избранное