예제 #1
0
 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)
예제 #2
0
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)
예제 #3
0
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
예제 #4
0
파일: level_ga.py 프로젝트: yashvesikar/DSP
 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
예제 #5
0
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
예제 #6
0

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)