This notebook illustrates how to “solve” (heuristically) a problem posted on OR Stack Exchange. In it, two integer values must be chosen (from specified ranges), and then of a large number (nStores) of stores must be assigned one of the two values, so as to minimize a nonlinear cost function. Assignments are constrained by a requirement that a certain nonlinear function fall within a specified range (referred to below as the “balance constraint”).

Problem setup

library(GA)      # the GA package provides a genetic algorithm implementation
Loading required package: foreach
Loading required package: iterators
  ____    _    
 / ___|  / \     Genetic 
| |  _  / _ \    Algorithms
| |_| |/ ___ \   
 \____/_/   \_\  version 3.2
Type 'citation("GA")' for citing this R package in publications.

Attaching package: ‘GA’

The following object is masked from ‘package:utils’:

    de
library(tictoc)  # to time the GA

We will make up parameters for test purposes, following the notation of the original post where possible. (The coefficient \(a\) in the original post is assumed without loss of generality to be 1.)

set.seed(123)    # seed the random number stream (for reproducibility)
nStores <- 1000  # number of stores
k1 <- 6          # first variant is between 1 and k1 inclusive
k2 <- 12         # second variant is between k1 and k2 inclusive
b <- -0.8        # exponent of the cost function
s1 <- runif(nStores, 1, 2)    # leading coefficients of cost function
s2 <- runif(nStores, k1, k2)  # numerators of cost function
s3 <- runif(nStores, 1, 3)    # numerators of the balance constraint
temp <- sum(s3) / k1          # target for the balance constraint
blo <- 0.95 * temp            # lower balance limit
bhi <- 1.05 * temp            # upper balance limit

Next, we set the cost function based on a vector of assignments to the stores.

cost <- function(x) {
  s1 %*% (s2 / x)^b
}

We also need a function that calculates the “balance” value for a vector of assignments.

balance <- function(x) {
  sum(s3 / x)
}

GA

The first solution approach will be to use a variant of a random key genetic algorithm, in which the chromosome combines two integer genes (designating the two values to be assigned) with nStores real genes that define a permutation of the stores, indicating the order in which stores will be assigned values.

We need a function to decode a GA “solution” (vector of nStores + 2 numbers) into a valid assignment. The first two values in the solution will be in the range [1, k1 + 1) and [k1, k2 + 1) respectively; we truncate them to get the two assignment choices (“variant1” and “variant2” in the original post). The remaining values are between 0 and 1, and are used to sequence the stores (dictating the order in which they will be assigned values). The return value will consist of a list containing the variants, the assignments and the solution cost.

decode <- function(x) {
  # Extract the variants.
  v1 <- floor(x[1])
  v2 <- floor(x[2])
  # The smaller variant is cheaper if b is negative; the larger variant is cheaper
  # if b is positive.
  if (b < 0) {
    cheap <- v1
  } else {
    cheap <- v2
  }
  # Translate the remaining values into a permutation vector for the stores.
  ix <- order(x[-(1:2)])
  # Initially assign every store the cheaper variant.
  a <- rep.int(cheap, nStores)
  # Calculate the value of the balance function.
  temp <- balance(a)
  # Iterate through stores until balance is achieved. At each store, switch
  # to the lower variant to increase the balance score if it is too low,
  # provided that the switch does not make the score too high, and vice versa if
  # the balance is too high.
  for (i in 1:nStores) {
    j <- ix[i]  # index of the store to mess with
    if (temp < blo & a[j] == v2) {
      # Compute the impact of switching to the smaller variant.
      delta <- s3[j] / v1 - s3[j] / v2
      # Test whether this would violate the upper limit.
      # If not, make the switch.
      if (temp + delta <= bhi) {
        a[j] <- v1
        temp <- temp + delta
      }
    } else if (temp > bhi & a[j] == v1) {
      # Compute the impact of switching to the larger variant.
      delta <- s3[j] / v2 - s3[j] / v1
      # Test whether this would violate the upper limit.
      # If not, make the switch.
      if (temp + delta >= blo) {
        a[j] <- v2
        temp <- temp + delta
      }
    } else if (temp >= blo & temp <= bhi) {
      # The solution is in balance, so break out of the loop.
      break
    }
  }
  # If the solution is still out of balance, issue a warning and return NA
  # (we failed to repair it).
  # Otherwise, return a list of variants, assignments and cost, as well as the
  # balance score.
  if (temp < blo | temp > bhi) {
    warning("Discarding an infeasible chromosome.")
    NA
  } else {
    list(cost = cost(a), variant1 = v1, variant2 = v2, assignment = a, balance = temp)
  }
}

Since the GA package maximizes fitness, we define the fitness of a solution to be the negative of the cost after decoding.

fit <- function(x) {
  -decode(x)$cost
}

Now we can run a genetic algorithm and see what we get. Several parameters (along with the random seed) can be played with.

tic("GA")
genalg <- ga(type = "real-valued",
             fitness = fit,
             lower = c(1, k1, rep.int(0, nStores)),
             upper = c(k1 + 1, k2 + 1, rep.int(1, nStores)),
             popSize = 100,   # number of solutions in each generation
             run = 20,        # stop after this many consecutive generations with no improvement
             maxiter = 1000)  # stop after this many generations even if still progressing
