So let’s pratice !!!

Spatial analyst:

Now let’s start with data contains the information of longitude and latitude of customer’s locations. Remember install data optimize before starting.

Code
#New manufacter:
new_manufacter= data.frame(
  Customers = str_c(rep("Manufacter"),1:3),
  Latitude =c(21.12256201,21.68421,20.34250),
  Longitude = c(105.9150683,105.1940,106.2946),
  Total.transactions = c(0,0,0),
  Inventory = c(3000,2000,2500))

route<-rbind(new_manufacter,
             optimize%>% select(Customers,
                                Longitude,
                                Latitude,
                                Total.transactions) %>% 
               mutate(Inventory = round(runif(50,100,400)))
)

colnames(route)[4]<-"Demand"

route$Node<-1:nrow(route)

## Adding status:
route$Status <- ifelse(route$Inventory - route$Demand > round(mean(route$Demand)/2),"Control",ifelse(route$Inventory- route$Demand  > 0,"Warning","Outstock" ))

So we have enough data to pratice. Let show this data in map for clearly understading.

Map of supply chain management

Code
#Prepare labels:
labels<- paste0("<strong> Customers </strong> ",
               route$Customers, "<br/> ",
               "<strong> Inventory: </strong> ",
               route$Inventory, "<br/> ",
               "<strong> Demand </strong> ",
               route$Demand, "<br/> ",
               "<strong> Status </strong> ",
               route$Status, "<br/> ") %>% 
         lapply(htmltools::HTML)

library(leaflet)
library(fontawesome) 
#If you don't have, try to install by: devtools::install_github("rstudio/fontawesome")
logos <- awesomeIconList(
  Customer = makeAwesomeIcon(
    icon = "home",
    iconColor = "white",
    markerColor = "blue",
    library = "fa"),
  Manufacter = makeAwesomeIcon(
    icon = "beer",
    iconColor = "gold",
    markerColor = "black",
    library = "fa")
)

#Prepare the logos:
route$ticker<-c(rep("Manufacter",3),
                rep("Customer",
                    nrow(route)-3))

leaflet(data = route) %>% 
  addTiles() %>%
  addAwesomeMarkers(
             lng = ~Longitude, 
             lat = ~Latitude, 
             label = ~labels,
             icon = ~logos[ticker]) %>% 
  setView(lng = mean(route$Longitude), 
          lat = mean(route$Latitude),
          zoom = 7) 

The location of all customers and internal manufacters

In the following code, I want to emphasize that the names of colors should have the first letter capitalized. For example, use “Red” instead of “red”.

You might be wondering why this is important, and I had the same question :)). After some online research, I found a response to a similar question about changing the color of markers in R using Leaflet Leaflet change color of markers (R).

It was mentioned that capitalizing the first letter allows R to color the markers based on different factors. If you don’t capitalize the first letter, R will color the markers randomly (I’m not sure why).

Code
#Setting the level of status
route$Status<-fct_relevel(route$Status,"Control","Warning","Outstock")

#Prepare palette for labeling control/warning/outstock:
palPwr <- leaflet::colorFactor(palette = c("Lightgreen","Yellow","Red"), 
                               domain = route$Status,
                               ordered = T)

#Prepare font for labeling
font<-labelOptions(noHide = T, 
                  direction = "bottom",
                  style = list(
        "font-family" = "serif",
        "font-style" = "ilatic",
        "box-shadow" = "3px 3px rgba(0,0,0,0.25)",
        "font-size" = "10px",
        "border-color" = "rgba(0,0,0,0.5)"
      ))

#Plot map with leaflet:
library(leaflet.extras)
Warning: package 'leaflet.extras' was built under R version 4.2.3
Code
leaflet(data = route) %>% 
  addProviderTiles("CartoDB.Positron") %>% 
  addCircleMarkers(radius = 10, # size of the dots
                   fillOpacity = .7, # alpha of the dots
                   stroke = FALSE, # no outline
                   label = ~labels,
                   lng = ~Longitude, 
                   lat = ~Latitude, 
                   color = ~palPwr(route$Status),
                   clusterOptions = markerClusterOptions(),
                   labelOptions = font) %>% 
  leaflet::addLegend(position = "bottomright",
            values = ~Status, # data frame column for legend
            opacity = .7,
            pal = palPwr, # palette declared earlier
            title = "Status") %>%   # legend titleƯ
  addResetMapButton()

The mini map by clustering the locations

Also for adjusting the base map, you can base on the preview of base map in Leaflet preview and copy the name of provider to paste in the argument {addProviderTitles}. For instance, I use provider = CartoDB.Positron.

Routing the vehicle’s path for Supply Chain Plan:

To set up the connection between RStudio and GitHub, you can use the source() function and assign the URL link of the GitHub repository that contains the R script you need. Remember to click on “Raw” to move to another page and then copy that URL.

