Я пытаюсь автоматизировать график для объекта смешивания. Я пытаюсь реализовать алгоритм Дейкстры таким образом, чтобы я мог выбрать тип смесей из выпадающего списка и ввести необходимое количество смесей. Это создаст список узлов с заранее определенной стоимостью в зависимости от предыдущей смеси (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