How would you look at developing an algorithm for this hotel problem?

前端 未结 11 1890
误落风尘
误落风尘 2020-12-13 10:51

There is a problem I am working on for a programming course and I am having trouble developing an algorithm to suit the problem. Here it is:

You are

相关标签:
11条回答
  • 2020-12-13 11:25

    Following is the MATLAB code for hotel problem.

    clc
    clear all
    
    % Data     
    % a = [0;50;180;150;50;40];    
    % a = [0, 200, 400, 600, 601];    
      a = [0,10,180,350,450,600];    
    % a = [0,1,2,3,201,202,203,403];
    
    n = length(a);    
    opt(1) = 0;    
    prev(1)= 1;
    
    for i=2:n
        opt(i) =Inf;
        for j = 1:i-1
            if(opt(i)>(opt(j)+ (200-a(i)+a(j))^2))
                opt(i)= opt(j)+ (200-a(i)+a(j))^2;
                prev(i) = j; 
            end
        end
        S(i) = opt(i);
    end
    
    k = 1;
    i = n;
    sol(1) = n;
    
    while(i>1)
       k = k+1;
       sol(k)=prev(i);
       i = prev(i);   
    end
    
    for i =k:-1:1
        stops(i) = sol(i);
    end
    stops
    
    0 讨论(0)
  • 2020-12-13 11:25

    Here is my Python solution using Dynamic Programming:

    distance = [150,180,250,340]
    
    def hotelStop(distance):
        n = len(distance)
        DP = [0 for _ in distance]
        for i in range(n-2,-1,-1):
            min_penalty = float("inf")
            for j in range(i+1,n):
                # going from hotel i to j in first day
                x = distance[j]-distance[i]
                penalty = (200-x)**2
                total_pentalty = penalty+ DP[j]
                min_penalty = min(min_penalty,total_pentalty)
            DP[i] = min_penalty
        return DP[0]
    
    hotelStop(distance)
    
    0 讨论(0)
  • 2020-12-13 11:27

    To answer your question concisely, a PSPACE-complete algorithm is usually considered "efficient" for most Constraint Satisfaction Problems, so if you have an O(n^2) algorithm, that's "efficient".

    I think the simplest method, given N total miles and 200 miles per day, would be to divide N by 200 to get X; the number of days you will travel. Round that to the nearest whole number of days X', then divide N by X' to get Y, the optimal number of miles to travel in a day. This is effectively a constant-time operation. If there were a hotel every Y miles, stopping at those hotels would produce the lowest possible score, by minimizing the effect of squaring each day's penalty. For instance, if the total trip is 605 miles, the penalty for travelling 201 miles per day (202 on the last) is 1+1+4 = 6, far less than 0+0+25 = 25 (200+200+205) you would get by minimizing each individual day's travel penalty as you went.

    Now, you can traverse the list of hotels. The fastest method would be to simply pick the hotel that is the closest to each multiple of Y miles. It's linear-time and will produce a "good" result. However, I do not think this will produce the "best" result in all cases.

    The more complex but foolproof method is to get the two closest hotels to each multiple of Y; the one immediately before and the one immediately after. This produces an array of X' pairs, which can be traversed in all possible permutations in 2^X' time. You can shorten this by applying Dijkstra to a map of these pairs, which will determine the least costly path for each day's travel, and will execute in roughly (2X')^2 time. This will probably be the most efficient algorithm that is guaranteed to produce the optimal result.

    0 讨论(0)
  • 2020-12-13 11:29

    This is equivalent to finding the shortest path between two nodes in a directional acyclic graph. Dijkstra's algorithm will run in O(n^2) time.

    Your intuition is better, though. Starting at the back, calculate the minimum penalty of stopping at that hotel. The first hotel's penalty is just (200-(200-x)^2)^2. Then, for each of the other hotels (in reverse order), scan forward to find the lowest-penalty hotel. A simple optimization is to stop as soon as the penalty costs start increasing, since that means you've overshot the global minimum.

    0 讨论(0)
  • 2020-12-13 11:30

    Step 1 of 2

    Sub-problem:

    In this scenario, "C(j)" has been considered as sub-problem for minimum penalty gained up to the hotel "ai" when "0<=i<=n". The required value for the problem is "C(n)".

    Algorithm to find minimum total penalty:

    If the trip is stopped at the location "aj" then the previous stop will be "ai" and the value of i and should be less than j. Then all the possibilities of "ai", has been follows:

    C(j) min{C(i)+(200-(aj-ai))^2}, 0<=i<=j.

    • Initialize the value of "C(0)" as "0" and “a0" as "0" to find the remaining values.

    • To find the optimal route, increase the value of "j" and "i" for each iteration of and use this detail to backtrack from "C(n)".

    Here, "C(n)" refers the penalty of the last hotel (That is, the value of "i" is between "0" and "n").

    Pseudocode:

    //Function definition

    Procedure min_tot()

    //Outer loop to represent the value of for j = 1 to n:

    //Calculate the distance of each stop C(j) = (200 — aj)^2

    //Inner loop to represent the value of for i=1 to j-1:

    //Compute total penalty and assign the minimum //total penalty to "c(j)"

    C(j) = min (C(i), C(i) + (200 — (aj — ai))^2}

    //Return the value of total penalty of last hotel

    return C(n)

    Step 2 of 2

    Explanation: The above algorithm is used to find the minimum total penalty from the starting point to the end point.

    • It uses the function "min()" to find the total penalty for the each stop in the trip and computes the minimum penalty value.

    Running time of the algorithm:

    This algorithm contains "n" sub-problems and each sub-problem take "O(n)" times to resolve.

    • It is needed to compute only the minimum values of "O(n)".

    • And the backtracking process takes "O(n)" times.

    • The total running time of the algorithm is nxn = n^2 = O(n^2) .

    Therefore, this algorithm totally takes "0(n^2)" times to solve the whole problem.

    0 讨论(0)
  • I don't think you can do it as easily as sysrqb states.

    On a side note, there is really no difference to starting from start or end; the goal is to find the minimum amount of stops each way, where each stop is as close to 200m as possible.

    The question as stated seems to allow travelling beyond 200m per day, and the penalty is equally valid for over or under (since it is squared). This prefers an overage of miles per day rather than underage, since the penalty is equal, but the goal is closer.

    However, given this layout

    A ----- B----C-------D------N
    0       190  210     390    590
    

    It is not always true. It is better to go to B->D->N for a total penalty of only (200-190)^2 = 100. Going further via C->D->N gives a penalty of 100+400=500.

    The answer looks like a full breadth first search with active pruning if you already have an optimal solution to reach point P, removing all solutions thus far where

    sum(penalty-x) > sum(penalty-p)  AND  distance-to-x <= distance-to-p - 200
    

    This would be an O(n^2) algorithm


    Something like...

    • Quicksort all hotels by distance from start (discard any that have distance > hotelN)
    • Create an array/list of solutions, each containing (ListOfHotels, I, DistanceSoFar, Penalty)
    • Inspect each hotel in order, for each hotel_I
        Calculate penalty to I, starting from each prior solution
    • Pruning
        For each prior solution that is beyond 200 distanceSoFar from
        current, and Penalty>current.penalty, remove it from list
    • loop
    0 讨论(0)
提交回复
热议问题