# 5. Solvers — MIPLearn 0.3

# 5. Solvers

## 5.1. LearningSolver

### Example

    [3]:

    import random

    import numpy as np
    from scipy.stats import uniform, randint
    from sklearn.linear_model import LogisticRegression

    from miplearn.classifiers.minprob import MinProbabilityClassifier
    from miplearn.classifiers.singleclass import SingleClassFix
    from miplearn.collectors.basic import BasicCollector
    from miplearn.components.primal.actions import SetWarmStart
    from miplearn.components.primal.indep import IndependentVarsPrimalComponent
    from miplearn.extractors.AlvLouWeh2017 import AlvLouWeh2017Extractor
    from miplearn.io import save
    from miplearn.problems.tsp import (
        TravelingSalesmanGenerator,
        build_tsp_model,
    )
    from miplearn.solvers.learning import LearningSolver

    # Set random seed to make example reproducible.
    random.seed(42)
    np.random.seed(42)

    # Generate a few instances of the traveling salesman problem.
    data = TravelingSalesmanGenerator(
        n=randint(low=10, high=11),
        x=uniform(loc=0.0, scale=1000.0),
        y=uniform(loc=0.0, scale=1000.0),
        gamma=uniform(loc=0.90, scale=0.20),
        fix_cities=True,
        round=True,
    ).generate(50)

    # Save instance data to data/tsp/00000.pkl.gz, data/tsp/00001.pkl.gz, ...
    all_data = save(data, "data/tsp")

    # Split train/test data
    train_data = all_data[:40]
    test_data = all_data[40:]

    # Collect training data
    bc = BasicCollector(time_limit_sec=3600)
    bc.collect(train_data, build_tsp_model, n_jobs=4)

    # Build learning solver
    solver = LearningSolver(
        components=[
            IndependentVarsPrimalComponent(
                base_clf=SingleClassFix(
                    MinProbabilityClassifier(
                        base_clf=LogisticRegression(),
                        thresholds=[0.95, 0.95],
                    ),
                ),
                extractor=AlvLouWeh2017Extractor(),
                action=SetWarmStart(),
            )
        ]
    )

    # Train ML models
    solver.fit(train_data)

    # Solve a test instance
    solver.optimize(test_data[0], build_tsp_model);

    Gurobi Optimizer version 9.5.2 build v9.5.2rc0 (linux64)
    Thread count: 6 physical cores, 12 logical processors, using up to 12 threads
    Optimize a model with 10 rows, 45 columns and 90 nonzeros
    Model fingerprint: 0x6ddcd141
    Coefficient statistics:
      Matrix range     [1e+00, 1e+00]
      Objective range  [4e+01, 1e+03]
      Bounds range     [1e+00, 1e+00]
      RHS range        [2e+00, 2e+00]
    Presolve time: 0.00s
    Presolved: 10 rows, 45 columns, 90 nonzeros

    Iteration    Objective       Primal Inf.    Dual Inf.      Time
           0    6.3600000e+02   1.700000e+01   0.000000e+00      0s
          15    2.7610000e+03   0.000000e+00   0.000000e+00      0s

    Solved in 15 iterations and 0.01 seconds (0.00 work units)
    Optimal objective  2.761000000e+03
    Set parameter LazyConstraints to value 1
    Gurobi Optimizer version 9.5.2 build v9.5.2rc0 (linux64)
    Thread count: 6 physical cores, 12 logical processors, using up to 12 threads
    Optimize a model with 10 rows, 45 columns and 90 nonzeros
    Model fingerprint: 0x74ca3d0a
    Variable types: 0 continuous, 45 integer (45 binary)
    Coefficient statistics:
      Matrix range     [1e+00, 1e+00]
      Objective range  [4e+01, 1e+03]
      Bounds range     [1e+00, 1e+00]
      RHS range        [2e+00, 2e+00]

    User MIP start produced solution with objective 2796 (0.01s)
    Loaded user MIP start with objective 2796

    Presolve time: 0.00s
    Presolved: 10 rows, 45 columns, 90 nonzeros
    Variable types: 0 continuous, 45 integer (45 binary)

    Root relaxation: objective 2.761000e+03, 14 iterations, 0.00 seconds (0.00 work units)

        Nodes    |    Current Node    |     Objective Bounds      |     Work
     Expl Unexpl |  Obj  Depth IntInf | Incumbent    BestBd   Gap | It/Node Time

         0     0     cutoff    0      2796.00000 2796.00000  0.00%     -    0s

    Cutting planes:
      Lazy constraints: 3

    Explored 1 nodes (15 simplex iterations) in 0.02 seconds (0.00 work units)
    Thread count was 12 (of 12 available processors)

    Solution count 1: 2796

    Optimal solution found (tolerance 1.00e-04)
    Best objective 2.796000000000e+03, best bound 2.796000000000e+03, gap 0.0000%

    User-callback calls 103, time in user-callback 0.00 sec
    Gurobi Optimizer version 9.5.2 build v9.5.2rc0 (linux64)
    Thread count: 6 physical cores, 12 logical processors, using up to 12 threads
    Optimize a model with 10 rows, 45 columns and 90 nonzeros
    Model fingerprint: 0x74ca3d0a
    Variable types: 0 continuous, 45 integer (45 binary)
    Coefficient statistics:
      Matrix range     [1e+00, 1e+00]
      Objective range  [4e+01, 1e+03]
      Bounds range     [1e+00, 1e+00]
      RHS range        [2e+00, 2e+00]
    Presolved: 10 rows, 45 columns, 90 nonzeros

    Continuing optimization...

    Cutting planes:
      Lazy constraints: 3

    Explored 1 nodes (15 simplex iterations) in 0.01 seconds (0.00 work units)
    Thread count was 12 (of 12 available processors)

    Solution count 1: 2796

    Optimal solution found (tolerance 1.00e-04)
    Best objective 2.796000000000e+03, best bound 2.796000000000e+03, gap 0.0000%

    User-callback calls 27, time in user-callback 0.00 sec

    [2]:

4. Primal Components 6. Benchmark Problems