I found the original code in Viktor Plamenov’s project on GitLab. I found it convenient to use, so I copied and uploaded it to my private GitHub repository. You can use this URL for your work.

The author created the package {vrpoptima} for easily install and using it. You can install by package {remote}, another details you can read in this link remotes

Code
library(vrpoptima)
colnames(optimize)[2:3]<-c("lat","lon")
colnames(new_manufacter)[2:3]<-c("lat","lon")

mat_optimize<-as.matrix(optimize[,2:3])

dist_optimize<-as.matrix(geodist::geodist(mat_optimize,measure = 'haversine')/1000)

mat_WH<-as.matrix(new_manufacter[,2:3])

Next, just simply add the criteria and run the code illustrated below.

$routes
          Visit_0 Visit_1 Visit_2 Visit_3 Visit_4 Visit_5 Visit_6 Visit_7
Vehicle_1       1       9      27      37      24      48      18      30
Vehicle_2       2      26      12      35      17      40       3      44
Vehicle_3       3      29      41      33      19      15      31      14
          Visit_8 Visit_9 Visit_10 Visit_11 Visit_12 Visit_13 Visit_14 Visit_15
Vehicle_1       8      22       23       49       36       50       38       47
Vehicle_2      32      20        4       46       25       13       42        5
Vehicle_3      43      16        1       39        2       34       21        7
          Visit_16 Visit_17 Visit_18 Visit_19 Visit_20 Visit_21
Vehicle_1       11        6       45       28        1       NA
Vehicle_2        2       NA       NA       NA       NA       NA
Vehicle_3       10        3       NA       NA       NA       NA

$max_distance
[1] 859.1384

