|
|
|
Помогите с задачей
|
|||
|---|---|---|---|
|
#18+
Задача взята из книги А. Шеня "Программирование теоремы и задачи". Решения задачи в книге не приводится. Если кто знает принцип, поясните его хотя бы в общих словах, или приведите ссылку на источник, буду благодарен. Просто долго мучаюсь с задачей и не могу найти правильного решения. Задача. Дана программа вычисления значения некоторого многочлена Р(х 1 , х 2 , ..., x n ), содержащая только комады присваивания. Их правые части - выражения, содержащие сложение, умножение, константы, переменные х 1 , х 2 , ..., x n и ранее встречавшиеся(в левой части) переменные. Доказать, что существует программа того же типа, вычисляющая все n частных производных, причем общее число арифмитических операций не более чем в С раз превосходит число арифметических операцийв исходной программе. Константа С не зависит от n. [Указание: Можно считать что каждая комманда - сложение двух чисел, умножение двух чисел или умножение на константу. Использовать индукцию по числу команд, применяя индуктивное предположение к программе, получающейся отбрасывание первой команды.] ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2009, 04:43:17 |
|
||
|
Помогите с задачей
|
|||
|---|---|---|---|
|
#18+
Я решал без индукции. Сначала преобразуем команды как сказано в подсказке, т.е. чтобы каждая состояла из одного сложения или одного умножения. Пусть их число равно K. Теперь построим графовую модель задачи. Граф будет DAG-ом, с помеченными дугами, из каждой вершины выходит от 0 до 2 дуг. n вершин будут соответствовать неизвестным x 1 , ..., x n . Рядом с ними можно подписать их векторы частных производных, каждый содержит все нули, кроме одной единицы. Ещё у нас будет K вершин, соответствующие командам, вернее, производным переменных, стоящих в левых частях команд. Для команд вида A = B + C производная равна A' = B' + C' поэтому из вершины, соответствующей A', рисуем дуги в вершины B' и C' с метками = 1. Для команд вида A = B * C производная равна A' = B' * C + B * C' из вершины A' рисуем дугу в B', помеченную C, и дугу в C', помеченную B. Структура графа известна до выполнения алгоритма, а метки на дугах станут известны в ходе вычислений. Если мы найдём метки на дугах и будем вычислять для каждой вершины соответствующий вектор из n частных производных, то сложность получится O(N*(N+K)). Но, если немного подумать, то можно заметить, что производную по x i можно найти так: если мы рассмотрим все пути, ведущие из корня в вершину x i , и для каждого перемножим метки на нём, и просуммируем всё, то получится искомая величина. И мы можем найти для каждой вершины такую сумму по всем путям из корня в данную вершину в сумме за O(N+K). Понятно, что граф в явном виде в программе строить не обязательно. Он нужен просто для упрощения понимая сути алгоритма. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.07.2009, 01:45:15 |
|
||
|
Помогите с задачей
|
|||
|---|---|---|---|
|
#18+
rmull, Спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.07.2009, 00:55:44 |
|
||
|
Помогите с задачей
|
|||
|---|---|---|---|
|
#18+
rmullЯ решал без индукции. Сначала преобразуем команды как сказано в подсказке, т.е. чтобы каждая состояла из одного сложения или одного умножения. Пусть их число равно K. Теперь построим графовую модель задачи. Граф будет DAG-ом, с помеченными дугами, из каждой вершины выходит от 0 до 2 дуг. n вершин будут соответствовать неизвестным x 1 , ..., x n . Рядом с ними можно подписать их векторы частных производных, каждый содержит все нули, кроме одной единицы. Ещё у нас будет K вершин, соответствующие командам, вернее, производным переменных, стоящих в левых частях команд. Для команд вида A = B + C производная равна A' = B' + C' поэтому из вершины, соответствующей A', рисуем дуги в вершины B' и C' с метками = 1. Для команд вида A = B * C производная равна A' = B' * C + B * C' из вершины A' рисуем дугу в B', помеченную C, и дугу в C', помеченную B. Структура графа известна до выполнения алгоритма, а метки на дугах станут известны в ходе вычислений. Если мы найдём метки на дугах и будем вычислять для каждой вершины соответствующий вектор из n частных производных, то сложность получится O(N*(N+K)). Но, если немного подумать, то можно заметить, что производную по x i можно найти так: если мы рассмотрим все пути, ведущие из корня в вершину x i , и для каждого перемножим метки на нём, и просуммируем всё, то получится искомая величина. И мы можем найти для каждой вершины такую сумму по всем путям из корня в данную вершину в сумме за O(N+K). Понятно, что граф в явном виде в программе строить не обязательно. Он нужен просто для упрощения понимая сути алгоритма. А не могли бы вы, если вас, конечно, не затруднит, написать небольшой простой пример к приведенной выше теории. Просто у меня были некоторые практические наработки, хотелось бы узнать есть ли что схожее с приведенной идеей, а разобраться полностью с теорией, которую вы написали, еще не сумел. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.07.2009, 04:44:38 |
|
||
|
Помогите с задачей
|
|||
|---|---|---|---|
|
#18+
студентик А не могли бы вы, если вас, конечно, не затруднит, написать небольшой простой пример к приведенной выше теории. Просто у меня были некоторые практические наработки, хотелось бы узнать есть ли что схожее с приведенной идеей, а разобраться полностью с теорией, которую вы написали, еще не сумел. Пусть у нас есть такая функция, считающая полином от трёх переменных: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Построим граф. Вершины обозначим x1p, x2p, x3p, ap, bp, cp, dp, ep. Дуги: ap -> x1p (вес = x2) ap -> x2p (вес = x1) bp -> x2p (вес = 1) bp -> x3p (вес = 1) cp -> ap (вес = b) cp -> bp (вес = a) dp -> bp (вес = 2) ep -> cp (вес = 1) ep -> dp (вес = 1) Функция, считающая производные: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. Можете вручную посчитать производные и сравнить найденные значения для различных x1, x2, x3. Для каждой команды из первоначальной функции добавляется новая переменная и не более двух команд +=. Следовательно, объём нового кода линейно зависит от объёма старого. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.07.2009, 05:55:15 |
|
||
|
Помогите с задачей
|
|||
|---|---|---|---|
|
#18+
rmull, Большое спасибо, теперь стало намного понятнее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.07.2009, 17:52:45 |
|
||
|
Помогите с задачей
|
|||
|---|---|---|---|
|
#18+
rmullстудентик А не могли бы вы, если вас, конечно, не затруднит, написать небольшой простой пример к приведенной выше теории. Просто у меня были некоторые практические наработки, хотелось бы узнать есть ли что схожее с приведенной идеей, а разобраться полностью с теорией, которую вы написали, еще не сумел. Пусть у нас есть такая функция, считающая полином от трёх переменных: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Построим граф. Вершины обозначим x1p, x2p, x3p, ap, bp, cp, dp, ep. Дуги: ap -> x1p (вес = x2) ap -> x2p (вес = x1) bp -> x2p (вес = 1) bp -> x3p (вес = 1) cp -> ap (вес = b) cp -> bp (вес = a) dp -> bp (вес = 2) ep -> cp (вес = 1) ep -> dp (вес = 1) Функция, считающая производные: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. Можете вручную посчитать производные и сравнить найденные значения для различных x1, x2, x3. Для каждой команды из первоначальной функции добавляется новая переменная и не более двух команд +=. Следовательно, объём нового кода линейно зависит от объёма старого. Что-то подобное приходило в голову, только смущало количество переменных на команду, хотя по идее некие промежуточные результаты в ходе вычислений можно и не сохранять в отдельной переменной, если в ходе вычислений они не используются. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.07.2009, 23:38:57 |
|
||
|
|

start [/forum/topic.php?fid=16&msg=36085362&tid=1344372]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
43ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
63ms |
get tp. blocked users: |
2ms |
| others: | 223ms |
| total: | 376ms |

| 0 / 0 |
