powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / help!
18 сообщений из 68, страница 3 из 3
help!
    #33262001
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вы все время путаете отображение данных и их хранение. Все Ваши таблицы рассчитаны на то, что они будут отображаться "как есть". Но форма отображения данных крайне неудобна для обработки данных. Причем, в большинстве случаев, сформировать нужный вид для отображения не так уж и сложно из любой формы хранения.

Следовательно, Вам необходимо всерьез заняться структурой хранения. Переделать ее таким образом, чтобы можно было удобно и быстро ее обрабатывать.

Скорость отображения в нужной форме должна быть на втором плане. Достаточно только иметь информацию для такого отображения.

Ну, например, если рассматривать лотерейный билет спортлото, то это набор ячеек. Вместо того, чтобы пытаться хранить данные "как есть", т.е. столбцы - это поля, а строки - это записи, надо представить каждую ячейку как набор 3 значений - Номер строки, Номер столбца, Значение. Плюс добавить номер карточки. В результате приходим к структуре таблицы из 4 полей. Обрабатывать такую структуру достаточно просто. Первести ее в форму для отображения тоже не представляет труда.
...
Рейтинг: 0 / 0
help!
    #33263144
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hi SDF!

Создаётся впечатление, что эту задачу нужно НАМ решать а не тебе, просто
клещами информацию приходится вытаскивать!

1) Неверная постановка задачи ведёт к заведомо неверному результату.
2) Правила, которым удовлетворяют комбинации ты так и не написал. Хорошо,
предположим что это правила руссколо лото.
3) Структура таблиц для АНАЛИЗА выбрана не совсем удачно.

Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
help!
    #33263223
SDF
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ya pitalsa snachala xranit dannie 'kak yest'. No, seychas,dlya xranenie dannix ya ispolzuyu bazk.dbf, a dlya otobrajenie bask1.dbf. To test, (pravila, kotoriy udovletvoryaet kombinatsii:
u menya v kajdom kartochke 3 stroka i 5 stolbets, a chisla rassortirovani po kolonkam v zavisimosti ot tovo k kakomu desyatku oni prinadlejit. Vsevo v kajdom kartochke 10 chislo. Iz nix 5 v verxnim 2 stroke, 5 v nijnim (poslednim) stroke naxoditsa.
No, dlya raboti proqrammi iz etoy tablitsu (bask1.dbf) poluchayu noviy -bask.dbf.
(vmesto 3-x zapisey 1 zapis) Ya dumal chto tak bistree budet rabotat.
VladimirM, yesli ya budu izmenyat strukturu tablitsu kak Vi qovorite, eto znachit ya vsyo proqrammu doljen menyat. No ya seychas budu ob etom dumat kak eti '4 pole'
obrobatovat.
...
Рейтинг: 0 / 0
help!
    #33264087
GrayFox
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Salam.Sen Bizim dilde yaz gorum ne etmek isteyirsen?
...
Рейтинг: 0 / 0
help!
    #33265304
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hi SDF!

Не уверен что правильно понял...

Т.е. в карточке 15 полей (3*5) но заполнено из них лишь 10.
5 в первых двух строках и 5 в последней (т.е. последняя строка заполнена
полностью)?
В столбцах содержатся числа из соответствующего десятка - т.е. в первом из
первого, в пятом - из пятого.
Не ясно могут ли в одной карточке повторяться числа? Если я понял между 1 и
2 строками повторений нет, а вот как насчёт между всеми 3-мя строками?
Опять же не понятно зачем тебе при розыгрыше анализировать "повторения", или
ты просто для уточнения (и создания алгоритма генерации тестовой базы) это
сказал, а реально никаких повторений не будет - т.е. в ходе игры это
проверять уже не надо?
Как я понимаю 2 первые строки не для красоты сделаны, а для того, чтобы
можно было в одной карточке иметь 2 значения из одного десятка? Т.е. в
первых двух строках могут быть пустые колонки (скажем есть числа 1 и 2, но
нету ни одного числа из 2-й десятки)...
Также не понятно это опечатка насчёт диапазона первой колонки (от 1 до 9)
или реально число 10 попадает во 2-ю колонку? Ибо получается дисбаланс - в
первой колонке возможно 9 чисел, во второй 11, в остальных по 10...
Сколько всего может быть билетов (вообще ограничено их число ВСЕГДА или
нет - скажем тираж 20Млн и не больше)?
Кстати говоря, в 3-й строке при таких условиях возможны всего 100 000
комбинаций, а в первых двух строках - всего 4 330 000 комбинаций - т.е.
задачу можно разбить - предварительно каждому из твоих 20 млн "билетов"
сопоставить 2 цифры - номера соответствующих комбинаций и искать уже через
посредство сравнительно небольших таблиц - но надо посмотреть поможет ли
такое "разбиение" ускорить процесс.
Также важно знать насколько критично время поиска выигрышных билетов - т.е.
это OnLine розыгрыш и нужно после каждого хода объявлять что столько-то
билетов выиграло и такой-то их выигрыш, или Offline - и скорость некритична.

Теперь насчёт алгоритма проверки - что и как проверяется.
Как я понял "выигрыш" - это если "закрыты" полностью первые 2 строки ИЛИ
закрыта полностью третья строка?
1-й тур:
До каких пор идёт игра? До появления первого выигрыша, или какое-то
фиксированное число ходов? Нужно просто найти все выигравшие или тут важно
на каком ходе они выиграли? Важен НОМЕР хода, или просто СКОЛЬКО билетов
выиграло на N-м ходу (ну чтобы разделить между ними часть призового фонда
поровну, тогда как собственно размер этой части от хода не зависит).
Про 2-й тур (и возможно последующие) вообще ничего не сказано...

Я для теста создал несколько другую структуру:
Код: 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.
CREATE TABLE t1 (nID I, cPart C( 1 ), cValue C( 1 ))
RAND( 1 )
CLEAR
SET TALK OFF
SET NOTIFY OFF
SET NOTIFY CURSOR OFF
LOCAL lnSec, lnID, ln1, laTmp( 10 )
lnSec = SECONDS()
FOR lnID =  1  TO  2000000 
 FOR ln1 =  0  TO  4 
  laTmp(m.ln1 *  2  +  1 ) = m.ln1 *  10  +  1  + INT(RAND()* 10 )
  laTmp(m.ln1 *  2  +  2 ) = m.ln1 *  10  +  1  + INT(RAND()* 10 )
  DO WHILE laTmp(m.ln1 *  2  +  2 ) = laTmp(m.ln1 *  2  +  1 )
   laTmp(m.ln1 *  2  +  2 ) = m.ln1 *  10  +  1  + INT(RAND()* 10 )
  ENDDO
 ENDFOR
 FOR ln1 =  10  TO  6  STEP - 1 
  ADEL(laTmp, INT( 1  + RAND() * m.ln1))
 ENDFOR
 FOR ln1 =  0  TO  4 
  laTmp( 6  + m.ln1) = m.ln1 *  10  +  1  + INT(RAND()* 10 )
 ENDFOR
 INSERT INTO t1 (nID, cPart, cValue) VALUES ;
   (m.lnID, "1", CHR( 32  + m.laTmp( 1 )))
 INSERT INTO t1 (nID, cPart, cValue) VALUES ;
   (m.lnID, "1", CHR( 32  + m.laTmp( 2 )))
 INSERT INTO t1 (nID, cPart, cValue) VALUES ;
   (m.lnID, "1", CHR( 32  + m.laTmp( 3 )))
 INSERT INTO t1 (nID, cPart, cValue) VALUES ;
   (m.lnID, "1", CHR( 32  + m.laTmp( 4 )))
 INSERT INTO t1 (nID, cPart, cValue) VALUES ;
   (m.lnID, "1", CHR( 32  + m.laTmp( 5 )))
 INSERT INTO t1 (nID, cPart, cValue) VALUES ;
   (m.lnID, "2", CHR( 32  + m.laTmp( 6 )))
 INSERT INTO t1 (nID, cPart, cValue) VALUES ;
   (m.lnID, "2", CHR( 32  + m.laTmp( 7 )))
 INSERT INTO t1 (nID, cPart, cValue) VALUES ;
   (m.lnID, "2", CHR( 32  + m.laTmp( 8 )))
 INSERT INTO t1 (nID, cPart, cValue) VALUES ;
   (m.lnID, "2", CHR( 32  + m.laTmp( 9 )))
 INSERT INTO t1 (nID, cPart, cValue) VALUES ;
   (m.lnID, "2", CHR( 32  + m.laTmp( 10 )))
ENDFOR
? SECONDS() - m.lnSec
INDEX ON cValue TAG cValue
INDEX ON cPart TAG cPart
? SECONDS() - m.lnSec
nID - номер билета, сPart - "раздел" (т.е. верхние неполные 2 строки, или
нижняя полная строка) и cValue - собственно значение находящееся в ячейке,
"завернутое" в ASCII символ. Порядок следования значений не играет никакой
роли. Создаются 2Млн записей примерно 6 минут (ну и ещё минуты 4-5
индексируются). В итоге получаем таблицу в 140Мб и индекс под 200Мб.
"Розыгрыш" выполняет следующий код (можно и эффективнее сделать - например
как в варианте заполнения - создать массив из 50 элементов, и на каждом ходу
"вынимать" оттуда один элемент - естественно удаляя его из массива, и
уменьшая его размер):
Код: 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.
CLEAR
CREATE TABLE t2 (cValue C( 1 ))
INDEX ON cValue TAG cValue
FOR ln1 =  1  TO  50 
    DO WHILE .T.
        lnRand = INT( 1  + RAND()* 50 )
        SELECT t2
        LOCATE FOR cValue == CHR( 32  + m.lnRand)
        IF !FOUND("t2")
            INSERT INTO t2 (cValue) VALUES (CHR( 32  + m.lnRand))
            EXIT
        ENDIF
    ENDDO
    lnSec = SECONDS()
    SELECT t1
    REPLACE cPart WITH "3" FOR cValue = CHR( 32  + m.lnRand) AND cPart = "1"
    REPLACE cPart WITH "4" FOR cValue = CHR( 32  + m.lnRand) AND cPart = "2"
    SELECT nID, ;
            cPart, ;
            COUNT(*) ;
        FROM t1 ;
        WHERE cPart = "3" OR cPart = "4" ;
        GROUP BY nID, cPart ;
        HAVING COUNT(*) >  4  ;
        INTO CURSOR csrRes
* Иной вариант
*    SELECT nID, ;
*            nPart, ;
*            COUNT(*) ;
*        FROM t1 INNER JOIN t2 ;
*            ON t1.cValue = t2.cValue ;
*        GROUP BY nID, cPart ;
*        HAVING COUNT(*) >  4  ;
*        INTO CURSOR csrRes
    ? m.ln1, SECONDS() - m.lnSec, _TALLY
ENDFOR

Поиск выигрышного билета занимает (напомню, что база 2Млн билетов) примерно
по 1-2 минуте на ход (это пока мне не надоело ждать - т.е. первые ходов 10 -
чем дальше тем медленнее, т.к. уже результатная выборка становится чересчур
велика).
Можно придумать и другие алгоритмы поиска... Можно для эффективности признак
"выбивания" числа сделать отдельным полем, и создать по нему BINARY индекс
(в VFP9) - индекс заметно уменьшится, правда сама таблица "подрастёт" на
15%...
Кстати используемую версию фокса я тоже не увидел нигде - это важно...

Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
help!
    #33265382
SDF
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Privet, Igor Korolyov!
V obshem Vi vse provilno ponyali.
Seychas ya poprobuyu otvetit na ostalnie voprosi.
1.V odnoy kartochke (vo vsex 3-x strokax) ne doljno povtoryatsa chislo.

2. Pri roziqrishe alqoritmov 'povtoreniya' ne nujen. V xode iqri eto proveryat uje ne nado.

3. Naschet diapazona:
1-ya kalonka- ot 1 do 9
2-ya kalonka- ot 10 do 19
3-ya kalonka- ot 20 do 29
4-ya kalonka- ot 30 do 39
5-ya kalonka- ot 40 do 50

4. Tiraj mojet bit i menshe 20 mln ili bolshe 20 mln Konkretno kloichestvo biletov
netu.
5. Vremya viqrivshnix biletov -ochen vajno
To yest, ya delal proqrammu uje rabotayushiy s 400000 zapisyami vremya 5-7 sek.
No uje bolshimi kolichestvami mojno skazat ne rabotaet.
Eto online roziqrish, i nujno posle kajdovo xoda obyavlyat chto skolko-to biletov viqrala, i takoyto ix viqrish, v kokom xode viqrala.
5. I tur zakanchivaetsa toqda, koqda 'zakrita' polnostyu pervie 2 stroka, ili zakrita
polnostyu 3-ya stroka. (Do poyavlenie 1-vo viqrisha)
6. II tur zakanchivaetsa toqda koqda polnostyu zakrita xotyabi odno kortichka.
...
Рейтинг: 0 / 0
help!
    #33265393
SDF
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FOXPRO-6
...
Рейтинг: 0 / 0
help!
    #33271845
SDF
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Privet, Igor Korolyov! Sposibo, za Vash takoy podrobniy otvet!
Seychas ya analiziroval napisanniy Vami kod.
No delo v tom chto, moya proqramma mojno skazat , chto uje qotovo (no, skorost ne raduet s takimi bolshimi tablitsami), i ya ne xocu
seychas vsyo izmenit (struktura tablitsu i t.d.), i na eto vremya netu.
Poetomo ,poka postarayus, kak nibud vsyo ostovlyaya kak yest, "uskorit"
vipolnenie proqrammi.
No, privedyonniy Komissara primer zapolnenie tablitsu rabotaet bistree, no, na obrabotku ochen mnoqo vremya zanimaet .
...
Рейтинг: 0 / 0
help!
    #33272238
Komissar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Извини, дружище! Хотел попробовать придумать алгоритм обработки, но получился небольшой аврал по работе... Еще и жена вчера ногу слегка сломала... :(
...
Рейтинг: 0 / 0
help!
    #33272360
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hi SDF!

Пока не могу ничем обнадёжить - мой вариант не будет работать выстрее, и
вообще я сильно сомневаюсь что силами одного лишь фокса можно сделать
ПРИЕМЛЕМЫЙ по скорости вариант для такого большого массива.
Мой код заполнения сейчас практически аналогичен тому что Komissar написал
(ну только с добавлением твоей 3-й строки карточки), и тем не менее 20Млн
записей создавались в течении 78 минут (больше часа). Я попробовал (слегка
изменив) твою структуру - получается что на ход затрачивается от 210 до 350
секунд (по мере роста числа "выигравших" билетов происходит существенное
замедление - оно и понятно - вынуть 14 записей и поместить их в курсор это
одно, а вынуть все 20Млн записей - это уже совсем другое :( )
Единственно чего я не учитывал - так это странностей распределения чисел в
твоей схеме - даже по последним приведенным данным выходит, что в первой
группе (первой колонке) всего 9 возможных значений, во 2, 3 и 4 по 10, а в
5-й 11... Просто лень под это закладываться, да и для результата это
некритично. вот что критично - так это объём файла. У тебя (и у Komissar
тоже) структура избыточна! ДАЖЕ если хранить числа в "полном" виде, то они
запросто влазят в поле C(1)! Я же и вовсе пошел дальше, и сохранил лишь
младший разряд от числа - т.к. старший разряд однозначно определяется
номером колонки (с учётом конечно вышеописанного мной "упрощения"). Можно
хранить и полное число, завернув его через CHR() в один символ.
Также номер карточки стоит хранить в поле типа Integer (занимает всего 4
байта вместо тех 8 что выделил ты). Итого получаем экономию в 2 раза!!!
Recsize() всего 20 байт - т.е. теоретически можно дойти до более чем 100Млн
карточек.
Твои служебные поля скорее всего не помогут в деле ускорения процесса - как
я понимаю что анализ на этапе Update, что анализ позже - разницы нету, а вот
dbf становится больше от этого...
Кстати на 200 тысячах карточек алгоритм отрабатывает примерно за 1.7 секунды
на ход (а заполнение таблицы занимает чуть менее 50 секунд)
Код: 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.
CREATE TABLE t3 (nID I, a1 C( 1 ), a2 C( 1 ), a3 c( 1 ), a4 C( 1 ), a5 C( 1 ), a6 
C( 1 ), a7 C( 1 ), a8 C( 1 ), a9 C( 1 ), a10 C( 1 ), b1 C( 1 ), b2 C( 1 ), b3 C( 1 ), b4 
C( 1 ), b5 C( 1 ))
RAND( 1 ) && Для получения всегда одной и той-же последовательности!!!
CLEAR
SET TALK OFF
SET NOTIFY OFF
SET NOTIFY CURSOR OFF
LOCAL lnSec, lnID, ln1, laTmp( 15 ), ln2
lnSec = SECONDS()
FOR lnID =  1  TO  20000000 
 FOR ln1 =  0  TO  4 
  laTmp(m.ln1 *  3  +  1 ) = INT(RAND()* 10 )
  laTmp(m.ln1 *  3  +  2 ) = INT(RAND()* 10 )
  DO WHILE laTmp(m.ln1 *  3  +  2 ) = laTmp(m.ln1 *  3  +  1 )
   laTmp(m.ln1 *  3  +  2 ) = INT(RAND()* 10 )
  ENDDO
  laTmp(m.ln1 *  3  +  3 ) = INT(RAND()* 10 )
  DO WHILE laTmp(m.ln1 *  3  +  3 ) = laTmp(m.ln1 *  3  +  1 ) OR ;
    laTmp(m.ln1 *  3  +  3 ) = laTmp(m.ln1 *  3  +  2 )
   laTmp(m.ln1 *  3  +  3 ) = INT(RAND()* 10 )
  ENDDO
 ENDFOR
 FOR ln1 =  1  TO  5 
  ln2 = INT(RAND()* 10 )
  ln2 =  1  + m.ln2 + INT(m.ln2/ 2 )
  DO WHILE laTmp(m.ln2) = - 1 
   ln2 = INT(RAND()* 10 )
   ln2 =  1  + m.ln2 + INT(m.ln2/ 2 )
  ENDDO
  laTmp(m.ln2) = - 1 
 ENDFOR
 FOR ln1 =  1  TO  15 
  IF laTmp(m.ln1) = - 1 
   laTmp(m.ln1) = ""
  ELSE
   laTmp(m.ln1) = STR(m.laTmp(m.ln1),  1 )
  ENDIF
 ENDFOR
 INSERT INTO t3 (nID, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, b1, b2, b3, 
b4, b5) VALUES ;
   (lnID, ;
   laTmp( 1 ), laTmp( 4 ), laTmp( 7 ), laTmp( 10 ), laTmp( 13 ), ;
   laTmp( 2 ), laTmp( 5 ), laTmp( 8 ), laTmp( 11 ), laTmp( 14 ), ;
   laTmp( 3 ), laTmp( 6 ), laTmp( 9 ), laTmp( 12 ), laTmp( 15 ))
ENDFOR
? SECONDS() - m.lnSec
Вот код процедуры розыгрыша (как дополнительная "навеска" - сразу и проверка
условия для второго тура).
Код: 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.
CLEAR
CREATE TABLE t2 (cValue C( 2 ))
INDEX ON cValue TAG cValue
SET ORDER TO  0 
RAND( 100 ) && Для получения всегда одной и той-же последовательности!!!
FOR ln1 =  1  TO  50 
 DO WHILE .T.
  lnRand = INT(RAND()* 50 )
  SELECT t2
  LOCATE FOR cValue == STR(m.lnRand,  2 )
  IF !FOUND("t2")
   INSERT INTO t2 (cValue) VALUES (STR(m.lnRand,  2 ))
   EXIT
  ENDIF
 ENDDO
 lnSec = SECONDS()
* START  v1
SELECT t3
ln2 = INT(m.lnRand/ 10 )
ln3 = STR(m.lnRand% 10 ,  1 )
DO CASE
CASE m.ln2 =  0 
 REPLACE a1 WITH "" FOR a1 = m.ln3
 REPLACE a6 WITH "" FOR a6 = m.ln3
 REPLACE b1 WITH "" FOR b1 = m.ln3
CASE m.ln2 =  1 
 REPLACE a2 WITH "" FOR a2 = m.ln3
 REPLACE a7 WITH "" FOR a7 = m.ln3
 REPLACE b2 WITH "" FOR b2 = m.ln3
CASE m.ln2 =  2 
 REPLACE a3 WITH "" FOR a3 = m.ln3
 REPLACE a8 WITH "" FOR a8 = m.ln3
 REPLACE b3 WITH "" FOR b3 = m.ln3
CASE m.ln2 =  3 
 REPLACE a4 WITH "" FOR a4 = m.ln3
 REPLACE a9 WITH "" FOR a9 = m.ln3
 REPLACE b4 WITH "" FOR b4 = m.ln3
CASE m.ln2 =  4 
 REPLACE a5 WITH "" FOR a5 = m.ln3
 REPLACE a10 WITH "" FOR a10 = m.ln3
 REPLACE b5 WITH "" FOR b5 = m.ln3
ENDCASE
SELECT nID ;
 FROM t3 ;
 WHERE (EMPTY(a1) AND ;
  EMPTY(a2) AND ;
  EMPTY(a3) AND ;
  EMPTY(a4) AND ;
  EMPTY(a5) AND ;
  EMPTY(a6) AND ;
  EMPTY(a7) AND ;
  EMPTY(a8) AND ;
  EMPTY(a9) AND ;
  EMPTY(a10)) OR ;
  (EMPTY(b1) AND ;
  EMPTY(b2) AND ;
  EMPTY(b3) AND ;
  EMPTY(b4) AND ;
  EMPTY(b5)) ;
 INTO CURSOR csrRes
* END  v4
 ? m.ln1, SECONDS() - m.lnSec, _TALLY
SELECT nID ;
 FROM t3 ;
 WHERE EMPTY(a1) AND ;
  EMPTY(a2) AND ;
  EMPTY(a3) AND ;
  EMPTY(a4) AND ;
  EMPTY(a5) AND ;
  EMPTY(a6) AND ;
  EMPTY(a7) AND ;
  EMPTY(a8) AND ;
  EMPTY(a9) AND ;
  EMPTY(a10) AND ;
  EMPTY(b1) AND ;
  EMPTY(b2) AND ;
  EMPTY(b3) AND ;
  EMPTY(b4) AND ;
  EMPTY(b5) ;
 INTO CURSOR csrRes2
 ?? SECONDS() - m.lnSec, _TALLY
ENDFOR
Основная таблица открывается (либо просто остаётся открытой после процедуры
заполнения) в EXCLUSIVE - это должно дать выигрыш в скорости.
Также используется REPLACE, поскольку он для массовой замены в монопольно
открытой таблице будет быстрее чем UPDATE.

Как замечание - для столь большой таблицы ОЧЕНЬ много времени тратится на
файловые операции, индексы по всем полям тут вряд-ли помогут (в тесте по
200000 таблице они дали замедление - ход просчитывался около 2.2 секунд) -
они во-первых занимают раза в 2 больше места чем сам dbf, и во-вторых (что
наверное важнее всего) - они очень мало "распределенные" в рамках одного
поля мы имеем всего 11 (или 10 для b* полей) возможных значений - т.е. тут
получается та-же беда что и с индексом по Deleted()...

В общем есть такое предположение, что для приемлемой скорости данную
процедуру нужно писать на C, а ещё лучше на ASM - и не с таблицей работать,
а непосредственно с памятью (если нормально "упаковать" данные, то одно
число из карточки будет занимать всего 1 байт - т.е. на твои 20Млн карточек
потребуется всего чуть менее 200 Мб - т.е. на нормальном современном компе
это вполне реально - главное чтобы эта память в своп не выпадала!). Конечно
сравнительно большое время займёт "загрузка" данных из таблицы в память, но
зато потом обработка будет проходить очень быстро...

Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
help!
    #33273424
Komissar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мдя... Пока отсутствовал - отстал от темы... :(
Вставлю таки свои 5 коп. насчет формирования таблицы - не надо RAND()! Тормозит ведь мрачно!
3-ий вариант!!!
...
Рейтинг: 0 / 0
help!
    #33273677
SDF
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Privet,Komissar! Jelayu Vam i vashey jene zdorovye.
Vashi varianti dlya formirovanie tablitsu ustraivaet menya. 20 mln. zapisey ne tak dolqo sformirovalsa,pravda seychas ne pomnyu skolko. (uchitivaya, cho eto odnorazoviy proses)..
No, obrabotka nad etoy tablitsoy s moimi proqrammami ochen dolqo idyot, primerno 3 mln. zapis -za 8-9 minut. A eto online roziqrish, i mne nado za korotkiy srok obyavit 1) vishedshiy nomer, 2) skolko biletov viqrala, 3) i kajdiy bilet skolko viqrala.

Mne Igor Korolyov sovetoval chto, s takimi bolshimi razmerami lucshe rabotat na C, ili asm. No ya rabotal na Delphi i Nemnojka Na Foxpro. V delphieto- yeshyo slojnee
(nascet vremeni).
...
Рейтинг: 0 / 0
help!
    #33275083
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hi SDF!

Я тут попросил коллегу нарисовать код на C#, возможно попробую на чистом C
тоже сделать - посмотрим как оно будет по скорости...

2 Komissar
1) Ты не учитываешь второй части карточки - с этим получится заметно
сложнее.
2) 51 подобный "блок" рисовать - как-то напряжно :( Конечно можно и по
другому попробовать.
3) Всё зависит от того какое "распределение" допустимо. Если
"последовательное" нормально - то конечно так, если же нет - то без RAND()
не обойтись. Хотя можно его вынести в другую часть - номера билетов им
генерить, а само "содержимое" каким-то последовательным методом (аналогичным
твоему).

Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
help!
    #33275264
Komissar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Igor Korolyov1) Ты не учитываешь второй части карточки - с этим получится заметно сложнее.
2) 51 подобный "блок" рисовать - как-то напряжно :( Конечно можно и по
другому попробовать.
3) Всё зависит от того какое "распределение" допустимо. Если "последовательное" нормально - то конечно так, если же нет - то без RAND() не обойтись. Хотя можно его вынести в другую часть - номера билетов им генерить, а само "содержимое" каким-то последовательным методом аналогичным твоему).
Привет, Игорь!
1. Поначалу разговора о второй части не было...
2. Вот и я сильно ограничился в примере... 100% можно придумать "автоматизацию", но ведь оно одноразовое...
3. Именно! Сгенерить последовательно, а потом "перетасовать"...
Впрочем, вопрос формирования уже не актуален...
...
Рейтинг: 0 / 0
help!
    #33277688
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hi SDF!

Код на C# обрабатывает 20Млн карточек за время от 2 до 10 секунд (в
зависимости от того сколько уже чисел "выпало" - поскольку сам массив НЕ
изменяется, просто каждый элемент проверяется на наличие в другом массиве -
"выигрышных" номеров - операция записи в память, как я понял, оказывается
"дороже" нескольких операций чтения и сравнения).
Поскольку в твоём случае с очень большой вероятностью первый тур закончится
на 5-м ходу :) то можно считать что время "отклика" составит 2 секунды.
P.S. Естественно что на машине ДОЛЖНО быть установлено как минимум 256 Мб
памяти (лучше 512 Мб) - иначе прога уйдёт в жестокий своп и считать будет на
порядок дольше.
P.P.S. Естественно что проверялся САМ ПРИНЦИП - т.е. для C# никто не делал
"правильного" генератора - т.е. просто карточки заполнялись 10-ю совершенно
случайными числами.

