Dynamic programming algorithm for facility locations

强颜欢笑 提交于 2019-12-07 14:47:21

问题


There are n houses at locations a_1, a_2,..., a_n along a line. We want to set up porta potties along that same line so that every house is within distance R of at least one porta potty. These porta potties are restricted to the specified locations b_1, b_2,..., b_m. Let c_i be the cost of setting up a porta potty at location b_i.

Find a dynamic programming algorithm that minimizes the total cost of setting up the porta potties. The algorithm should be able to detect if a solution does not exist. Assume that all a and b values are distinct.

Inputs:

  • A[1, 2,...n] holds the house locations

  • B[1, 2,...m] holds the potential porta potty locations

  • C[1, 2,...m] holds the cost of setting up a porta potty at each location

Output: the minimum cost of placing the porta potties under the constraint that every house must be within distance R of some porta potty

I'm having trouble figuring out a recursive expression to work off of. Any help would be appreciated!


回答1:


Your question gave me the chance to write some code for a similar problem which often appears as cellphone tower placing problem or cellphone base coverage problem.

Pseudocode follows:

1) Sort houses in ascending order
2) Sort facilities positions and their costs in ascending order by facilities positions
3) Let dp(i) be the minimum cost to cover i houses and lastBase(j) the last base used to cover j houses
4) Set the base case dp(0) = 0 and lastBase(0) = -1
5) For each house i:
6)   Check if previous solution is either valid or in range of this new house
7)   if it is -> grab it as solution
8)   else
9)     find a new base starting from lastBase(i) + 1 which can cover this house
10)    let it be the minimum-cost one
11)  if a base could be found -> add it to the previous solution
12)  else -> Problem cannot be solved

I recommend trying it out yourself first.

For completeness' sake: explanation, images and C++ code are available here.

Feedback or errors are welcome.




回答2:


I am going to give you an idea of how to proceed, how you code it is up to you.
Given A,B,C (also assumption is that all elements in A and B are on the number line) -

-> Sort A in ascending order.

-> Sort B and C together(as they are dependent) based on B's values in ascending order. 

-> Maintain a temp array(size n) which keeps track of which "porta potty" 
  an A element belongs to,by mapping to the "porta potty" index.

-> Now take each element from B and move both forward and backward R steps from that 
   point on the number line.

-> If any A element is found in those R steps(on the number line) 
   AND if(and only if) it does not presently belong to any "porta potty" OR 
   the cost of setting up the current "porta potty" element is more than the "porta potty" 
   it(A element) already belongs to, then only shall you set the value in temp array 
   for that A element to the current "porta potty" index number.

-> Now once we are done with all B points, do the following

-> Traverse the temp array and push the "porta potty" index numbers we have into a set

-> You now have a list of all the "porta potty" indices which are the cheapest
   yet crucial to be placed.

Think this out and let me know if something is unclear to you. Also the sorting part is only to improve performance.




回答3:


This one is for cellphone tower placing problem. Your's should be similar i guess.




回答4:


There ought to be a recursion for this. Here is a commented example in Python, which assumes sorted input:

a = [1, 7,11,13,15]
b = [1,8,9,12,13]
c = [1,3,2, 2, 5]
r = 3

na = len(a)
nb = len(b)

def f (ia,ib,prev_ib,s):
  # base case no suitable potties
  if ib == nb:
    return 1000  # a number larger than sum of all costs

  # base case end of row of houses
  if ia == na:
    return s

  # house is in range of last potty
  if prev_ib >= 0 and abs(a[ia] - b[prev_ib]) < r:
    return f(ia + 1,ib,prev_ib,s)

  # house is too far
  if abs(a[ia] - b[ib]) >= r:
    # house is west of potty
    if a[ia] < b[ib]:
      return 1000
    # house is east of potty
    else:
      return f(ia,ib + 1,prev_ib,s)

  # house is in range of current potty
  else: 
    # choose or skip
    return min(f(ia + 1,ib + 1 if ib < nb - 1 else ib,ib,s + c[ib]),f(ia,ib + 1,prev_ib,s))

Output:

print f(0,0,-1,0) # 8


来源:https://stackoverflow.com/questions/33177619/dynamic-programming-algorithm-for-facility-locations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!