GA | iter = 1 | Mean = -1243.641 | Best = -1078.233
GA | iter = 2 | Mean = -1203.701 | Best = -1078.233
GA | iter = 3 | Mean = -1175.706 | Best = -1078.025
GA | iter = 4 | Mean = -1145.919 | Best = -1078.025
GA | iter = 5 | Mean = -1127.332 | Best = -1078.025
GA | iter = 6 | Mean = -1114.580 | Best = -1077.494
GA | iter = 7 | Mean = -1104.081 | Best = -1077.254
GA | iter = 8 | Mean = -1099.836 | Best = -1077.254
GA | iter = 9 | Mean = -1090.922 | Best = -1076.654
GA | iter = 10 | Mean = -1085.036 | Best = -1076.654
GA | iter = 11 | Mean = -1080.940 | Best = -1076.654
GA | iter = 12 | Mean = -1078.029 | Best = -1076.654
GA | iter = 13 | Mean = -1077.861 | Best = -1076.406
GA | iter = 14 | Mean = -1077.706 | Best = -1076.406
GA | iter = 15 | Mean = -1077.492 | Best = -1076.058
GA | iter = 16 | Mean = -1077.398 | Best = -1076.058
GA | iter = 17 | Mean = -1077.282 | Best = -1076.058
GA | iter = 18 | Mean = -1077.146 | Best = -1076.058
GA | iter = 19 | Mean = -1077.087 | Best = -1076.058
GA | iter = 20 | Mean = -1077.046 | Best = -1076.058
GA | iter = 21 | Mean = -1076.997 | Best = -1076.058
GA | iter = 22 | Mean = -1076.980 | Best = -1076.058
GA | iter = 23 | Mean = -1076.911 | Best = -1076.058
GA | iter = 24 | Mean = -1076.826 | Best = -1076.058
GA | iter = 25 | Mean = -1076.706 | Best = -1076.058
GA | iter = 26 | Mean = -1076.635 | Best = -1076.058
GA | iter = 27 | Mean = -1076.535 | Best = -1076.058
GA | iter = 28 | Mean = -1076.472 | Best = -1076.058
GA | iter = 29 | Mean = -1076.369 | Best = -1075.975
GA | iter = 30 | Mean = -1076.349 | Best = -1075.829
GA | iter = 31 | Mean = -1076.308 | Best = -1075.829
GA | iter = 32 | Mean = -1076.259 | Best = -1075.829
GA | iter = 33 | Mean = -1076.177 | Best = -1075.677
GA | iter = 34 | Mean = -1076.150 | Best = -1075.677
GA | iter = 35 | Mean = -1076.096 | Best = -1075.677
GA | iter = 36 | Mean = -1076.073 | Best = -1075.677
GA | iter = 37 | Mean = -1076.052 | Best = -1075.677
GA | iter = 38 | Mean = -1075.985 | Best = -1075.604
GA | iter = 39 | Mean = -1075.906 | Best = -1075.575
GA | iter = 40 | Mean = -1075.868 | Best = -1075.575
GA | iter = 41 | Mean = -1075.846 | Best = -1075.575
GA | iter = 42 | Mean = -1075.801 | Best = -1075.575
GA | iter = 43 | Mean = -1075.783 | Best = -1075.575
GA | iter = 44 | Mean = -1075.753 | Best = -1075.575
GA | iter = 45 | Mean = -1075.706 | Best = -1075.522
GA | iter = 46 | Mean = -1075.688 | Best = -1075.522
GA | iter = 47 | Mean = -1075.675 | Best = -1075.471
GA | iter = 48 | Mean = -1075.642 | Best = -1075.464
GA | iter = 49 | Mean = -1075.610 | Best = -1075.464
GA | iter = 50 | Mean = -1075.566 | Best = -1075.453
GA | iter = 51 | Mean = -1075.516 | Best = -1075.453
GA | iter = 52 | Mean = -1075.503 | Best = -1075.443
GA | iter = 53 | Mean = -1075.491 | Best = -1075.443
GA | iter = 54 | Mean = -1075.478 | Best = -1075.397
GA | iter = 55 | Mean = -1075.467 | Best = -1075.397
GA | iter = 56 | Mean = -1075.461 | Best = -1075.288
GA | iter = 57 | Mean = -1075.458 | Best = -1075.202
GA | iter = 58 | Mean = -1075.453 | Best = -1075.202
GA | iter = 59 | Mean = -1075.452 | Best = -1075.202
GA | iter = 60 | Mean = -1075.435 | Best = -1075.202
GA | iter = 61 | Mean = -1075.421 | Best = -1075.202
GA | iter = 62 | Mean = -1075.375 | Best = -1075.122
GA | iter = 63 | Mean = -1075.346 | Best = -1075.122
GA | iter = 64 | Mean = -1075.311 | Best = -1075.118
GA | iter = 65 | Mean = -1075.251 | Best = -1075.106
GA | iter = 66 | Mean = -1075.207 | Best = -1074.872
GA | iter = 67 | Mean = -1075.198 | Best = -1074.872
GA | iter = 68 | Mean = -1075.201 | Best = -1074.872
GA | iter = 69 | Mean = -1075.192 | Best = -1074.872
GA | iter = 70 | Mean = -1075.156 | Best = -1074.872
GA | iter = 71 | Mean = -1075.112 | Best = -1074.872
GA | iter = 72 | Mean = -1075.052 | Best = -1074.872
GA | iter = 73 | Mean = -1075.105 | Best = -1074.864
GA | iter = 74 | Mean = -1075.008 | Best = -1074.852
GA | iter = 75 | Mean = -1074.950 | Best = -1074.661
GA | iter = 76 | Mean = -1074.929 | Best = -1074.661
GA | iter = 77 | Mean = -1074.909 | Best = -1074.600
GA | iter = 78 | Mean = -1074.856 | Best = -1074.600
GA | iter = 79 | Mean = -1074.801 | Best = -1074.581
GA | iter = 80 | Mean = -1074.728 | Best = -1074.514
GA | iter = 81 | Mean = -1074.722 | Best = -1074.514
GA | iter = 82 | Mean = -1074.630 | Best = -1074.464
GA | iter = 83 | Mean = -1074.614 | Best = -1074.464
GA | iter = 84 | Mean = -1074.616 | Best = -1074.342
GA | iter = 85 | Mean = -1074.587 | Best = -1074.280
GA | iter = 86 | Mean = -1074.533 | Best = -1074.280
GA | iter = 87 | Mean = -1074.492 | Best = -1074.255
GA | iter = 88 | Mean = -1074.454 | Best = -1074.255
GA | iter = 89 | Mean = -1074.423 | Best = -1074.255
GA | iter = 90 | Mean = -1074.367 | Best = -1074.205
GA | iter = 91 | Mean = -1074.300 | Best = -1074.203
GA | iter = 92 | Mean = -1074.272 | Best = -1074.156
GA | iter = 93 | Mean = -1074.239 | Best = -1074.156
GA | iter = 94 | Mean = -1074.232 | Best = -1074.110
GA | iter = 95 | Mean = -1074.212 | Best = -1074.024
GA | iter = 96 | Mean = -1074.200 | Best = -1074.024
GA | iter = 97 | Mean = -1074.182 | Best = -1074.024
GA | iter = 98 | Mean = -1074.140 | Best = -1074.024
GA | iter = 99 | Mean = -1074.118 | Best = -1073.952
GA | iter = 100 | Mean = -1074.068 | Best = -1073.949
GA | iter = 101 | Mean = -1074.028 | Best = -1073.824
GA | iter = 102 | Mean = -1074.011 | Best = -1073.824
GA | iter = 103 | Mean = -1073.993 | Best = -1073.824
GA | iter = 104 | Mean = -1073.971 | Best = -1073.809
GA | iter = 105 | Mean = -1073.944 | Best = -1073.809
GA | iter = 106 | Mean = -1073.913 | Best = -1073.809
GA | iter = 107 | Mean = -1073.891 | Best = -1073.718
GA | iter = 108 | Mean = -1073.855 | Best = -1073.718
GA | iter = 109 | Mean = -1073.842 | Best = -1073.718
GA | iter = 110 | Mean = -1073.812 | Best = -1073.718
GA | iter = 111 | Mean = -1073.795 | Best = -1073.718
GA | iter = 112 | Mean = -1073.783 | Best = -1073.711
GA | iter = 113 | Mean = -1073.761 | Best = -1073.697
GA | iter = 114 | Mean = -1073.735 | Best = -1073.677
GA | iter = 115 | Mean = -1073.725 | Best = -1073.677
GA | iter = 116 | Mean = -1073.716 | Best = -1073.677
GA | iter = 117 | Mean = -1073.725 | Best = -1073.677
GA | iter = 118 | Mean = -1073.715 | Best = -1073.582
GA | iter = 119 | Mean = -1073.713 | Best = -1073.582
GA | iter = 120 | Mean = -1073.700 | Best = -1073.582
GA | iter = 121 | Mean = -1073.680 | Best = -1073.582
GA | iter = 122 | Mean = -1073.655 | Best = -1073.361
GA | iter = 123 | Mean = -1073.639 | Best = -1073.361
GA | iter = 124 | Mean = -1073.611 | Best = -1073.361
GA | iter = 125 | Mean = -1073.548 | Best = -1073.334
GA | iter = 126 | Mean = -1073.475 | Best = -1073.334
GA | iter = 127 | Mean = -1073.398 | Best = -1073.334
GA | iter = 128 | Mean = -1073.367 | Best = -1073.313
GA | iter = 129 | Mean = -1073.363 | Best = -1073.156
GA | iter = 130 | Mean = -1073.354 | Best = -1073.156
GA | iter = 131 | Mean = -1073.350 | Best = -1073.113
GA | iter = 132 | Mean = -1073.336 | Best = -1073.113
GA | iter = 133 | Mean = -1073.307 | Best = -1073.113
GA | iter = 134 | Mean = -1073.271 | Best = -1073.072
GA | iter = 135 | Mean = -1073.255 | Best = -1073.072
GA | iter = 136 | Mean = -1073.217 | Best = -1072.987
GA | iter = 137 | Mean = -1073.163 | Best = -1072.987
GA | iter = 138 | Mean = -1073.110 | Best = -1072.987
GA | iter = 139 | Mean = -1073.056 | Best = -1072.987
GA | iter = 140 | Mean = -1073.011 | Best = -1072.986
GA | iter = 141 | Mean = -1072.994 | Best = -1072.986
GA | iter = 142 | Mean = -1073.001 | Best = -1072.976
GA | iter = 143 | Mean = -1072.993 | Best = -1072.976
GA | iter = 144 | Mean = -1072.993 | Best = -1072.924
GA | iter = 145 | Mean = -1072.997 | Best = -1072.924
GA | iter = 146 | Mean = -1072.997 | Best = -1072.924
GA | iter = 147 | Mean = -1072.987 | Best = -1072.924
GA | iter = 148 | Mean = -1072.998 | Best = -1072.924
GA | iter = 149 | Mean = -1072.988 | Best = -1072.924
GA | iter = 150 | Mean = -1072.986 | Best = -1072.924
GA | iter = 151 | Mean = -1072.985 | Best = -1072.924
GA | iter = 152 | Mean = -1072.979 | Best = -1072.924
GA | iter = 153 | Mean = -1072.967 | Best = -1072.881
GA | iter = 154 | Mean = -1072.951 | Best = -1072.803
GA | iter = 155 | Mean = -1072.943 | Best = -1072.803
GA | iter = 156 | Mean = -1072.935 | Best = -1072.803
GA | iter = 157 | Mean = -1072.932 | Best = -1072.803
GA | iter = 158 | Mean = -1072.922 | Best = -1072.803
GA | iter = 159 | Mean = -1072.904 | Best = -1072.747
GA | iter = 160 | Mean = -1072.886 | Best = -1072.747
GA | iter = 161 | Mean = -1072.862 | Best = -1072.735
GA | iter = 162 | Mean = -1072.831 | Best = -1072.722
GA | iter = 163 | Mean = -1072.799 | Best = -1072.591
GA | iter = 164 | Mean = -1072.777 | Best = -1072.573
GA | iter = 165 | Mean = -1072.753 | Best = -1072.573
GA | iter = 166 | Mean = -1072.736 | Best = -1072.573
GA | iter = 167 | Mean = -1072.714 | Best = -1072.573
GA | iter = 168 | Mean = -1072.679 | Best = -1072.573
GA | iter = 169 | Mean = -1072.642 | Best = -1072.566
GA | iter = 170 | Mean = -1072.622 | Best = -1072.566
GA | iter = 171 | Mean = -1072.589 | Best = -1072.566
GA | iter = 172 | Mean = -1072.584 | Best = -1072.566
GA | iter = 173 | Mean = -1072.585 | Best = -1072.556
GA | iter = 174 | Mean = -1072.576 | Best = -1072.556
GA | iter = 175 | Mean = -1072.572 | Best = -1072.508
GA | iter = 176 | Mean = -1072.574 | Best = -1072.508
GA | iter = 177 | Mean = -1072.570 | Best = -1072.448
GA | iter = 178 | Mean = -1072.567 | Best = -1072.360
GA | iter = 179 | Mean = -1072.562 | Best = -1072.360
GA | iter = 180 | Mean = -1072.541 | Best = -1072.360
GA | iter = 181 | Mean = -1072.527 | Best = -1072.360
GA | iter = 182 | Mean = -1072.508 | Best = -1072.291
GA | iter = 183 | Mean = -1072.500 | Best = -1072.291
GA | iter = 184 | Mean = -1072.484 | Best = -1072.291
GA | iter = 185 | Mean = -1072.452 | Best = -1072.253
GA | iter = 186 | Mean = -1072.446 | Best = -1072.253
GA | iter = 187 | Mean = -1072.412 | Best = -1072.253
GA | iter = 188 | Mean = -1072.379 | Best = -1072.245
GA | iter = 189 | Mean = -1072.342 | Best = -1072.245
GA | iter = 190 | Mean = -1072.304 | Best = -1072.245
GA | iter = 191 | Mean = -1072.283 | Best = -1072.245
GA | iter = 192 | Mean = -1072.275 | Best = -1072.245
GA | iter = 193 | Mean = -1072.265 | Best = -1072.240
GA | iter = 194 | Mean = -1072.263 | Best = -1072.240
GA | iter = 195 | Mean = -1072.261 | Best = -1072.191
GA | iter = 196 | Mean = -1072.263 | Best = -1072.191
GA | iter = 197 | Mean = -1072.259 | Best = -1072.191
GA | iter = 198 | Mean = -1072.264 | Best = -1072.191
GA | iter = 199 | Mean = -1072.257 | Best = -1072.178
GA | iter = 200 | Mean = -1072.257 | Best = -1072.178
GA | iter = 201 | Mean = -1072.252 | Best = -1072.082
GA | iter = 202 | Mean = -1072.242 | Best = -1072.082
GA | iter = 203 | Mean = -1072.243 | Best = -1072.050
GA | iter = 204 | Mean = -1072.222 | Best = -1072.050
GA | iter = 205 | Mean = -1072.196 | Best = -1072.050
GA | iter = 206 | Mean = -1072.144 | Best = -1072.016
GA | iter = 207 | Mean = -1072.100 | Best = -1072.016
GA | iter = 208 | Mean = -1072.081 | Best = -1071.918
GA | iter = 209 | Mean = -1072.065 | Best = -1071.918
GA | iter = 210 | Mean = -1072.047 | Best = -1071.870
GA | iter = 211 | Mean = -1072.034 | Best = -1071.870
GA | iter = 212 | Mean = -1072.303 | Best = -1071.870
GA | iter = 213 | Mean = -1072.028 | Best = -1071.870
GA | iter = 214 | Mean = -1071.983 | Best = -1071.797
GA | iter = 215 | Mean = -1071.951 | Best = -1071.797
GA | iter = 216 | Mean = -1071.927 | Best = -1071.797
GA | iter = 217 | Mean = -1071.926 | Best = -1071.797
GA | iter = 218 | Mean = -1071.912 | Best = -1071.797
GA | iter = 219 | Mean = -1071.903 | Best = -1071.797
GA | iter = 220 | Mean = -1071.902 | Best = -1071.797
GA | iter = 221 | Mean = -1071.902 | Best = -1071.797
GA | iter = 222 | Mean = -1071.892 | Best = -1071.786
GA | iter = 223 | Mean = -1071.856 | Best = -1071.769
GA | iter = 224 | Mean = -1072.848 | Best = -1071.769
GA | iter = 225 | Mean = -1071.837 | Best = -1071.769
GA | iter = 226 | Mean = -1071.809 | Best = -1071.744
GA | iter = 227 | Mean = -1071.799 | Best = -1071.700
GA | iter = 228 | Mean = -1071.792 | Best = -1071.700
GA | iter = 229 | Mean = -1071.786 | Best = -1071.597
GA | iter = 230 | Mean = -1071.782 | Best = -1071.539
GA | iter = 231 | Mean = -1071.769 | Best = -1071.539
GA | iter = 232 | Mean = -1071.753 | Best = -1071.539
GA | iter = 233 | Mean = -1071.744 | Best = -1071.539
GA | iter = 234 | Mean = -1071.720 | Best = -1071.539
GA | iter = 235 | Mean = -1071.693 | Best = -1071.539
GA | iter = 236 | Mean = -1071.670 | Best = -1071.539
GA | iter = 237 | Mean = -1071.658 | Best = -1071.539
GA | iter = 238 | Mean = -1071.632 | Best = -1071.528
GA | iter = 239 | Mean = -1071.634 | Best = -1071.528
GA | iter = 240 | Mean = -1071.620 | Best = -1071.512
GA | iter = 241 | Mean = -1071.624 | Best = -1071.512
GA | iter = 242 | Mean = -1071.610 | Best = -1071.512
GA | iter = 243 | Mean = -1071.603 | Best = -1071.506
GA | iter = 244 | Mean = -1071.602 | Best = -1071.506
GA | iter = 245 | Mean = -1071.574 | Best = -1071.478
GA | iter = 246 | Mean = -1071.574 | Best = -1071.454
GA | iter = 247 | Mean = -1071.572 | Best = -1071.410
GA | iter = 248 | Mean = -1071.546 | Best = -1071.410
GA | iter = 249 | Mean = -1071.520 | Best = -1071.169
GA | iter = 250 | Mean = -1071.502 | Best = -1071.169
GA | iter = 251 | Mean = -1071.440 | Best = -1071.169
GA | iter = 252 | Mean = -1071.393 | Best = -1071.169
GA | iter = 253 | Mean = -1071.354 | Best = -1071.139
GA | iter = 254 | Mean = -1071.309 | Best = -1071.139
GA | iter = 255 | Mean = -1071.288 | Best = -1071.139
GA | iter = 256 | Mean = -1071.264 | Best = -1071.093
GA | iter = 257 | Mean = -1071.206 | Best = -1071.059
GA | iter = 258 | Mean = -1071.205 | Best = -1071.059
GA | iter = 259 | Mean = -1071.180 | Best = -1071.059
GA | iter = 260 | Mean = -1071.171 | Best = -1070.989
GA | iter = 261 | Mean = -1071.154 | Best = -1070.989
GA | iter = 262 | Mean = -1071.124 | Best = -1070.912
GA | iter = 263 | Mean = -1071.476 | Best = -1070.912
GA | iter = 264 | Mean = -1071.117 | Best = -1070.912
GA | iter = 265 | Mean = -1071.091 | Best = -1070.912
GA | iter = 266 | Mean = -1071.052 | Best = -1070.896
GA | iter = 267 | Mean = -1070.985 | Best = -1070.837
GA | iter = 268 | Mean = -1070.941 | Best = -1070.837
GA | iter = 269 | Mean = -1070.924 | Best = -1070.837
GA | iter = 270 | Mean = -1070.913 | Best = -1070.837
GA | iter = 271 | Mean = -1070.899 | Best = -1070.837
GA | iter = 272 | Mean = -1070.876 | Best = -1070.772
GA | iter = 273 | Mean = -1070.848 | Best = -1070.693
GA | iter = 274 | Mean = -1070.833 | Best = -1070.663
GA | iter = 275 | Mean = -1070.813 | Best = -1070.663
GA | iter = 276 | Mean = -1070.783 | Best = -1070.663
GA | iter = 277 | Mean = -1070.780 | Best = -1070.663
GA | iter = 278 | Mean = -1070.755 | Best = -1070.663
GA | iter = 279 | Mean = -1070.723 | Best = -1070.596
GA | iter = 280 | Mean = -1070.693 | Best = -1070.596
GA | iter = 281 | Mean = -1070.695 | Best = -1070.596
GA | iter = 282 | Mean = -1070.678 | Best = -1070.596
GA | iter = 283 | Mean = -1070.683 | Best = -1070.596
GA | iter = 284 | Mean = -1071.044 | Best = -1070.596
GA | iter = 285 | Mean = -1070.683 | Best = -1070.596
GA | iter = 286 | Mean = -1070.659 | Best = -1070.596
GA | iter = 287 | Mean = -1070.642 | Best = -1070.556
GA | iter = 288 | Mean = -1070.625 | Best = -1070.556
GA | iter = 289 | Mean = -1070.613 | Best = -1070.540
GA | iter = 290 | Mean = -1070.611 | Best = -1070.540
GA | iter = 291 | Mean = -1070.597 | Best = -1070.517
GA | iter = 292 | Mean = -1070.589 | Best = -1070.467
GA | iter = 293 | Mean = -1070.584 | Best = -1070.446
GA | iter = 294 | Mean = -1070.579 | Best = -1070.446
GA | iter = 295 | Mean = -1070.578 | Best = -1070.446
GA | iter = 296 | Mean = -1070.557 | Best = -1070.446
GA | iter = 297 | Mean = -1070.558 | Best = -1070.446
GA | iter = 298 | Mean = -1070.555 | Best = -1070.354
GA | iter = 299 | Mean = -1070.533 | Best = -1070.354
GA | iter = 300 | Mean = -1070.889 | Best = -1070.354
GA | iter = 301 | Mean = -1070.527 | Best = -1070.346
GA | iter = 302 | Mean = -1070.484 | Best = -1070.346
GA | iter = 303 | Mean = -1070.464 | Best = -1070.329
GA | iter = 304 | Mean = -1070.439 | Best = -1070.311
GA | iter = 305 | Mean = -1070.450 | Best = -1070.265
GA | iter = 306 | Mean = -1070.438 | Best = -1070.242
GA | iter = 307 | Mean = -1070.435 | Best = -1070.242
GA | iter = 308 | Mean = -1070.440 | Best = -1070.232
GA | iter = 309 | Mean = -1070.422 | Best = -1070.232
GA | iter = 310 | Mean = -1070.406 | Best = -1070.232
GA | iter = 311 | Mean = -1070.407 | Best = -1070.232
GA | iter = 312 | Mean = -1070.399 | Best = -1070.232
GA | iter = 313 | Mean = -1070.378 | Best = -1070.232
GA | iter = 314 | Mean = -1070.377 | Best = -1070.219
GA | iter = 315 | Mean = -1070.364 | Best = -1070.219
GA | iter = 316 | Mean = -1070.362 | Best = -1070.199
GA | iter = 317 | Mean = -1070.356 | Best = -1070.199
GA | iter = 318 | Mean = -1070.379 | Best = -1070.199
GA | iter = 319 | Mean = -1070.366 | Best = -1070.199
GA | iter = 320 | Mean = -1070.330 | Best = -1070.176
GA | iter = 321 | Mean = -1070.314 | Best = -1070.176
GA | iter = 322 | Mean = -1070.297 | Best = -1070.134
GA | iter = 323 | Mean = -1070.275 | Best = -1070.134
GA | iter = 324 | Mean = -1070.253 | Best = -1070.134
GA | iter = 325 | Mean = -1070.251 | Best = -1070.134
GA | iter = 326 | Mean = -1070.23 | Best = -1070.13
GA | iter = 327 | Mean = -1070.206 | Best = -1070.084
GA | iter = 328 | Mean = -1070.183 | Best = -1070.084
GA | iter = 329 | Mean = -1070.173 | Best = -1070.081
GA | iter = 330 | Mean = -1071.022 | Best = -1070.081
GA | iter = 331 | Mean = -1070.163 | Best = -1070.081
GA | iter = 332 | Mean = -1070.149 | Best = -1070.081
GA | iter = 333 | Mean = -1070.151 | Best = -1070.081
GA | iter = 334 | Mean = -1070.137 | Best = -1070.081
GA | iter = 335 | Mean = -1070.133 | Best = -1070.081
GA | iter = 336 | Mean = -1070.141 | Best = -1070.081
GA | iter = 337 | Mean = -1070.126 | Best = -1070.081
GA | iter = 338 | Mean = -1070.129 | Best = -1070.081
GA | iter = 339 | Mean = -1070.122 | Best = -1070.081
GA | iter = 340 | Mean = -1070.121 | Best = -1070.081
GA | iter = 341 | Mean = -1070.121 | Best = -1070.016
GA | iter = 342 | Mean = -1070.128 | Best = -1070.016
GA | iter = 343 | Mean = -1070.117 | Best = -1070.016
GA | iter = 344 | Mean = -1070.107 | Best = -1070.016
GA | iter = 345 | Mean = -1070.103 | Best = -1069.963
GA | iter = 346 | Mean = -1070.080 | Best = -1069.881
GA | iter = 347 | Mean = -1070.071 | Best = -1069.881
GA | iter = 348 | Mean = -1070.039 | Best = -1069.828
GA | iter = 349 | Mean = -1070.000 | Best = -1069.767
GA | iter = 350 | Mean = -1069.980 | Best = -1069.767
GA | iter = 351 | Mean = -1069.937 | Best = -1069.767
GA | iter = 352 | Mean = -1069.903 | Best = -1069.767
GA | iter = 353 | Mean = -1069.885 | Best = -1069.767
GA | iter = 354 | Mean = -1069.895 | Best = -1069.767
GA | iter = 355 | Mean = -1069.876 | Best = -1069.767
GA | iter = 356 | Mean = -1069.874 | Best = -1069.767
GA | iter = 357 | Mean = -1069.856 | Best = -1069.767
GA | iter = 358 | Mean = -1069.844 | Best = -1069.767
GA | iter = 359 | Mean = -1069.834 | Best = -1069.767
GA | iter = 360 | Mean = -1069.821 | Best = -1069.767
GA | iter = 361 | Mean = -1069.814 | Best = -1069.767
GA | iter = 362 | Mean = -1069.808 | Best = -1069.732
GA | iter = 363 | Mean = -1069.801 | Best = -1069.732
GA | iter = 364 | Mean = -1069.802 | Best = -1069.732
GA | iter = 365 | Mean = -1069.800 | Best = -1069.646
GA | iter = 366 | Mean = -1069.790 | Best = -1069.634
GA | iter = 367 | Mean = -1069.788 | Best = -1069.634
GA | iter = 368 | Mean = -1069.783 | Best = -1069.551
GA | iter = 369 | Mean = -1069.780 | Best = -1069.551
GA | iter = 370 | Mean = -1069.775 | Best = -1069.551
GA | iter = 371 | Mean = -1069.768 | Best = -1069.551
GA | iter = 372 | Mean = -1069.751 | Best = -1069.551
GA | iter = 373 | Mean = -1069.733 | Best = -1069.551
GA | iter = 374 | Mean = -1069.716 | Best = -1069.551
GA | iter = 375 | Mean = -1069.704 | Best = -1069.551
GA | iter = 376 | Mean = -1069.652 | Best = -1069.551
GA | iter = 377 | Mean = -1069.614 | Best = -1069.519
GA | iter = 378 | Mean = -1069.566 | Best = -1069.519
GA | iter = 379 | Mean = -1069.553 | Best = -1069.514
GA | iter = 380 | Mean = -1069.555 | Best = -1069.514
GA | iter = 381 | Mean = -1069.548 | Best = -1069.514
GA | iter = 382 | Mean = -1069.547 | Best = -1069.514
GA | iter = 383 | Mean = -1069.546 | Best = -1069.500
GA | iter = 384 | Mean = -1069.544 | Best = -1069.500
GA | iter = 385 | Mean = -1069.544 | Best = -1069.500
GA | iter = 386 | Mean = -1069.541 | Best = -1069.500
GA | iter = 387 | Mean = -1069.54 | Best = -1069.50
GA | iter = 388 | Mean = -1069.54 | Best = -1069.50
GA | iter = 389 | Mean = -1069.54 | Best = -1069.50
GA | iter = 390 | Mean = -1069.528 | Best = -1069.500
GA | iter = 391 | Mean = -1069.527 | Best = -1069.490
GA | iter = 392 | Mean = -1069.523 | Best = -1069.480
GA | iter = 393 | Mean = -1069.518 | Best = -1069.460
GA | iter = 394 | Mean = -1069.512 | Best = -1069.460
GA | iter = 395 | Mean = -1069.508 | Best = -1069.395
GA | iter = 396 | Mean = -1069.493 | Best = -1069.358
GA | iter = 397 | Mean = -1069.471 | Best = -1069.262
GA | iter = 398 | Mean = -1069.429 | Best = -1069.262
GA | iter = 399 | Mean = -1069.377 | Best = -1069.236
GA | iter = 400 | Mean = -1069.345 | Best = -1069.211
GA | iter = 401 | Mean = -1069.314 | Best = -1069.139
GA | iter = 402 | Mean = -1069.284 | Best = -1069.139
GA | iter = 403 | Mean = -1069.273 | Best = -1069.139
GA | iter = 404 | Mean = -1069.264 | Best = -1069.139
GA | iter = 405 | Mean = -1069.250 | Best = -1069.139
GA | iter = 406 | Mean = -1069.234 | Best = -1069.125
GA | iter = 407 | Mean = -1069.212 | Best = -1069.029
GA | iter = 408 | Mean = -1069.196 | Best = -1069.029
GA | iter = 409 | Mean = -1069.190 | Best = -1069.029
GA | iter = 410 | Mean = -1069.201 | Best = -1069.029
GA | iter = 411 | Mean = -1069.188 | Best = -1069.029
GA | iter = 412 | Mean = -1069.181 | Best = -1069.029
GA | iter = 413 | Mean = -1069.176 | Best = -1069.029
GA | iter = 414 | Mean = -1069.166 | Best = -1069.029
GA | iter = 415 | Mean = -1069.137 | Best = -1069.029
GA | iter = 416 | Mean = -1069.124 | Best = -1069.029
GA | iter = 417 | Mean = -1069.118 | Best = -1069.029
GA | iter = 418 | Mean = -1069.107 | Best = -1069.029
GA | iter = 419 | Mean = -1069.105 | Best = -1069.009
GA | iter = 420 | Mean = -1069.091 | Best = -1068.991
GA | iter = 421 | Mean = -1069.077 | Best = -1068.991
GA | iter = 422 | Mean = -1069.069 | Best = -1068.971
GA | iter = 423 | Mean = -1069.051 | Best = -1068.971
GA | iter = 424 | Mean = -1069.049 | Best = -1068.971
GA | iter = 425 | Mean = -1069.054 | Best = -1068.971
GA | iter = 426 | Mean = -1069.050 | Best = -1068.971
GA | iter = 427 | Mean = -1069.044 | Best = -1068.958
GA | iter = 428 | Mean = -1069.045 | Best = -1068.958
GA | iter = 429 | Mean = -1069.037 | Best = -1068.812
GA | iter = 430 | Mean = -1069.032 | Best = -1068.812
GA | iter = 431 | Mean = -1069.027 | Best = -1068.812
GA | iter = 432 | Mean = -1069.019 | Best = -1068.812
GA | iter = 433 | Mean = -1069.017 | Best = -1068.812
GA | iter = 434 | Mean = -1068.985 | Best = -1068.812
GA | iter = 435 | Mean = -1068.953 | Best = -1068.812
GA | iter = 436 | Mean = -1068.954 | Best = -1068.804
GA | iter = 437 | Mean = -1068.936 | Best = -1068.775
GA | iter = 438 | Mean = -1068.922 | Best = -1068.775
GA | iter = 439 | Mean = -1068.905 | Best = -1068.751
GA | iter = 440 | Mean = -1068.882 | Best = -1068.751
GA | iter = 441 | Mean = -1068.840 | Best = -1068.751
GA | iter = 442 | Mean = -1068.843 | Best = -1068.751
GA | iter = 443 | Mean = -1068.839 | Best = -1068.751
GA | iter = 444 | Mean = -1068.825 | Best = -1068.751
GA | iter = 445 | Mean = -1068.800 | Best = -1068.751
GA | iter = 446 | Mean = -1069.489 | Best = -1068.739
GA | iter = 447 | Mean = -1069.009 | Best = -1068.739
GA | iter = 448 | Mean = -1068.784 | Best = -1068.739
GA | iter = 449 | Mean = -1068.783 | Best = -1068.708
GA | iter = 450 | Mean = -1068.778 | Best = -1068.697
GA | iter = 451 | Mean = -1068.772 | Best = -1068.697
GA | iter = 452 | Mean = -1068.763 | Best = -1068.695
GA | iter = 453 | Mean = -1068.764 | Best = -1068.653
GA | iter = 454 | Mean = -1068.754 | Best = -1068.648
GA | iter = 455 | Mean = -1068.750 | Best = -1068.603
GA | iter = 456 | Mean = -1068.729 | Best = -1068.603
GA | iter = 457 | Mean = -1068.712 | Best = -1068.553
GA | iter = 458 | Mean = -1068.677 | Best = -1068.553
GA | iter = 459 | Mean = -1068.649 | Best = -1068.550
GA | iter = 460 | Mean = -1068.615 | Best = -1068.529
GA | iter = 461 | Mean = -1068.604 | Best = -1068.529
GA | iter = 462 | Mean = -1068.583 | Best = -1068.338
GA | iter = 463 | Mean = -1068.539 | Best = -1068.338
GA | iter = 464 | Mean = -1068.511 | Best = -1068.326
GA | iter = 465 | Mean = -1068.479 | Best = -1068.311
GA | iter = 466 | Mean = -1068.442 | Best = -1068.311
GA | iter = 467 | Mean = -1068.396 | Best = -1068.299
GA | iter = 468 | Mean = -1068.347 | Best = -1068.299
GA | iter = 469 | Mean = -1068.344 | Best = -1068.299
GA | iter = 470 | Mean = -1068.347 | Best = -1068.246
GA | iter = 471 | Mean = -1068.339 | Best = -1068.246
GA | iter = 472 | Mean = -1068.329 | Best = -1068.246
GA | iter = 473 | Mean = -1068.324 | Best = -1068.246
GA | iter = 474 | Mean = -1068.313 | Best = -1068.230
GA | iter = 475 | Mean = -1068.318 | Best = -1068.214
GA | iter = 476 | Mean = -1068.308 | Best = -1068.214
GA | iter = 477 | Mean = -1068.310 | Best = -1068.214
GA | iter = 478 | Mean = -1068.288 | Best = -1068.202
GA | iter = 479 | Mean = -1068.287 | Best = -1068.174
GA | iter = 480 | Mean = -1068.279 | Best = -1068.174
GA | iter = 481 | Mean = -1068.277 | Best = -1068.144
GA | iter = 482 | Mean = -1068.278 | Best = -1068.144
GA | iter = 483 | Mean = -1068.268 | Best = -1068.144
GA | iter = 484 | Mean = -1068.275 | Best = -1068.144
GA | iter = 485 | Mean = -1068.249 | Best = -1068.144
GA | iter = 486 | Mean = -1068.256 | Best = -1068.142
GA | iter = 487 | Mean = -1068.247 | Best = -1068.142
GA | iter = 488 | Mean = -1068.241 | Best = -1068.101
GA | iter = 489 | Mean = -1068.233 | Best = -1068.101
GA | iter = 490 | Mean = -1068.210 | Best = -1068.054
GA | iter = 491 | Mean = -1068.188 | Best = -1068.021
GA | iter = 492 | Mean = -1068.161 | Best = -1068.021
GA | iter = 493 | Mean = -1068.147 | Best = -1068.021
GA | iter = 494 | Mean = -1068.133 | Best = -1068.011
GA | iter = 495 | Mean = -1068.121 | Best = -1068.011
GA | iter = 496 | Mean = -1068.101 | Best = -1068.011
GA | iter = 497 | Mean = -1068.075 | Best = -1067.928
GA | iter = 498 | Mean = -1068.064 | Best = -1067.928
GA | iter = 499 | Mean = -1068.033 | Best = -1067.928
GA | iter = 500 | Mean = -1068.039 | Best = -1067.928
GA | iter = 501 | Mean = -1068.034 | Best = -1067.928
GA | iter = 502 | Mean = -1068.028 | Best = -1067.928
GA | iter = 503 | Mean = -1068.020 | Best = -1067.928
GA | iter = 504 | Mean = -1068.008 | Best = -1067.928
GA | iter = 505 | Mean = -1067.993 | Best = -1067.928
GA | iter = 506 | Mean = -1067.998 | Best = -1067.928
GA | iter = 507 | Mean = -1068.004 | Best = -1067.928
GA | iter = 508 | Mean = -1067.989 | Best = -1067.928
GA | iter = 509 | Mean = -1067.973 | Best = -1067.928
GA | iter = 510 | Mean = -1067.950 | Best = -1067.928
GA | iter = 511 | Mean = -1067.935 | Best = -1067.928
GA | iter = 512 | Mean = -1067.938 | Best = -1067.928
GA | iter = 513 | Mean = -1067.938 | Best = -1067.928
GA | iter = 514 | Mean = -1067.934 | Best = -1067.928
GA | iter = 515 | Mean = -1067.932 | Best = -1067.891
GA | iter = 516 | Mean = -1067.929 | Best = -1067.891
GA | iter = 517 | Mean = -1067.933 | Best = -1067.841
GA | iter = 518 | Mean = -1067.927 | Best = -1067.841
GA | iter = 519 | Mean = -1067.921 | Best = -1067.732
GA | iter = 520 | Mean = -1067.915 | Best = -1067.732
GA | iter = 521 | Mean = -1067.906 | Best = -1067.699
GA | iter = 522 | Mean = -1067.905 | Best = -1067.699
GA | iter = 523 | Mean = -1067.889 | Best = -1067.699
GA | iter = 524 | Mean = -1067.866 | Best = -1067.699
GA | iter = 525 | Mean = -1067.831 | Best = -1067.640
GA | iter = 526 | Mean = -1067.776 | Best = -1067.640
GA | iter = 527 | Mean = -1067.724 | Best = -1067.640
GA | iter = 528 | Mean = -1067.704 | Best = -1067.605
GA | iter = 529 | Mean = -1067.690 | Best = -1067.605
GA | iter = 530 | Mean = -1067.681 | Best = -1067.590
GA | iter = 531 | Mean = -1067.662 | Best = -1067.590
GA | iter = 532 | Mean = -1067.642 | Best = -1067.590
GA | iter = 533 | Mean = -1067.637 | Best = -1067.590
GA | iter = 534 | Mean = -1067.622 | Best = -1067.391
GA | iter = 535 | Mean = -1067.619 | Best = -1067.391
GA | iter = 536 | Mean = -1067.610 | Best = -1067.391
GA | iter = 537 | Mean = -1067.597 | Best = -1067.391
GA | iter = 538 | Mean = -1067.589 | Best = -1067.391
GA | iter = 539 | Mean = -1067.571 | Best = -1067.391
GA | iter = 540 | Mean = -1067.556 | Best = -1067.391
GA | iter = 541 | Mean = -1067.555 | Best = -1067.374
GA | iter = 542 | Mean = -1067.530 | Best = -1067.374
GA | iter = 543 | Mean = -1067.489 | Best = -1067.374
GA | iter = 544 | Mean = -1067.459 | Best = -1067.374
GA | iter = 545 | Mean = -1067.415 | Best = -1067.374
GA | iter = 546 | Mean = -1067.405 | Best = -1067.374
GA | iter = 547 | Mean = -1067.411 | Best = -1067.373
GA | iter = 548 | Mean = -1067.420 | Best = -1067.373
GA | iter = 549 | Mean = -1067.397 | Best = -1067.324
GA | iter = 550 | Mean = -1067.403 | Best = -1067.324
GA | iter = 551 | Mean = -1067.391 | Best = -1067.324
GA | iter = 552 | Mean = -1067.396 | Best = -1067.324
GA | iter = 553 | Mean = -1067.402 | Best = -1067.324
GA | iter = 554 | Mean = -1067.402 | Best = -1067.324
GA | iter = 555 | Mean = -1067.392 | Best = -1067.324
GA | iter = 556 | Mean = -1067.378 | Best = -1067.209
GA | iter = 557 | Mean = -1067.365 | Best = -1067.209
GA | iter = 558 | Mean = -1067.341 | Best = -1067.209
GA | iter = 559 | Mean = -1067.324 | Best = -1067.209
GA | iter = 560 | Mean = -1067.327 | Best = -1067.209
GA | iter = 561 | Mean = -1067.321 | Best = -1067.157
GA | iter = 562 | Mean = -1067.317 | Best = -1067.157
GA | iter = 563 | Mean = -1067.299 | Best = -1067.157
GA | iter = 564 | Mean = -1067.294 | Best = -1067.149
GA | iter = 565 | Mean = -1067.272 | Best = -1067.149
GA | iter = 566 | Mean = -1067.243 | Best = -1067.149
GA | iter = 567 | Mean = -1067.220 | Best = -1067.085
GA | iter = 568 | Mean = -1067.194 | Best = -1067.085
GA | iter = 569 | Mean = -1067.188 | Best = -1067.071
GA | iter = 570 | Mean = -1067.173 | Best = -1067.071
GA | iter = 571 | Mean = -1067.162 | Best = -1067.071
GA | iter = 572 | Mean = -1067.169 | Best = -1067.029
GA | iter = 573 | Mean = -1067.148 | Best = -1067.029
GA | iter = 574 | Mean = -1067.142 | Best = -1067.029
GA | iter = 575 | Mean = -1067.141 | Best = -1067.029
GA | iter = 576 | Mean = -1067.131 | Best = -1067.029
GA | iter = 577 | Mean = -1067.116 | Best = -1067.029
GA | iter = 578 | Mean = -1067.115 | Best = -1067.029
GA | iter = 579 | Mean = -1067.091 | Best = -1067.029
GA | iter = 580 | Mean = -1067.084 | Best = -1067.029
GA | iter = 581 | Mean = -1067.080 | Best = -1067.029
GA | iter = 582 | Mean = -1067.084 | Best = -1066.991
GA | iter = 583 | Mean = -1067.077 | Best = -1066.967
GA | iter = 584 | Mean = -1067.080 | Best = -1066.948
GA | iter = 585 | Mean = -1067.057 | Best = -1066.948
GA | iter = 586 | Mean = -1067.062 | Best = -1066.775
GA | iter = 587 | Mean = -1067.045 | Best = -1066.775
GA | iter = 588 | Mean = -1067.030 | Best = -1066.775
GA | iter = 589 | Mean = -1066.991 | Best = -1066.775
GA | iter = 590 | Mean = -1066.963 | Best = -1066.775
GA | iter = 591 | Mean = -1066.902 | Best = -1066.745
GA | iter = 592 | Mean = -1066.849 | Best = -1066.745
GA | iter = 593 | Mean = -1066.825 | Best = -1066.745
GA | iter = 594 | Mean = -1066.822 | Best = -1066.742
GA | iter = 595 | Mean = -1066.824 | Best = -1066.742
GA | iter = 596 | Mean = -1066.815 | Best = -1066.742
GA | iter = 597 | Mean = -1066.823 | Best = -1066.729
GA | iter = 598 | Mean = -1066.812 | Best = -1066.729
GA | iter = 599 | Mean = -1066.810 | Best = -1066.729
GA | iter = 600 | Mean = -1066.799 | Best = -1066.729
GA | iter = 601 | Mean = -1066.782 | Best = -1066.561
GA | iter = 602 | Mean = -1066.771 | Best = -1066.561
GA | iter = 603 | Mean = -1066.748 | Best = -1066.561
GA | iter = 604 | Mean = -1066.734 | Best = -1066.561
GA | iter = 605 | Mean = -1066.717 | Best = -1066.561
GA | iter = 606 | Mean = -1066.704 | Best = -1066.561
GA | iter = 607 | Mean = -1066.689 | Best = -1066.561
GA | iter = 608 | Mean = -1066.673 | Best = -1066.530
GA | iter = 609 | Mean = -1066.633 | Best = -1066.530
GA | iter = 610 | Mean = -1066.628 | Best = -1066.522
GA | iter = 611 | Mean = -1066.615 | Best = -1066.522
GA | iter = 612 | Mean = -1066.596 | Best = -1066.522
GA | iter = 613 | Mean = -1066.602 | Best = -1066.473
GA | iter = 614 | Mean = -1066.584 | Best = -1066.466
GA | iter = 615 | Mean = -1067.085 | Best = -1066.466
GA | iter = 616 | Mean = -1066.575 | Best = -1066.466
GA | iter = 617 | Mean = -1066.557 | Best = -1066.458
GA | iter = 618 | Mean = -1066.539 | Best = -1066.458
GA | iter = 619 | Mean = -1066.528 | Best = -1066.458
GA | iter = 620 | Mean = -1066.513 | Best = -1066.458
GA | iter = 621 | Mean = -1066.506 | Best = -1066.458
GA | iter = 622 | Mean = -1066.501 | Best = -1066.458
GA | iter = 623 | Mean = -1066.480 | Best = -1066.458
GA | iter = 624 | Mean = -1066.481 | Best = -1066.458
GA | iter = 625 | Mean = -1066.481 | Best = -1066.458
GA | iter = 626 | Mean = -1066.486 | Best = -1066.458
GA | iter = 627 | Mean = -1066.485 | Best = -1066.378
GA | iter = 628 | Mean = -1066.480 | Best = -1066.378
GA | iter = 629 | Mean = -1066.486 | Best = -1066.378
GA | iter = 630 | Mean = -1066.480 | Best = -1066.378
GA | iter = 631 | Mean = -1066.480 | Best = -1066.378
GA | iter = 632 | Mean = -1066.468 | Best = -1066.378
GA | iter = 633 | Mean = -1066.788 | Best = -1066.378
GA | iter = 634 | Mean = -1066.473 | Best = -1066.378
GA | iter = 635 | Mean = -1066.467 | Best = -1066.378
GA | iter = 636 | Mean = -1066.464 | Best = -1066.378
GA | iter = 637 | Mean = -1066.461 | Best = -1066.378
GA | iter = 638 | Mean = -1066.458 | Best = -1066.378
GA | iter = 639 | Mean = -1066.449 | Best = -1066.359
GA | iter = 640 | Mean = -1066.449 | Best = -1066.359
GA | iter = 641 | Mean = -1066.441 | Best = -1066.276
GA | iter = 642 | Mean = -1066.447 | Best = -1066.246
GA | iter = 643 | Mean = -1066.433 | Best = -1066.246
GA | iter = 644 | Mean = -1066.421 | Best = -1066.246
GA | iter = 645 | Mean = -1066.403 | Best = -1066.246
GA | iter = 646 | Mean = -1066.383 | Best = -1066.246
GA | iter = 647 | Mean = -1066.351 | Best = -1066.179
GA | iter = 648 | Mean = -1066.316 | Best = -1066.179
GA | iter = 649 | Mean = -1066.278 | Best = -1066.151
GA | iter = 650 | Mean = -1066.248 | Best = -1066.151
GA | iter = 651 | Mean = -1066.247 | Best = -1066.151
GA | iter = 652 | Mean = -1066.245 | Best = -1066.092
GA | iter = 653 | Mean = -1066.229 | Best = -1066.092
GA | iter = 654 | Mean = -1066.223 | Best = -1066.092
GA | iter = 655 | Mean = -1066.235 | Best = -1066.092
GA | iter = 656 | Mean = -1066.221 | Best = -1066.061
GA | iter = 657 | Mean = -1066.220 | Best = -1066.061
GA | iter = 658 | Mean = -1066.199 | Best = -1066.061
GA | iter = 659 | Mean = -1066.203 | Best = -1066.061
GA | iter = 660 | Mean = -1066.201 | Best = -1066.061
GA | iter = 661 | Mean = -1066.179 | Best = -1066.058
GA | iter = 662 | Mean = -1066.147 | Best = -1066.058
GA | iter = 663 | Mean = -1066.104 | Best = -1066.058
GA | iter = 664 | Mean = -1066.112 | Best = -1066.019
GA | iter = 665 | Mean = -1066.097 | Best = -1066.019
GA | iter = 666 | Mean = -1066.083 | Best = -1066.019
GA | iter = 667 | Mean = -1066.086 | Best = -1066.019
GA | iter = 668 | Mean = -1066.079 | Best = -1066.019
GA | iter = 669 | Mean = -1066.092 | Best = -1066.019
GA | iter = 670 | Mean = -1066.075 | Best = -1066.019
GA | iter = 671 | Mean = -1066.069 | Best = -1066.019
GA | iter = 672 | Mean = -1066.067 | Best = -1066.019
GA | iter = 673 | Mean = -1066.061 | Best = -1066.019
GA | iter = 674 | Mean = -1066.061 | Best = -1065.945
GA | iter = 675 | Mean = -1066.062 | Best = -1065.945
GA | iter = 676 | Mean = -1066.060 | Best = -1065.945
GA | iter = 677 | Mean = -1066.059 | Best = -1065.945
GA | iter = 678 | Mean = -1066.060 | Best = -1065.945
GA | iter = 679 | Mean = -1066.051 | Best = -1065.945
GA | iter = 680 | Mean = -1066.049 | Best = -1065.945
GA | iter = 681 | Mean = -1066.059 | Best = -1065.945
GA | iter = 682 | Mean = -1066.059 | Best = -1065.945
GA | iter = 683 | Mean = -1066.052 | Best = -1065.945
GA | iter = 684 | Mean = -1066.056 | Best = -1065.945
GA | iter = 685 | Mean = -1066.042 | Best = -1065.945
GA | iter = 686 | Mean = -1066.046 | Best = -1065.945
GA | iter = 687 | Mean = -1066.042 | Best = -1065.945
GA | iter = 688 | Mean = -1066.037 | Best = -1065.945
GA | iter = 689 | Mean = -1066.038 | Best = -1065.945
GA | iter = 690 | Mean = -1066.051 | Best = -1065.945
GA | iter = 691 | Mean = -1066.052 | Best = -1065.945
GA | iter = 692 | Mean = -1066.042 | Best = -1065.945
GA | iter = 693 | Mean = -1066.045 | Best = -1065.945
toc()
GA: 49.239 sec elapsed

