|
v8: Анализатор произвольных формул | ☑ | ||
---|---|---|---|---|
0
mzelensky
10.04.13
✎
10:21
|
Доброго всем!
Есть вроде как примитивная задачка (для человека), которую никак не удается реализовать программно. Имеется формула (ее вводит пользователь, значения параметров подаются из вне): Результат = П1 * ( П2 + П3) где П1= 10 П2= 5 П3= 2 Не нужно быть гением, дабы догадаться, что результат будет равен "70". Рассчитать данную формулу в 1С не составляет труда через "Вычислить()" или "Выполнить()". Но у меня встает обратная задача. Допустим, мне измвестно: Результат=70 П2= 5 П3= 2 И нужно найти значение параметра "П1". КАК ЭТО СДЕЛАТЬ?! |
|||
1
В тылу врага
10.04.13
✎
10:23
|
Результат = П1*П1
Результат = 4 П1 = ? |
|||
2
vde69
10.04.13
✎
10:23
|
пусть пользователь напишет ВТОРУЮ формулу
|
|||
3
cw014
10.04.13
✎
10:24
|
Разбираешь формулу на составляющие, делаешь парсер, от него обратный парсер. Ничего сложного
|
|||
4
Волшебник
10.04.13
✎
10:24
|
П1 = Результат/(П2+П3)
|
|||
5
vmv
10.04.13
✎
10:25
|
простешие уравнения в 5-м классе проходят
*достал ранец* |
|||
6
mzelensky
10.04.13
✎
10:25
|
(2) не вариант. Формула может быь большой (с большим количеством параметров) и искомый параметр может быть ЛЮБЫМ. Один любой из множества. Вводить формулу для каждого параметра это не вариант.
|
|||
7
В тылу врага
10.04.13
✎
10:26
|
ответьте на (1) пожалуйста
|
|||
8
HeroShima
10.04.13
✎
10:26
|
поиск апроксимирующей функции
|
|||
9
mzelensky
10.04.13
✎
10:26
|
(4) молодец! А теперь как формулу
"П1 = Результат/(П2+П3)" получить программно?! Или ты сам пойдешь на 0,000001 ставки - формулы переворачивать?! |
|||
10
В тылу врага
10.04.13
✎
10:26
|
какие операции допустимы?
|
|||
11
mzelensky
10.04.13
✎
10:27
|
(3) нука, как будет выглядеть парсер такой формулы:
"((П1 + п2) * П3)/П4 " ?! |
|||
12
cw014
10.04.13
✎
10:27
|
(9) Не майся ерундой, только если за это не заплатят более 200 000 деревянных
|
|||
13
mzelensky
10.04.13
✎
10:27
|
(10) К сожалению, любые арифметические.
Т.е. все, что могу тпереварить эти функции: "Вычислить()" или "Выполнить()". |
|||
14
Godofsin
10.04.13
✎
10:28
|
(12) ++++++
|
|||
15
mzelensky
10.04.13
✎
10:29
|
(7) 2
|
|||
16
В тылу врага
10.04.13
✎
10:29
|
(13) арифметичиских операций в 1С всего 4 вроде как, ну еще %
|
|||
17
В тылу врага
10.04.13
✎
10:29
|
(15) а почему не -2?
|
|||
18
mzelensky
10.04.13
✎
10:29
|
(12) это ты так признал тот факт ,что ты не можешь ничего путного предложить?!
|
|||
19
cw014
10.04.13
✎
10:30
|
(17) +++++++++++++++
|
|||
20
mzelensky
10.04.13
✎
10:30
|
(16) Ок, пусть даже так.
|
|||
21
HeroShima
10.04.13
✎
10:31
|
а если формула известна, исходим из того, что у каждой операции есть обратная. строим уравнение относительно неизвестного
|
|||
22
fmrlex
10.04.13
✎
10:31
|
||||
23
mzelensky
10.04.13
✎
10:31
|
(17) Может и -2, но в 99% случаев используются положительные параметры. Ты указал на "исключение". Предложи хотя бы реализацию "общего", идеального случая из (0)
|
|||
24
mzelensky
10.04.13
✎
10:32
|
(21) как построить это уравнение программно!? научи?!
|
|||
25
mzelensky
10.04.13
✎
10:32
|
(22)оооох, давненько я на этот сайт не захаживал :)
|
|||
26
cw014
10.04.13
✎
10:33
|
(25) Да, и ерунду всякую не спрашивал... ))))))
|
|||
27
fmrlex
10.04.13
✎
10:33
|
||||
28
HeroShima
10.04.13
✎
10:33
|
(24) порой алгоритмы солверов
|
|||
29
В тылу врага
10.04.13
✎
10:34
|
(23) это только частный случай, можно подобрать и посложнее ))
|
|||
30
fmrlex
10.04.13
✎
10:34
|
А вообще рекомендую подключаться к математическим библиотекам. Т.к. задача не тривиальная. OpenSource мат библиотеки есть, погугли
|
|||
31
В тылу врага
10.04.13
✎
10:36
|
давай лучше аналог 1С писать
|
|||
32
Rovan
гуру
10.04.13
✎
10:37
|
(0) передаешь формулу сайту nigma.ru
- он всё посчитает например (x + 7) * 8 = 2 |
|||
33
HeroShima
10.04.13
✎
10:37
|
(31) пишите лучше что-то превосходящее)
|
|||
34
Волшебник
10.04.13
✎
10:38
|
(9) MatLab прикрути
|
|||
35
Rovan
гуру
10.04.13
✎
10:38
|
||||
36
Lexusss
10.04.13
✎
10:39
|
В общем случае задача не решаема.
|
|||
37
fmrlex
10.04.13
✎
10:40
|
http://alglib.sources.ru/ загляни сюда
|
|||
38
mzelensky
10.04.13
✎
10:40
|
(32) Прикольно! А типа "сервиса" под это нет?!
|
|||
39
mzelensky
10.04.13
✎
10:41
|
(35) да. я уже попробовал. Вот ток как результат забрать?!
|
|||
40
Эмбеддер
10.04.13
✎
10:42
|
есть такая функция solve, она решает уравнения
|
|||
41
HeroShima
10.04.13
✎
10:43
|
||||
42
В тылу врага
10.04.13
✎
10:43
|
(33) конечно превосходящее, это просто известный мем
|
|||
43
Rovan
гуру
10.04.13
✎
10:43
|
(39) парсишь результирующую страницу - ищешь подстроку
onclick="CancelEvent(event); plainMathText('x= |
|||
44
Зойч
10.04.13
✎
10:44
|
методом дихотомии или золотого сечения, если формула заранее не известна
|
|||
45
Эмбеддер
10.04.13
✎
10:46
|
(44) ниче не получится, если больше 1 минимума/максимума
|
|||
46
mzelensky
10.04.13
✎
10:46
|
(33) запаришься перебирать
|
|||
47
mzelensky
10.04.13
✎
10:47
|
(46) -> (44)
|
|||
48
Михаил Козлов
10.04.13
✎
10:47
|
Если речь идет о ЧИСЛЕННОМ решении уравнения, то см. численные методы решения уравнений.
Если о ФОРМУЛЕ вычисления корней уравнения, то для полиномов степени > 4 такой формулы не существует. Поэтому, либо численное решение, либо ограничиться классом видов уравнения. |
|||
49
Зойч
10.04.13
✎
10:48
|
(46) ты не знаком с дихотомией? фиииии
|
|||
50
Torquader
11.04.13
✎
00:59
|
В общем случае, задача решения не имеет.
Например, может быть задано уравнение пятой степени, которое аналитически не решается и т.п. Численные методы, конечно, позволяют решить то, что не решается аналитически, но тоже не всегда. |
|||
51
Злопчинский
11.04.13
✎
01:42
|
формулы писать через ПОЛИЗ в стек. тогда рзабор и вычисление недостающего параметра будет своидится к простому линейному чтению из стека..
??? |
|||
52
Ksandr
11.04.13
✎
07:50
|
П1*П2^4+П3*П2^2+П5=0
Найдешь П2? |
|||
53
Rovan
гуру
11.04.13
✎
08:04
|
||||
54
vde69
11.04.13
✎
08:47
|
кто сможет разобрать формулу:
результат = мин(а,б,в,г) а вот еще Результат = МодульНДС.ПолучитьСтавку(А) интересно какой к черту solve знает как обратить функцию из глобальника? еще раз говорю - задача НЕРЕШАЕМА! |
|||
55
Steelvan
11.04.13
✎
10:05
|
На инфостарте был анализатор таких выражений.
Там поищи. |
|||
56
HeroShima
11.04.13
✎
10:10
|
(54) x > 0.0, найти x
вполне математическая формулировка |
|||
57
successful
11.04.13
✎
10:21
|
(52) А в чем проблема
П2^2=Y и решаем стандартное квадратичное... |
|||
58
Кирпич
11.04.13
✎
10:34
|
Ну если в формуле только константы, переменные и стандартные операции +-/*, то задача вполне решаема. Дайте денег программисту и всё.
|
|||
59
successful
11.04.13
✎
10:38
|
(58) Серьезно? Полиномиальное уравнение 5 степени вполне представимо записью операций +-/*
|
|||
60
Кирпич
11.04.13
✎
10:42
|
(59) Ну задача вроде то же самое, что поиск решения в Excel
|
|||
61
toypaul
гуру
11.04.13
✎
10:43
|
(0) в общем случае не всегда есть обратная функция
|
|||
62
NS
11.04.13
✎
10:49
|
(0) Численные методы поиска корня. Метод ньютона и т.д.
|
|||
63
NS
11.04.13
✎
10:50
|
||||
64
NS
11.04.13
✎
10:57
|
В общем случае один из корней можно найти таким методом.
Привести к виду f(x)=0; Просто вычитая из левой части правую часть. Найти максимум (на самом деле любое положительное значение) Найти минимум (на самом деле любое отрицательное) Если не смогли найти либо то, либо то - то выдаем что ответа нет. Если нашли - то уже куча методов поиска корня, например методом деления отрезка пополам. |
|||
65
NS
11.04.13
✎
11:02
|
Получить положительное и отрицательное значение можно просто наложив сетку на область определения.
|
|||
66
GANR
11.04.13
✎
12:27
|
wiki:Метод_бисекции, например, никто не отменял. Это простейшее, что можно предпринять.
|
|||
67
Кирпич
11.04.13
✎
18:16
|
накропал алгоритм решения уравнения с одним неизвестным типа как в (0)
короче надо, как в (64) уже сказано, привести к виду f(x)=0, а потом хитрым перебором найти неизвестное. ничего особо сложного нету. автор, давай пять тыщ. |
|||
68
Михаил Козлов
11.04.13
✎
18:45
|
(67) Раскройте тайну хитрого перебора. Пожалуйста.
|
|||
69
Кирпич
11.04.13
✎
18:56
|
(68) Да просто двоичный поиск. Типа как в (66)
|
|||
70
Кирпич
11.04.13
✎
19:15
|
+(69) хотя соврал я. это не двоичный поиск, а какая то другая фигня. сам изобрел. хотя это скорее всего изобретено уже.
короче берешь фиксированный диапазон значений например Min := -99999999999; Max := 99999999999; и в нем ищешь сначала близкий к решению диапазон шириной в в 1000000000, потом в этом диапазоне ищешь диапазон шириной 100000000, потом 1000000, потом 10000, 1000, 100, 10, 1, потом 0.1,0.01,0.001 и далее. вроде работает и скорость нормальная. Замерил: 100000 решений за 1,5 секунды. Правда это на Delph. На 1С конечно минут 10 будет считать. короче велосипед едет. можно еще что нибудь попробовать, но уже лень. |
|||
71
NS
11.04.13
✎
19:27
|
(68) А чем плохо наложить сетку на область определения, либо монте-карло по области определения, а потом дихотомией между каждой парой соседних точек с разными знаками значения функции в них?
Найти корни функции одной переменной - это совсем просто. |
|||
72
Кирпич
11.04.13
✎
19:37
|
(71)ну вроде автору только одну переменную нужно угодать. нафиг тут монтыкарлы городить.
|
|||
73
NS
11.04.13
✎
19:43
|
(72) Чтоб искать корень функции с несколькими экстремумами (например полином третьей степени) - нужно сначала найти область, в которой этот корень содержиться.
Монте-Карло по сложности написания ничем не отличается от наложении сетки. Сетка. а=нач; Пока а<=кон цикл // взяли значение в точке а=а+(кон-нач)/(количествоточекразбиения-1); Конеццикла; Монтекарло Для а=1 по количсетвоточекрабиения // взяли значение в точке нач+(кон-нач)*Random(); Конеццикла; Монте-Карло это очень просто, и городить тут ничего не надо. |
|||
74
Кирпич
11.04.13
✎
19:46
|
а. ну у меня как раз монте карло и получился :)
|
|||
75
NS
11.04.13
✎
19:50
|
Поиск самого корня.
Нужно две точки, а и b такие что f(a)>0 и f(b)<0 Тогда сам поиск корня fa=f(a); fb=f(b); Пока abs(a-b)>точность цикл c=(a+b)/2 fc=f(c); Если f(c)>0 тогда a=c; fa=fc; Иначеесли f(c)<0 тогда b=c; fb=fc; иначе а=с; b=с; прервать; конецесли; КонецЦикла; Сообщить("Корень: "+((a+b)/2)); |
|||
76
NS
11.04.13
✎
19:56
|
А лучше
c=окр((a+b)/2,10); Чтоб не налететь на резкое замедление из-за того что 1С хранит все знаки после точки. |
|||
77
Лефмихалыч
11.04.13
✎
20:06
|
(0) вело сипедо изо бретун.
Задачу озвучь |
|||
78
NS
11.04.13
✎
20:17
|
перем maxX,minX; // область определения функции
перем точность; Функция f(x) // искомая функция Возврат x*x-2; // найдем решение уравнения x^2-2=0, или что тоже самое x^2=2 КонецФункции Процедура СообщитьКореньВИнтервале(знач a,знач b); fa=f(a); fb=f(b); Если fa*fb>0 Тогда Возврат; КонецЕсли; Если fa=0 Тогда сообщить(a); возврат; КонецЕсли; Если fb=0 Тогда возврат; // на следующей итерации будет выведен этот корень КонецЕсли; Если fa<0 Тогда c=a; a=b; b=c; // поменяем значения местами fa=f(a); fb=f(b); КонецЕсли; // теперь у нас f(a)>0 и f(b)<0 Пока макс((a-b),(b-a))>точность цикл c=окр((a+b)/2,10); fc=f(c); Если f(c)>0 тогда a=c; fa=fc; Иначеесли f(c)<0 тогда b=c; fb=fc; иначе а=c; b=c; прервать; конецесли; КонецЦикла; Сообщить("Корень: "+((a+b)/2)); Конецпроцедуры Процедура Сформировать() minX=-100; MaxX=100; точность=0.000000001; Для а=0 по 999 Цикл СообщитьКореньВИнтервале(minX+(MaxX-MinX)*а/1000,minX+(MaxX-MinX)*(а+1)/1000); КонецЦикла; КонецПроцедуры |
|||
79
NS
11.04.13
✎
20:32
|
Одна буква "а" была не в том регистре :)
Вот правильно перем maxX,minX; // область определения функции перем точность; Функция f(x) // искомая функция Возврат x*x-2; // найдем решение уравнения x^2-2=0, или что тоже самое x^2=2 КонецФункции Процедура СообщитьКореньВИнтервале(знач a,знач b); fa=f(a); fb=f(b); Если fa*fb>0 Тогда Возврат; КонецЕсли; Если fa=0 Тогда сообщить("Корень: "+a); возврат; КонецЕсли; Если fb=0 Тогда возврат; // на следующей итерации будет выведен этот корень КонецЕсли; Если fa<0 Тогда c=a; a=b; b=c; // поменяем значения местами fa=f(a); fb=f(b); КонецЕсли; // теперь у нас f(a)>0 и f(b)<0 Пока макс((a-b),(b-a))>точность цикл c=окр((a+b)/2,10); fc=f(c); Если fc>0 тогда a=c; fa=fc; Иначеесли fc<0 тогда b=c; fb=fc; иначе a=c; b=c; прервать; конецесли; КонецЦикла; Сообщить("Корень: "+((a+b)/2)); Конецпроцедуры Процедура Сформировать() minX=-100; MaxX=100; точность=0.000000001; Для а=0 по 999 Цикл СообщитьКореньВИнтервале(minX+(MaxX-MinX)*а/1000,minX+(MaxX-MinX)*(а+1)/1000); КонецЦикла; КонецПроцедуры |
|||
80
Кирпич
12.04.13
✎
13:31
|
А вот почти готовое решение. Вводи уравнение и переменную, которую нужно угадать.
|
|||
81
HeroShima
21.04.13
✎
21:44
|
||||
82
Лефмихалыч
21.04.13
✎
21:46
|
пора секцию создавать "Что еще нафиг не нужно в 1С". Ведущим по четным будет автор, а по нечетным - Ненавижу1С (если из бани выздоровеет)
|
|||
83
Кирпич
06.05.13
✎
16:34
|
+(80) надо вынести за цикл вот эти строчки, кстати. будет быстрее работать.
МояПеременная = Л; ТЛ = Абс(Вычислить(Выр)); МояПеременная = П; ТП = Абс(Вычислить(Выр)); |
|||
84
sda553
06.05.13
✎
16:45
|
Предлагаю решать методом последовательного приближения
|
|||
85
Кирпич
06.05.13
✎
16:58
|
да уж решили давно. вот усовершенствовал. так будет быстрее.
|
|||
86
Infsams654
06.05.13
✎
17:08
|
(85) - не прокатит, про обратную польскую запись слышали?
|
|||
87
_Demos_
06.05.13
✎
17:30
|
такие задачи через деревья легче всего решить
|
|||
88
Aprobator
06.05.13
✎
17:36
|
чего только народ на 1С не пытается написать. Вот интересно, молотком никто не пробовал бумагу клеить?
|
|||
89
HeroShima
08.05.13
✎
01:42
|
Только что в (82) OpenCL гонял. Никому не надо? )
|
|||
90
zladenuw
08.05.13
✎
01:56
|
(89) а че там ? подумаю это направление изучить но пока все на 1с :(
|
|||
91
HeroShima
08.05.13
✎
02:04
|
(90) Мультиплатформенный массивный параллелизм с ускорением на GPU, или без.
|
|||
92
zladenuw
08.05.13
✎
02:16
|
(91) типа понял о чем ты :)
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |