Гость
Форумы / Microsoft Office [игнор отключен] [закрыт для гостей] / Распараллелить вложенные циклы VBA / 14 сообщений из 14, страница 1 из 1
13.03.2015, 09:11
    #38903336
_s_e_r_g_e_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распараллелить вложенные циклы VBA
Коллеги, доброго времени.
Помогите пожалуйста, решить проблему.

Существуют вложенные циклы (пишу на vba под excel).

В общем полный перебор. Все операции только в памяти с помощью массивов (на экран ничего не вывожу).
И все равно если stop1,..., stop6 очень большие (может быть под 80 млн. комбинаций) расчет выполняется очень медленно, даже терпения не хватило дождаться.

Например в с++ существует OpenMP. Моя задача написана на vba. Очень много кода нет желания все переписывать на с++.
Хочется решить проблему малой кровью.
Существует ли способ как-то распараллелить процесс?

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
for i1=start1 to stop1 step step1
     for i2=start2 to stop2 step step2
       for i3=start3 to stop3 step step3
            for i4=start4 to stop4 step step4
              for i5=start5 to stop5 step step5 
                 for i6=start6 to stop6 step step6
 
                       ' что-то делаем
                next i6
           next i5
        next i4
     next i3
   next i2
  next i1 
...
Рейтинг: 0 / 0
13.03.2015, 10:21
    #38903432
Казанский
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распараллелить вложенные циклы VBA
Оптимизируйте алгоритм. Это может дать выигрыш на порядки, а распараллеливание - в лучшем случае в разы.
Пример оптимизации перебора - во второй закрепленной теме: Пособие для студентов и школьников
...
Рейтинг: 0 / 0
13.03.2015, 10:42
    #38903464
dvim
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распараллелить вложенные циклы VBA
_s_e_r_g_e_,

На vba не существует возможности такой.
Можно вызывать внешнюю библиотеку, а там распараллелить
...
Рейтинг: 0 / 0
13.03.2015, 10:54
    #38903481
_s_e_r_g_e_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распараллелить вложенные циклы VBA
спасибо большое, подумаю
...
Рейтинг: 0 / 0
13.03.2015, 10:56
    #38903484
_s_e_r_g_e_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распараллелить вложенные циклы VBA
dvim_s_e_r_g_e_,

На vba не существует возможности такой.
Можно вызывать внешнюю библиотеку, а там распараллелить

Не подскажите какую библиотеку можно использовать?
...
Рейтинг: 0 / 0
13.03.2015, 11:07
    #38903498
Казанский
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распараллелить вложенные циклы VBA
И, конечно, переменные должны быть правильного типа. Быстрее всего крутятся циклы с переменными типа Long:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
DefLng I

Sub bb()
Dim s&, t!: t = Timer
  For i1 = 1 To 20
    For i2 = 1 To 20
      For i3 = 1 To 20
        For i4 = 1 To 20
          For i5 = 1 To 20
            For i6 = 1 To 25
              s = s + 1
              ' что-то делаем
            Next i6
          Next i5
        Next i4
      Next i3
    Next i2
  Next i1
  Debug.Print Round(Timer - t, 2) & " сек", s
End Sub

1,84 сек       80000000 

C типом Integer уже хуже
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
DefInt I

Sub bb()
Dim s&, t!: t = Timer
  For i1 = 1 To 20
    For i2 = 1 To 20
      For i3 = 1 To 20
        For i4 = 1 To 20
          For i5 = 1 To 20
            For i6 = 1 To 25
              s = s + 1
              ' что-то делаем
            Next i6
          Next i5
        Next i4
      Next i3
    Next i2
  Next i1
  Debug.Print Round(Timer - t, 2) & " сек", s
End Sub

2,09 сек       80000000

Ну а если не объявлять тип, т.е. переменные будут типа Variant, то:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
Sub bb()
t = Timer
  For i1 = 1 To 20
    For i2 = 1 To 20
      For i3 = 1 To 20
        For i4 = 1 To 20
          For i5 = 1 To 20
            For i6 = 1 To 25
              s = s + 1
              ' что-то делаем
            Next i6
          Next i5
        Next i4
      Next i3
    Next i2
  Next i1
  Debug.Print Round(Timer - t, 2) & " сек", s
