Роман Артемьев
Посетитель
Всего сообщений: 13
Дата регистрации: 27.01.2017
|
Создано:
27.01.2017 21:27:16
|
Добрый день, уважаемые пользователи форума.
Пишу макрос. Суть такова: определяем перегруженные ветви в сети. Заносим их в отдельную таблицу.
Вопрос. Допустим у меня есть перегруженная ветвь. узлы 1-2. 1 - начальный узел , 2 - конечный узел. Можно ли как - то определить, какие узлы подключены ко второму узлу и затем какие узлы подключены к узлам, подключенным к узлу 2? К примеру, есть узел 2. К нему присоединены 3,4,5. К узлам 3,4,5 подключены 6,7,8 соответственно и т.д.
Заранее спасибо за помощь!
|
|
|
Евгений Машалов
Администратор
Всего сообщений: 1059
Дата регистрации: 23.04.2007
|
Создано:
28.01.2017 00:16:36
|
В комплекте RastrWin3 есть макрос "включить остров с ветвями". Изучите его на предмет работы с базой данных. Алгоритм, который Вы хотите реализовать называется DFS. Если что, есть еще BFS.
|
|
|
Роман Артемьев
Посетитель
Всего сообщений: 13
Дата регистрации: 27.01.2017
|
Создано:
29.01.2017 20:37:04
|
Спасибо, Евгений, могли бы Вы загрузить данный макрос сюда? Не могу найти его у себя в папке macro
|
|
|
Евгений Машалов
Администратор
Всего сообщений: 1059
Дата регистрации: 23.04.2007
|
Создано:
29.01.2017 20:43:14
|
Documents\RastrWin3\contextmacro\in_ostrov.rbs
|
|
|
Роман Артемьев
Посетитель
Всего сообщений: 13
Дата регистрации: 27.01.2017
|
Создано:
07.02.2017 16:29:24
|
Добрый вечер, Евгений!
Могли бы Вы подсказать, как можно решить проблему: пытаюсь работать с массивами, чтобы сократить количество дополнительно создаваемых таблиц. Массивы с заданным колвом элементов растр позволяет создавать, а при создании массива с () размером возникает ошибка с диапазоном: "индекс выходит за пределы допустимого диапазона" и адресует на выделенную строку
Код |
---|
Dim EndNodesArr()
Rastr.PrintP "конечные узлы: "
for i=0 to Mount-1
EndNodesArr(i)=EndNodes.Z(i)
if EndNodesArr(i)<>0 then
Rastr.PrintP EndNodesArr(i)
end if
next |
*В столбце EndNodes 15 строк(т.е. для растра 14). Mount = 15
а если задаю верхнюю границу массива как
Код |
---|
Dim EndNodesArr(spLoad.Size) | , то выдает ошибку следующего рода: "предполагается наличие константы целого типа."
Заранее спасибо!
|
|
|
bogdanov
Модератор
Всего сообщений: 61
Дата регистрации: 11.10.2012
|
Создано:
07.02.2017 16:59:54
|
Код |
---|
ReDim EndNodesArr(Mount) |
Подробнее про VBScript
|
|
|
Михаил Реутов
Постоянный посетитель
Всего сообщений: 224
Дата регистрации: 21.11.2007
|
Создано:
10.02.2017 16:10:50
|
Также рекомендую использовать объект Dictionary. Это "типо" массив с произвольным количеством элементов.
Пример использования:
Код |
---|
Set Dict = CreateObject("Scripting.Dictionary")
Dict.Add "a", "One"
Dict.Add 1, "Two"
Dict.Item(1) = "Один"
Dict.Item("a") = "Два"
For Each d In Dict.Items
MsgBox d
Next
|
|
|
|
Роман Артемьев
Посетитель
Всего сообщений: 13
Дата регистрации: 27.01.2017
|
Создано:
27.02.2017 13:16:14
|
Спасибо, Михаил, полезный объект!
|
|
|
Роман Артемьев
Посетитель
Всего сообщений: 13
Дата регистрации: 27.01.2017
|
Создано:
27.02.2017 13:17:12
|
Цитата |
---|
Код
ReDim EndNodesArr(Mount)
Подробнее про VBScript |
Спасибо за помощь
|
|
|
Роман Артемьев
Посетитель
Всего сообщений: 13
Дата регистрации: 27.01.2017
|
Создано:
28.02.2017 09:51:36
|
|
Добрый день, уважаемые форумчане!
Возвращаясь к своему первому вопросу, хочу сказать, что пока что не пришло полное понимание, как можно реализовать DFS в Rastr'e...
Рассмотрел макрос in_ostrov, понял, что он выполняет функцию поиска ветвей подключенных к данному узлу ny и далее, если ip=ny=n, то nf = iq , тем самым мы можем идти в глубину подструктуры, определяя ветви, связанные прямо или косвенно с перегруженной ветвью.
На данный момент получилось реализовать поиск узлов (подузлов), подключенных к конечному узлу перегруженного элемента. Подузлы могут быть расположены на разных подуровнях. Минус в том, что написанный код не ищет подузлы до самой глубины ветви, а производит поиск ограниченное число раз в зависимости от количества заданных подуровней.
Если у Вас будут мысли, как можно зациклить процедуру поиска до самой глубины, буду премного Вам благодарен.
Еще один минус заключается в том, что если ветвь, к примеру, 10-12 будет задана как 12-10, то подузел 12 не будет определен...
Прикрепляю код:
Код |
---|
Mount = 0 ' найденные узлы сохраняю в таблице, поэтому нужен счетчик строк для столбца EndNodes
for m=0 to spLoad.Size-1 ' spLoad - таблица перегруженных элементов
EndNodes.Z(Mount)=spLiq.Z(m) ' заносим конечные узлы перегруженных элементов в столбец EndNodes
Mount=Mount+1 ' переходим на след. строку
next
Qount=0 ' счетчик для столбца SubNodes
for k = 0 to Mount-1
spVetv.SetSel ("ip="&EndNodes.Z(k)) ' ищем ветви, ip которых являются конечные узлы перегруженных элементов
Index = spVetv.FindNextSel(-1)
while Index <>-1
SubNodes.Z(Qount)=spIq.Z(Index) ' записываем узлы первого подуровня в столбец SubNodes
Index=spVetv.FindNextSel(Index)
Qount=Qount+1
wend
next
Tount=0 ' счетчик для столбца SubSubNodes. тот же принцип: ищем узлы, подключенные к узлам из столбца SubNodes
for p = 0 to Qount
spVetv.SetSel ("(ip="&SubNodes.Z(p)&")&!sta")
Index1 = spVetv.FindNextSel(-1)
while Index1 <>-1
if SubNodes.Z(p)>0 then
SubSubNodes.Z(Tount)=spIq.Z(Index1) ' сохраняем найденные узлы в столбец SubSubNodes
Index1=spVetv.FindNextSel(Index1)
Tount=Tount+1
end if
wend
next
Iount=0
for r = 0 to Tount
spVetv.SetSel "ip="&SubSubNodes.Z®
Index2 = spVetv.FindNextSel(-1)
while Index2 <>-1
if SubSubNodes.Z®>0 then
SubSubSubNodes.Z(Iount)=spIq.Z(Index2)
Index2=spVetv.FindNextSel(Index2)
Iount=Iount+1
end if
wend
next
Eount=0
for v = 0 to Iount
spVetv.SetSel ("ip="&SubSubSubNodes.Z(v))
Index3 = spVetv.FindNextSel(-1)
while Index3 <>-1
if SubSubSubNodes.Z(v)>0 then
SubSubSubSubNodes.Z(Eount)=spIq.Z(Index3)
Index3=spVetv.FindNextSel(Index3)
Eount=Eount+1
end if
wend
next
|
Получилось 4 подуровня.
Заранее спасибо за помощь!
|
|
|
bogdanov
Модератор
Всего сообщений: 61
Дата регистрации: 11.10.2012
|
Создано:
28.02.2017 13:58:42
|
|
DFS это способ обхода графа.
Обходить граф по списку ребер (таблица "Ветви") не самая лучшая идея.
Стоит преобразовать список ребер в список смежности и работать уже с этой структурой.
Например:
Код |
---|
Set adj = CreateObject("Scripting.Dictionary") 'список смежности
set vetv = Rastr.Tables("vetv")
set v_ip = vetv.Cols("ip")
set v_iq = vetv.Cols("iq")
'формируем список смежности
For i=0 to vetv.Size-1
ip = v_ip.Z(i)
iq = v_iq.Z(i)
IF adj.Exists(ip) Then
adj.Item(ip).Add(iq)
Else
Set list = CreateObject("System.Collections.ArrayList")
list.Add(iq)
adj.Add ip, list
End if
IF adj.Exists(iq) Then
adj.Item(iq).Add(ip)
Else
Set list = CreateObject("System.Collections.ArrayList")
list.Add(ip)
adj.Add iq, list
End if
Next
' печать содержимого
k = adj.Keys
itm = adj.Items
For i=0 to adj.Count-1
Rastr.printp CStr(k(i)) + " -> "+ join(itm(i).ToArray(), ", ")
Next
|
Use case:
Код |
---|
set list = adj.item( номер_узла ) ' вернет список смежных узлов
For Each id In list 'обход списка
Rastr.Printp id
Next
|
|
|
|
Роман Артемьев
Посетитель
Всего сообщений: 13
Дата регистрации: 27.01.2017
|
Создано:
03.03.2017 13:26:51
|
|
bogdanov,
спасибо большое! Изменил этапы алгоритма, только с использованием списка смежности у меня опять получается, что сколько уровней поиска подузлов я задам, столько макрос и найдет. Допустим, если уровней 50, а я задал поиск только для 45, то другие 5 не будут определены. Как напишу, загружу сюда.
Возник также небольшой вопрос по работе с ArrayList. Пример:
Код |
---|
Set list = CreateObject("System.Collections.ArrayList")
a = 10
b = 20
c = 30
list.Add(a)
list.Add(b)
list.Add©
for i=0 to list.Count-1
Rastr.PrintP list.Item(i)
next
for k=0 to list.Count-1
if list.Item(k) = a then
list.RemoveAt(k)
end if
next
Rastr.Printp ""
for l=0 to list.Count-1
Rastr.Printp list.Item(l)
next |
Если я задаю очередь добавления чисел в массив как: a,b,c и затем хочу удалить из массива элемент, равный a, то возникает ошибка: "Индекс за пределами диапазона. Индекс должен быть положительным числом , а его размер не должен превышать размер коллекции. Имя параметра index"
Если же я хочу удалить элемент, равный c, который был добавлен в массив последним, то тогда все благополучно удаляется и на выходе мы получаем:
10
20
30
10
20
Заранее спасибо за помощь!
|
|
|
Евгений Машалов
Администратор
Всего сообщений: 1059
Дата регистрации: 23.04.2007
|
Создано:
03.03.2017 14:31:04
|
for/next определяет количество итераций и инкремент в заголовке один раз. Поэтому, когда Вы удаляете элемент с индексом, скажем - 0, то следующая итерация приходит уже на индекс 1, несмотря на то что список сдвинулся и у Вас снова есть нулевой элемент. Кроме того, текущий размер списка никак не влияет на цикл и он в конце концов выходит на несуществующий индекс.
Совет 1: использовать while/wend или do/loop.
Совет 2: этот форум про RastrWin. Про программирование это примерно тут
|
|
|
Роман Артемьев
Посетитель
Всего сообщений: 13
Дата регистрации: 27.01.2017
|
Создано:
05.03.2017 07:54:44
|
Евгений Машалов,
Спасибо Евгений! Я вас понял, с изменяемым размером коллекции разобрался).
Подскажите пожалуйста, возможно ли, чтобы одна выборка сбивалась следующей выборкой по той же таблице?
Пример:
Код |
---|
выборка1 по spVetv
index1 = spVetv.FindNextSel(-1)
while index1 <> -1
выполнение некоторых операций
выборка2 по spVetv
index2 = spVetv.FindNextSel(-1)
while index2 <> -1
выполнение некоторых операций
index2 = spVetv.FindNextSel(index2)
wend
index1 = spVetv.FindNextSel(index1)
wend |
|
|
|
Евгений Машалов
Администратор
Всего сообщений: 1059
Дата регистрации: 23.04.2007
|
Создано:
05.03.2017 13:43:44
|
SetSel устанавливает атрибут поиска для объекта ITable. Объект у Вас один, поэтому вторая выборка заменяет первую, а заодно заменяет список индексов, в которых найдены соответствующие выборке строки. Чтобы сделать выборки независимыми - создайте второй ITable - скажем - spVetv2 и вторую выборку применяйте к нему. Но в данном случае у меня есть твёрдая уверенность что от второй выборки можно избавиться и обойтись только внешней.
|
|
|
Роман Артемьев
Посетитель
Всего сообщений: 13
Дата регистрации: 27.01.2017
|
Создано:
06.03.2017 13:34:17
|
Евгений Машалов,
Спасибо, проблема решена!
|
|
|
Роман Артемьев
Посетитель
Всего сообщений: 13
Дата регистрации: 27.01.2017
|
Создано:
06.03.2017 15:20:13
|
|
Возник еще один вопрос по RastrWin.
Примерная структура макроса:
)Загрузка rg2 файла: Rastr.Load 1, "path", ""
)Задание ссылок на таблицы и столбцы:
set table = Rastr.Tables("table")
set column = table.Cols("column")
)Расчеты и т.п.
)Вывод результатов
Скажите пожалуйста, верно ли я понимаю, что, если у нас возникает необходимость снова загрузить оригинальный файл режима, допустим в части "Расчеты и т.п.", то понадобится по-новой создавать ссылки на таблицы/столбцы? иначе если после каждой загрузки оригинального файла режима не задать ссылки на таблицы/столбцы Rastr начинает ругаться.
Вот как пример:
Возникает ошибка: 3629277Разборка формулы "pn>0&qn>0": Идентификатор не найден (qn)
Код |
---|
set spVetv1 = Rastr.Tables("vetv")
set spNode1 = Rastr.Tables("node")
set spPn = spNode1.Cols("pn")
set spQn = spNode1.Cols("qn")
for i=0 to 3
Rastr.Load 1,"path",""
spNode1.SetSel ("pn>0&qn>0")
index = spNode1.FindNextSel(-1)
while index <> -1
spPn.Z(index)=spPn.Z(index)+spPn.Z(index)*0.01*i
spQn.Z(index)=spQn.Z(index)+spQn.Z(index)*0.01*i
index=spNode1.FindNextSel(index)
wend
Rastr.rgm ("")
next |
В этом случае ошибки не возникает
Код |
---|
for i=0 to 3
Rastr.Load 1,"path",""
set spVetv1 = Rastr.Tables("vetv")
set spNode1 = Rastr.Tables("node")
set spPn = spNode1.Cols("pn")
set spQn = spNode1.Cols("qn")
spNode1.SetSel ("pn>0&qn>0")
index = spNode1.FindNextSel(-1)
while index <> -1
spPn.Z(index)=spPn.Z(index)+spPn.Z(index)*0.01*i
spQn.Z(index)=spQn.Z(index)+spQn.Z(index)*0.01*i
index=spNode1.FindNextSel(index)
wend
Rastr.rgm ("")
next |
|
|
|
Евгений Машалов
Администратор
Всего сообщений: 1059
Дата регистрации: 23.04.2007
|
Создано:
06.03.2017 16:17:40
|
Да
|
|
|
Михаил Реутов
Постоянный посетитель
Всего сообщений: 224
Дата регистрации: 21.11.2007
|
Создано:
09.03.2017 18:26:45
|
Цитата |
---|
Если у Вас будут мысли, как можно зациклить процедуру поиска до самой глубины, буду премного Вам благодарен. |
Рекурсивный вызов функции. Это когда функция вызывается внутри той же функции и т.д. Глубина может быть любой. Главное корректно задать условия вызова очередной функции.
|
|
|
Роман Артемьев
Посетитель
Всего сообщений: 13
Дата регистрации: 27.01.2017
|
Создано:
26.03.2017 10:56:23
|
|
Добрый день! Подскажите пожалуйста, если есть решение данной проблемы:
Есть ветвь ip-iq. В узле iq есть нагрузка. Также генерация в узле iq, допустим 0,002 МВт. При изменении генерации с 0,002 + 0,001. Первые одно-два изменения, загрузка ветви ip-iq меняется. Затем нет: с изменением генерации загрузка ветви не меняется, если приращение генерации у нас 0,001.
Если же мы изменим в один шаг генерацию с 0,002 до 0,1, то загрузка изменится.
Например: узел iq нагрузка 18 кВт. Загрузка ветви: 12,541170 %. Подключаем генерацию к узлу iq 9 кВт.
После расчета режима. Загрузка ветви не изменилась...
При подключении 10 кВт. Загрузка резко изменяется на 7,198735 %.
Почему при малом приращении(изменении) генерации в узле, загрузка в ветви не изменяется? Быть может нужно изменить какие-либо настройки в растре, чтобы он при малых изменениях, рассчитывал загрузку по-новой.
Расчет режима производится после каждого изменения.
Точность столбца i_zag: Prop(3) = 15.
Заранее спасибо!
Добавлено
Еще наблюдение: есть ветвь. Потери dp = 40.62 кВт. от данной ветви отходят 10 узлов с одинаковыми нагрузками 18 кВт. К каждому из узлов подключаем генератор с мощностью 10 кВт.
Потери в ветви изменяются. Затем увеличиваем мощность генераторов до 11 кВт. Потери в ветви не изменяются... Резко увеличиваем мощность генераторов до 50 кВт. Потери изменяются. После этого уменьшаем генерацию до 11 кВт и ... потери в ветви изменяются.
|
|
|
Евгений Машалов
Администратор
Всего сообщений: 1059
Дата регистрации: 23.04.2007
|
Создано:
26.03.2017 21:40:17
|
Может точность расчета УР увеличить ?
Код |
---|
rastr.tables("com_regim").cols("neb_p").Z(0) = 1E-6 |
|
|
|
Роман Артемьев
Посетитель
Всего сообщений: 13
Дата регистрации: 27.01.2017
|
Создано:
26.03.2017 23:07:53
|
Евгений Машалов,
Спасибо, Евгений! Возможность видеть какие-то изменения появилась при 1E-10. Правда при такой точности "Превышено предельное число итераций".
Поискал информацию на neb_p, нашел) com_regim это, видимо, какой-то объект?
В разделе 14.3 документации пользователя представлены различные таблицы и возникла сложность с пониманием, как вызвать некоторые параметры...
Допустим, хочу я посчитать кол-во отключенных узлов. Я могу использовать, как вариант, выборку и счетчик, а могу воспользоваться параметром "ny_o". Как я могу его вызвать? (Например: Rastr.PrintP ny_o или sum("node","1","sta") - при этих командах он ругается =) )
Или еще мне интересна минимизация потерь в ветвях и я нашел параметр min_pot. Аналогичный вопрос, как добраться до данного параметра?
И еще вопрос: есть ли возможность пошагово исполнять каждую строчку кода? Какой-нибудь debug?
|
|
|
Евгений Машалов
Администратор
Всего сообщений: 1059
Дата регистрации: 23.04.2007
|
Создано:
26.03.2017 23:50:28
|
com_regim это таблица. Вы же вроде бы макросы писали, синтаксис предложенной выше конструкции должен быть Вам понятен.
Количество отключенных узлов рассчитывается в таблице "Общая информация". Добраться из макроса:
Код |
---|
Rastr.PrintP Rastr.Tables("com_cxema").Cols("ny_o").Z(0) |
min_pot доступен в "Общие параметры оптимизации" : com_optim
Отладчик в новой версии имеется
http://www.rastrwin.ru/rastr/modification.php
п. 13.
|
|
|
Роман Артемьев
Посетитель
Всего сообщений: 13
Дата регистрации: 27.01.2017
|
Создано:
28.03.2017 18:00:05
|
Евгений Машалов, прошу прощения, не обратил внимания, что структура вызова такая же как и для столбцов в таблицах "vetv" или "node".
|
|
|