@@ -61,12 +61,22 @@ mutable struct _VariableInfo
61
61
upper:: Float64
62
62
# Track integrality
63
63
type:: _TypeEnum
64
+ start:: Union{Nothing,Float64}
64
65
function _VariableInfo (
65
66
index:: MOI.VariableIndex ,
66
67
column:: HighsInt ,
67
68
bound:: _BoundEnum = _BOUND_NONE,
68
69
)
69
- return new (index, " " , column, bound, - Inf , Inf , _TYPE_CONTINUOUS)
70
+ return new (
71
+ index,
72
+ " " ,
73
+ column,
74
+ bound,
75
+ - Inf ,
76
+ Inf ,
77
+ _TYPE_CONTINUOUS,
78
+ nothing ,
79
+ )
70
80
end
71
81
end
72
82
363
373
364
374
MOI. get (model:: Optimizer , :: MOI.RawSolver ) = model
365
375
366
- function MOI. get (:: Optimizer , :: MOI.ListOfVariableAttributesSet )
367
- return MOI. AbstractVariableAttribute[MOI. VariableName ()]
376
+ function MOI. get (model:: Optimizer , :: MOI.ListOfVariableAttributesSet )
377
+ ret = MOI. AbstractVariableAttribute[MOI. VariableName ()]
378
+ if any (info -> info. start != = nothing , values (model. variable_info))
379
+ push! (ret, MOI. VariablePrimalStart ())
380
+ end
381
+ return ret
368
382
end
369
383
370
384
function MOI. get (model:: Optimizer , :: MOI.ListOfModelAttributesSet )
@@ -720,6 +734,37 @@ function _rebuild_name_to_variable(model::Optimizer)
720
734
return
721
735
end
722
736
737
+ #
738
+ # MOI.VariablePrimalStart
739
+ #
740
+
741
+ function MOI. supports (
742
+ :: Optimizer ,
743
+ :: MOI.VariablePrimalStart ,
744
+ :: Type{MOI.VariableIndex} ,
745
+ )
746
+ return true
747
+ end
748
+
749
+ function MOI. set (
750
+ model:: Optimizer ,
751
+ :: MOI.VariablePrimalStart ,
752
+ x:: MOI.VariableIndex ,
753
+ start:: Union{Nothing,Float64} ,
754
+ )
755
+ info = _info (model, x)
756
+ info. start = start
757
+ return
758
+ end
759
+
760
+ function MOI. get (
761
+ model:: Optimizer ,
762
+ :: MOI.VariablePrimalStart ,
763
+ x:: MOI.VariableIndex ,
764
+ )
765
+ return _info (model, x). start
766
+ end
767
+
723
768
# ##
724
769
# ## Objectives
725
770
# ##
@@ -1616,6 +1661,22 @@ function _store_solution(model::Optimizer, ret::HighsInt)
1616
1661
return
1617
1662
end
1618
1663
1664
+ function _set_variable_primal_start (model:: Optimizer )
1665
+ if all (info -> info. start === nothing , values (model. variable_info))
1666
+ return
1667
+ end
1668
+ start = zeros (Cdouble, length (model. variable_info))
1669
+ for (x, info) in model. variable_info
1670
+ # For the default start, pick the lower bound if it exists, otherwise
1671
+ # the minimum of the upper bound and zero.
1672
+ default = isfinite (info. lower) ? info. lower : min (info. upper, 0.0 )
1673
+ start[info. column+ 1 ] = something (info. start, default)
1674
+ end
1675
+ ret = Highs_setSolution (model, start, C_NULL , C_NULL , C_NULL )
1676
+ _check_ret (ret)
1677
+ return
1678
+ end
1679
+
1619
1680
function MOI. optimize! (model:: Optimizer )
1620
1681
for info in model. binaries
1621
1682
Highs_changeColBounds (
@@ -1625,6 +1686,7 @@ function MOI.optimize!(model::Optimizer)
1625
1686
min (1.0 , info. upper),
1626
1687
)
1627
1688
end
1689
+ _set_variable_primal_start (model)
1628
1690
ret = Highs_run (model)
1629
1691
_store_solution (model, ret)
1630
1692
# TODO (odow): resetting the bounds here invalidates previously stored
@@ -2366,6 +2428,14 @@ function MOI.copy_to(dest::Optimizer, src::MOI.ModelLike)
2366
2428
MOI. ObjectiveFunction {F} (),
2367
2429
MOI. Utilities. map_indices (mapping, f_obj),
2368
2430
)
2431
+ # VariablePrimalStart
2432
+ start_attr = MOI. VariablePrimalStart ()
2433
+ if start_attr in MOI. get (src, MOI. ListOfVariableAttributesSet ())
2434
+ for x in MOI. get (src, MOI. ListOfVariableIndices ())
2435
+ start = MOI. get (src, start_attr, x)
2436
+ MOI. set (dest, start_attr, mapping[x], start)
2437
+ end
2438
+ end
2369
2439
return mapping
2370
2440
end
2371
2441
0 commit comments