저는 Vertex Cover Problem에 대한 최소 해결책을 찾으려고하는 프로젝트의 코드를 작성하고 있습니다. 그래프가 주어지면 그래프를 덮는 데 필요한 최소 정점 수를 찾으십시오.
전체 솔루션 공간에서 무차별 대입 검색을위한 프로그램을 작성하려고합니다. 지금 내 코드는 다음을 수행하여 작동합니다.
4 개의 노드를 사용한 예 :
현재 내 코드는 5 개 노드에서 작동합니다. 문제는 고정 된 수의 중첩 while 루프를 사용하여 이러한 순열을 검색한다는 것입니다. 6 개의 노드를 실행하려면 다른 While 루프를 추가해야합니다. 노드 수 자체가 변수가 될 수 있도록 코드를 일반화하려고합니다.
코드는 위의 솔루션 공간을 기반으로 이진수 행을 트리거하여 솔루션을 찾습니다. 예를 들어 시도중인 솔루션이 {1,2,4}이면 첫 번째, 두 번째 및 네 번째 이진 값은 1과 같게 설정됩니다. 세 번째는 0으로 설정됩니다. 이러한 입력을 사용하여 그래프를 포함하는지 여부를 결정하도록 행렬이 설정됩니다. 이것이 어떻게 작동하는지 더 보여주는 그림입니다.
이것을 노드 수에 일반화하는 방법에 대한 아이디어가 있습니까? 재귀에 대한 생각?
또한 코드에는 1 초 동안 대기하는 섹션이 있습니다. 이것은 단지 미학을위한 것이며 코드를보기에 재미있게 만드는 것 외에 어떤 목적도 제공하지 않습니다.
i = 0
j = 0
k = 0
m = 0
Range("Z22").Select
While i < 5 'Checks to see if a single vertice can cover the graph.
Cells(5, 20 + i).Value = 1
Application.Wait (Now + TimeValue("0:00:1"))
If Cells(21, 13).Value = Cells(22, 26).Value Then
GoTo Line1
Else
Cells(5, 20 + i) = 0
i = i + 1
End If
Wend
i = 0
While i < 4 'Checks to see if two vertices can cover the graph
Cells(5, 20 + i).Value = 1
j = i + 1
While j < 5
Cells(5, 20 + j).Value = 1
Application.Wait (Now + TimeValue("0:00:1"))
If Cells(21, 13).Value = Cells(22, 26).Value Then
GoTo Line1
Else
Cells(5, 20 + j) = 0
j = j + 1
End If
Wend
Cells(5, 20 + i) = 0
i = i + 1
Wend
k = 0
While k < 3 'Checks to see if three vertices can cover the graph
Cells(5, 20 + k) = 1
i = k + 1
While i < 4
Cells(5, 20 + i).Value = 1
j = i + 1
While j < 5
Cells(5, 20 + j).Value = 1
Application.Wait (Now + TimeValue("0:00:1"))
If Cells(21, 13).Value = Cells(22, 26).Value Then
GoTo Line1
Else
Cells(5, 20 + j) = 0
j = j + 1
End If
Wend
Cells(5, 20 + i) = 0
i = i + 1
Wend
Cells(5, 20 + k).Value = 0
k = k + 1
Wend
While m < 2 'Checks to see if four vertices can cover the graph
Cells(5, 20 + m).Value = 1
k = m + 1
While k < 3
Cells(5, 20 + k) = 1
i = k + 1
While i < 4
Cells(5, 20 + i).Value = 1
j = i + 1
While j < 5
Cells(5, 20 + j).Value = 1
Application.Wait (Now + TimeValue("0:00:1"))
If Cells(21, 13).Value = Cells(22, 26).Value Then
GoTo Line1
Else
Cells(5, 20 + j) = 0
j = j + 1
End If
Wend
Cells(5, 20 + i) = 0
i = i + 1
Wend
Cells(5, 20 + k).Value = 0
k = k + 1
Wend
Cells(5, 20 + m).Value = 0
m = m + 1
Wend
If Cells(21, 13).Value <> Cells(22, 26).Value Then 'Final effort
Range("T5:X5") = 1
MsgBox ("It takes all five vertices.")
End If
Line1:
Application.DisplayAlerts = True
End Sub
이것은 모든 n에 대한 조합을 만듭니다. 재귀를 사용하지 않습니다. 재귀를 적용 할 수 있을지 생각해야합니다 (더 간단하게 만들까요?).
Option Explicit
Const nnodes = 6
Dim a&(), icol&
Sub Main()
ThisWorkbook.Sheets("sheet1").Activate
Cells.Delete
Dim i&, j&
For i = 1 To nnodes ' from 1 to nnodes
ReDim a(i)
For j = 1 To i ' -- start with 1 up
a(j) = j
Next j
Cells(i, 1) = i ' show
icol = 2 ' for show
Do ' -- show combination and get next combination
Loop While doi(i)
Next i
End Sub
Function doi(i) As Boolean ' show and get next
Dim j&, s$
For j = 1 To i ' build string for show
If j > 1 Then s = s & ","
s = s & Str$(a(j))
Next j
Cells(i, icol) = "{" & s & "}" ' show
icol = icol + 1
' -- get next combination (if)
For j = i To 1 Step -1 ' check if any more
If a(j) < nnodes - i + j Then Exit For
Next j
If j < 1 Then doi = False: Exit Function ' no more
a(j) = a(j) + 1 ' build next combination
While j < i
a(j + 1) = a(j) + 1
j = j + 1
Wend
doi = True
End Function
편집 : "순열"을 "조합"으로 변경했습니다.
EDIT2 : 계속 재귀로 돌아 왔습니다. 코드를 단순화합니다.
Option Explicit
Dim icol& ' for showing combinations
Sub Main() ' get (non-empty) partitions of nnodes
Const nnodes = 6
Dim k&
ThisWorkbook.Sheets("sheet2").Activate
Cells.Delete
For k = 1 To nnodes ' k = 1 to n
Cells(k, 1) = k ' for showing
icol = 2
Call Comb("", 0, 1, nnodes, k) ' combinations(n,k)
Next k
End Sub
Sub Comb(s$, lens&, i&, n&, k&) ' build combination
Dim s2$, lens2&, j&
For j = i To n + lens + 1 - k '
If lens = 0 Then s2 = s Else s2 = s & ", "
s2 = s2 & j
lens2 = lens + 1
If lens2 = k Then ' got it?
Cells(k, icol) = "{" & s2 & "}" ' show combination
icol = icol + 1
Else
Call Comb(s2, lens2, j + 1, n, k) ' recurse
End If
Next j
End Sub
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다