How can I implement dijkstra's algorithm to optimize a blending schedule?

两盒软妹~` 提交于 2019-12-25 00:08:33

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!