Option Explicit ' Optimised Carraghan, R., Pardalos, P. M. ' by using a heuristic vertex colouring and a backtrack search Private moClasses() As Long, mnClassesCount As Long Private level_nodes() As Long, nStart() As Long, NodesNum() As Long ' number of nodes on level Private t As Long, mnMaxClique As Long Private nLevelWAcc() As Long Private nLevelDegree() As Long Private nMaxCliques() As Long ' Public Function Start() As Long Dim i As Long, t_minus_1 As Long, nn As Long, wt As Long ReDim level_nodes(1 To Nodes, 1 To Nodes, 0 To 1) ReDim nMaxCliques(1 To Nodes) '''''' each level has its own set of nodes For i = 1 To Nodes level_nodes(1, i, 0) = i Next ''''''''''''''''''''''''''''''''''' DefineClasses ResortByWeights For i = 1 To Nodes level_nodes(1, i, 1) = i Next ReDim NodesNum(1 To mnClassesCount) ReDim nStart(1 To mnClassesCount) ReDim nLevelDegree(1 To mnClassesCount) ReDim nLevelWAcc(1 To mnClassesCount) NodesNum(1) = Nodes For nn = Nodes To 1 Step -1 t = 2 NodesNum(t) = 0 nLevelWAcc(t) = w(level_nodes(1, nn, 0)) For i = nn + 1 To Nodes If arr(level_nodes(1, nn, 0), level_nodes(1, i, 0)) Then NodesNum(t) = NodesNum(t) + 1 level_nodes(t, NodesNum(t), 0) = level_nodes(1, i, 0) level_nodes(t, NodesNum(t), 1) = level_nodes(1, i, 1) End If Next If NodesNum(t) = 0 Then t = t - 1 If nLevelWAcc(t + 1) > mnMaxClique Then mnMaxClique = nLevelWAcc(t + 1) End If Else nStart(t) = 0 End If While t >= 2 nStart(t) = nStart(t) + 1 If NodesNum(t) < nStart(t) Then t = t - 1 Else If (nLevelWAcc(t) + nMaxCliques(level_nodes(t, nStart(t), 1))) > _ mnMaxClique Then If nStart(t) > 1 Then If (moClasses(level_nodes(t, nStart(t), 0)) <> _ moClasses(level_nodes(t, nStart(t) - 1, 0))) Then nLevelDegree(t) = nLevelDegree(t) - w(level_nodes(t, nStart(t) - 1, 0)) Else nLevelDegree(t) = nLevelDegree(t) - w(level_nodes(t, nStart(t) - 1, 0)) _ + w(level_nodes(t, nStart(t), 0)) End If Else ''' calculate degree on new depth nLevelDegree(t) = LevelDegree() End If If (nLevelWAcc(t) + nLevelDegree(t)) > mnMaxClique Then t_minus_1 = t t = t + 1 nStart(t) = 0 NodesNum(t) = 0 nLevelWAcc(t) = nLevelWAcc(t_minus_1) + _ w(level_nodes(t_minus_1, nStart(t_minus_1), 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), 0), _ level_nodes(t_minus_1, i, 0)) Then NodesNum(t) = NodesNum(t) + 1 level_nodes(t, NodesNum(t), 0) = level_nodes(t_minus_1, i, 0) level_nodes(t, NodesNum(t), 1) = level_nodes(t_minus_1, i, 1) End If Next If NodesNum(t) = 0 Then t = t - 1 If nLevelWAcc(t + 1) > mnMaxClique Then mnMaxClique = nLevelWAcc(t + 1) End If End If Else t = t - 1 End If Else t = t - 1 End If End If Wend nMaxCliques(nn) = mnMaxClique Next ''' return size of maximu clique Start = mnMaxClique End Function Private Sub DefineClasses() Dim class_init() As Boolean '' show if node exists 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, 0) If i <> mnRemainNodes Then ''' swap rows level_nodes(1, i, 0) = level_nodes(1, mnRemainNodes, 0) level_nodes(1, mnRemainNodes, 0) = 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, 0) class_init(nkNode) = arr(nNodeNum, nkNode) Next Else For k = 1 To mnRemainNodes nkNode = level_nodes(1, k, 0) 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, 0)) Then Exit For Next Wend Wend End Sub Private Function LevelDegree() As Long Dim res As Long, i As Long, nClass As Long, aClass As Long For i = NodesNum(t) To nStart(t) Step -1 ''' for node on level define class (moClasses) and mark it as existing nClass = moClasses(level_nodes(t, i, 0)) If nClass <> aClass Then res = res + w(level_nodes(t, i, 0)) aClass = nClass End If Next LevelDegree = res End Function Public Sub ResortByWeights() Dim i As Long, j As Long, maxi As Long, maxw As Long, aClass As Long Dim nNode As Long For i = Nodes To 2 Step -1 maxi = i nNode = level_nodes(1, maxi, 0) maxw = w(nNode) aClass = moClasses(nNode) For j = i - 1 To 1 Step -1 nNode = level_nodes(1, j, 0) If moClasses(nNode) <> aClass Then Exit For If maxw < w(nNode) Then maxi = j maxw = w(nNode) End If Next If i <> maxi Then nNode = level_nodes(1, i, 0) level_nodes(1, i, 0) = level_nodes(1, maxi, 0) level_nodes(1, maxi, 0) = nNode End If Next End Sub