$dist_history
   [1] 2157.0102 2019.8126 2019.8126 1993.6344 1962.7287 1929.4141 1929.4141
   [8] 1838.2808 1838.2808 1838.2808 1829.7096 1829.7096 1820.7964 1792.3697
  [15] 1792.3697 1789.3234 1779.1908 1779.1908 1768.4646 1768.4646 1695.6682
  [22] 1695.6682 1695.6682 1691.3768 1688.8695 1573.9464 1526.4847 1526.4847
  [29] 1526.4847 1526.4847 1524.2393 1524.2393 1511.3719 1511.3719 1511.3719
  [36] 1511.3719 1511.3719 1506.9532 1506.9532 1506.9532 1476.2815 1476.2815
  [43] 1476.2815 1461.1313 1461.1313 1461.1313 1461.1313 1454.0843 1426.1140
  [50] 1426.1140 1407.0913 1407.0913 1403.3359 1403.3359 1403.3359 1402.8698
  [57] 1400.5365 1400.5365 1400.5365 1400.5365 1400.5365 1400.5365 1336.9537
  [64] 1336.9537 1336.5818 1336.5818 1332.9991 1332.9991 1332.9991 1332.9991
  [71] 1332.9991 1305.5091 1305.5091 1305.5091 1293.7938 1293.7938 1293.7938
  [78] 1293.5113 1293.5113 1293.5113 1293.5113 1293.5113 1289.1817 1289.1817
  [85] 1289.1817 1289.0453 1288.0207 1288.0207 1288.0207 1288.0207 1288.0207
  [92] 1287.5702 1287.5702 1287.5702 1287.5702 1287.5702 1284.4084 1284.4084
  [99] 1272.1119 1267.3489 1267.3489 1267.3489 1267.3489 1260.7566 1260.7566
 [106] 1260.7566 1260.7566 1260.7566 1260.7566 1260.7566 1252.7571 1252.2824
 [113] 1252.2824 1252.2824 1252.2824 1249.5125 1249.5125 1248.2594 1248.2594
 [120] 1248.2594 1248.2594 1159.9196 1159.9196 1159.9196 1158.9226 1141.3769
 [127] 1141.3769 1141.3769 1133.7011 1133.7011 1133.7011 1132.6252 1132.6252
 [134] 1129.1544 1129.1544 1129.1544 1129.1544 1129.1544 1129.1544 1129.1544
 [141] 1129.1544 1129.1544 1129.1544 1129.1544 1122.1943 1122.1943 1122.1943
 [148] 1122.1943 1118.9316 1118.9316 1110.5421 1110.5421 1106.5385 1106.5385
 [155] 1106.5385 1106.5385 1106.5385 1106.5385 1106.5385 1106.5385 1101.9891
 [162] 1101.9891 1101.9891 1101.9891 1097.4732 1097.4732 1097.4732 1097.4732
 [169] 1097.4732 1097.4732 1097.4732 1097.4732 1097.4732 1094.5156 1094.5156
 [176] 1094.5156 1094.5156 1094.5156 1094.5156 1094.5156 1094.5156 1094.5156
 [183] 1094.5156 1094.5156 1094.5156 1088.5980 1088.5980 1088.5980 1023.0246
 [190] 1023.0246 1023.0246 1023.0246 1023.0246 1023.0246 1023.0246 1023.0246
 [197] 1020.9148 1020.9148 1020.9148 1020.9148 1020.9148 1020.9148 1020.9148
 [204] 1020.9148 1020.9148 1020.9148 1020.9148 1020.1796 1020.1796 1020.1796
 [211] 1019.8530 1014.2421 1014.2421 1010.2909 1010.2909 1010.2909 1010.2909
 [218] 1003.2305 1003.2305 1003.2305 1003.2305 1003.2305 1003.2305 1003.2305
 [225] 1003.2305 1003.2305 1003.2305 1003.2305 1003.2305 1003.2305  999.4814
 [232]  999.4814  999.4814  999.4814  999.4814  999.4814  999.4814  999.4814
 [239]  999.4814  999.4814  999.4814  999.4814  995.5133  995.5133  995.5133
 [246]  995.5133  995.5133  995.5133  995.5133  995.5133  995.5133  995.5133
 [253]  988.9405  988.9405  988.9405  988.9405  988.9405  988.9405  988.9405
 [260]  988.9405  988.9405  988.9405  988.9405  988.9405  988.9405  988.6217
 [267]  988.6217  988.6217  988.6217  988.6217  988.6217  988.6217  988.6217
 [274]  988.6217  988.6217  988.6217  973.7638  973.7638  973.7638  973.7638
 [281]  973.7638  973.7638  973.7638  973.7638  973.7638  973.7638  973.7638
 [288]  973.7638  973.5686  973.5686  973.5686  967.6367  967.6367  967.6367
 [295]  967.6367  967.6367  967.6367  967.6367  967.6367  967.6367  967.1687
 [302]  967.1687  967.1687  967.1687  967.1687  967.1687  965.2506  965.2506
 [309]  965.2506  952.3005  952.3005  952.3005  952.3005  952.3005  952.3005
 [316]  949.9239  949.9239  936.2193  936.2193  936.2193  933.7378  933.7378
 [323]  933.7378  933.7378  929.3341  929.3341  929.3341  929.3341  929.3341
 [330]  929.3341  929.3341  929.3341  929.3341  929.3341  929.3341  929.3341
 [337]  929.3341  919.5941  919.5941  919.5941  919.5941  919.5941  919.5941
 [344]  919.5941  919.5941  919.5941  919.5941  919.5941  919.5941  919.5941
 [351]  919.5941  919.5941  919.5941  918.8515  918.8515  918.8515  918.8515
 [358]  918.8515  918.8515  918.8515  903.6400  903.6400  903.6400  902.2651
 [365]  902.2651  902.2651  902.2651  902.2651  902.2651  902.2651  902.2651
 [372]  902.2651  902.2651  902.2651  902.2651  902.2651  902.2651  902.2651
 [379]  901.8053  901.8053  901.8053  901.8053  901.8053  901.8053  901.8053
 [386]  901.8053  901.8053  901.8053  900.7952  900.7952  900.7952  900.7952
 [393]  900.7952  900.7952  900.7952  900.7952  900.7952  900.7952  900.7952
 [400]  900.7952  900.7952  900.7952  900.7952  900.7952  900.7952  900.7952
 [407]  898.1420  898.1420  898.1420  898.1420  898.1420  898.1420  898.1420
 [414]  898.1420  898.1420  898.1420  898.1420  898.1420  898.1420  898.1420
 [421]  898.1420  898.1420  898.1420  898.1420  898.1420  898.1420  898.1420
 [428]  898.1420  898.1420  898.1420  898.1420  898.1420  898.1420  898.1420
 [435]  898.1420  898.1420  898.1420  898.1420  898.1420  898.1420  898.1420
 [442]  898.1420  898.1420  898.1420  898.1420  898.1420  898.1420  898.1420
 [449]  898.1420  898.1420  898.1420  898.1420  898.1420  898.1420  898.1420
 [456]  898.1420  898.1420  898.1420  898.1420  898.1420  898.1420  880.0303
 [463]  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303
 [470]  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303
 [477]  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303
 [484]  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303
 [491]  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303
 [498]  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303
 [505]  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303
 [512]  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303
 [519]  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303
 [526]  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303
 [533]  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303
 [540]  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303  880.0303
 [547]  880.0303  880.0303  880.0303  880.0303  880.0303  876.8357  876.8357
 [554]  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357
 [561]  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357
 [568]  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357
 [575]  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357
 [582]  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357
 [589]  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357
 [596]  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357
 [603]  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357
 [610]  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357
 [617]  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357
 [624]  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357
 [631]  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357
 [638]  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357
 [645]  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357
 [652]  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357  876.8357
 [659]  876.4823  876.4823  876.4823  876.4823  876.4823  876.4823  876.4823
 [666]  876.4823  876.4823  876.2715  876.2715  876.2715  876.2715  876.2715
 [673]  876.2715  876.2715  876.2715  876.2715  876.2715  876.2715  876.2715
 [680]  876.2715  876.2715  876.2715  876.2715  876.2715  876.2715  876.2715
 [687]  876.2715  876.2715  876.2715  876.2715  876.2715  876.2715  869.4151
 [694]  869.4151  869.4151  869.4151  869.4151  869.4151  869.3025  869.3025
 [701]  869.3025  869.3025  869.3025  869.3025  869.3025  869.3025  869.3025
 [708]  869.3025  869.3025  869.3025  869.3025  869.3025  869.3025  869.3025
 [715]  869.3025  869.3025  869.3025  869.3025  869.3025  869.3025  869.3025
 [722]  869.3025  869.3025  868.9277  868.9277  868.9277  868.9277  868.9277
 [729]  867.3143  867.3143  867.3143  867.3143  867.3143  867.3143  867.3143
 [736]  867.3143  867.3143  867.3143  867.3143  867.3143  867.3143  867.3143
 [743]  867.3143  867.3143  867.3143  867.3143  867.3143  867.3143  867.3143
 [750]  867.2557  867.2557  867.2557  867.2557  867.2557  867.2557  867.2557
 [757]  867.2557  867.2557  867.2557  867.2557  861.6750  861.6750  861.6750
 [764]  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750
 [771]  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750
 [778]  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750
 [785]  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750
 [792]  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750
 [799]  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750
 [806]  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750
 [813]  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750
 [820]  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750
 [827]  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750
 [834]  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750
 [841]  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750
 [848]  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750
 [855]  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750
 [862]  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750  861.6750
 [869]  861.6750  861.6750  861.6750  861.6750  861.6750  861.4012  861.4012
 [876]  861.4012  861.4012  861.4012  861.4012  861.4012  861.4012  861.4012
 [883]  861.4012  861.4012  861.4012  861.4012  861.4012  861.4012  861.4012
 [890]  861.4012  861.4012  861.4012  861.4012  861.4012  861.4012  861.4012
 [897]  861.4012  861.4012  861.4012  861.4012  861.4012  861.4012  861.4012
 [904]  861.4012  861.4012  861.4012  859.6236  859.6236  859.6236  859.6236
 [911]  859.6236  859.6236  859.6236  859.6236  859.6236  859.6236  859.6236
 [918]  859.6236  859.6236  859.6236  859.6236  859.6236  859.6236  859.6236
 [925]  859.6236  859.6236  859.6236  859.6236  859.6236  859.6236  859.6236
 [932]  859.6236  859.6236  859.6236  859.6236  859.6236  859.6236  859.6236
 [939]  859.6236  859.6236  859.6236  859.6236  859.6236  859.6236  859.6236
 [946]  859.6236  859.6236  859.6236  859.6236  859.6236  859.6236  859.6236
 [953]  859.6236  859.6236  859.6236  859.6236  859.6236  859.6236  859.6236
 [960]  859.6236  859.6236  859.6236  859.6236  859.6236  859.6236  859.6236
 [967]  859.6236  859.6236  859.6236  859.6236  859.6236  859.6236  859.6236
 [974]  859.1384  859.1384  859.1384  859.1384  859.1384  859.1384  859.1384
 [981]  859.1384  859.1384  859.1384  859.1384  859.1384  859.1384  859.1384
 [988]  859.1384  859.1384  859.1384  859.1384  859.1384  859.1384  859.1384
 [995]  859.1384  859.1384  859.1384  859.1384  859.1384  859.1384

$tour_lengths
[1] 867.1374 842.1410 729.5229

Finally, plot the results of optimization by two functions:

  • PlotToursCombined function: use to display of the combined routes created with the genetic program.

  • PlotToursIndividual function: use to display of the individual routes created with the genetic program.

Code
#Plot the results:
routes <- solution$routes
rownames(routes) <- 1:nrow(routes)
routes_list = RoutesDataPrep(routes = solution$routes, 
                             visit_points = mat_optimize, 
                             agent_points = as.matrix(new_manufacter[,2:3]))


# Display all routes at the same time
PlotToursCombined(solution = solution, 
                  routes_list = routes_list,
                  agent_locations = as.matrix(new_manufacter[,2:3]),
                  orientation = "vertical")

Code
# Display all the inidividual routes on a single figure block
PlotToursIndividual(solution = solution, 
                    routes_list = routes_list)

References:

Thanks to all authors of documentaions below that help me complete this pratice.