Finally, we decode the best solution and display the results.

solution <- decode(genalg@solution[1,])
cat("Solution cost = ", solution$cost, "\n",
    "Variants chosen = ", solution$variant1, ", ", solution$variant2, "\n",
    "Assignments:\n", solution$assignment, "\n",
    "Balance score (low = ", blo, ", high = ", bhi, ") = ", solution$balance, "\n")
Solution cost =  1065.945 
 Variants chosen =  5 ,  6 
 Assignments:
 5 5 6 5 5 6 5 5 6 5 6 6 6 5 6 6 6 6 6 5 6 6 6 5 5 5 6 5 6 6 6 6 6 6 6 6 5 6 6 6 6 5 6 6 6 6 6 6 6 5 5 6 6 6 6 6 6 6 6 6 6 6 5 6 5 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 5 6 5 6 6 5 6 6 6 6 6 6 5 5 6 6 6 5 6 6 5 6 6 6 6 5 5 6 6 5 6 6 5 5 6 6 6 6 6 6 6 6 5 6 5 6 6 6 6 5 5 6 6 6 5 6 5 6 6 6 6 6 6 5 5 6 5 6 5 5 6 6 6 6 6 6 6 6 5 6 5 6 6 6 6 5 6 6 5 5 6 5 6 6 5 6 6 5 6 6 5 5 6 6 5 6 6 5 6 5 5 6 6 6 6 6 5 6 5 6 6 6 5 5 6 5 6 6 6 6 6 6 5 6 6 6 5 6 6 6 6 6 6 6 5 6 6 6 5 5 6 5 6 6 6 6 5 6 5 5 6 6 6 6 6 5 6 6 6 6 6 5 6 5 6 5 5 5 6 6 6 5 5 6 5 6 6 5 6 5 6 6 6 5 6 6 6 5 6 6 6 6 6 6 6 6 6 5 6 6 6 6 5 6 5 5 6 5 6 5 6 5 5 6 6 5 6 6 5 5 5 5 6 6 6 6 6 6 5 6 6 6 5 6 6 5 6 5 5 6 5 5 5 6 5 5 6 6 5 6 6 6 6 5 6 6 6 6 6 6 5 5 6 6 6 6 6 6 5 6 6 5 6 6 6 5 6 6 6 6 5 5 6 6 5 6 6 5 6 5 5 6 5 6 5 6 6 6 6 6 6 6 5 6 6 6 6 6 5 5 5 5 6 6 5 6 6 5 6 6 6 5 5 6 6 6 5 6 6 5 6 6 5 5 6 5 6 6 6 6 6 6 6 6 6 6 5 6 6 6 6 5 6 5 6 5 5 5 5 6 5 5 6 6 5 5 6 6 5 6 6 6 6 5 6 6 5 5 5 6 5 6 5 6 6 6 6 6 6 6 5 6 6 6 5 6 5 5 6 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 5 6 6 6 6 5 6 6 6 5 6 6 5 6 6 6 6 6 6 5 6 5 6 6 6 6 5 6 6 6 6 6 6 6 6 6 5 5 6 6 6 6 6 5 6 6 6 6 5 6 6 6 5 6 5 6 5 5 6 6 5 5 5 6 6 6 6 5 6 5 5 6 6 6 5 6 6 6 5 5 6 5 6 6 6 6 5 5 6 6 6 5 6 5 6 5 6 6 6 6 6 6 6 5 6 6 6 5 5 6 6 6 5 5 6 6 6 6 6 6 6 6 6 5 5 5 6 6 5 6 6 6 6 6 6 5 5 6 6 5 6 6 5 6 5 6 6 5 5 6 6 6 5 6 5 6 6 6 5 5 6 5 6 6 6 6 5 5 6 6 6 6 6 5 5 6 6 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 5 6 6 6 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 5 5 6 6 6 6 6 6 5 6 6 6 5 5 6 6 6 6 5 6 6 6 6 6 6 6 6 5 6 6 6 6 6 6 5 5 6 6 6 6 6 6 5 5 6 6 6 6 6 5 5 6 6 6 6 6 5 6 6 6 6 5 5 5 6 6 6 6 6 6 6 6 6 6 5 6 6 6 6 6 6 6 6 5 6 6 6 5 5 6 6 5 6 6 6 6 5 6 6 5 6 5 6 6 6 6 5 6 6 5 6 6 6 5 6 6 5 6 6 6 6 6 6 6 6 6 6 5 5 6 5 6 6 6 5 6 6 6 5 6 5 6 5 6 5 5 6 6 6 5 5 6 6 5 5 6 5 6 6 5 6 5 5 6 5 6 5 6 6 6 6 6 6 6 5 6 6 6 5 5 6 6 6 6 5 5 6 6 6 6 5 6 5 6 6 5 6 5 6 6 6 6 5 6 6 5 6 6 5 6 5 6 5 6 5 6 6 6 6 6 6 6 5 6 6 5 6 6 5 6 6 6 6 6 6 6 6 5 6 6 6 6 6 6 6 5 6 6 6 5 6 6 6 6 5 6 5 5 6 6 6 6 6 6 6 6 6 6 5 6 6 6 
 Balance score (low =  316.2245 , high =  349.5113 ) =  349.4964 

