EDIT: Apparently, I should have posted my original recommendation about the facility location problem as a reply to your question, not as an answer. I am new to the forum, but I get it now.
Any way, I believe your problem can be formulated as follows.
Let $y_i$ = 1 if supply center i is opened and 0 otherwise
$x_i,_j$ = 1 if supply center i feeds shop j and 0 otherwise
$c_i,_j$ = distance from supply center i to shop j
Then you want to solve the following linear programming problem.
minimize $\sum_i\sum_jc_i,_jx_i,_j$
subject to $\sum_ix_i,_j = 1$ j = 1,...,1000 (or the number of shops you have)
$\sum_jx_i,_j \le 1000y_i$ i = 1,...,28 (If you have a max capacity for each supply center, use that number instead of 1000; 1000 assumes there is no max capacity so one center could feasibly supply all shops)
$\sum_iy_i \le 20$ (max of 20 supply centers chosen)
$x_i,_j$ = 0 or 1 i=1,...,28; j =1,...,1000
$y_i$ = 0 or 1 i=1,...,14
The Rsymphony package in R can solve this problem for you. You will need a vector of the distances $c_i,_j$ and 0's for each $y_i$ as well as a matrix to take care of the constraints (the three summations starting after "subject to"). If you aren't familiar with the constraint matrix, each column contains the coefficients for that variable. The help file for the Rsymphony package has a couple examples that should help with that. Don't forget to include columns for the $y_i$ in the matrix as well. You will also need to set the $x_i,_j$ and $y_i$ to be binary by using
types = "B"
As an example, suppose we have 3 shops and 2 supply centers with distances between them as $x_1,_1$ = 2.8, $x_1,_2$ = 5.4, $x_1,_3$ = 1.4, $x_2,_1$ = 4.2, $x_2,_2$ = 3.0, $x_2,_3$ = 6.3. Then
library(Rsymphony)
obj <- c(2.8, 5.4, 1.4, 4.2, 3.0, 6.3, 0, 0)
mat <- matrix(c(1,0,0,1,0,0,0,1,0,1,0,0,0,0,1,1,0,0,1,0,0,0,1,0,0,1,0,0,1,0,0,0,1,0,1,0,0,0,0,-3,0,1,0,0,0,0,-3,1), nrow = 6)
dir <- c("==", "==", "==", "<=", "<=", "<=")
rhs <- c(1, 1, 1, 0, 0, 2)
max <- FALSE
types <- "B"
fac.loc <- Rsymphony_solve_LP(obj, mat, dir, rhs, types = types, max = max, write_lp = TRUE)
fac.loc
tells us that we should open both supply centers and supply center 1 will supply shops 1 and 3 and supply center 2 will supply shop 2, for a total distance of 7.2.
I hope this helps.
Best Answer
Genetic algorithms are really only useful in multi-variable problems because you need a problem for which the potential solutions can be cut into parts which can be fitted together in new ways. Your problem is of this type. You want to maximise
This function is your fitness function.
You start by finding an initial population of possible solutions. I am going to generate random values between $0$ and $6$, so the initial population looks like this:
Each row is one possible solution. Now loop over the following steps:
f
.Here is the first iteration of the loop. The fitness values for the $5$ vectors in the initial population are:
48 84 183 184 81
So the mother is
5 5 6
with a value of183
and the father is6 2 6
with a value of184
. Now we have to create the children. This is usually done by choosing a place to cut and following the mother up to that place and the father beyond it, or vice versa. Here, we can either cut after the first entry, to give5 2 6
and6 5 6
, or after the second entry to give5 5 6
and6 2 6
. Usually, some children will be produced by randomly choosing from these. So let's suppose we got the first three. Then our new population isNow we should also do some mutations (otherwise, in fact, we will never reach the solution in this example.) One way of doing this is to change the values in the children up or down with some (small) probability. Let's suppose, after these random mutations, child 1 changes to
5 3 6
and child 3 changes to6 5 6
, and child 2 stays the same. Then the population at the end of the first iteration of the loop is now:In the second generation, the new mother and father will be
6 5 6
. All the children will be6 5 6
as well, and we have to keep going until we get a lucky mutation when the middle5
mutates to a6
. This is the only way to reach the maximum in this example.Note that there are many variations on this procedure. Your book may well teach a different one. But the basic steps are
Note that this particular problem is not well-suited to genetic algorithms. You really want to use them when the fitness function is complicated with many local maxima (or minima) or possibly when you want to increase the value of a function without necessarily maximising it (like in real-life evolution.)
And (as you can see) they are slow!
Here is a really cool example if you haven't seen it before: Boxcar2d.