def test_some_sequences(self): data = np.load('dp_solver.npy', allow_pickle=True)[:100] problem = load_problem(T=6) for i in data: d = i[0] seq = i[1:].astype(int) solver = solve_sequence(problem=problem, seq=seq) self.assertTrue(solver.result.feasible) self.assertAlmostEqual(d, solver.result.distance)
def repopulate_queue(Q, solutions): rand = np.random.permutation(len(solutions)) old_pop = [solutions[rand[i]] for i in range(10)] problem = load_problem() for s in old_pop: if s: solver = solve_sequence(problem, s[-1]) if solver.feasible: res = sliding_window(2, 1, solver, return_first=False, restrict_available=False) if res.feasible: Q.append(res)
def old_sliding_window(k, n, S, return_first=False): success = 0 fail = 0 seq, sched, problem = S.seq, S.result.schedule, S.problem best_dist = 1e10 best_solver = None n += 1 for i in range(len(seq) - n): avail = problem.ships_in_working_area(start=sched[i], end=sched[i + n]) avail = set(avail) - set(seq[:i + 1] + seq[i + n:]) if 0 in avail: avail.remove(0) sub_seq = list(itertools.permutations(avail, k)) # # MOD # sub_seq = [s for s in sub_seq if len(set(seq[i + 1:i + n]) - set(s)) == 0] for ship in sub_seq: _seq = seq[:i + 1] + list(ship) + seq[i + n:] result = solve_sequence(problem=problem, seq=_seq) if result.result.feasible: success += 1 # Return the first feasible solution if return_first: return result if result.result.distance < best_dist: best_dist = result.result.distance best_solver = result else: fail += 1 return best_solver
def _evaluate(self, x, out, *args, algorithm=None, **kwargs): seq = [0] + x.tolist() + [0] solver = solve_sequence(self.data, seq) out["F"] = solver.result.distance out["G"] = 0.0 if solver.result.feasible else 1.0 out["solver"] = solver
def sliding_window(insert, remove, S, return_first=False, restrict_available=False): """ :param insert: Number of ships to expand by :param remove: Number of ships to remove :param S: DPSolver instance :return: """ success = 0 fail = 0 best_dist = 1e10 best_solver = None # Algorithm works on gaps between ships not ships themselves, hence remove += 1 remove += 1 problem = load_problem() if isinstance(S, list): _solver = solve_sequence(problem=problem, seq=S) elif isinstance(S, DPSolver): _solver = copy.copy(S) _solver.get_result() else: print("FAIL SLIDING WINDOW") return sequence, schedule, distances = _solver.seq[:], _solver.result.schedule[:], [min(s.distances) for s in _solver.states] for i in range(len(sequence) - remove): window = sequence[i+1:i + remove] start = min(S.states[i].schedule) # Minimum feasible available time from the ship states before the window end = problem.get_ship(window[-1]).times[1] # Maximum available time for the ship in WA following the window avail = problem.ships_in_working_area(start=start, end=end) avail = set(avail) - set(sequence[:i+1] + sequence[i + remove:]) if 0 in avail: avail.remove(0) sub_seq = list(itertools.permutations(avail, insert)) if restrict_available: sub_seq = [s for s in sub_seq if len(set(sequence[i + 1:i + remove]) - set(s)) == 0] candidates = [] # Candidate solutions for full evaluation for ship in sub_seq: solver = copy.copy(_solver) solver.get_result() # Update the solver to the correct transition point while len(solver.seq) != len(sequence[:i+1]): solver.pop_state() # Evaluate the transition with the new permutation skip = False for l, j in enumerate(ship): b = solver.next(j) new_sched = solver.states[-1].schedule new_dist = min(solver.states[-1].distances) if len(solver.states[-1].distances) else 1e6 # If the new schedule has less possible transitions or the new minimum distance is greate if len(new_sched) < len(schedule) or new_dist > distances[i+1+l]: skip = True break if skip: # Move to next permutation fail += 1 continue else: # Update candidate permutations based on distance success += 1 heapq.heappush(candidates, (min(solver.states[-1].distances), copy.copy(solver))) # Evaluate all candidate solutions for c in range(len(candidates)): d, sver = heapq.heappop(candidates) for s in sequence[i + remove:]: sver.next(s) result = sver.get_result() if result.feasible: if return_first: return sver if result.distance < best_dist: best_dist = result.distance best_solver = sver return best_solver
if __name__ == "__main__": from dsp.Problem import Problem, load_problem from dsp.Solver import DPSolver from dsp.HTSolver import HeuristicTreeSolver import time import pprint as pp # Create sequence solver object P = load_problem() truncation_args = {'limit': 100, 'method': "distance"} # ALPHA = set(P.ships_in_working_area()) # SeqSolver = SequenceSolver(problem=P, height_limit=5) # result = SeqSolver.sequence_search(available=ALPHA, truncation_args=truncation_args) sol = solve_sequence(problem=P, seq=[0, 32, 30, 63, 12, 0]) # sol2 = solve_sequence(problem=P, seq=[0, 32, 30, 63, 12, 0]) sol2 = solve_sequence(problem=P, seq=[0, 8, 5, 30, 63, 12, 0]) # start = time.time() # result = old_sliding_window(1, 1, sol) # end = time.time() # print(f"Old Result 2 Time: {end-start}") # print(f"Old Result: {result}") # # start = time.time() # result2 = sliding_window(1, 1, sol2) # end = time.time() # print(f"Result Time: {end-start}") # print(f"Result: {result2}") ping_pong_solver([sol, sol2], fast=False)