|
|
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Windows XP, Office XP Имеется: Код: plaintext 1. 2. 3. 4. 5. Требуется найти всех потомков какой-либо персоны (например 29) и записать их и номер поколения в таблицу потомки. Код: 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. 30. При большем количестве производительнось катострофически падает. Так за 30 мин определяется около 2500 потомков. Посоветуйте, как существенно повысить производительность? Все имеющееся на форумах прочел... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.05.2004, 21:23 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Хорошо бы постановку задачи озвучить целиком. Типа есть то-то и то-то, получить надо вот это... А то не понятно почему именно такие таблицы. Или это какая-то классическая компоновка о которой все знают? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.05.2004, 22:08 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 lobodava Эти таблицы - часть генеалогической базы данных, отображающие родственные отношения. В общепринятом формате (так называемом GedCom стандарте) существуют два вида отношений: а) персона - семья родителей (отец и мать); б) персона - супруг(а) - дети. Эти отношения, имхо, отражают предложенные таблицы. М.б. можно и по другому... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.05.2004, 22:48 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Вау!!! А где почитать о GedCom стандарте? Ссылки есть? А то ни как не пойму как цепочка выстраивается из тех таблиц, что предложены. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.05.2004, 23:10 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Вижу логическую ошибку. Переменная rst As Recordset описана на уровне модуля, однако при каждом обращении к процедуре FindDescendant этой переменной заново делается Set и какое-то количество раз MoveNext. При возврате из очередного обращения к FindDescendant эта переменная уже имеет совершенно не то значение, которое было ей дано перед входом туда. По-моему, это должно вообще приводить к неправильной работе программы, а не то что к замедлению. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 00:15 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 lobodava Ссылок на стандарт можно найти мгого, только на английском. Например: The GEDCOM Standard Release 5.5 The GEDCOM Standard Release 5.5 (pdf) Кратко суть такова: В текстовом файле последовательно размещаются: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 08:42 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 Владимиру Санычу авторПри возврате из очередного обращения к FindDescendant эта переменная уже имеет совершенно не то значение, которое было ей дано перед входом туда. Именно так! На этом и построен алгоритм: Код: plaintext 1. 2. 3. 4. В прилагаемом текстовом файле есть реальные таблицы. Можно было построить следующий алгоритм: Код: plaintext 1. 2. 3. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 09:09 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Но если написано Set rst = dbs.OpenRecordset... With rst Do While Not .EOF '***' .MoveNext то, наверно, .MoveNext и While Not .EOF должны относиться к тому же объекту, которому сделан Set. Однако в приведенной программе это не так, потому что в части '***' делается другой Set. Может, все-таки надо перенести Dim rst As Recordset внутрь процедуры? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:08 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
авторDim rst As Recordset внутрь процедуры? Саныч, утечку памяти это не предотвратит - что в лоб, что по лбу ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:19 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Почему не предотвратит? Просто будет несколько экземпляров рекордсета, но каждый будет закрываться когда ему положено. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:22 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
кто же его закроет, если ему это явно не сказано? А если сказано, то то и указатели в стеке плодить не обязательно - одного хватит, на уровне модуля. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:25 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Close надо добавить, это несомненно. Независимо ни от чего. Но одного не хватит, потому что они должны использоваться одновременно. Второй должен открываться прежде, чем закроется первый, и т.д. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:30 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Саныч прав должно выглядеть так (чтобы рекордсеты разных поколений, и счетчики поколений в рекурсии были автономными) Код: 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. 30. 31. 32. 33. 34. по мужу и жене наверное надо бы залудить индексы. Но на больших объемах все равно будут проблемы - как вы думаете, сколько стоит взять несколько десятков тысяч разных запросов (да, не дай бог, с предварительной оптимизацией)? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:30 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Кстати! Вот если поставить Close, то тут-то и станет очевидно, что программа работает неправильно. Потому что после первого выполненного Close сразу начнутся сообщения об ошибках. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:31 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
то есть если ты про то, что процедура рекурсивный характер имеет (блин - должна иметь) - это несомненно. Но при этом рекордсет не обязателен. достаточно dcount-ом проверить, есть ли дети и и одним update-запросом. проставить им уровень. ЗЫ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:35 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 Victosha: Полностью согласен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:37 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 Саныч Стандарт! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:42 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 Владимир Саныч, 2 Victosha Определенно вы друг-друга понимаете :) Я вас - нет :( Нельзя ли конкретизировать в виде кода? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:45 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
и самое главное. на размещение в памяти тысячи рекордсетов потребуется до шиша памяти. т.ч. может и имеет смысл обходиться одним рекордсетом, но по возвращении из рекурсии надо возобновлять _старый_ (т.е. _этого уровня_ наследственности) рекордсет, и вместо MoveNext ходить Find-ом на следующий. еще одно решение - сделать поле муж/жена общим (персона) (+ поле признака (тип) + уникальный индекс по 3-м полям (семья,персона,тип), открывать семью не запросом, а рекордсетом по указанному индексу и бегать seek-ом (по возвращении во внешний уровень переходить seek-ом на следующее значение индекса). (то же можно и при разных полях мух/жана, но пробегая процедуру по 2-м индексам (семья,муж), (семья,жена)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:48 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Код: 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. 30. 31. 32. Это без учета того, что сказали фыыф и Victosha. Потому что они абсолютно правы, но это потребует более серьезных изменений. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 11:53 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Да, действительно, надо выбросить (многократные, и затратные) открытия рекордсетов из рекурсии. Открывать один раз один набор семей снаружи, как dbOpenTable, и при входе/возвращении на уровень изменять только параметры Seek-а (много быстрее чем Find), для чего озаботиться необходимыми индексами и переменными уровня рекурсивной процедуры для их текущего хранения. Это (для mdb) будет наискорейшим выходом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 12:00 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 фыыв модификация - на ado открыь 2 client-side рекордсета, локально их индексировать, дальше и FindFirst (не вижу зачем) и Filter их будут успешно пользовать. Рекурсию придется линеаризировать циклами. ps кто ж такие "потомки" - что-то в "ТЗ" их не наблюдается ?.... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 12:11 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 Владимир Саныч Проверил работу твоего кода. Производительность не изменилась :( Кстати, объявление переменных в рекурсивных процедурах уменьшает память. Это не я сказал :) Рекомендуют объявлять их на уровне модуля. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 12:44 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 Victosha авторкто ж такие "потомки" - что-то в "ТЗ" их не наблюдается ?.... Не пойму, в чем вопрос? Родитель > ребенок > его ребенок > и т.д. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 12:47 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Я не говорил о производительности. Я говорил о правильности. Если несколько рекурсивно вызванных экземпляров процедуры пользуются одним и тем же экземпляром некой переменной, то возникает конфликт! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 12:49 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 фыыф автор... для чего озаботиться необходимыми индексами и переменными уровня рекурсивной процедуры для их текущего хранения. Нельзя ли по-подробнее. Я с этого начинал и пришел в тупик. Скорее всего по собственной ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 12:51 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 Владимир Саныч Очевидно так. Но конфликтов у меня не происходило. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 12:53 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 Victosha автормодификация - на ado открыь 2 client-side рекордсета, локально их индексировать, дальше и FindFirst (не вижу зачем) и Filter их будут успешно пользовать. Рекурсию придется линеаризировать циклами. С ado не работал. Если не в лом, напиши реализацию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 12:59 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Попробуй что-то в этом роде: Код: 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. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. По поводу "конфликта" саныч неправильно выразился. Там не будет конфликта программного (если не закрывать рекордсеты на уровнях явным образом). Там при возврате из вложенной процедуры будешь иметь совсем не тот рекордсет, который был задан на ЭТОМ уровне рекурсии (он переопределится на другом). Т.е. "конфликт" логический. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 13:20 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
фыыфПо поводу "конфликта" саныч неправильно выразился... Т.е. "конфликт" логический. А я и не говорил, что будет какой-то иной конфликт, кроме логического... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 13:26 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Вот тебе и на!!! Ушёл решать задачку когда шесть постов было, а пришёл - топик на двух страницах уже. Круто!!! Предлагаю свой вариант без использования рекурсии. Прикреплённый файл для Access 2000 Данные из этого поста Самый плодовитый предок под номером 65 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 13:46 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 lobodava На работе экран стоит :( Скачать нельзя. Посмотрю только дома, спасибо! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 14:24 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Копирую решение lobodava сюда: Код: 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. 30. 31. 32. 33. 34. 35. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 14:25 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Владимир Саныч, весьма признателен! 2 lobodava: авторСамый плодовитый предок под номером 65 61 д.б. таким же - они супруги! :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 14:39 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Таблицы: tblFam: Fam, Papa, Mama tblKids: Kid, Fam, ID tblDescendants: Kid, Generation В последнюю таблицу записываются все потомки PersonID и их поколение ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 14:39 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
автор61 д.б. таким же - они супруги! :) Понятное дело ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 14:46 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
lobodava, увы... Время работы на больших таблицах осталось прежним. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 15:42 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
авторд.б. таким же - они супруги ответ неверный. есть случаи нескольких семей у персоны. гаремы, опять же. и бастарды. :о) и все равно прогонка по индексированному рекордсету (курсору - на сервере) должна работать (в данном случае) быстрее нескольких запросов. А именно - за счет "подготовки" запросов. Да, и в случае разделенных данных/кода вместо set dbs=currentDb, открывай DB данных. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 15:48 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
авторВремя работы на больших таблицах осталось прежним не мудрено, если таблицы не индексированы по полям, по которым идет поиск (тут, у лободавы, не помешают индексы (Fam,Papa) и (Fam,Mama), причем как будут себя вести индексы при OR в ON в JOIN-е фих его знает. Возможно лучше (для больших таблиц) разбить запросы на 2 запроса - отельно по папам и отдельно по мамам). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 16:00 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 фыыф авторответ неверный Все так. Но в конкретном случае других браков не было :) А по сути предложенного решения - разбираюсь с индексами. Можно по-четче (для меня): у каких полей какие индексы? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 16:02 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
для процедуры прогонки по рекордсету индексы (их имена) приведены в коде, состав полей - под ним. для запросов со связями (или со сложным WHERE) индексы должны быть по возможности отсеивающими большую часть таблиц по условию. Для связи по нескольким полям - индексы должны быть составными по всем полям связи (если такая связь не определена как связь с поддержанием целостности на уровне схемы данных - т.к. в последнем случае Аксесом автоматически создаются служебные индексы (вторичные ключи), не отображаемые во вкладке "индексы" таблицы). Причем они должны быть одинаково структурированными для обеих связываемых таблиц.. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 16:11 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
почетче в tblFam у полей Fam,Papa,Mama поставь в конструкторе таблиц свойство "индексирован=Да(допускаются совпадения)" в tblKids сделай то же для поля Fam в tblDescendants для поля Kid и сделайте составной индекс (Generation,Kid) PS тип: преобразовав в простой селект, сохраните запрос как стандартный запрос акцесс и натравите на него Сервис->Анализ->Быстродействие ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.05.2004, 16:15 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 фыыф Разобрался с индексами в вашем коде. Проверил - начинает работать шустро, но... После найденных одной-двух тысяч потомков работа практически останавливаетя. Что-то переполняется (память, кэш ???). Есть ли какие соображения? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 09:28 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
а ты не пробовал перед открытием рекордсета определить что ты будешь сним делать Код: plaintext 1. 2. 3. 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 12:23 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 Zenia Проверил. Результат тот же :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 13:06 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
соображения такие: рекурсия приводит к сохранению на каждом уровне переменных уровня рекурсии Dim i As Long, nS As Long, nR As Long, iSx As Long Dim sIn(0 To 1) As String не думаю, что пара тысяч этих переменных убьет процесс. Но вот каждая процедура должна при рекурсии еще и помнить, куда она должна вернуть результат/управление. Что там происходит - а бог его знает. Посему, если грешить на рекурсию и переполнения, а не на банальный баг, который где-то недочищен (и зацикливает процедуру при редком сочетании данных), имеет смысл избавиться от рекурсии. Идея - в решении lobodava (в циклическом переборе по поколениям). Но, видимо, имеет смысл не выполнять запросы, а в предложенном мной цикле выбросить рекурсивный вызов процедурой самой-себя, добавить параметры вызова (вернее - переменные уровня модуля), необходимые для нового вызова процедуры для следующего поколения из внешней процедуры-цикла (видимо - 2 массива: 1. массив потомков данного уровня, 2. массив потомков следующего, и, возможно, номер уровня) а во внешней процедуре вызывать процедуру в двойном цикле - до возврата пустого массива потомков следующего уровня, а во внутреннем цикле (двойного, внешней процедуры) - и осуществлять вызов - по массиву потомков текущего уровня (заполняя одновременно массив следующего). Почему массивы? Потому что иначе придется повторять операции чтения (вытягивать данные запросами, пусть и по индексированным таблицам), что дольше. предполагаемый выигрыш: - освобождение от рекурсий и вместо смены индекса и поиска практически всякий раз Seek-ом, можно после первого Seek делать просто MoveNext (индекс то задан, и не меняется ни он, ни положение текущей записи в рекурсивных вызовах), до выхода по сравнению ключа. Что быстрее. затраты: - 2 массива Long, переменной длинны, объявленные на уровне модуля, приватные; но на потомков только одного уровня (если будем вычислять потомков Адама или Евы, боюсь, памяти простой персоналки не хватит, но и запросы на таких объемах - не фонтан, результаты же их все равно надо куда-то складывать, если только не пытаться открыть рекордсет с последовательным доступом и т.п...). + Минимальная переделка процедуры FindDescendantT (выброска ре-Seek-ов и ре-Index; замена самовызова на блок пополнения массива потомков следующего уровня); и написание процедуры ее вызова как FindDescendantT(Pc(i), iGeneration) в цикле. (первый вызов - как и было). Вот только не найдем ли мы в итоге логический "баг", наподобие ошибки в данных - нахождение кольца по предкам/потомкам? Или еще чего. ___ ЗЫ : ДА, есть теоретический вопрос. Если пипл является потомком другого более чем одного уровня (по паре веток разной длинны), то и его потомки будут дважды считаться в таблице потомков :). Что об этом случае думает генеология? (хорошо, что чел не может быть собственным предком, но база, кстати, об этом не знает - если нет триггеров/правил, отслеживающих кольца). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 13:10 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
1) попробуй поставить DBEngine.Idle перед Next iSx 2) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 13:11 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Результат работы кода фыыф'а (самого быстрого): Время Кол-во записей 1 сек. 4500 5 сек. 5500 10 сек. 6000 15 сек. 6100 и далее в той же прогрессии. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 13:21 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
и все таки мыслится, что если процедура именно "останавливается", то надо посмотреть на вероятные баги в режиме отладки (уж очень мало). Очень может быть, что чегой-то я недоглядел. Но есть и идейка о том, что задалбливают перечтения индексов, количество которых (перечтений) растет быстрее, чем число потомков (по возвращению из рекурсий со сменой пола - новое перечтение). Одна надежда, что индексы в кеш влезают. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 13:22 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
еще раз: попробуй поставить DBEngine.Idle ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 13:25 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 Victosha Увы :( А что под № 2) ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 13:25 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 13:26 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2) - минорный улучшайзинг- закешируй обращения к полям и используй .Collect ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 13:26 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 фыыф Вы очень хорошо обо мне думаете :) Мне только, чтобы разобраться в смысле написанного потребуется день! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 13:28 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 Victosha Что это Collect? В справке не нашел. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 13:31 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
давай еще раз попробуем 1) DBENgine.Idle dbRefreshCache 2 ) перед AddNew поставь DBENgine.BeginTrans после Update поставь DBEngine.CommitTrans ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 13:33 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
о! идея (находюся) откройте 2 рекордсета rstS(0 to 1) и сразу при открытии один раз (не в рекурсивной части) Код: plaintext 1. 2. 3. Код: plaintext 1. 2. 3. 4. 5. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 13:34 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 Zenia Есть семьи без детей. В какой-то версии возникала ошибка. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 13:35 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
пардон Collect - соврал - он - .CollectionIndex - недокументированный и самый быстрый способ обращения к значению поля для DAO.Recordset ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 13:39 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 Victosha Проверил. Без улучшения. Код: 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. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 13:44 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
т.е. (с учетом "хорошо думаю") попробуйте вот так: (и приведите результаты, если не сложно) Код: 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. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 13:45 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
блин, просмотрел! - выкиньте еще: Dim sIn(0 To 1) As String sIn(0) = "Мid": sIn(1) = "Жid" из рекурсивной части ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 13:47 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 фыыф авторо! идея (находюся) Я не успеваю за вами. Нельзя ли идею в полном виде? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 13:49 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
именно к этому "идея" см. полный код 13:45 + примечание 13:47 главное - есть ли профит (от неперечтения индексов, но с платой - лишним рекордсетом) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 13:52 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 фыыф Профита нет. Совсем :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 13:59 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
ну вот еще один заход шаманский - не уверен, что поможет, но результат услышать бы хотелось. попробуй после DBEngine.Idle поставить DoEvents ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 14:00 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
именно те же количества? за те же времена? а вызывали вы именно FindDescendantM (с помощью startM), ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 14:00 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
что-то я сегодня совсем зарапартовался- видно спать пора - CollectionIndex - он, конечно, не значение возвращает, а номер поля в наборе данных пошел спать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 14:18 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 фыыф Запускал из нового модуля, так что без ошибок (своих :0) )... Результаты теже. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 14:19 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 Victosha авторпопробуй после DBEngine.Idle поставить DoEvents По прежнему... авторпошел спать Спокойного сна! Возвращайся! :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 14:28 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
ну, попробу так (без рекурсий) что-то сомневаюсь я, но все таки должен быть другой тип зависимости времени от числа возвращенных записей: Код: 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. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. обрати внимание на вызовы (имена :). И приведи таки вид зависимости от времени. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 14:45 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
проснулся СТОП - а потомки там часом не индексированы ли ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 14:54 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 Victosha мдя, я тут не фигней ли занимаюсь в поэлементном присвоении массива? Нельзя ли его как-то с помощью передачи указателя(ей) передвинуть? ЗЫ (была как-то задачка, для которой тип. содержащий коллекции и массивы (не помню, но кажется массивы с членами - коллекциями) неплохо б было клонировать. Так там тоже было бы невредно исхитрятся без поэлементного присвоении, только там область памяти как-то надо было еще "сдвигать" (а стало быть и все указатели на объектные поля типа) - после клонирования действия над объектами (коллекциями и их членами) были разные). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 15:36 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 фыыф 1) собственно массива "на присвоение" я тут не проглядываю, 2) в переводе с русского на русский - сие есть глубокий хакинг, применительно к тому месту о котором ты говоришь - надо в DAO SDK углубляться - я этого не делал. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 15:41 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 Victosha это я спрашал исключительно про кусок нерекурсивного варианта (последнего из предложенных), касательно сдвига следующего поколения в текущий: Код: plaintext 1. 2. 3. 4. _______________ ЗЫ. а задачка со сдвигом/клонированием объектов возникла при идее использовать "человеческие" описания "генов" в генетическом алгоритме (типы со значащими полями, а не строки бит) для конкретной задачки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 15:53 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
да в случае Erase pC ReDim pC(0 To UBound(pN)) For iC = 0 To UBound(pN) pC(iC) = pN(iC) Next iC можно воспользоваться API функцией rtlMoveMemory (часто используемое подстановочное имя - CopyMemory) () Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _ lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long) тогда, навскидку, строка будет выглядеть примерно так CopyMemory pC(0), pN(0), x*(UBound(pN)+1) где x - количество байт в элементе массива - для инт - 2 для лонга 4 будет работать для любого линейного массива, в том числе для массива строк фиксированной длины. видимость эффекта на самом деле сильно сависит от длины массива. Дело в том, что вызов API- функций - относительно дорогая операция и для маленьких массивов эффективность копирования сожрется накладными расходами по вызову Расходы можно чуть уменьшить , загрузив (в данном случае kernel32) в адресное пространство акцесса - я, правда, так не делаю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 16:05 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 фыыф 1 сек. 5000 5 сек. 5890 далее кол-во не изменяется, цикл продолжается. Причина не ясна. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 16:07 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Не выходит из цикла Function FindDescendantA Переданное ей id имеет значение, не содержащееся в таблицах. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 16:18 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
автордалее кол-во не изменяется, цикл продолжается. Причина не ясна. По моему, у тебя где-то проходит на бесконечный цикл без присвоения. (или ты все таки вызываешь ту же функцию, что и раньше, а не текущий вариант). 1.Запаузь Ctrl+Break (при работе, в момент "причина не ясна") (посмотри, заодно, какая ф-я крутится) 2.Включи в настройках режим прерывания "при любой ошибке" (не сбрасывая процедуру). 3.продолжи - ( Например объектная переменная в отсутствии, или за границу массивов вылетаем - кривой код и т.п.) если ошибок нет (прерывающих прогу), то ошибка в логике циклов, или данных, тогда опять: 4. запаузь, 5.поставь точки останова на While-ах и Do 6.и посмотри, как крутится, почему не попадает на присвоение и не выходит наружу. (то ли поколения не сдвигаются, то ли еще какая мототень, и нет ли одноименных Public переменных.). Заодно приведи размеры массивов поколений ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 16:23 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
за выход отвечает Do While .Fields(iSx + 1) = id если поля в таблице переместились(их индексы не 1 и 2), то вместо (iSx + 1) надо в явном виде задавть имена полей ("муж", "жена"). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 16:29 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
и шибко похоже, что у тебя нет объектной переменной, или ты за границами массивов. В конечной реализации обработку ошибок надо сделать правильно. (В зависимости от того, нужны ли частичные результаты, не нужны никакие, нужно ли сообщение и т.п. а не On Error Resume Next, которая в таких случаях приводит к бесконечному циклу). зы: надеюсь ремарки ' со старого кода ты не снимал. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 16:39 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 фыыф Уже ничего не соображаю :( Нужно начать сначала и упростить задачу. Определять только потомков, без поколений. М.б. писать их в массив, а не в таблицу (это быстрее или нет?). Если это возможно, не мог бы я передать вам таблицы? Не примите за нахальство - делаю не для денег, просто есть заинтересованный круг людей, занимающихся генеалогией. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 16:40 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
авторЕсли это возможно, не мог бы я передать вам таблицы? хорошая идея ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 16:47 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
16:23 - краткий курс отладчика. Довольно полный, для вашего случая. Попробуйте добить до конца. цикл, даже если в него попала байда, должен выплюнуть. Если он крутиться - вероятно за счет отсутствия объектной переменной, к которым отсылаются сравнения While (и конструкции On error resume Next, приписанной сюда от балды, закомментируйте ее на крайняк перед следующим запуском). Есть вероятность моего логического бага (кроме пресловутой ошибки), но я его не вижу. а файл, мне мниться, размером под гигабайт. Я его не съем :). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 16:57 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 Victosha 16:05 Спасибо. "Будем посмотреть". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 17:06 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 фыыф автора файл, мне мниться, размером под гигабайт. Я его не съем :). 600 кб две таблицы в сжатом текстовом файле. Как скажете... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 17:51 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Нашел махоньки баг: добавь: Код: plaintext 1. 2. 3. 4. Код: plaintext 1. 2. (после Erase, UBound не рюхает. Не сразу понял. Старый стал. Глюпий. Мои извинения) _________ 2 Victosha. Работает, кажется Ваш рецептик: Erase pC ReDim pC(0 To UBoundE(pN)) CopyMemory pC(0), pN(0), 4 * (UBoundE(pN) + 1) но на моем объеме (в этой задаче) времена гуляют в обоих случаях на 2 порядка (очень мало данных, соответсвенно маленькие массивы), пришлось гонять в цикле всю процедуру по 100 раз. Времена совпадают в пределах ошибки. (т.е. полное время процедуры мало зависит от копирования (маленьких) массивов, и сл-но, метода. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 18:06 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Код: plaintext Боюсь, почта от вас не дойдет. - На общедоступные почтовики я не ходок. И почта с общедоступных не проходит. Если только выложите где -нть на доступном месте (по http). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 18:11 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 фыыф 5890 ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 18:19 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 фыыф А zip с сайта заберете? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 18:23 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
если сайт не закрыт моей проксей, заберу. Давайте адрес. а что такое 5890 ... ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 18:28 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Две упакованные таблицы. Берите. 5890 записей - получился тот же результат, что и до последнего исправления. На нем зацикливается. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 18:46 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 фыыв я, конечно, взрослый мальчик, но ко мне на ты легко. ЗЫ с с копимемори главная проблема "попасть в вызов" где ему byVal отдать, а где ByRef. Моя мозговая кость не так остра, чтобы положиться без проверки. Вот и поосторожничал в выражениях. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 18:51 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
а какой id предка вызывает такие длинные деревья? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 19:00 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 All Для затравки :) Есть программа, по моему на Дельфи, которая находит в этих файлах более 30000 потомков и записывает их в листбокс за 40 сек. Ну не совсем в этих, а преобразованных ей самой из gedcom файла. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 19:03 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
автора какой id предка вызывает такие длинные деревья? 29 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 19:08 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
У №29, судя по той программе должно быть 33047 потомков ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 19:12 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
есть баги. во всех версиях строки: If .NoMatch Then Exit Do замени на: If .NoMatch Or .EOF Then Exit Do но есть еще какая-то лажа-с. на 7-м id рекурсивный алгоритм (2-й) накидал мне уже 12078, и не собирается останавливаться. Судя по всему, у вас там петля-с. типа внучек оказался предком бабушки. (пока просто смотрю на умножение задублированных потомков в разных поколениях при увеличении времени счета. (неужто баг такой:) так же ведет себя и нерекурсивный. буду смотреть завтра :). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 19:28 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
ссори, накидал болше 120000, куда то цифирь делась ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 19:29 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Записал с каждым найденным потомком текущее время. Группировка по времени, число записей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2004, 22:30 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
По таблицам: 148 и 149 (четвертое поколение от 29) - брат и сестра!!! Инцест налицо. Не исключено что таких пар больше чем одна. По моему алгоритму их потомки считаются дважды. а 93907 - это вообще гермафродит - то он жена, то муж. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.05.2004, 02:12 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 lobodava В этой жизни и не такое возможно :) Между прочим, это родичи Рюрика... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.05.2004, 07:05 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
вероятно, проблема во внутрисемейных браках между поколениями. За счет этого число вхождений потомка в таблицу быстро растет. (чтобы отсеять подозрения на петли, запускаем ваш первый рекурсивный алгоритм (с моими правками, ес-сно). Там, если бы мы наткнулись на петлю, то рекурсия бы из этой ветки никогда не вышла, и число вхождений некоего потомка в таблицу росло бы бесконечно (если петля короткая, то это было бы и легко заметно). Пока я не вижу быстрого роста числа входений одной и той же выделенной группы лиц (может быть группа и есть, но "слабо изолирована" - т.е. имеет множество "непетлевых" потомков, число входений которых в группу растет. Но, мне кажется, это пока не подверждается) запускаем (у меня таблица "потомки" не индексирована !!! - т.е. возможно многократное повторение вставки потомка на уровень): Start(7) при числе потомков 155090 (не дожидаясь окончания счета) прерываемся и видим: Код: plaintext 1. 2. 3. 4. 5. 6. это запрос вида: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. и Код: plaintext 1. 2. 3. 4. 5. 6. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. О графике: Именно потому, что количество потомков на уровень быстро растет, видимо будут расти и размеры массивов текущего/следующего уровня при нерекурсивной процедуре. А это потребует изрядного времени на их копирование (из одного в другой). При наличии уникальных индексов в таблице потомков, будет расти время работы вхолостую (попытки вставить имеющейся пары (потомок,уровень) Если надо найти только потомков (т.е. хотя бы одно вхождение), то скорость счета можно увеличить, отбрасывая повторные вхождения потомка в набор (в другом поколении). ___ Как ускорить текущую задачу: 1. Так же надо добавить процедуру(ы) "индексирования" массивов (быстрое упорядочивание массива поколения с удалением дубликатов, или даже вставки в уже упорядоченный набор (без вставки дублей). Тогда разрастания массива за счет множественности вхождений не потребуется. 2. Возлагать отбрасывание повторных вхождений потомков на уровень на Jet - за счет уникального индекса (потомок, уровень) - для нерекурсиной процедуры вряд ли имеет смысл (если только не заменять процедуру заполнение массива текущего уровня чтением из таблицы). И я не уверен, что проверка уникальности на большой таблице (т.е. с чтением индекса) будет быстрее (таких же) методов быстрого поиска, но внутри исключительно (!уже) размещенного в памяти массива. Однако подкупает простота реализации. Попробуйте. (Не надо передирать методов быстрого поиска/сортировки/вставки_в_сортированный_список из каких - нить букварей - все реализовано в движке jet). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.05.2004, 11:38 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
итак, не входя в сортировку массивов, добавляем потомкам уникальные индексы (iGen,Childe) и наоборот + правим рекурсивные процедуры (по крайней мере "моя" StartT(7) - прогонка по рекордсету начинает завершаться в разумное время -222718 потомков(с вероятностью нескольки вхождений на РАзные уровни), из них 36874 уникальных. (а сл-но, петель таки нет). Код: 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. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. Код: plaintext 1. 2. 3. 4. 5. 6. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.05.2004, 12:09 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
и напоследок времена (все модифицировано аналогично) запускаем подряд: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. удач. С праздничком. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.05.2004, 12:40 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 фыыф/assa Супер! Для Рюрика (40436) ищет 33886 потомков за 5 сек! авторНо, поскольку задачка сродни любой иерархической (справочники/каталоги и т.п.), то попозже посмотрю - имеет не токмо факультативный интерес. Не забудьте и про поиск предков :) Спасибо и с наступающим праздником! З.Ы. Для №29 находит 33046 потомков,а по упомянутой выше программе 33047. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.05.2004, 12:55 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Постскриптум предыдущего сообщения ошибочен! Там к потомкам добавляется и сама персона. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.05.2004, 04:25 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Еще одна заморочка :( В таблице нужно поле parent. Добавляем в код Код: plaintext Код: plaintext 1. 2. Нужно заменить поле parent в соответствии с новой нумерацией. Делаю так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Может есть лучшее решение? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.05.2004, 11:15 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Что-то я зарапортовался в последнем посте. Правильная последовательность в детях (которая определена в таблице "дети" по счетчику) нарушается при создании таблицы "потомки", т.к. сортировка производится по индексу "СемьяРебенок". Это касается и последовательности семей. Нужно в таблицу "семьи" добавить счетчик и сортировку проводить с его участием. В случае, когда более одного брака, нужна привязка ребенка к номеру брака. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.05.2004, 07:06 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Вообщем, последовательность записей для 40436 д.б. такой: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.05.2004, 09:25 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
Гы. А я сразу понял, что вам никакая рекурсия на..фих не нужна. Вам нужен эффективный механизм построения выборок из почти статических данных в аксесс (т.е. в системе, не поддерживающей запросы иерархического вида /вроде в оракле что-то есть)). Тогда вам, видимо, надо построить "индексную таблицу". Такую, из которой все последующие вещи считаются простыми запросами (наборы полей связи для всех мыслимых запросов проиндексировать). Поскольку первичные данные меняются редко, то и перестройка вспомогательной таблицы должна проводиться не каждый раз, а только при изменении, причем перестройка не всей таблицы, а только конкретного участка. __________ Нумеровать "логический" порядок счетчиками – гнилое дело. Да и для семей в счетчике может крыться проблема. Добавьте поля "физическая очередность брака" для каждой из персон (тут в общем счетчике возможна масса логических казусов, особо для активных единовременных многоженцев, повторных браков со старым партнером и т.п., боюсь, возможен и некоторый "релятивизм", когда один порядок потребуется для одного партнера, другой – для другого. А поле-то общее. Некой экономии, кажется, можно добиться объявив поля меньшей длинны – например - как байтовые, но идущие физически друг за другом). ____ PS Если вы хотите модифицировать способ хранения данных – 3 минуты - не проблема. (Продумайте один раз способ хранения и время от времени (по изменении данных) перестраивайте вспомогательные структуры. Если же нужна именно выборка – не делайте UPDATE (дисковая операция), просто верните NewNumber(parent) (и т.п. – если нужно выводить несколько значений, - при первом обращении к функции заполните _коллекцию_, с индексом (key) элементов cStr( id) (id – старый id предка), простым MoveNext (а не Find!!! – что много быстрее, тогда и набор можете открыть только для прямого прохода) при повторных вызовах дергайте члены из коллекции по id , представляется, для коллекции васиком должно строиться что-то типа индекса в памяти по key – что много ускоряет поиск, если я ошибаюсь (в догадках) - получите тот же результат, что и Find-ом (еще и память похерите зря)). А rst, по любому, открывайте как статический набор. ___ ЗЫ ( к "нерекурсивной процедуре): (кстати, переприсваивать массивы потомков из "следующих" в "текущие" не обязательно. Надо разветвить процедуру для четных/нечетных поколений. (можно и простым копи/пастом). Одно из "изячных" решений – объявить тип "поколение" содержащий массив поколения, и объявить массив p(0 To 1) из двух поколений – на уровне модуля pC==p(iG mod 2); pN==p((iG+1) mod 2)), а "ветвить" не код а просто за счет подстановки нужных индексов при четном/нечетном поколении менять поколение – источник и поколение – адресат.. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.05.2004, 13:00 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2фыыф авторТогда вам, видимо, надо построить "индексную таблицу". Такую, из которой все последующие вещи считаются простыми запросами (наборы полей связи для всех мыслимых запросов проиндексировать). Можно какой-нибудь пример? И еще вопрос: что означает "0" в выражении Код: plaintext ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.05.2004, 13:20 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
вот ваша табличка потомков и есть вспомогательная, если добавить id семьи, есс-но (и не надо ее перестраивать по запросу, а только по изменению данных удалять не все, а только "ветку" от этой семьи удалить/вставить). чтобы таблица была удобна для шустрых выборок, нужны соответствующие индексы (id,ребенок) - он и так видимо ключ (или могабыть (id,уровень,ребенок) - если учитываете все сепени родства по всем линиям - тут надо подумать над оптимальным порядком полей (уровень,ребенок) - чтобы не строить лишних индексов) - будут пользоваться в запросах на потомков id; (ребенок,уровень,id) - // - в запросах на предков ребенка, (ну, посмотрите, как у вас строятся запросы, так и индексы составные подберите). И будет это все зело огромным, но за счет индексов выборки будут строиться быстро. Причем чем индексов больше, тем цена вставки и редактирования выше. Но если данные почти не меняются (таблица не переписывается целиком), то основной минус - объем базы. И время восстановления/сжатия (при сжатии аксесс, кажется, перестраивает индексы целиком). :) Да, наткнулся я тут, образовываясь, на тип индексов "битовые карты" - там составные индексы не нужны. ибо эти карты, кажется аддитивны (как средства поиска) поиск по составному индексу - просто на лету производимая комбинация поиска по простым. (не копал, надо посмотреть). Но, к сожалению, в аксессе их нет. ______ 0- просто второе поле поиска индекса пишите при первом вызове .Seek ">=", id - в данном случае это не важно (ребенок>=0, not null) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.05.2004, 14:13 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 фыыф После долгих раздумин, определил структуру таблицы "потомки" для правильной ее сортировки: Код: plaintext 1. 2. 3. 4. Для получения orderPehson в функцию нужно включить третий аргумент, определяемый из поля "счетчик" таблицы "дети" для предка в семье его родителей. С первым вызовом все понятно, а дальше ничего не смог придумать :( Код: 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. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.05.2004, 09:04 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
1. для ПРАВИЛЬНОГО получения номера поколения по КРАТЧАЙШЕЙ ЛИНИИ надо таки отказаться от иерархического вызова (пишет первое найденное вхождение потомка, по первой попавшейся линии). Или дополнить (в случае Err в .Add проверкой записанного и текущего (в рекурсивной процедуре) поколения, а при необходимости и .Edit (номер поколения, и генетические веса, если потребуется). 2. НАстоятельно рекомендую не завязываться на id предка но на id семьи (вдвое снизит объем таблицы, запросы будут более прозрачными логически). Но если вы склоняетесь не к постоянно заполненной (редко обновляемой) таблице, то возможно имеет смысл делать как сочтете нужным. 3. не совсем понимаю, что такое "номер персоны в семье" и на кой он нужен (внутри поколения нумерация вообще произвольна). Но такого рода нумерация легко производится в нерекурсивной (последовательный перебор по поколениям) процедуре. ______ для "постоянно заполненной таблицы транзиктивных связей" примерно следующая структура: id персона pid семья предков (соотв уровня) generation поколение (уровень наследования) weght вес (семьи предков) в генетическом наследстве, Double /* (степень родства суммарно по всем линиям) */ при этом семья: id муж жена nмуж № брака, байт nжена № брака, байт дети - как есть Семья Ребенок /* счетчик в вашей структуре лишний == Ребенок*/ + желательо поле очередности ребенка в семье. но я б ввел вместо него дату рождения - дата/время, правда не всегда оно известно, а для близнецов пришлось бы манипулировать искуственно временем +- часы/минуты. Т.ч. возможно и очередность не худший выход. и я бы ввел пол, и избавился от муж/жена в структуре данных для семьи, но, как я понял, встречаются гермафродиты хотя для семей возможно лучше разбить таблицы: семья: (уникум, служит для организации связей с потомками и супругами) id -PKey супруги: id - Fkey семья(id) idp - персона Fkey дети ( sx - роль в семье, boolean nсемьи - номер брака В таком виде данных в семье/супруги/дети более чем достаточно для первичного расчета таблицы связей "потомки", а полного набора таблиц с (учетом последней таблицы) - для формирования практически за счет одного SQL всех возможных отчетов. Если же вы настаиваете на нумерации внутри "линии", то это заведомо относительное (отсчитывается от произвольно выбранного предка) поле можно расчитывать динамически (как я писал - заполняя коллекцию или массив) при выводе отчетов, не перестраивая таблицу "потомков". __________ ЗЫ - Если затруднились переформировать нерекурсивную разновидность процедуры, то сейчас поищу... вот, с какими-то лишними наворотами: Код: 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. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. и я б еще поэкспериментировал с поиском в большой коллекции по "key". если окажется быстрее, чем выборка из массива перебором по значению (или модификаций с вставкой в упорядоченные массивы - с "раздвижкой", что долго), то легко решается проблема пересчета генетического веса без вызова .edit при повторном нахождении (на этапе прохода по поколению результаты грузятся в коллекцию записей с инедексом str(id) (определенный пользователем тип, вес в поколении просто пересчитывается, при ошибке добавления по ключу), а по проходу все поколение записывается из коллекции в таблицу (add or edit ранее вставленных записей). Но это именно в случае желания иметь степень генетического родства с учетом множественности линий наследования. В конце-концов может оказаться что даже вся ваша табла "потомков" шустро влезет в такую коллекцию в разумный объем памяти (у вас что-то до 40000 "записей" длиной 8 байт, +, если я праильно соображаю на счет конструкции "коллекций" и их "индексов", структурка будет более рыхлой, чем массив (записей) на некий множитель, не больший, видимо, 5-10 (вроде как даже таблички не более чем в 5 раз более рыхлы, чем плоские файлы), и ваша коллекция записей (для одного предка) влезет в 1.6 -3.2 мегабайта. Что уже интересно с точки зрения переноса логики связи не на таблицу потомков, а на функцию(и) связей, рботающую с такими массивами по предложенной ранее схеме... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.05.2004, 11:41 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 фыыф автор3. не совсем понимаю, что такое "номер персоны в семье" и на кой он нужен (внутри поколения нумерация вообще произвольна). Но такого рода нумерация легко производится в нерекурсивной (последовательный перебор по поколениям) процедуре. Внутри поколения нумерация д.б. не произвольна! Потомков нужно показывать по старшинству предков. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.05.2004, 12:34 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
а где вы возьмете старшинство внутри одной семьи (старшинство предков-то тут одинаково)? а то у вас в таблицах старшинства детей в семье и нет [:0) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.05.2004, 16:16 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
2 фыыф авторв таблицах старшинства детей в семье и нет [:0) Есть - это счетчик. Дети в каждой семье записаны уже в нужном порядке. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.05.2004, 16:51 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
я так и думал, что применено какое-нить мм... решение. :0) постройте индекс "новый" по "детям" ==(семья,счетчик, ребенок) вместо (Семья,ребенок) и бегайте по этому индексу. (замените на rstD.Index ="новый") к тому ж в неиерархическом случае Seek у вас используется только во входе (".=", id). Внутри семьи потомки будут перебираться в порядке "счетчика", вот в этом порядке и наваривайте ваше поле старшинства по всей иерархии. ---- или, чтобы не переписывать: обновите мужей/жен в семьях на значение "счетчик" из детей затем "ребенков" в "детях" на (то же) значение "счетчик" (после чего поле счетчика можете грохнуть за ненадобностью, и ввести нормальное поле для учета порядка в семьях) (Семья,ребенок) станут упорядочены внутри семей по старшинству детей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.05.2004, 19:11 |
|
||
|
Иерархия и рекурсия
|
|||
|---|---|---|---|
|
#18+
авторобновите мужей/жен в семьях на значение "счетчик" из детей затем "ребенков" в "детях" на (то же) значение "счетчик" (после чего поле счетчика можете грохнуть за ненадобностью, и ввести нормальное поле для учета порядка в семьях) (Семья,ребенок) станут упорядочены внутри семей по старшинству детей. Вот этого я и добиваюсь, пока безуспешно :( Знаю что нужно, не знаю как... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.05.2004, 20:26 |
|
||
|
|

start [/forum/topic.php?all=1&fid=45&tid=1674665]: |
0ms |
get settings: |
8ms |
get forum list: |
11ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
167ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
112ms |
get tp. blocked users: |
1ms |
| others: | 267ms |
| total: | 583ms |

| 0 / 0 |
