@@ -493,6 +493,7 @@ def __init__(
493
493
maxNodes = None ,
494
494
logPath = None ,
495
495
threads = None ,
496
+ warmStart = False ,
496
497
):
497
498
"""
498
499
:param bool mip: if False, assume LP even if integer variables
@@ -504,6 +505,7 @@ def __init__(
504
505
:param int maxNodes: max number of nodes during branching. Stops the solving when reached.
505
506
:param str logPath: path to the log file
506
507
:param int threads: sets the maximum number of threads
508
+ :param bool warmStart: if True, the solver will use the current value of variables as a start
507
509
"""
508
510
super ().__init__ (
509
511
mip = mip ,
@@ -515,6 +517,7 @@ def __init__(
515
517
maxNodes = maxNodes ,
516
518
logPath = logPath ,
517
519
threads = threads ,
520
+ warmStart = warmStart ,
518
521
)
519
522
520
523
def findSolutionValues (self , lp ):
@@ -538,17 +541,36 @@ def findSolutionValues(self, lp):
538
541
"restartlimit" : constants .LpStatusNotSolved ,
539
542
"unknown" : constants .LpStatusUndefined ,
540
543
}
544
+ possible_solution_found_statuses = (
545
+ "optimal" ,
546
+ "timelimit" ,
547
+ "userinterrupt" ,
548
+ "nodelimit" ,
549
+ "totalnodelimit" ,
550
+ "stallnodelimit" ,
551
+ "gaplimit" ,
552
+ "memlimit" ,
553
+ )
541
554
status = scip_to_pulp_status [solutionStatus ]
542
- lp .assignStatus (status )
543
-
544
- if status == constants .LpStatusOptimal :
545
- solution = lp .solverModel .getBestSol ()
546
- for variable in lp ._variables :
547
- variable .varValue = solution [variable .solverVar ]
548
- for constraint in lp .constraints .values ():
549
- constraint .slack = lp .solverModel .getSlack (
550
- constraint .solverConstraint , solution
551
- )
555
+
556
+ if solutionStatus in possible_solution_found_statuses :
557
+ try : # Feasible solution found
558
+ solution = lp .solverModel .getBestSol ()
559
+ for variable in lp ._variables :
560
+ variable .varValue = solution [variable .solverVar ]
561
+ for constraint in lp .constraints .values ():
562
+ constraint .slack = lp .solverModel .getSlack (
563
+ constraint .solverConstraint , solution
564
+ )
565
+ if status == constants .LpStatusOptimal :
566
+ lp .assignStatus (status , constants .LpSolutionOptimal )
567
+ else :
568
+ status = constants .LpStatusOptimal
569
+ lp .assignStatus (status , constants .LpSolutionIntegerFeasible )
570
+ except : # No solution found
571
+ lp .assignStatus (status , constants .LpSolutionNoSolutionFound )
572
+ else :
573
+ lp .assignStatus (status )
552
574
553
575
# TODO: check if problem is an LP i.e. does not have integer variables
554
576
# if :
@@ -649,6 +671,17 @@ def buildSolverModel(self, lp):
649
671
name = name ,
650
672
)
651
673
674
+ ##################################################
675
+ # add warm start
676
+ ##################################################
677
+ if self .optionsDict .get ("warmStart" , False ):
678
+ s = lp .solverModel .createPartialSol ()
679
+ for var in lp .variables ():
680
+ if var .varValue is not None :
681
+ # Warm start variables having an initial value
682
+ lp .solverModel .setSolVal (s , var .solverVar , var .varValue )
683
+ lp .solverModel .addSol (s )
684
+
652
685
def actualSolve (self , lp ):
653
686
"""
654
687
Solve a well formulated lp problem
0 commit comments