问题
I am attempting to automate the schedule for a blending facility. I am trying to implement Dijkstra's algorithm in a way that will allow me to select the type of blends from a drop down list, and input the quantity of blends needed. This will generate a list of nodes with a predetermined cost depending on the previous blend (Blender requires a full-day wash when switching from blend 1 to blend 2, but not when going from blend 1 to blend 1 etc). The starting and ending nodes don't matter, only that all of the blends including the repeats are included once. The end product will be a list of blends/washes laid out over a series of 5 day work-weeks. I found an implementation of the algorithm online somewhere, but I cant seem to relate the cost graph (excel matrix) to the queue array. I have very limited experience so this feels a bit over my head. Any pointers are welcomed. I have tried to understand this implementation of the algorithm, but I don't understand it well enough to know where to go from here. Please let me know if this is even the right way to approach this problem.
I currently have: A 6x6 matrix of made up costs from a-a, a-b etc; that is pulled into an edge matrix. A variable equal to the total number of nodes needed to cover all of the different blends. An array that is fills a queue of all the nodes needed, including repeats using the name of the blend and the quantity needed. A variable equal to the number of different blends. This is where my understanding falls apart. I have attempted to relate the name of last/current blend with the cost associated with doing any of the other blends, but have no idea if I am doing this correctly because I do not understand how this algorithm functions, despite watching tutorial after tutorial. Because of this, I find myself completely stuck.
'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
来源:https://stackoverflow.com/questions/56027779/how-can-i-implement-dijkstras-algorithm-to-optimize-a-blending-schedule