Накопление одностороннего потока через узлы сети

avatar
Jürgen O.
8 августа 2021 в 15:54
42
0
0

Я пытаюсь рассчитать поток через (маленькую) сеть с помощью GNU Octave.

У меня есть данные из узлов сети, сформированные как

nodes(1,:) = {100,NaN};
nodes(2,:) = {150,1};
nodes(3,:) = {200,2};
nodes(4,:) = {100,NaN};
nodes(5,:) = {50,4};
nodes(6,:) = {200,[3,7]};
nodes(7,:) = {350,5};

где первое значение представляет собой поток, а второе значение представляет собой количество узлов выше по течению, к которым подключен фактический узел (все они являются «узлами», даже если некоторые из них нет реального пересечения, потому что в модели больше притока, но из других перечисленных узлов...).

Итак, мне нужен совокупный поток (от восходящего к нисходящему) через фактический узел:

nodes(1,:) = {100,NaN,100};
nodes(2,:) = {150,1,250};
nodes(3,:) = {200,2,450};
nodes(4,:) = {100,NaN,100};
nodes(5,:) = {50,4,150};
nodes(6,:) = {200,[3,7],800};
nodes(7,:) = {350,5,450};

Это примеры значений. Реальные данные могут быть немного более обширными, но на данный момент есть только один или два узла восходящего потока (ЕСЛИ есть решение для большего количества, мне все равно интересно).

clear; clear all;

% data:
nodes(1,:) = {100,NaN};
nodes(2,:) = {150,1};
nodes(3,:) = {200,2};
nodes(4,:) = {100,NaN};
nodes(5,:) = {50,4};
nodes(6,:) = {200,[3,7]};
nodes(7,:) = {350,5};

flow     = nodes(:,1);
upstream = nodes(:,2);

% loop to cumulate the flow
for i=1:length(nodes)
  
  % first setting the flow in the starting point(s)
  if isnan(cell2mat((nodes(i,[2]))))
      nodes(i,[3]) = flow(i);
  
  % then calculate the flow through the other nodes(s)
  else
      addnode=cell2mat(upstream(i));
      for j=1:length(addnode)
          nodes(i,[3]) = flow(i);
          nodes(i,[3]) = cell2mat(nodes(i,[3]))+cell2mat(nodes(addnode(j),3));
      endfor
  endif
end

что меня заводит

>> nodes(:,3)
ans =
{
  [1,1] =  100
  [2,1] =  250
  [3,1] =  450
  [4,1] =  100
  [5,1] =  150
  [6,1] = [](0x0)
  [7,1] =  500
}

Думаю, потому что алгоритм вычисляет плюс NaN = пусто, когда дело доходит до узлов(6,:), которые содержат поток от узла(7,:), который в данный момент не вычисляется.

Я имею в виду что-то вроде каскада, в котором сначала вычисляются узлы с одним вышестоящим узлом, но это не распространяется на случаи, когда один узел получает поток от узла пересечения, или случай, когда существуют два узла пересечения и их порядок в список «неправильный»:

clear; clear all;

nodes(1,:) = {100,NaN};
nodes(2,:) = {150,1};
nodes(3,:) = {200,2};
nodes(4,:) = {100,NaN};
nodes(5,:) = {50,4};
nodes(6,:) = {200,[3,7]};
nodes(7,:) = {300,5};
nodes(8,:) = {100,NaN};
nodes(9,:) = {200,6};
nodes(10,:) = {300,[8 9]};

flow     = nodes(:,1);
upstream = nodes(:,2);

for i=1:length(nodes)
  if isnan(cell2mat((nodes(i,[2]))))
      nodes(i,[3]) = flow(i);
  else
      addnode=cell2mat(upstream(i));
      for j=1:length(addnode)
          if length(addnode) == 1;
            nodes(i,[3]) = cell2mat(flow(i))+cell2mat(nodes(addnode(j),3));
          endif
      endfor
  endif
end

for i=1:length(nodes)
  if ~isnan(cell2mat((nodes(i,[2]))))
    addnode=cell2mat(upstream(i));
    if length(addnode) != 1
      nodes(i,[3]) = cell2mat(flow(i));
      for j=1:length(addnode)
          nodes(i,[3]) = cell2mat(nodes(i,[3]))+cell2mat(nodes(addnode(j),3));
      endfor
    endif
  endif
endfor

выход:

nodes(:,3)
ans =
{
  [1,1] =  100
  [2,1] =  250
  [3,1] =  450
  [4,1] =  100
  [5,1] =  150
  [6,1] =  1100
  [7,1] =  450
  [8,1] =  100
  [9,1] = [](0x0)
  [10,1] = [](0x0)
}

Есть ли передовой опыт для такого рода задач?

Источник

Ответы (0)