1
2
3
4
5
6
7
8
|
// Copyright (c) 2016 Frank Fischer <frank-fischer@shadow-soft.de>
//
// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
|
|
|
1
2
3
4
5
6
7
8
|
// Copyright (c) 2016, 2017 Frank Fischer <frank-fischer@shadow-soft.de>
//
// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
|
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
|
self.nxt_y.add(&self.cur_y, &self.nxt_d);
self.nxt_mod = self.master.get_primoptval();
self.sgnorm = self.master.get_dualoptnorm2().sqrt();
self.expected_progress = self.cur_val - self.nxt_mod;
// update multiplier from master solution
for i in 0..self.problem.num_subproblems() {
for m in self.minorants[i].iter_mut() {
m.multiplier = self.master.multiplier(m.index);
}
}
debug!("Model result");
debug!(" cur_val ={}", self.cur_val);
debug!(" nxt_mod ={}", self.nxt_mod);
|
|
|
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
|
self.nxt_y.add(&self.cur_y, &self.nxt_d);
self.nxt_mod = self.master.get_primoptval();
self.sgnorm = self.master.get_dualoptnorm2().sqrt();
self.expected_progress = self.cur_val - self.nxt_mod;
// update multiplier from master solution
for i in 0..self.problem.num_subproblems() {
for m in &mut self.minorants[i] {
m.multiplier = self.master.multiplier(m.index);
}
}
debug!("Model result");
debug!(" cur_val ={}", self.cur_val);
debug!(" nxt_mod ={}", self.nxt_mod);
|
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
|
if nxt_ub > descent_bnd {
// upper bound will produce null-step
if self.cur_val - nxt_lb > (self.cur_val - self.nxt_mod) * self.params.nullstep_factor.max(0.5) {
warn!("Relative precision of returned objective interval enforces null-step.");
self.iterinfos.push(IterationInfo::UpperBoundNullStep);
}
}
} else {
// lower bound gives already a null step
if self.cur_val - nxt_lb > 0.8 * (self.cur_val - self.nxt_mod) {
// subgradient won't yield much improvement
warn!("Shallow cut (subgradient won't yield much improvement)");
self.iterinfos.push(IterationInfo::ShallowCut);
}
}
debug!("Step");
debug!(" cur_val ={}", self.cur_val);
debug!(" nxt_mod ={}", self.nxt_mod);
debug!(" nxt_ub ={}", self.nxt_val);
debug!(" descent_bnd={}", descent_bnd);
// do a descent step or null step
if nxt_ub <= descent_bnd {
self.descent_step();
return Ok(Step::Descent);
} else {
self.null_step();
return Ok(Step::Null);
}
}
/**
* Return the bound on the function value that enforces a
* nullstep.
*
|
|
>
<
|
|
|
<
|
|
|
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
|
if nxt_ub > descent_bnd {
// upper bound will produce null-step
if self.cur_val - nxt_lb > (self.cur_val - self.nxt_mod) * self.params.nullstep_factor.max(0.5) {
warn!("Relative precision of returned objective interval enforces null-step.");
self.iterinfos.push(IterationInfo::UpperBoundNullStep);
}
}
} else if self.cur_val - nxt_lb > 0.8 * (self.cur_val - self.nxt_mod) {
// TODO: double check with ConicBundle if this test makes sense.
// lower bound gives already a null step
// subgradient won't yield much improvement
warn!("Shallow cut (subgradient won't yield much improvement)");
self.iterinfos.push(IterationInfo::ShallowCut);
}
debug!("Step");
debug!(" cur_val ={}", self.cur_val);
debug!(" nxt_mod ={}", self.nxt_mod);
debug!(" nxt_ub ={}", self.nxt_val);
debug!(" descent_bnd={}", descent_bnd);
// do a descent step or null step
if nxt_ub <= descent_bnd {
self.descent_step();
Ok(Step::Descent)
} else {
self.null_step();
Ok(Step::Null)
}
}
/**
* Return the bound on the function value that enforces a
* nullstep.
*
|