Option
Explicit
' Optimised
Carraghan, R., Pardalos, P.
M. algorithm
' by
using a heuristic vertex colouring classes for pruning' and a backtrack search
by
' colour
classes
Private moClasses()
As Long, mnClassesCount As Long
Private nLevelDegree()
As Long
Private level_nodes()
As Long, nStart() As Long, NodesNum()
As Long
Private t
As Long, mnMaxClique As Long
Private nMaxCliques()
As Long
'
Public
Function Start() As Long
Dim i As Long,
t_minus_1 As Long, nn As Long
ReDim level_nodes(0
To Nodes, 1 To Nodes)
mnMaxClique
= 0
'''''' each level has its own set of nodes
For i = 1 To Nodes
level_nodes(0, i) = i
Next
'''''
DefineClasses
ReDim NodesNum(0
To mnClassesCount + 1)
ReDim nStart(1
To mnClassesCount + 1)
ReDim nLevelDegree(1
To mnClassesCount + 1)
ReDim nMaxCliques(1
To Nodes)
NodesNum(1) = 0
For nn = 1 To mnClassesCount
t = 1
nStart(1) = 0
For i = Nodes To 1 Step -1
If moClasses(level_nodes(0, i)) <= nn Then
nStart(1) = nStart(1) + 1
level_nodes(1, nStart(1))
= level_nodes(0, i)
Else
Exit For
End If
Next
NodesNum(1) = nStart(1)
nMaxCliques(nn) = Nodes
While t >= 1
''' Degree control
If NodesNum(t) < 1 Then
t = t - 1
NodesNum(t) = NodesNum(t) - 1
Else
''' if it is not first node (for fist
node degree can not be adjusted)
''' and prev.
node class is not the same then decrease degree (can do since vertices are
sorted
''' and if cur.
vertex class is not the same as for previous then prev class is not any longer existing)
If nStart(t) > NodesNum(t) Then
If (moClasses(level_nodes(t, NodesNum(t))) <>
moClasses(level_nodes(t, NodesNum(t) + 1))) Then
nLevelDegree(t) = nLevelDegree(t) - 1
End If
Else
''' calculate degree on new depth
nLevelDegree(t) = LevelDegree()
End If
If ((t - 1 + nLevelDegree(t)) <= mnMaxClique) Or _
((t - 1 + nMaxCliques(moClasses(level_nodes(t, NodesNum(t))))) <= mnMaxClique)
Then
t = t - 1
NodesNum(t) = NodesNum(t) - 1
Else
t_minus_1 = t
t = t + 1
NodesNum(t) = 0
''' define nodes for the next level
For i = 1
To NodesNum(t_minus_1) - 1
If arr(level_nodes(t_minus_1,
NodesNum(t_minus_1)), level_nodes(t_minus_1,
i)) Then
NodesNum(t) = NodesNum(t) + 1
level_nodes(t, NodesNum(t))
= level_nodes(t_minus_1, i)
End If
Next
nStart(t) = NodesNum(t)
If NodesNum(t) = 0 Then
t = t - 1
NodesNum(t) = NodesNum(t) - 1
If t > mnMaxClique
Then
mnMaxClique = t
t = 0
End If
End If
End If
End If
Wend
nMaxCliques(nn) = mnMaxClique
Next
''' return size of maximu
clique
Start = mnMaxClique
End
Function
Private
Function LevelDegree() As Long
Dim res As Long, i
As Long, nClass As Long, aClass
As Long
For i = 1 To NodesNum(t)
''' for node on level define class (moClasses) and mark it as existing
nClass
= moClasses(level_nodes(t, i))
If nClass
<> aClass Then
aClass
= nClass
res = res + 1
End If
Next
LevelDegree = res
End Function
Private Sub
DefineClasses()
Dim class_init() As Boolean '' show if
node exist
Dim i As Long, k As Long
Dim mnRemainNodes
As Long, bFirstNode As Boolean, nkNode
As Long, nNodeNum As Long
mnClassesCount
= 0
ReDim class_init(1
To Nodes)
''' get info about existing nodes
ReDim moClasses(1
To Nodes)
'''''
mnRemainNodes
= Nodes
While True
''' build up new class
mnClassesCount
= mnClassesCount + 1
bFirstNode
= True
''' position of first node
i = mnRemainNodes
While i > 0
''' swap nodes
nNodeNum
= level_nodes(0, i)
If i <> mnRemainNodes Then
''' swap rows
level_nodes(0, i)
= level_nodes(0, mnRemainNodes)
level_nodes(0, mnRemainNodes)
= nNodeNum
End If
'''
moClasses(nNodeNum) = mnClassesCount
mnRemainNodes
= mnRemainNodes - 1
If mnRemainNodes
= 0 Then Exit Sub
If bFirstNode
Then
For k = 1 To mnRemainNodes
nkNode
= level_nodes(0, k)
class_init(nkNode)
= arr(nNodeNum, nkNode)
Next
bFirstNode
= False
Else
For k = 1 To mnRemainNodes
nkNode
= level_nodes(0, k)
class_init(nkNode)
= arr(nNodeNum, nkNode) Or class_init(nkNode)
Next
End If
For i = mnRemainNodes To 1 Step -1
If Not class_init(level_nodes(0,
i)) Then Exit For
Next
Wend
Wend
End Sub