Ну и собственно код - он компилируется в консольное Win32 приложение.
(Надеюсь индекс i не воспримется за тег в блоке кода).
Код: 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.
using System;

namespace Cards
{
 class Class1
 {
  [STAThread]
  static void Main(string[] args)
  {
   if ( args.Length <  2  )
   {
    Console.WriteLine( "Запуск: cards <количество карточек> <число> [<число> 
....]" );
    return;
   }

   Console.Write( "Создание и заполнение {0:# ### ##0} карточек... ", 
Convert.ToInt32( args[ 0 ] ) );
   DateTime d = DateTime.Now;
   byte [] bytes = new byte[ Convert.ToInt32( args[ 0 ] ) *  10  ];
   Random rnd = new Random();

   for ( int i = bytes.Length; --i >= 0; )
    bytes[i] = Convert.ToByte( rnd.Next(  50  ) +  1  );
   Console.WriteLine( DateTime.Now - d );

   byte [] numbers = new byte[ args.Length- 1  ];
   for ( int i = numbers.Length; --i >= 0; )
    numbers[i] = Convert.ToByte( args[i+ 1 ] );


   Console.Write( "Поиск... " );
   d = DateTime.Now;
   int Count =  0 ;
   for ( int i =  0 ; i < bytes.Length; i +=  10  )
    if ( Find( bytes, i, numbers ) || Find( bytes, i+ 5 , numbers ) )
     Count++;
   Console.WriteLine( DateTime.Now - d );
   Console.WriteLine( "Найдено: {0}", Count );
  }

