Option Explicit ' Optimised Carraghan, R., Pardalos, P. M. algorithm ' by using a heuristic vertex colouring classes for pruning 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 ' Public Function Start() As Long Dim i As Long, t_minus_1 As Long ReDim level_nodes(1 To Nodes, 1 To Nodes) mnMaxClique = 0 '''''' each level has its own set of nodes For i = 1 To Nodes level_nodes(1, i) = i Next ''''' DefineClasses ReDim NodesNum(1 To mnClassesCount) ReDim nStart(1 To mnClassesCount) ReDim nLevelDegree(1 To mnClassesCount) NodesNum(1) = Nodes t = 1 nStart(t) = 0 ''''''''''''''''''''''''''''''''''' While t >= 1 nStart(t) = nStart(t) + 1 ''' Degree control If NodesNum(t) < nStart(t) Then t = 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 be done since vertices are sorted ''' and if cur. vertex class is not the same as for previous then ''' the prev. class is not any longer existing) If nStart(t) > 1 Then If (moClasses(level_nodes(t, nStart(t))) <> moClasses(level_nodes(t, nStart(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 Then t_minus_1 = t t = t + 1 nStart(t) = 0 NodesNum(t) = 0 ''' define nodes for the next level For i = nStart(t_minus_1) + 1 To NodesNum(t_minus_1) If arr(level_nodes(t_minus_1, nStart(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 If NodesNum(t) = 0 Then t = t - 1 If t > mnMaxClique Then mnMaxClique = t End If End If Else t = t - 1 End If End If Wend ''' return size of maximum 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 = nStart(t) 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 Dim 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(1, i) If i <> mnRemainNodes Then ''' swap rows level_nodes(1, i) = level_nodes(1, mnRemainNodes) level_nodes(1, 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(1, k) class_init(nkNode) = arr(nNodeNum, nkNode) Next Else For k = 1 To mnRemainNodes nkNode = level_nodes(1, k) class_init(nkNode) = arr(nNodeNum, nkNode) Or class_init(nkNode) Next End If bFirstNode = False For i = mnRemainNodes To 1 Step -1 If Not class_init(level_nodes(1, i)) Then Exit For Next Wend Wend End Sub