Greedy heuristic

The second approach considers all combinations of ‘variant1’ and ‘variant2’, using a greedy heuristic to make store assignments. The combination with assignments yielding the lowest cost wins.

incumbent.cost <- Inf   # incumbent (lowest) cost
variant1 <- NA          # incumbent value of the first variant
variant2 <- NA          # incumbent value of the second variant
assignment <- NA        # incumbent store assignments
tic("Greedy")
# If b > 0, larger is cheaper, so we loop through variant 2 first and then variant
# 1, largest to smallest. If b < 0, smaller is cheaper, so we loop through variant
# 1 first (smallest to largest) and then variant 2.
if (b > 0) {
  range1 <- k2:k1
  range2 <- k1:1
} else {
  range1 <- 1:k1
  range2 <- k1:k2
}
# Try values from the first range.
for (v1 in range1) {
  # Try values from the second range.
  for (v2 in range2) {
    # Initially use v1 in every store.
    a <- rep.int(v1, nStores)
    # Compute a balance score.
    temp <- balance(a)
    # If out of balance, try to fix it by swapping to v2.
    if ((temp < blo & v2 < v1) | (temp > bhi & v1 < v2)) {
      # Compute for each store the ratio of the change in balance value to
      # the change in cost, switching from v1 to v2.
      delta.cost <- s1 * ((s2 / v2)^b - (s2 / v1)^b)
      delta.balance <- s3 / v2 - s3 / v1
      ratio <- abs(delta.balance) / delta.cost
      # Sort stores into descending ratio order ("biggest bang for the buck"
      # first).
      ix <- order(ratio, decreasing = TRUE)
      # Switch stores to v2 greedily until the balance constraint is met.
      j <- 0
      nflips <- 0
      while ((temp < blo & v2 < v1) | (temp > bhi & v1 < v2)) {
        j <- j + 1  # position in list of next store to flip
        i <- ix[j]  # index of store to flip
        # Switch store i to v2.
        a[i] <- v2
        nflips <- nflips + 1
        # Update the running balance value.
        temp <- temp + delta.balance[i]
      }
    }
    # Compute the cost of the (presumably now feasible) assignment.
    z <- cost(a)
    # If it is a new incumbent, record (and announce) it.
    if (z < incumbent.cost) {
      incumbent.cost <- z
      variant1 <- min(v1, v2)
      variant2 <- max(v1, v2)
      assignment <- a
      cat("(", variant1, ", ", variant2, ") cost = ", z, " (", nflips, " stores flipped)\n")
    }
  }
}
( 1 ,  6 ) cost =  1093.768  ( 982  stores flipped)
( 2 ,  6 ) cost =  1076.801  ( 957  stores flipped)
( 3 ,  6 ) cost =  1063.729  ( 917  stores flipped)
( 4 ,  6 ) cost =  1056.057  ( 845  stores flipped)
( 5 ,  7 ) cost =  1051.735  ( 354  stores flipped)
toc()
Greedy: 0.176 sec elapsed

