...меньшая суммарная степень самого старшего монома позволит чаще делать редукцию других многочленов, (предположительно) уменьшая общее число операций...
Не, так себе подход. Контрпример. Если редуцировать начинать с помощью полиномов
p младшей степени, то полином
q, который, возможно, редуцировался бы полиномом самой старшей степени
P (из имеющихся в списке) уже может оказаться не редуцируемым с его помощью. Тогда (в предположении, что остаток от
q после редукции не нулевой) информацию, заключённую в паре полиномов
q и
P, можно будет извлечь только построив их зацепление, что более трудоёмко, чем просто редукция оригинального
q с помощью
P (особенно учитывая, что редукция, как правило, значительно увеличивает в полиноме количество мономов с младшими переменными).
С другой стороны, если начать с младших полиномов
p, то полином
q может оказаться редуцируемым в ноль, но не после того, как он был сначала редуцируем с помощью полинома
P. Вот если бы для полиномов списка можно было доказать, что последняя ситуация невозможна, то всё бы однозначно встало на свои места, и редуцировать надо было бы начинать с полиномов старшей степени.
Пока мне видится такая
реализация алгоритма Бухбергера:
- Инициализация. Завести упорядоченный список полиномов и простую очередь. Список оставить пустым, очередь заполнить исходными полиномами.
- Главный цикл. Повторять, пока очередь не пуста.
- Достать полином из очереди.
- Редуцировать его с помощью всех полиномов из списка начиная со старшего (цикл по списку).
- Если результат нулевой, перейти к следующей итерации.
- Если результат константа, то закончить работу алгоритма, выдав в качестве базиса Грёбнера один-единственный полином-константу "1".
- Остаток редуцирования — нетривиальный полином R. Проверить редуцируемость полиномов списка с его помощью (цикл по списку). Редуцируемые в ноль полиномы списка удалить, а нетривиально редуцируемые — удалить и добавить остаток в очередь (потому что эти остатки могут редуцировать другие полиномы списка или сами редуцироваться с их помощью — это всё будет проверено на следующих итерациях).
- Построить все зацепления полинома R с полиномами списка и добавить результаты в очередь (цикл по списку).
- Добавить полином R в список в соответствии с порядком.
- Выдать в качестве минимального базиса Грёбнера список полиномов.
В качестве списка полиномов лучше всего использовать упорядоченное множество. Оно гарантирует логарифмическое (от размера множества) время добавления очередного элемента (в отличие от линейного для связного списка или массива), а так же гарантирует порядок при итерировании по нему.
(РАЗМЫШЛЕНИЯ О ТРУДОЁМКОСТИ)
По идее, порядок и содержимое пунктов 5 и 6 должно гарантировать, что число операций зацепления, выполняемых в процессе алгоритма минимально. Нет смысла стоить зацепление, когда один полином редуцирует другой. Вернее, в результате такого зацепления получится результат редукции. Но при этом пункт 5 гарантирует, что добавляемый в список в пункте 7 полином R не редуцирует никакой полином списка. Это гарантирует минимальность списка на любой итерации, что в свою очередь должно гарантировать минимальность зацеплений. "Должно" — потому что число итераций может оказаться при таком подходе гораздо больше. То есть я уменьшаю один из множителей произведения (в формуле трудоёмкости, делаю это, потому что гарантированно могу), но это может происходить за счёт несоразмерного увеличения второго множителя, что, вопреки желанию, может привести к росту этого самого произведения.
Алгоритм корректен, потому что он:
- Не теряет информацию. Полиномы отбрасываются, только когда они редуцируемы в ноль, то есть представимы в виде линейной комбинации полиномов некоторого подмножества всего множества полиномов (список плюс очередь).
- Все зацепления в списке редуцируемы (пункт 6 алгоритма обеспечивает это).
- Полиномы списка не редуцируют друг друга (пункт 5, минимальность списка).
Я же нигде ничего не напутал?