Решение системы линейных уравнений

Публикация № 1027730

Программирование - Практика программирования

Расчет систем линейных уравнений

29
Пример использования объекта Расчет систем линейных уравнений.

Начиная с версии платформы 8.3.14.1565 в 1С:Предприятие стал доступен объект для решения системы линейных уравнений. Следует предположить, что данный функционал не вызвал значительного интереса, так как  я не нашел на infostart ни одного упоминания, относящегося к данному предмету. Поиск через Яндекс вывел на статью "Механизм решения систем линейных алгебраических уравнений", которая всем хороша, за исключением того, что не содержит примера применения нового класса РасчетСистемЛинейныхУравнений. Этот пробел я и постараюсь восполнить. Решать будем систему из трех уравнений, которая вынесена в заголовок статьи.

                                                           x  -3y+5z  =-10

                                                         2x + y  - z   =5

                                                         4x+2y+3z   =5

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

                    

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

//-----------------------------------------------------------------
// куда - таблица значений, в которую добавляются свободные члены
// что - строка со значениями коэффициентов из правой части уравнения,
//       которые разделены ';'

Функция ДобавитьСвободныеЧлены(куда,что)
	данные=СтрРазделить(что,";",ЛОЖЬ);
	инд=1;
	для каждого к из данные цикл
		запись=куда.Добавить();
		запись.уравнение=инд  ;
		инд=инд+1             ;
		запись.Ч=число(к)     ;
	конеццикла;	
	
	возврат куда;
КонецФункции	


//--------------------------------------------------------------------------------------------
// куда - таблица значений, в которую добавляются коэффициенты уравнения из левой части
// что - строка со значениями коэффициентов,которые разделены ';'
// номер_уравнения - номер уравнения, которому относятся коэффициенты


Функция ДобавитьКоэффициенты(куда,что,номер_уравнения)
	данные=СтрРазделить(что,";",ЛОЖЬ);
	инд=1;
	для каждого к из данные цикл
		запись=куда.Добавить()           ;
		запись.уравнение=номер_уравнения ;
		запись.номер=инд                 ;
		инд=инд+1                        ;
		запись.Ч=число(к)                ;
	конеццикла;	
	
	возврат куда;
КонецФункции	

Теперь выполним подготовительные процедуры.

   ТипЧисло=новый ОписаниеТипов("Число");
   
   СвободныеЧлены=новый ТаблицаЗначений                     ;
   СвободныеЧлены.Колонки.Добавить("уравнение",ТипЧисло)    ;
   СвободныеЧлены.Колонки.Добавить("Ч",ТипЧисло)            ;
   //заносим в таблицу значения свободных членов
   ДобавитьСвободныеЧлены(СвободныеЧлены,"-10;5;5")         ;
   
   Коэффициенты=новый ТаблицаЗначений                 ;
   Коэффициенты.Колонки.Добавить("уравнение",ТипЧисло);
   Коэффициенты.Колонки.Добавить("номер",ТипЧисло)    ;
   Коэффициенты.Колонки.Добавить("Ч",ТипЧисло)        ;
   //заносим значения коэффициентов из левой части
   ДобавитьКоэффициенты(Коэффициенты,"1;-3;5",1)      ;
   ДобавитьКоэффициенты(Коэффициенты,"2;1;-1",2)      ;
   ДобавитьКоэффициенты(Коэффициенты,"4;2;3",3)       ;

На следующем шаге переходим к работе с объектом РасчетСистемЛинейныхУравнений. У него есть два свойства, первое - ИсточникДанныхУзлов, через которое передаются значения свободных коэффициентов,  и свойство ИсточникДанныхСвязей для передачи значений коэффициентов из левой части системы линейных уравнений. Отметим, что кроме сформированных таблиц мы указываем имена колонок, в которых хранится номер уравнения и номер переменной.

   Расчет=новый РасчетСистемЛинейныхУравнений    ;
   //коэффициенты из левой части уравнения
   Расчет.ИсточникДанныхСвязей=Коэффициенты     ;
   Расчет.КолонкаУравненияВСвязях ="уравнение"  ;           
   Расчет.КолонкаПеременныеВСвязях="номер"      ;
   //коэффициенты из правой части уравнения
   Расчет.ИсточникДанныхУзлов=СвободныеЧлены        ;
   Расчет.КолонкаУравненияВУзлах="уравнение"        ;

