tsp_vb.vb


版权2023、Gurobi优化LLC狗万app足彩“解决旅行商问题对随机产生的一组点使用懒惰的约束。基地MIP模型只包括“2阶的约束,要求每个节点有两个事件的边缘。解决这个模型可能包含subtours——“旅游不访问每个节点。懒惰的约束回调的增加新的约束剿灭他们。进口Gurobi类tsp_vb继承GRBCallback私人var GRBVar(,)公共子新(xvars GRBVar (,)) var = xvars结束子' Subtour取消回调。每当找到可行解,“找到最小的subtour,添加一个subtour消除约束”如果旅游不访问每个节点。保护覆盖子回调()如果在= GRB.Callback试试。MIPSOL然后”发现一个整数可行解——访问每个节点吗?昏暗的n作为整数= vars.GetLength(0)暗之旅为整数()= findsubtour (GetSolution (var))如果旅行。长度< n然后“添加subtour消除约束昏暗expr GRBLinExpr = 0时因为我旅游的整数= 0。长度为j - 1整数= i + 1。长度- 1 expr.AddTerm (1.0, var(旅游(我),旅游(j)))下接下来AddLazy (expr < =。长度- 1)结束,如果结束如果抓住e GRBException控制台。WriteLine(错误代码:& e。ErrorCode &”。 " & e.Message) Console.WriteLine(e.StackTrace) End Try End Sub ' Given an integer-feasible solution 'sol', returns the smallest ' sub-tour (as a list of node indices). Protected Shared Function findsubtour(sol As Double(,)) As Integer() Dim n As Integer = sol.GetLength(0) Dim seen As Boolean() = New Boolean(n - 1) {} Dim tour As Integer() = New Integer(n - 1) {} Dim bestind As Integer, bestlen As Integer Dim i As Integer, node As Integer, len As Integer, start As Integer For i = 0 To n - 1 seen(i) = False Next start = 0 bestlen = n+1 bestind = -1 node = 0 While start < n For node = 0 To n - 1 if Not seen(node) Exit For End if Next if node = n Exit While End if For len = 0 To n - 1 tour(start+len) = node seen(node) = true For i = 0 To n - 1 if sol(node, i) > 0.5 AndAlso Not seen(i) node = i Exit For End If Next If i = n len = len + 1 If len < bestlen bestlen = len bestind = start End If start = start + len Exit For End If Next End While For i = 0 To bestlen - 1 tour(i) = tour(bestind+i) Next System.Array.Resize(tour, bestlen) Return tour End Function ' Euclidean distance between points 'i' and 'j' Protected Shared Function distance(x As Double(), y As Double(), _ i As Integer, j As Integer) As Double Dim dx As Double = x(i) - x(j) Dim dy As Double = y(i) - y(j) Return Math.Sqrt(dx * dx + dy * dy) End Function Public Shared Sub Main(args As String()) If args.Length < 1 Then Console.WriteLine("Usage: tsp_vb nnodes") Return End If Dim n As Integer = Convert.ToInt32(args(0)) Try Dim env As New GRBEnv() Dim model As New GRBModel(env) ' Must set LazyConstraints parameter when using lazy constraints model.Parameters.LazyConstraints = 1 Dim x As Double() = New Double(n - 1) {} Dim y As Double() = New Double(n - 1) {} Dim r As New Random() For i As Integer = 0 To n - 1 x(i) = r.NextDouble() y(i) = r.NextDouble() Next ' Create variables Dim vars As GRBVar(,) = New GRBVar(n - 1, n - 1) {} For i As Integer = 0 To n - 1 For j As Integer = 0 To i vars(i, j) = model.AddVar(0.0, 1.0, distance(x, y, i, j), _ GRB.BINARY, "x" & i & "_" & j) vars(j, i) = vars(i, j) Next Next ' Degree-2 constraints For i As Integer = 0 To n - 1 Dim expr As GRBLinExpr = 0 For j As Integer = 0 To n - 1 expr.AddTerm(1.0, vars(i, j)) Next model.AddConstr(expr = 2.0, "deg2_" & i) Next ' Forbid edge from node back to itself For i As Integer = 0 To n - 1 vars(i, i).UB = 0.0 Next model.SetCallback(New tsp_vb(vars)) model.Optimize() If model.SolCount > 0 Then Dim tour As Integer() = findsubtour(model.Get(GRB.DoubleAttr.X, vars)) Console.Write("Tour: ") For i As Integer = 0 To tour.Length - 1 Console.Write(tour(i) & " ") Next Console.WriteLine() End If ' Dispose of model and environment model.Dispose() env.Dispose() Catch e As GRBException Console.WriteLine("Error code: " & e.ErrorCode & ". " & e.Message) Console.WriteLine(e.StackTrace) End Try End Sub End Class