Dynamic programming algorithm for facility locations

烈酒焚心 提交于 2019-12-05 22:30:32

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.

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.

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

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