def solve(self, problem: Problem, init_vars: np.ndarray = None, show_process: bool = False): if init_vars is None: init_vars = np.random.rand(problem.dim) self.reset() start = time.time() vars_current = init_vars objv_current = problem.aim_func(vars_current) grad_value = problem.cal_gradient(vars_current) ng = np.linalg.norm(grad_value) # record self.cpu_time_arr.append(0) self.f_value_arr.append(objv_current) self.g_norm_arr.append(ng) iter_count = 0 while ng > self.tol and iter_count < self.max_iter: current = time.time() # INNER STEP1: get d_k, use s_k or -grad_value hessian = problem.cal_hessian(vars_current) s_k = None s_k_available = False if (np.linalg.det(hessian) >= 1e-6): # invertible s_k = -np.linalg.inv(hessian) @ grad_value if -grad_value @ s_k >= min( self.beta1, self.beta2 * np.linalg.norm(s_k, self.p)) * np.linalg.norm(s_k)**2: s_k_available = True if s_k_available: d_k = s_k else: d_k = -grad_value # INNER STEP2: get a_k alpha = self.s # initial alpha as self.s objv_next = problem.aim_func(vars_current + alpha * d_k) while np.isnan(objv_next) or ( (objv_next - objv_current) > (self.gamma * alpha * grad_value @ d_k)): alpha *= self.sigma objv_next = problem.aim_func(vars_current + alpha * d_k) vars_current = vars_current + alpha * d_k objv_current = problem.aim_func(vars_current) grad_value = problem.cal_gradient(vars_current) ng = np.linalg.norm(grad_value) iter_count += 1 if show_process: print(f'iteration {iter_count} : {round(ng, 8)}', end=' ') print( f'time: {round(time.time() - current, 3)} second(self.s)') # record self.cpu_time_arr.append(time.time() - start) self.f_value_arr.append(objv_current) self.g_norm_arr.append(ng) self.final_solution = vars_current self.surface_points = problem.get_all_surface_points(vars_current) return vars_current, grad_value, objv_current, ng, iter_count
def solve(self, problem: Problem, init_vars: np.ndarray = None, show_process: bool = False): if init_vars is None: init_vars = np.random.rand(problem.dim) self.reset() start = time.time() # Step1: calculate the gradient and its norm named 'ng' vars_current = init_vars grad_value = problem.cal_gradient(vars_current) ng = np.linalg.norm(grad_value) hessian = problem.cal_hessian(vars_current) # ng_seq = [] # Step2: Iteration objv_current = problem.aim_func(vars_current) iter_count = 0 # Record self.cpu_time_arr.append(0) self.f_value_arr.append(objv_current) self.g_norm_arr.append(ng) while ng > self.tol and iter_count < self.max_iter: current = time.time() # INNER STEP1: get d_k d_k = -grad_value # INNER STEP2: get a_k #alpha = self.s # initial alpha as s alpha = -grad_value.T * d_k / (d_k.T @ hessian @ d_k) # print(alpha) vars_current = vars_current + alpha * d_k # Update vars objv_current = problem.aim_func(vars_current) grad_value = problem.cal_gradient(vars_current) ng = np.linalg.norm(grad_value) iter_count += 1 # ng_seq.append(ng) if show_process: print(f'iteration {iter_count} : {round(ng, 8)}', end=' ') print( f'time: {round(time.time() - current, 3)} second(self.s)') self.cpu_time_arr.append(time.time() - start) self.f_value_arr.append(objv_current) self.g_norm_arr.append(ng) self.final_solution = vars_current self.surface_points = problem.get_all_surface_points(vars_current) return vars_current, grad_value, objv_current, ng, iter_count