The final solution is as follows.

cat("Solution cost = ", cost(assignment), "\n",
    "Variants chosen = ", variant1, ", ", variant2, "\n",
    "Assignments:\n", assignment, "\n",
    "Balance score (low = ", blo, ", high = ", bhi, ") = ", balance(assignment), "\n")
Solution cost =  1051.735 
 Variants chosen =  5 ,  7 
 Assignments:
 5 5 5 5 5 7 5 5 5 5 5 5 5 5 7 5 7 7 5 5 7 5 7 5 5 5 7 5 5 7 5 5 5 5 5 7 5 7 7 7 7 5 5 7 7 7 7 5 5 5 7 5 7 5 7 5 7 5 5 7 5 7 5 7 5 5 5 5 7 7 5 7 7 7 7 7 5 5 7 5 5 5 7 5 7 5 5 5 5 5 5 5 5 5 5 7 7 7 5 5 7 5 5 7 7 5 5 5 7 7 5 5 5 5 5 5 7 5 5 7 5 5 5 5 7 5 7 7 5 7 5 5 5 5 7 5 5 5 5 5 7 5 5 5 5 5 5 7 7 5 5 7 7 5 7 5 5 7 5 5 7 5 5 7 5 5 5 7 5 7 5 7 5 5 5 5 5 7 5 7 5 5 5 7 7 5 7 7 5 5 5 5 5 7 5 5 7 5 7 5 7 5 7 5 5 5 5 7 7 5 5 7 5 5 7 5 5 7 5 5 5 5 5 5 7 5 5 5 7 5 5 7 5 7 5 5 7 5 5 5 5 5 5 7 7 5 5 5 5 5 7 7 5 5 5 5 5 5 5 7 5 7 5 5 7 5 5 7 5 5 5 7 5 5 7 7 7 5 7 5 5 7 5 7 7 5 7 5 7 5 5 7 5 5 5 5 5 7 7 7 5 7 5 7 7 5 5 7 7 5 5 5 5 7 7 5 5 7 5 5 5 5 7 5 7 5 5 5 5 5 5 5 5 5 7 5 5 7 7 5 5 5 7 7 5 5 5 5 7 5 7 5 5 7 5 5 5 5 5 5 7 7 5 7 5 5 5 7 5 5 7 5 5 5 5 5 5 7 5 7 5 5 7 5 7 5 7 7 5 7 5 5 5 5 7 7 5 7 7 5 5 7 5 7 7 5 5 7 5 5 7 7 5 5 7 5 5 5 7 5 7 7 5 7 5 5 5 7 7 5 7 5 5 5 5 5 5 7 5 7 5 5 5 5 5 7 5 5 5 5 7 5 5 7 7 7 5 5 7 5 5 7 7 5 5 7 5 5 5 5 5 5 5 5 5 7 7 7 7 5 5 5 7 5 7 5 5 5 5 7 5 5 7 7 7 7 7 5 5 5 7 7 7 5 7 7 7 7 5 7 5 7 5 5 5 7 5 5 7 5 7 5 7 5 5 5 5 5 5 7 7 5 7 5 7 5 5 5 7 7 5 5 5 7 5 5 5 7 5 5 7 5 5 5 7 5 5 5 5 7 7 5 5 5 5 5 5 5 5 7 5 5 5 5 5 5 5 5 5 7 5 5 5 5 5 7 7 5 5 5 7 7 5 5 5 5 5 7 7 5 5 5 5 7 5 5 7 5 7 5 7 7 5 5 7 5 5 5 5 7 5 5 5 7 7 7 5 5 5 5 7 5 5 5 5 5 5 5 5 7 5 7 5 5 7 7 7 7 7 5 5 7 7 5 5 5 5 7 5 7 5 5 7 5 7 7 5 7 5 5 5 5 7 5 5 5 5 7 5 5 5 5 7 5 5 5 5 7 5 7 5 5 5 7 7 7 5 7 7 7 5 5 5 5 5 7 5 7 7 5 7 5 5 5 5 7 5 7 5 7 7 5 5 5 5 7 5 5 5 5 7 5 5 5 7 7 5 5 7 7 5 5 5 5 7 5 5 5 5 5 7 5 5 7 5 5 5 5 7 7 7 5 5 5 5 7 7 5 7 7 5 5 5 5 7 7 7 5 5 5 5 5 5 7 5 5 7 5 7 7 5 5 7 7 5 5 7 7 5 7 5 7 5 5 7 5 5 7 5 7 7 5 7 7 7 5 5 7 5 5 7 5 5 7 5 7 5 7 7 5 7 5 7 5 5 5 7 5 7 7 5 5 7 7 5 5 5 5 5 5 7 5 5 5 7 5 5 7 7 7 7 5 5 5 5 7 7 7 5 5 7 5 5 5 5 7 7 5 5 7 7 5 7 7 5 7 5 5 7 7 5 7 5 5 5 5 7 7 5 5 5 5 5 5 7 7 7 5 5 7 7 7 5 5 7 5 5 7 7 5 5 7 7 5 5 5 7 5 7 7 5 5 5 5 5 5 5 5 5 7 5 7 5 5 5 7 5 7 5 5 5 7 5 5 5 5 5 7 5 5 7 5 5 5 5 5 7 5 5 5 5 7 5 5 7 5 5 5 7 5 7 5 5 5 5 5 7 5 5 5 7 5 7 5 5 5 5 5 5 7 
 Balance score (low =  316.2245 , high =  349.5113 ) =  349.4712 
