multiobj_vb.vb#

' Copyright 2025, Gurobi Optimization, LLC

' Want to cover four different sets but subject to a common budget of
' elements allowed to be used. However, the sets have different priorities to
' be covered; and we tackle this by using multi-objective optimization.

Imports Gurobi

Class multiobj_vb

    Shared Sub Main()

        Try
            ' Sample data
            Dim groundSetSize As Integer = 20
            Dim nSubsets As Integer = 4
            Dim Budget As Integer = 12

            Dim [Set] As Double(,) = New Double(,) { _
                {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, _
                {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1}, _
                {0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0}, _
                {0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0}}

            Dim SetObjPriority As Integer() = New Integer() {3, 2, 2, 1}
            Dim SetObjWeight As Double() = New Double() {1.0, 0.25, 1.25, 1.0}
            Dim e As Integer, i As Integer, status As Integer, nSolutions As Integer

            ' Create environment
            Dim env As New GRBEnv("multiobj_vb.log")

            ' Create initial model
            Dim model As New GRBModel(env)
            model.ModelName = "multiobj_vb"

            ' Initialize decision variables for ground set:
            ' x[e] == 1 if element e is chosen for the covering.
            Dim Elem As GRBVar() = model.AddVars(groundSetSize, GRB.BINARY)
            For e = 0 To groundSetSize - 1
                Dim vname As String = "El" & e.ToString()
                Elem(e).VarName = vname
            Next

            ' Constraint: limit total number of elements to be picked to be at most
            ' Budget
            Dim lhs As New GRBLinExpr()
            For e = 0 To groundSetSize - 1
                lhs.AddTerm(1.0, Elem(e))
            Next
            model.AddConstr(lhs, GRB.LESS_EQUAL, Budget, "Budget")

            ' Set global sense for ALL objectives
            model.ModelSense = GRB.MAXIMIZE

            ' Limit how many solutions to collect
            model.Parameters.PoolSolutions = 100

            ' Set and configure i-th objective
            For i = 0 To nSubsets - 1
                Dim vname As String = String.Format("Set{0}", i)
                Dim objn As New GRBLinExpr()
                For e = 0 To groundSetSize - 1
                    objn.AddTerm([Set](i, e), Elem(e))
                Next

                model.SetObjectiveN(objn, i, SetObjPriority(i), SetObjWeight(i), _
                                    1.0 + i, 0.01, vname)
            Next

            ' Save problem
            model.Write("multiobj_vb.lp")

            ' Optimize
            model.Optimize()

            ' Status checking
            status = model.Status

            If status = GRB.Status.INF_OR_UNBD OrElse _
               status = GRB.Status.INFEASIBLE OrElse _
               status = GRB.Status.UNBOUNDED Then
                Console.WriteLine("The model cannot be solved " & _
                         "because it is infeasible or unbounded")
                Return
            End If
            If status <> GRB.Status.OPTIMAL Then
                Console.WriteLine("Optimization was stopped with status {0}", status)
                Return
            End If

            ' Print best selected set
            Console.WriteLine("Selected elements in best solution:")
            Console.Write(vbTab)
            For e = 0 To groundSetSize - 1
                If Elem(e).X < 0.9 Then
                    Continue For
                End If
                Console.Write("El{0} ", e)
            Next
            Console.WriteLine()

            ' Print number of solutions stored
            nSolutions = model.SolCount
            Console.WriteLine("Number of solutions found: {0}", nSolutions)

            ' Print objective values of solutions
            If nSolutions > 10 Then
                nSolutions = 10
            End If
            Console.WriteLine("Objective values for first {0} solutions:", nSolutions)
            For i = 0 To nSubsets - 1
                model.Parameters.ObjNumber = i

                Console.Write(vbTab & "Set" & i)
                For e = 0 To nSolutions - 1
                    model.Parameters.SolutionNumber = e
                    Console.Write("{0,8}", model.ObjNVal)
                Next
                Console.WriteLine()
            Next

            model.Dispose()
            env.Dispose()

        Catch e As GRBException
            Console.WriteLine("Error code = {0}", e)
            Console.WriteLine(e.Message)

        End Try
    End Sub
End Class