End Sub

5,02 сек       80000000
...
Рейтинг: 0 / 0
13.03.2015, 11:11
    #38903504
cross join
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распараллелить вложенные циклы VBA
_s_e_r_g_e_Все операции только в памяти с помощью массивов (на экран ничего не вывожу).
Откуда берутся массивы?
Даже если они формируются динамически, то если "выкинуть" их на страницу и сделать "переюор" cross join запросом - будет на порядок быстрее, чем "тупой перебор" в циклах.

... и по-поводу "распараллеливания", гложат меня сомнения, что вы под мейнфрейм пишите, а на "сирой и убогой" рабочей станции, это "распараллеливание" только увеличит общее время
...
Рейтинг: 0 / 0
13.03.2015, 13:52
    #38903845
_s_e_r_g_e_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распараллелить вложенные циклы VBA
cross join_s_e_r_g_e_Все операции только в памяти с помощью массивов (на экран ничего не вывожу).
Откуда берутся массивы?
Даже если они формируются динамически, то если "выкинуть" их на страницу и сделать "переюор" cross join запросом - будет на порядок быстрее, чем "тупой перебор" в циклах.

... и по-поводу "распараллеливания", гложат меня сомнения, что вы под мейнфрейм пишите, а на "сирой и убогой" рабочей станции, это "распараллеливание" только увеличит общее время

массивы формируются во внутреннем цикле в зависимости от комбинации.
опишу задачу более подробно чтобы было понятно. Существует 6 продуктов(6 циклов). С помощью которых формирую партии производства продуктов (комбинации). Пример комбинации: 5 тыс.л;10 тыс.л.;8 тыс.л.; 11 тыс.л.; 20 тыс.л.; 14 тыс.л. Таких комбинаций может быть много.

Существуют рецептуры с закладками сырья для производства продукта.


ингридиент продукт закладка
код сырья6 код продукта 1 0,115
код сырья8 код продукта 1 0,252
код сырья1 код продукта 2 0,35
код сырья5 код продукта 2 0,08
код сырья8 код продукта 2 0,25
код сырья7 код продукта 3 0,354
код сырья8 код продукта 3 0,111
код сырья3 код продукта 4 0,065
код сырья4 код продукта 4 0,254
код сырья8 код продукта 4 0,345
код сырья2 код продукта 5 0,187
код сырья8 код продукта 5 0,274
код сырья9 код продукта 5 0,114
код сырья4 код продукта 6 0,118
код сырья8 код продукта 6 0,2


Сырье хранится в бочках у которых есть вес. Задача найти такую комбинацию чтобы вырабатывались все бочки под ноль (от 95% до 100% бочки), т.е. после производства не должно быть открытых бочек.

Внутри циклов в массив сохраняю комбинацию. Пересчитываю по рецептуре потребность сырья и смотрю (запоминаю) сколько видов сырья вырабатываю под целые бочки. Если в следующей итерации я получаю большее число выработанных бочек , то запоминаю это число.
...
Рейтинг: 0 / 0
13.03.2015, 15:29
    #38904050
ПЕНСИОНЕРКА
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распараллелить вложенные циклы VBA
_s_e_r_g_e_т.е. после производства не должно быть открытых бочек.
значит заранее известно количество бочек
могут ли остаться закрытые бочкм

для сырья1 при нормативах с11-с61
п1*с11+п2+с21+п3*с31+п4*с41+п5*с51+п6*с61<б1*(вес_бочки)
.....
получили сочетания п1-п6 считаем сырье 2
.....

п1-п6 --может быть заранее просчитанная таблица и из нее только выборка по текущему количеству бочек с1
...
Рейтинг: 0 / 0
13.03.2015, 15:40
    #38904074
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распараллелить вложенные циклы VBA
_s_e_r_g_e_опишу задачу более подробно чтобы было понятно
...
Задача найти такую комбинацию чтобы вырабатывались все бочки под ноль (от 95% до 100% бочки), т.е. после производства не должно быть открытых бочек.
Простите, но для решения такой задачи и программировать ничего не требуется. С ней легко справится штатная надстройка "Поиск решения".
...
Рейтинг: 0 / 0
13.03.2015, 16:26
    #38904176