LS0tCnRpdGxlOiAiU3RvcmUgQWxsb2NhdGlvbnMiCm91dHB1dDogaHRtbF9ub3RlYm9vawphdXRob3I6IFBhdWwgQS4gUnViaW4KZGF0ZTogU2VwdGVtYmVyIDMwLCAyMDIwCi0tLQoKVGhpcyBub3RlYm9vayBpbGx1c3RyYXRlcyBob3cgdG8gInNvbHZlIiAoaGV1cmlzdGljYWxseSkgYSBbcHJvYmxlbV0oaHR0cHM6Ly9vci5zdGFja2V4Y2hhbmdlLmNvbS9xdWVzdGlvbnMvNDc3Ny9jb21iaW5hdG9yaWFsLW9wdGltaXNhdGlvbi1hbGxvY2F0aW9uLXByb2JsZW0pIHBvc3RlZCBvbiBPUiBTdGFjayBFeGNoYW5nZS4gSW4gaXQsIHR3byBpbnRlZ2VyIHZhbHVlcyBtdXN0IGJlIGNob3NlbiAoZnJvbSBzcGVjaWZpZWQgcmFuZ2VzKSwgYW5kIHRoZW4gb2YgYSBsYXJnZSBudW1iZXIgKG5TdG9yZXMpIG9mIHN0b3JlcyBtdXN0IGJlIGFzc2lnbmVkIG9uZSBvZiB0aGUgdHdvIHZhbHVlcywgc28gYXMgdG8gbWluaW1pemUgYSBub25saW5lYXIgY29zdCBmdW5jdGlvbi4gQXNzaWdubWVudHMgYXJlIGNvbnN0cmFpbmVkIGJ5IGEgcmVxdWlyZW1lbnQgdGhhdCBhIGNlcnRhaW4gbm9ubGluZWFyIGZ1bmN0aW9uIGZhbGwgd2l0aGluIGEgc3BlY2lmaWVkIHJhbmdlIChyZWZlcnJlZCB0byBiZWxvdyBhcyB0aGUgImJhbGFuY2UgY29uc3RyYWludCIpLgoKIyBQcm9ibGVtIHNldHVwCgpgYGB7cn0KbGlicmFyeShHQSkgICAgICAjIHRoZSBHQSBwYWNrYWdlIHByb3ZpZGVzIGEgZ2VuZXRpYyBhbGdvcml0aG0gaW1wbGVtZW50YXRpb24KbGlicmFyeSh0aWN0b2MpICAjIHRvIHRpbWUgdGhlIEdBCmBgYAoKV2Ugd2lsbCBtYWtlIHVwIHBhcmFtZXRlcnMgZm9yIHRlc3QgcHVycG9zZXMsIGZvbGxvd2luZyB0aGUgbm90YXRpb24gb2YgdGhlIG9yaWdpbmFsIHBvc3Qgd2hlcmUgcG9zc2libGUuIChUaGUgY29lZmZpY2llbnQgJGEkIGluIHRoZSBvcmlnaW5hbCBwb3N0IGlzIGFzc3VtZWQgd2l0aG91dCBsb3NzIG9mIGdlbmVyYWxpdHkgdG8gYmUgMS4pCgpgYGB7cn0Kc2V0LnNlZWQoMTIzKSAgICAjIHNlZWQgdGhlIHJhbmRvbSBudW1iZXIgc3RyZWFtIChmb3IgcmVwcm9kdWNpYmlsaXR5KQpuU3RvcmVzIDwtIDEwMDAgICMgbnVtYmVyIG9mIHN0b3JlcwprMSA8LSA2ICAgICAgICAgICMgZmlyc3QgdmFyaWFudCBpcyBiZXR3ZWVuIDEgYW5kIGsxIGluY2x1c2l2ZQprMiA8LSAxMiAgICAgICAgICMgc2Vjb25kIHZhcmlhbnQgaXMgYmV0d2VlbiBrMSBhbmQgazIgaW5jbHVzaXZlCmIgPC0gLTAuOCAgICAgICAgIyBleHBvbmVudCBvZiB0aGUgY29zdCBmdW5jdGlvbgpzMSA8LSBydW5pZihuU3RvcmVzLCAxLCAyKSAgICAjIGxlYWRpbmcgY29lZmZpY2llbnRzIG9mIGNvc3QgZnVuY3Rpb24KczIgPC0gcnVuaWYoblN0b3JlcywgazEsIGsyKSAgIyBudW1lcmF0b3JzIG9mIGNvc3QgZnVuY3Rpb24KczMgPC0gcnVuaWYoblN0b3JlcywgMSwgMykgICAgIyBudW1lcmF0b3JzIG9mIHRoZSBiYWxhbmNlIGNvbnN0cmFpbnQKdGVtcCA8LSBzdW0oczMpIC8gazEgICAgICAgICAgIyB0YXJnZXQgZm9yIHRoZSBiYWxhbmNlIGNvbnN0cmFpbnQKYmxvIDwtIDAuOTUgKiB0ZW1wICAgICAgICAgICAgIyBsb3dlciBiYWxhbmNlIGxpbWl0CmJoaSA8LSAxLjA1ICogdGVtcCAgICAgICAgICAgICMgdXBwZXIgYmFsYW5jZSBsaW1pdApgYGAKCk5leHQsIHdlIHNldCB0aGUgY29zdCBmdW5jdGlvbiBiYXNlZCBvbiBhIHZlY3RvciBvZiBhc3NpZ25tZW50cyB0byB0aGUgc3RvcmVzLgoKYGBge3J9CmNvc3QgPC0gZnVuY3Rpb24oeCkgewogIHMxICUqJSAoczIgLyB4KV5iCn0KYGBgCgpXZSBhbHNvIG5lZWQgYSBmdW5jdGlvbiB0aGF0IGNhbGN1bGF0ZXMgdGhlICJiYWxhbmNlIiB2YWx1ZSBmb3IgYSB2ZWN0b3Igb2YgYXNzaWdubWVudHMuCgpgYGB7cn0KYmFsYW5jZSA8LSBmdW5jdGlvbih4KSB7CiAgc3VtKHMzIC8geCkKfQpgYGAKCiMgR0EKClRoZSBmaXJzdCBzb2x1dGlvbiBhcHByb2FjaCB3aWxsIGJlIHRvIHVzZSBhIHZhcmlhbnQgb2YgYSByYW5kb20ga2V5IGdlbmV0aWMgYWxnb3JpdGhtLCBpbiB3aGljaCB0aGUgY2hyb21vc29tZSBjb21iaW5lcyB0d28gaW50ZWdlciBnZW5lcyAoZGVzaWduYXRpbmcgdGhlIHR3byB2YWx1ZXMgdG8gYmUgYXNzaWduZWQpIHdpdGggblN0b3JlcyByZWFsIGdlbmVzIHRoYXQgZGVmaW5lIGEgcGVybXV0YXRpb24gb2YgdGhlIHN0b3JlcywgaW5kaWNhdGluZyB0aGUgb3JkZXIgaW4gd2hpY2ggc3RvcmVzIHdpbGwgYmUgYXNzaWduZWQgdmFsdWVzLgoKV2UgbmVlZCBhIGZ1bmN0aW9uIHRvIGRlY29kZSBhIEdBICJzb2x1dGlvbiIgKHZlY3RvciBvZiBuU3RvcmVzICsgMiBudW1iZXJzKSBpbnRvIGEgdmFsaWQgYXNzaWdubWVudC4gVGhlIGZpcnN0IHR3byB2YWx1ZXMgaW4gdGhlIHNvbHV0aW9uIHdpbGwgYmUgaW4gdGhlIHJhbmdlIFsxLCBrMSArIDEpIGFuZCBbazEsIGsyICsgMSkgcmVzcGVjdGl2ZWx5OyB3ZSB0cnVuY2F0ZSB0aGVtIHRvIGdldCB0aGUgdHdvIGFzc2lnbm1lbnQgY2hvaWNlcyAoInZhcmlhbnQxIiBhbmQgInZhcmlhbnQyIiBpbiB0aGUgb3JpZ2luYWwgcG9zdCkuIFRoZSByZW1haW5pbmcgdmFsdWVzIGFyZSBiZXR3ZWVuIDAgYW5kIDEsIGFuZCBhcmUgdXNlZCB0byBzZXF1ZW5jZSB0aGUgc3RvcmVzIChkaWN0YXRpbmcgdGhlIG9yZGVyIGluIHdoaWNoIHRoZXkgd2lsbCBiZSBhc3NpZ25lZCB2YWx1ZXMpLiBUaGUgcmV0dXJuIHZhbHVlIHdpbGwgY29uc2lzdCBvZiBhIGxpc3QgY29udGFpbmluZyB0aGUgdmFyaWFudHMsIHRoZSBhc3NpZ25tZW50cyBhbmQgdGhlIHNvbHV0aW9uIGNvc3QuCgpgYGB7cn0KZGVjb2RlIDwtIGZ1bmN0aW9uKHgpIHsKICAjIEV4dHJhY3QgdGhlIHZhcmlhbnRzLgogIHYxIDwtIGZsb29yKHhbMV0pCiAgdjIgPC0gZmxvb3IoeFsyXSkKICAjIFRoZSBzbWFsbGVyIHZhcmlhbnQgaXMgY2hlYXBlciBpZiBiIGlzIG5lZ2F0aXZlOyB0aGUgbGFyZ2VyIHZhcmlhbnQgaXMgY2hlYXBlcgogICMgaWYgYiBpcyBwb3NpdGl2ZS4KICBpZiAoYiA8IDApIHsKICAgIGNoZWFwIDwtIHYxCiAgfSBlbHNlIHsKICAgIGNoZWFwIDwtIHYyCiAgfQogICMgVHJhbnNsYXRlIHRoZSByZW1haW5pbmcgdmFsdWVzIGludG8gYSBwZXJtdXRhdGlvbiB2ZWN0b3IgZm9yIHRoZSBzdG9yZXMuCiAgaXggPC0gb3JkZXIoeFstKDE6MildKQogICMgSW5pdGlhbGx5IGFzc2lnbiBldmVyeSBzdG9yZSB0aGUgY2hlYXBlciB2YXJpYW50LgogIGEgPC0gcmVwLmludChjaGVhcCwgblN0b3JlcykKICAjIENhbGN1bGF0ZSB0aGUgdmFsdWUgb2YgdGhlIGJhbGFuY2UgZnVuY3Rpb24uCiAgdGVtcCA8LSBiYWxhbmNlKGEpCiAgIyBJdGVyYXRlIHRocm91Z2ggc3RvcmVzIHVudGlsIGJhbGFuY2UgaXMgYWNoaWV2ZWQuIEF0IGVhY2ggc3RvcmUsIHN3aXRjaAogICMgdG8gdGhlIGxvd2VyIHZhcmlhbnQgdG8gaW5jcmVhc2UgdGhlIGJhbGFuY2Ugc2NvcmUgaWYgaXQgaXMgdG9vIGxvdywKICAjIHByb3ZpZGVkIHRoYXQgdGhlIHN3aXRjaCBkb2VzIG5vdCBtYWtlIHRoZSBzY29yZSB0b28gaGlnaCwgYW5kIHZpY2UgdmVyc2EgaWYKICAjIHRoZSBiYWxhbmNlIGlzIHRvbyBoaWdoLgogIGZvciAoaSBpbiAxOm5TdG9yZXMpIHsKICAgIGogPC0gaXhbaV0gICMgaW5kZXggb2YgdGhlIHN0b3JlIHRvIG1lc3Mgd2l0aAogICAgaWYgKHRlbXAgPCBibG8gJiBhW2pdID09IHYyKSB7CiAgICAgICMgQ29tcHV0ZSB0aGUgaW1wYWN0IG9mIHN3aXRjaGluZyB0byB0aGUgc21hbGxlciB2YXJpYW50LgogICAgICBkZWx0YSA8LSBzM1tqXSAvIHYxIC0gczNbal0gLyB2MgogICAgICAjIFRlc3Qgd2hldGhlciB0aGlzIHdvdWxkIHZpb2xhdGUgdGhlIHVwcGVyIGxpbWl0LgogICAgICAjIElmIG5vdCwgbWFrZSB0aGUgc3dpdGNoLgogICAgICBpZiAodGVtcCArIGRlbHRhIDw9IGJoaSkgewogICAgICAgIGFbal0gPC0gdjEKICAgICAgICB0ZW1wIDwtIHRlbXAgKyBkZWx0YQogICAgICB9CiAgICB9IGVsc2UgaWYgKHRlbXAgPiBiaGkgJiBhW2pdID09IHYxKSB7CiAgICAgICMgQ29tcHV0ZSB0aGUgaW1wYWN0IG9mIHN3aXRjaGluZyB0byB0aGUgbGFyZ2VyIHZhcmlhbnQuCiAgICAgIGRlbHRhIDwtIHMzW2pdIC8gdjIgLSBzM1tqXSAvIHYxCiAgICAgICMgVGVzdCB3aGV0aGVyIHRoaXMgd291bGQgdmlvbGF0ZSB0aGUgdXBwZXIgbGltaXQuCiAgICAgICMgSWYgbm90LCBtYWtlIHRoZSBzd2l0Y2guCiAgICAgIGlmICh0ZW1wICsgZGVsdGEgPj0gYmxvKSB7CiAgICAgICAgYVtqXSA8LSB2MgogICAgICAgIHRlbXAgPC0gdGVtcCArIGRlbHRhCiAgICAgIH0KICAgIH0gZWxzZSBpZiAodGVtcCA+PSBibG8gJiB0ZW1wIDw9IGJoaSkgewogICAgICAjIFRoZSBzb2x1dGlvbiBpcyBpbiBiYWxhbmNlLCBzbyBicmVhayBvdXQgb2YgdGhlIGxvb3AuCiAgICAgIGJyZWFrCiAgICB9CiAgfQogICMgSWYgdGhlIHNvbHV0aW9uIGlzIHN0aWxsIG91dCBvZiBiYWxhbmNlLCBpc3N1ZSBhIHdhcm5pbmcgYW5kIHJldHVybiBOQQogICMgKHdlIGZhaWxlZCB0byByZXBhaXIgaXQpLgogICMgT3RoZXJ3aXNlLCByZXR1cm4gYSBsaXN0IG9mIHZhcmlhbnRzLCBhc3NpZ25tZW50cyBhbmQgY29zdCwgYXMgd2VsbCBhcyB0aGUKICAjIGJhbGFuY2Ugc2NvcmUuCiAgaWYgKHRlbXAgPCBibG8gfCB0ZW1wID4gYmhpKSB7CiAgICB3YXJuaW5nKCJEaXNjYXJkaW5nIGFuIGluZmVhc2libGUgY2hyb21vc29tZS4iKQogICAgTkEKICB9IGVsc2UgewogICAgbGlzdChjb3N0ID0gY29zdChhKSwgdmFyaWFudDEgPSB2MSwgdmFyaWFudDIgPSB2MiwgYXNzaWdubWVudCA9IGEsIGJhbGFuY2UgPSB0ZW1wKQogIH0KfQpgYGAKClNpbmNlIHRoZSBHQSBwYWNrYWdlIG1heGltaXplcyBmaXRuZXNzLCB3ZSBkZWZpbmUgdGhlIGZpdG5lc3Mgb2YgYSBzb2x1dGlvbiB0byBiZSB0aGUgbmVnYXRpdmUgb2YgdGhlIGNvc3QgYWZ0ZXIgZGVjb2RpbmcuCgpgYGB7cn0KZml0IDwtIGZ1bmN0aW9uKHgpIHsKICAtZGVjb2RlKHgpJGNvc3QKfQpgYGAKCk5vdyB3ZSBjYW4gcnVuIGEgZ2VuZXRpYyBhbGdvcml0aG0gYW5kIHNlZSB3aGF0IHdlIGdldC4gU2V2ZXJhbCBwYXJhbWV0ZXJzIChhbG9uZyB3aXRoIHRoZSByYW5kb20gc2VlZCkgY2FuIGJlIHBsYXllZCB3aXRoLgoKYGBge3J9CnRpYygiR0EiKQpnZW5hbGcgPC0gZ2EodHlwZSA9ICJyZWFsLXZhbHVlZCIsCiAgICAgICAgICAgICBmaXRuZXNzID0gZml0LAogICAgICAgICAgICAgbG93ZXIgPSBjKDEsIGsxLCByZXAuaW50KDAsIG5TdG9yZXMpKSwKICAgICAgICAgICAgIHVwcGVyID0gYyhrMSArIDEsIGsyICsgMSwgcmVwLmludCgxLCBuU3RvcmVzKSksCiAgICAgICAgICAgICBwb3BTaXplID0gMTAwLCAgICMgbnVtYmVyIG9mIHNvbHV0aW9ucyBpbiBlYWNoIGdlbmVyYXRpb24KICAgICAgICAgICAgIHJ1biA9IDIwLCAgICAgICAgIyBzdG9wIGFmdGVyIHRoaXMgbWFueSBjb25zZWN1dGl2ZSBnZW5lcmF0aW9ucyB3aXRoIG5vIGltcHJvdmVtZW50CiAgICAgICAgICAgICBtYXhpdGVyID0gMTAwMCkgICMgc3RvcCBhZnRlciB0aGlzIG1hbnkgZ2VuZXJhdGlvbnMgZXZlbiBpZiBzdGlsbCBwcm9ncmVzc2luZwp0b2MoKQpgYGAKRmluYWxseSwgd2UgZGVjb2RlIHRoZSBiZXN0IHNvbHV0aW9uIGFuZCBkaXNwbGF5IHRoZSByZXN1bHRzLgoKYGBge3J9CnNvbHV0aW9uIDwtIGRlY29kZShnZW5hbGdAc29sdXRpb25bMSxdKQpjYXQoIlNvbHV0aW9uIGNvc3QgPSAiLCBzb2x1dGlvbiRjb3N0LCAiXG4iLAogICAgIlZhcmlhbnRzIGNob3NlbiA9ICIsIHNvbHV0aW9uJHZhcmlhbnQxLCAiLCAiLCBzb2x1dGlvbiR2YXJpYW50MiwgIlxuIiwKICAgICJBc3NpZ25tZW50czpcbiIsIHNvbHV0aW9uJGFzc2lnbm1lbnQsICJcbiIsCiAgICAiQmFsYW5jZSBzY29yZSAobG93ID0gIiwgYmxvLCAiLCBoaWdoID0gIiwgYmhpLCAiKSA9ICIsIHNvbHV0aW9uJGJhbGFuY2UsICJcbiIpCmBgYAojIEdyZWVkeSBoZXVyaXN0aWMKClRoZSBzZWNvbmQgYXBwcm9hY2ggY29uc2lkZXJzIGFsbCBjb21iaW5hdGlvbnMgb2YgJ3ZhcmlhbnQxJyBhbmQgJ3ZhcmlhbnQyJywgdXNpbmcgYSBncmVlZHkgaGV1cmlzdGljIHRvIG1ha2Ugc3RvcmUgYXNzaWdubWVudHMuIFRoZSBjb21iaW5hdGlvbiB3aXRoIGFzc2lnbm1lbnRzIHlpZWxkaW5nIHRoZSBsb3dlc3QgY29zdCB3aW5zLgoKYGBge3J9CmluY3VtYmVudC5jb3N0IDwtIEluZiAgICMgaW5jdW1iZW50IChsb3dlc3QpIGNvc3QKdmFyaWFudDEgPC0gTkEgICAgICAgICAgIyBpbmN1bWJlbnQgdmFsdWUgb2YgdGhlIGZpcnN0IHZhcmlhbnQKdmFyaWFudDIgPC0gTkEgICAgICAgICAgIyBpbmN1bWJlbnQgdmFsdWUgb2YgdGhlIHNlY29uZCB2YXJpYW50CmFzc2lnbm1lbnQgPC0gTkEgICAgICAgICMgaW5jdW1iZW50IHN0b3JlIGFzc2lnbm1lbnRzCnRpYygiR3JlZWR5IikKIyBJZiBiID4gMCwgbGFyZ2VyIGlzIGNoZWFwZXIsIHNvIHdlIGxvb3AgdGhyb3VnaCB2YXJpYW50IDIgZmlyc3QgYW5kIHRoZW4gdmFyaWFudAojIDEsIGxhcmdlc3QgdG8gc21hbGxlc3QuIElmIGIgPCAwLCBzbWFsbGVyIGlzIGNoZWFwZXIsIHNvIHdlIGxvb3AgdGhyb3VnaCB2YXJpYW50CiMgMSBmaXJzdCAoc21hbGxlc3QgdG8gbGFyZ2VzdCkgYW5kIHRoZW4gdmFyaWFudCAyLgppZiAoYiA+IDApIHsKICByYW5nZTEgPC0gazI6azEKICByYW5nZTIgPC0gazE6MQp9IGVsc2UgewogIHJhbmdlMSA8LSAxOmsxCiAgcmFuZ2UyIDwtIGsxOmsyCn0KIyBUcnkgdmFsdWVzIGZyb20gdGhlIGZpcnN0IHJhbmdlLgpmb3IgKHYxIGluIHJhbmdlMSkgewogICMgVHJ5IHZhbHVlcyBmcm9tIHRoZSBzZWNvbmQgcmFuZ2UuCiAgZm9yICh2MiBpbiByYW5nZTIpIHsKICAgICMgSW5pdGlhbGx5IHVzZSB2MSBpbiBldmVyeSBzdG9yZS4KICAgIGEgPC0gcmVwLmludCh2MSwgblN0b3JlcykKICAgICMgQ29tcHV0ZSBhIGJhbGFuY2Ugc2NvcmUuCiAgICB0ZW1wIDwtIGJhbGFuY2UoYSkKICAgICMgSWYgb3V0IG9mIGJhbGFuY2UsIHRyeSB0byBmaXggaXQgYnkgc3dhcHBpbmcgdG8gdjIuCiAgICBpZiAoKHRlbXAgPCBibG8gJiB2MiA8IHYxKSB8ICh0ZW1wID4gYmhpICYgdjEgPCB2MikpIHsKICAgICAgIyBDb21wdXRlIGZvciBlYWNoIHN0b3JlIHRoZSByYXRpbyBvZiB0aGUgY2hhbmdlIGluIGJhbGFuY2UgdmFsdWUgdG8KICAgICAgIyB0aGUgY2hhbmdlIGluIGNvc3QsIHN3aXRjaGluZyBmcm9tIHYxIHRvIHYyLgogICAgICBkZWx0YS5jb3N0IDwtIHMxICogKChzMiAvIHYyKV5iIC0gKHMyIC8gdjEpXmIpCiAgICAgIGRlbHRhLmJhbGFuY2UgPC0gczMgLyB2MiAtIHMzIC8gdjEKICAgICAgcmF0aW8gPC0gYWJzKGRlbHRhLmJhbGFuY2UpIC8gZGVsdGEuY29zdAogICAgICAjIFNvcnQgc3RvcmVzIGludG8gZGVzY2VuZGluZyByYXRpbyBvcmRlciAoImJpZ2dlc3QgYmFuZyBmb3IgdGhlIGJ1Y2siCiAgICAgICMgZmlyc3QpLgogICAgICBpeCA8LSBvcmRlcihyYXRpbywgZGVjcmVhc2luZyA9IFRSVUUpCiAgICAgICMgU3dpdGNoIHN0b3JlcyB0byB2MiBncmVlZGlseSB1bnRpbCB0aGUgYmFsYW5jZSBjb25zdHJhaW50IGlzIG1ldC4KICAgICAgaiA8LSAwCiAgICAgIG5mbGlwcyA8LSAwCiAgICAgIHdoaWxlICgodGVtcCA8IGJsbyAmIHYyIDwgdjEpIHwgKHRlbXAgPiBiaGkgJiB2MSA8IHYyKSkgewogICAgICAgIGogPC0gaiArIDEgICMgcG9zaXRpb24gaW4gbGlzdCBvZiBuZXh0IHN0b3JlIHRvIGZsaXAKICAgICAgICBpIDwtIGl4W2pdICAjIGluZGV4IG9mIHN0b3JlIHRvIGZsaXAKICAgICAgICAjIFN3aXRjaCBzdG9yZSBpIHRvIHYyLgogICAgICAgIGFbaV0gPC0gdjIKICAgICAgICBuZmxpcHMgPC0gbmZsaXBzICsgMQogICAgICAgICMgVXBkYXRlIHRoZSBydW5uaW5nIGJhbGFuY2UgdmFsdWUuCiAgICAgICAgdGVtcCA8LSB0ZW1wICsgZGVsdGEuYmFsYW5jZVtpXQogICAgICB9CiAgICB9CiAgICAjIENvbXB1dGUgdGhlIGNvc3Qgb2YgdGhlIChwcmVzdW1hYmx5IG5vdyBmZWFzaWJsZSkgYXNzaWdubWVudC4KICAgIHogPC0gY29zdChhKQogICAgIyBJZiBpdCBpcyBhIG5ldyBpbmN1bWJlbnQsIHJlY29yZCAoYW5kIGFubm91bmNlKSBpdC4KICAgIGlmICh6IDwgaW5jdW1iZW50LmNvc3QpIHsKICAgICAgaW5jdW1iZW50LmNvc3QgPC0gegogICAgICB2YXJpYW50MSA8LSBtaW4odjEsIHYyKQogICAgICB2YXJpYW50MiA8LSBtYXgodjEsIHYyKQogICAgICBhc3NpZ25tZW50IDwtIGEKICAgICAgY2F0KCIoIiwgdmFyaWFudDEsICIsICIsIHZhcmlhbnQyLCAiKSBjb3N0ID0gIiwgeiwgIiAoIiwgbmZsaXBzLCAiIHN0b3JlcyBmbGlwcGVkKVxuIikKICAgIH0KICB9Cn0KdG9jKCkKYGBgClRoZSBmaW5hbCBzb2x1dGlvbiBpcyBhcyBmb2xsb3dzLgoKYGBge3J9CmNhdCgiU29sdXRpb24gY29zdCA9ICIsIGNvc3QoYXNzaWdubWVudCksICJcbiIsCiAgICAiVmFyaWFudHMgY2hvc2VuID0gIiwgdmFyaWFudDEsICIsICIsIHZhcmlhbnQyLCAiXG4iLAogICAgIkFzc2lnbm1lbnRzOlxuIiwgYXNzaWdubWVudCwgIlxuIiwKICAgICJCYWxhbmNlIHNjb3JlIChsb3cgPSAiLCBibG8sICIsIGhpZ2ggPSAiLCBiaGksICIpID0gIiwgYmFsYW5jZShhc3NpZ25tZW50KSwgIlxuIikKYGBgCgo=