Заключительный штрих. Для того чтобы все заработало надо добавить ОписанияСистемЛинейныхУравнений в коллекцию ОписанияСистем  класса РасчетСистемЛинейныхУравнений.

   описание=Расчет.ОписанияСистем.Добавить();
   описание.КолонкаКоэффициентовВСвязях="Ч" ;
   описание.КолонкаКоэффициентовВУзлах ="Ч" ; 

И наконец непосредственный расчет.

   ответ=Расчет.РассчитатьСистемыЛинейныхУравнений() ;
   для каждого запись из ответ цикл
	   сообщить(запись.Решение1);
   конеццикла;	   
   

Точное решение для данной системы : 

x=1;

y=2;

z=-1

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

29

См. также

Специальные предложения

Комментарии
Избранное Подписка Сортировка: Древо
1. docerman 45 26.03.19 14:22 Сейчас в теме
А вот бы еще пояснили на простом примере как расчет системы линейных уравнений используется при расчете себестоимости в РАУЗ.
3. Xershi 632 26.03.19 15:20 Сейчас в теме
Минус за корявый код!

Также уравнение написали бы текстом.
Дополнительно не понятно, а где ответы?
1 - 6 - 5 = -10 в целом сходится, но это же надо еще посчитать.
Дооформите, чтобы глаза не резало!
DrAku1a; rpgshnik; +2 Ответить
4. dabu-dabu 7 26.03.19 15:41 Сейчас в теме
Механизм был бы классный, если бы они использовали другой метод для расчета СЛАУ.
У метода простых итераций слишком серьезные минусы и использование его в финансовых системах - очень сомнительная идея.
Что и показывает ваш простенький пример - вместо 1, получили 0,(9).
Да, и в РАУЗе используется тот-же метод, но не уверен, что расчет идет через данный объект.
А представление СЛАУ в табличном виде, все-таки, лучше в матричном виде делать.
5. Darklight 17 26.03.19 15:59 Сейчас в теме
(4)В УПП не будет типовой поддержки этого класса. в ERP 2.х скорее всего появится в этом году (ближе к зиме).
6. s_vidyakin 26.03.19 17:12 Сейчас в теме
(4) Вообще-то они на хабре обосновывали зачем придумали свой метод решения, он как раз быстрее стандартных именно в финансовых системах - на разреженных больших матрицах
7. dabu-dabu 7 26.03.19 20:53 Сейчас в теме
(6) Он быстрее только за счет того, что они забили на контроль вырожденности матрицы.
А это в свою очередь приводит к бредовым цифрам, если в исходных данных что-то не так. И эти цифры еще надо обнаружить. Когда появился РАУЗ очень многие этому удивлялись, но в 1С, видимо, решили что оно так лучшее. Зато у программистов на сопровождении всегда есть работа.
Циник; EMelihoff; Dach; +3 Ответить
8. Циник 27.03.19 15:21 Сейчас в теме
(7) Тут статья по результатам попытки использования РАУЗ в розничной сети. В вкратце, из-за постоянного пересорта товаров в магазинах и, как следствие, отрицательные остатки до проведения инвентаризации, все основные отчеты приходили в полную негодность после расчета себестоимости (триллионы в списанной себестоимости на оборотке и в типовых отчетах). Причем как повезет, иногда ошибка с отрицательным остатком не приводит к постоянному увеличению отклонения, а иногда приводит. Но так как ассортимент большой и магазинов было под 50, ситуация с некорректным расчетом возникала постоянно. А постоянные пересорты и отрицательные остатки в рознице — это данность с которой ничего не сделать.
Оставьте свое сообщение