void DoubletSolver::solve_helper(std::string str) { std::string consider = priority_queue->peek(); priority_queue->remove(); closed_list.insert(consider); // std::cout << consider << " "; if (consider == goal_word) { parent_of[consider] = str; print_solution(consider); std::cout << "\nexpansion = " << expansions << std::endl; return; } expansions++; for (std::vector<std::string>::iterator neighbor = dictionary.begin(); neighbor != dictionary.end(); ++neighbor) { if (differs_by_one(*neighbor, consider) && (closed_list.count(*neighbor) == 0)) { if (priority_queue->is_in_heap(*neighbor)) { if (g_value[*neighbor] > (g_value[consider] + 1) ) { g_value[*neighbor] = g_value[consider] + 1; parent_of[*neighbor] = consider; priority_queue->update(*neighbor, get_priority(g_value[*neighbor], get_h_value(*neighbor))); } } else { g_value[*neighbor] = g_value[consider] + 1; parent_of[*neighbor] = consider; priority_queue->add(*neighbor, get_priority(g_value[*neighbor], get_h_value(*neighbor))); } } } solve_helper(consider); }
void solver<height,width>::solve_helper(int stars_to_place) { if(!stars_to_place) { if(is_answer()) { ans = b; solved = true; } return; } if(is_constraint_violated()) return; auto& locs = b._board; auto constraints = b._constraint_positions; for(const auto constraint : constraints) { auto& cell = locs[constraint]; /* Handle More Efficiently */ if(cell.constraint_value <= 0) continue; /* For each adjacent entry, attempt to place the stars */ auto cur_pos = cell.pos; for(auto j = 0; j < offsets.size(); ++j) { auto loc = cur_pos + offsets[j].first * width + offsets[j].second; bool assigned = false; /* Place star if at a valid position that doesn't have a num or star yet */ if(b.is_in_bounds(cur_pos, offsets[j]) && is_cell_assignable(loc)) { update_star_count(loc, star_action::STAR_ADD); solve_helper(stars_to_place - 1); assigned = true; } if(solved) return; if(b.is_in_bounds(cur_pos, offsets[j]) && assigned) update_star_count(loc, star_action::STAR_REMOVE); } } /* Handle case where each constraint is satisfied but stars remain */ }
//============================================================================ double AccountValue::Solve (mcenum_solve_type a_SolveType ,int a_SolveBeginYear ,int a_SolveEndYear ,mcenum_solve_target a_SolveTarget ,double a_SolveTargetCsv ,int a_SolveTargetYear ,mcenum_gen_basis a_SolveGenBasis ,mcenum_sep_basis a_SolveSepBasis ) { SolveBeginYear_ = a_SolveBeginYear; SolveEndYear_ = a_SolveEndYear; SolveTarget_ = a_SolveTarget; SolveTargetCsv_ = a_SolveTargetCsv; SolveTargetDuration_ = a_SolveTargetYear; SolveGenBasis_ = a_SolveGenBasis; SolveSepBasis_ = a_SolveSepBasis; LMI_ASSERT(0 <= SolveBeginYear_); LMI_ASSERT( SolveBeginYear_ <= SolveEndYear_); LMI_ASSERT( SolveEndYear_ <= BasicValues::GetLength()); LMI_ASSERT(0 < SolveTargetDuration_); LMI_ASSERT( SolveTargetDuration_ <= BasicValues::GetLength()); // Defaults: may be overridden by some cases // We aren't interested in negative solve results double lower_bound = 0.0; double upper_bound = 0.0; root_bias bias = mce_solve_for_tax_basis == SolveTarget_ ? bias_lower : bias_higher ; int decimals = 0; // Many things don't plausibly exceed max input face for(int j = 0; j < SolveTargetDuration_; j++) { upper_bound = std::max (upper_bound ,DeathBfts_->specamt()[j] + yare_input_.TermRiderAmount ); } // TODO ?? Wait--initial premium may exceed input face, so // for now we'll bail out with this: no amount solved for can // plausibly reach one billion dollars. upper_bound = 999999999.99; switch(a_SolveType) { case mce_solve_specamt: { // This: // upper_bound = 1000000.0 * Outlay_->GetPmts()[0]; // is not satisfactory; what would be better? solve_set_fn = &AccountValue::SolveSetSpecAmt; decimals = round_specamt().decimals(); // TODO ?? Respect minimum specamt? } break; case mce_solve_ee_prem: { solve_set_fn = &AccountValue::SolveSetEePrem; decimals = round_gross_premium().decimals(); } break; case mce_solve_er_prem: { solve_set_fn = &AccountValue::SolveSetErPrem; decimals = round_gross_premium().decimals(); } break; case mce_solve_loan: { solve_set_fn = &AccountValue::SolveSetLoan; decimals = round_loan().decimals(); } break; case mce_solve_wd: { // TODO ?? Is minimum wd respected? solve_set_fn = &AccountValue::SolveSetWD; decimals = round_withdrawal().decimals(); if(yare_input_.WithdrawToBasisThenLoan) { // Withdrawals and loans might be rounded differently. // To obtain a level income as a mixture of loans and // withdrawals, both should be rounded to the less // precise number of decimals normally used for either. decimals = std::min (round_withdrawal().decimals() ,round_loan ().decimals() ); } } break; default: { fatal_error() << "Case " << a_SolveType << " not found." << LMI_FLUSH ; } } std::ostream os_trace(status().rdbuf()); std::ofstream ofs_trace; if(contains(yare_input_.Comments, "idiosyncrasyT") && !SolvingForGuarPremium) { ofs_trace.open("trace.txt", ios_out_app_binary()); os_trace.rdbuf(ofs_trace.rdbuf()); } SolveHelper solve_helper(*this); root_type solution = decimal_root (lower_bound ,upper_bound ,bias ,decimals ,solve_helper ,false ,os_trace ); if(root_not_bracketed == solution.second) { solution.first = 0.0; // Don't want this firing continually in census runs. if(!SolvingForGuarPremium) { warning() << "Solution not found: using zero instead." << LMI_FLUSH; // TODO ?? What can we do when no solution exists for guar prem? } } // The account and ledger values set as a side effect of solving // aren't necessarily what we need, for two reasons: // - find_root() need not return the last iterand tested; and // - the 'Solving' flag has side effects. // The first issue could be overcome easily enough in find_root(), // but the second cannot. Therefore, the final solve parameters // are stored now, and values are regenerated downstream. Solving = false; (this->*solve_set_fn)(solution.first); return solution.first; }
void DoubletSolver::solve() { g_value[start_word] = 0; priority_queue->add(start_word,0); solve_helper(start_word); }
void solver<height, width>::solver<height, width>::solve() { solve_helper(star_count); }