_s_e_r_g_e_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распараллелить вложенные циклы VBA
спасибо всем большое за ответы. Я думал использовать поиск решения, но не получилось.

Приложил файл, помогите сделать с помощью поиска решений

Максимизировать необходимо H44

Изменяемые ячейки C2:C10
...
Рейтинг: 0 / 0
13.03.2015, 17:40
    #38904322
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распараллелить вложенные циклы VBA
Блин, да тут ни циклов, ни поиска решения не надо! Всего-то и надо, что подумать. А точнее - составить матрицу входимостей.

продукт1продукт2продукт3продукт4продукт5продукт6продукт7продукт8продукт9сырье1107.2сырье2120.63сырье3157.230.4177.8сырье4179.530.6сырье549.97сырье636.6сырье730.2сырье879.3136.2145.4141150.3120.410397.6сырье968.7
И сразу видно, как надо делать.
Например, сначала подбираем количество Продукта 2 так, чтобы расходовать целое количество бочек Сырья 1.
Затем подбираем количество Продукта 7 так, чтобы расходовать целое количество бочек Сырья 2.
Затем подбираем количество Продукта 9 так, чтобы вместе с посчитанным ранее расходовать целое количество бочек Сырья 3.
Аналогично подбираем для пар Продукт 3 - Сырьё 5, Продукт 4 - Сырьё 6, Продукт 6 - Сырьё 7, Продукт 8 - Сырьё 9, Продукт 5 - Сырьё 8, и наконец Продукт 1 - Сырьё 4.

В результате можем получить, например, такое решение:
ПродуктКоличествопродукт11.26продукт22.27продукт35.26продукт46.14продукт51.7продукт68.6продукт71.93продукт83.94продукт91.69
СырьёВес бочкиПотребностьКол-во бочекОстаток в бочкесырье10.24440.2433440.9956792140.004320786сырье20.2330.23281590.9992098710.000790129сырье30.2390.7159982.9958075310.004192469сырье40.280.278190.9935357140.006464286сырье50.2630.26284220.99940.0006сырье60.2250.2247240.9987733330.001226667сырье70.260.259720.9989230770.001076923сырье80.2754.12459514.998527270.001472727сырье90.2710.2706780.9988118080.001188192
Хочешь - программируй это дело, хочешь - руками считай...
...
Рейтинг: 0 / 0
13.03.2015, 17:47
    #38904334
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распараллелить вложенные циклы VBA
Порядок подбора может быть и другим.
Алгоритмически это так.
1) Выбираем любую строку таблицы (сырьё), в которой имеется ОДНО значение. Для неё подбираем количество продукта такое, чтобы расходовать целое количество бочек. Затем выбрасываем из таблицы эти строку и столбец.
2) Снова выбираем любую строку таблицы (сырьё), в которой имеется ОДНО значение. Для неё подбираем количество продукта такое, чтобы (с учётом посчитанных ранее) расходовать целое количество бочек. Затем выбрасываем из таблицы эти строку и столбец.
3) Продолжаем выполнять пункт 2, пока таблица не кончится.
...
Рейтинг: 0 / 0
13.03.2015, 18:06
    #38904364
_s_e_r_g_e_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Распараллелить вложенные циклы VBA
Akina, спасибо большое. Я именно так и делал сначала, удалил связь по сырью 8, т.е. разбил на подзадачи. Количество вложенных циклов уменьшилось максимум до 3. Это уже решаемая задача. А после нахождения партий для подгрупп выравнивал сырье 8.
В общем нечто похожее на то что показали вы. Но все не так просто, дело в том, что объемы партий зависят от спроса и сегодня это может быть один расклад , а завтра необходим другой. При чем можно производить как все продукты , если есть необходимость, а можно и не все. Партии всегда нужно подгонять под спрос. Сегодня одна рецептура, а завтра может появится рецептура с гораздо большим количеством вхождений. Поэтому решил создать универсальную систему. Спасибо еще раз.
...
Рейтинг: 0 / 0
Форумы / Microsoft Office [игнор отключен] [закрыт для гостей] / Распараллелить вложенные циклы VBA / 14 сообщений из 14, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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