  static bool Find ( byte [] bytes, int index, byte [] numbers )
  {
   for ( int i = index +  5 ; --i >= index; )
   {
    bool ok = false;
    for ( int j = numbers.Length; --j >= 0; )
     if ( bytes[i] == numbers[j] )
     {
      ok = true;
      break;
     }

    if ( !ok ) return false;
   }
   return true;
  }
 }
}


Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
help!
    #33277836
SDF
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Privet, Igor!
Spasibo, Vam za vsyo eto.
2 ili 10 sek. za 20 mln. zapis, eto konyeshno ochen xorosho .
No, ya pro C# nichevo neznayu, i seychas kak proverit etot kod neznayu.
I yeshyo dumayu chto izucat C# za tokoy korotkiy srok - nichevo ne poluchitsa.
...
Рейтинг: 0 / 0
help!
    #33284877
Igor Korolyov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hi SDF!

Ну тут я ничем помочь не могу уж. В принципе всё то-же самое можно на чистом
C сделать, скомпилировать в dll/fll и пользовать из фокса...

Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
help!
    #33306487
SDF
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ya ponyal chto imenno eto chast proqrammi ochen dolqo rabotaet.
No kak eto chast proqrammi ili voobshi alqoritm mojno optimizirovat (ne silno menyaya strukturu tablitsu)- nicevo ne nashel.


lnValue - Vishel kakoy-to nomer.

1. Proveryayu etot nomer kakoy diapozon vxodit.
2. Obnulyayu vse eti znachenie yesli yest takaya
3. Proveryayu summa znachenie vsex poley 'AA' (sum_a=AA1+AA2+....AA14)
Yesli eto summa =0 toqda 1-y tur zakanchivaetsa.





if lnValue<=9
update bask set aa1 = 0 where aa1 = m.lnValue
update bask set aa8 = 0 where aa8 = m.lnValue
update bask set bb1 = 0 where bb1 = m.lnValue
endi

if lnValue>=10.and.lnValue<=19
update bask set aa2 = 0 where aa2 = m.lnValue
update bask set aa9 = 0 where aa9 = m.lnValue
update bask set bb2 = 0 where bb2 = m.lnValue
end

....
....
....
...
Рейтинг: 0 / 0
18 сообщений из 68, страница 3 из 3
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / help!
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]