Как я могу реализовать алгоритм Дейкстры для оптимизации графика смешивания? - PullRequest
0 голосов
/ 07 мая 2019

Я пытаюсь автоматизировать график для объекта смешивания. Я пытаюсь реализовать алгоритм Дейкстры таким образом, чтобы я мог выбрать тип смесей из выпадающего списка и ввести необходимое количество смесей. Это создаст список узлов с заранее определенной стоимостью в зависимости от предыдущей смеси (Blender требует промывки на весь день при переходе от смеси 1 к смеси 2, но не при переходе от смеси 1 к смеси 1 и т. Д.). Начальный и конечный узлы не имеют значения, только то, что все смеси, включая повторы, включены один раз. Конечным продуктом будет список смесей / стирок, выложенных в течение 5 рабочих дней. Я где-то нашел реализацию алгоритма в сети, но не могу связать график затрат (матрицу Excel) с массивом очереди. У меня очень ограниченный опыт, так что я чувствую это немного над головой. Любые указатели приветствуются. Я пытался понять эту реализацию алгоритма, но я не понимаю его достаточно хорошо, чтобы знать, куда идти дальше. Пожалуйста, дайте мне знать, если это даже правильный способ решения этой проблемы.

В настоящее время у меня есть: матрица 6x6 скомпенсированных затрат от a-a, a-b и т. Д .; это втягивается в краевую матрицу. Переменная, равная общему количеству узлов, необходимых для покрытия всех различных смесей. Массив, который заполняет очередь всех необходимых узлов, включая повторы, используя имя смеси и необходимое количество. Переменная, равная количеству разных смесей. Вот где мое понимание рушится. Я попытался связать название последней / текущей смеси со стоимостью, связанной с выполнением любых других смесей, но не знаю, правильно ли я это делаю, потому что я не понимаю, как работает этот алгоритм, несмотря на просмотр учебного пособия после учебного пособия. Из-за этого я совершенно застрял.

    'Dijkstra globals
Option Explicit
Public n, i, j, nn, y, v, u, b, dist, alt, x, z, d, nnn As Single
Const MaxGraph As Integer = 100 'max. number of nodes in graph
Const Infinity = 1E+308
Dim E(1 To MaxGraph, 1 To MaxGraph) As Double  'the edge costs (Infinity if no edge)
Dim A(1 To MaxGraph) As Double                 'the distances calculated
Dim P(1 To MaxGraph) As Integer                'the previous/path array
Dim Q(1 To MaxGraph) As Boolean                'the queue


Public Sub Dijkstra(n, start)

  'simple implementation of Dijkstra's algorithm
  'n = number of nodes in graph
  'start = index of start node
  'init distances A


    For j = 1 To n
      A(j) = Infinity
    Next j
    A(start) = 0
  'init P (path) to "no paths" and Q = set of all nodes
  For j = 1 To n
    Q(j) = True
    P(j) = 0
  Next j

  Do While True 'loop will exit! (see below)
  'find node u in Q with smallest distance to start
    dist = Infinity
    For i = 1 To n
      If Q(i) Then
        If A(i) < dist Then
          dist = A(i)
          u = i
        End If
      End If
    Next i
    If dist = Infinity Then Exit Do 'no more nodes available - done!
    'remove u from Q
    Q(u) = False
    'loop over neighbors of u that are in Q
    For j = 1 To n
        For d = 1 To b

            If queue(u) = "A" Then y = 1
            If queue(u) = "B" Then y = 2
            If queue(u) = "C" Then y = 3
            If queue(u) = "D" Then y = 4
            If queue(u) = "E" Then y = 5
            If queue(u) = "F" Then y = 6
            z = 7
            E(z, y) = Infinity

            If j > 1 And P(j - 1) = "A" Then z = 1
            If j > 1 And P(j - 1) = "B" Then z = 2
            If j > 1 And P(j - 1) = "C" Then z = 3
            If j > 1 And P(j - 1) = "D" Then z = 4
            If j > 1 And P(j - 1) = "E" Then z = 5
            If j > 1 And P(j - 1) = "F" Then z = 6



            If Q(j) And E(z, y) <> Infinity Then
                'check if path to neighbor j via u is shorter than current estimated distance to j
                alt = A(u) + E(z, y)
                If alt < A(j) Then
                    'yes, replace with new distance and remember "previous" hop on the path
                    A(j) = alt
                    P(j) = queue(u)
                    'sched()
                End If
            End If
      Next d
    Next j
  Loop
End Sub

Public Function GetPath(source, target) As String
 'reconstruct shortest path from source to target
 'by working backwards from target using the P(revious) array
 Dim path As String
 If P(target) = 0 Then
   GetPath = "No path"
 Else
   path = ""
   u = target
   Do While P(u) > 0
     path = Format$(u) & " " & path
     u = P(u)
   Loop
   GetPath = Format$(source) & " " & path
 End If
End Function


Public Sub DijkstraTest()
'main function to solve Dijkstra's algorithm and return shortest path between
'a node and every other node in a digraph

' define problem:
' number of nodes


n = Sheets("Main").Range("F33").Value
b = Sheets("Main").Range("F34").Value
Dim quan(1 To 6) As Integer
Dim queue(1 To 18) As String




' reset connection/cost per edge

'(row,column)
For i = 1 To b
  For j = 1 To b
    E(i, j) = Sheets("Main").Cells(33 + i, 8 + j).Value
  Next j
  P(i) = 0
  nn = 1
Next i
nn = 1
nnn = 0

For y = 1 To b
    quan(y) = Sheets("Main").Range("C" & 33 + y).Value

    For x = nn To quan(y) + nnn
        If x > n Then GoTo queued
        queue(x) = Sheets("Main").Range("A" & 33 + y).Value
    Next x
    nnn = quan(y) + nn
    nn = quan(y) + nn
Next y

queued:
'Solve it for every node

For v = 1 To n
  Dijkstra n, v
  'Print solution
  Debug.Print "From", "To", "Cost", "Path"

  For j = 1 To n
    If v <> j Then Debug.Print v, j, IIf(A(j) = Infinity, "---", A(j)), GetPath(v, j)
  Next j

  Debug.Print
Next v
End Sub
...