1
0
Fork 0
mirror of https://github.com/graphhopper/jsprit.git synced 2020-01-24 07:45:05 +01:00

add multiple vehicles

This commit is contained in:
oblonski 2015-05-29 21:24:12 +02:00
parent d6c316fdca
commit ed95f90fc5
75 changed files with 7884 additions and 0 deletions

View file

@ -0,0 +1,172 @@
/*******************************************************************************
* Copyright (C) 2014 Stefan Schroeder
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package jsprit.instance.reader;
import jsprit.core.problem.Location;
import jsprit.core.problem.VehicleRoutingProblem;
import jsprit.core.problem.VehicleRoutingProblem.FleetSize;
import jsprit.core.problem.job.Service;
import jsprit.core.problem.vehicle.VehicleImpl;
import jsprit.core.problem.vehicle.VehicleTypeImpl;
import jsprit.core.util.Coordinate;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/**
* Reader that reads the well-known solomon-instances.
*
* <p>See: <a href="http://neo.lcc.uma.es/vrp/vrp-instances/capacitated-vrp-with-time-windows-instances/">neo.org</a>
*
* @author stefan
*
*/
public class BelhaizaReader {
/**
* @param costProjectionFactor the costProjectionFactor to set
*/
public void setVariableCostProjectionFactor(double costProjectionFactor) {
this.variableCostProjectionFactor = costProjectionFactor;
}
private static Logger logger = LogManager.getLogger(BelhaizaReader.class);
private final VehicleRoutingProblem.Builder vrpBuilder;
private double coordProjectionFactor = 1;
private double timeProjectionFactor = 1;
private double variableCostProjectionFactor = 1;
private double fixedCostPerVehicle = 0.0;
public BelhaizaReader(VehicleRoutingProblem.Builder vrpBuilder) {
super();
this.vrpBuilder = vrpBuilder;
}
public BelhaizaReader(VehicleRoutingProblem.Builder vrpBuilder, double fixedCostPerVehicle) {
super();
this.vrpBuilder = vrpBuilder;
this.fixedCostPerVehicle=fixedCostPerVehicle;
}
public void read(String solomonFile){
vrpBuilder.setFleetSize(FleetSize.INFINITE);
BufferedReader reader = getReader(solomonFile);
int vehicleCapacity = 0;
int counter = 0;
String line;
while((line = readLine(reader)) != null){
String[] tokens = line.replace("\r", "").trim().split("\\s+");
counter++;
if(counter == 2){
vehicleCapacity = Integer.parseInt(tokens[1]);
continue;
}
if(counter > 2){
if(tokens.length < 7) continue;
Coordinate coord = makeCoord(tokens[1],tokens[2]);
String customerId = tokens[0];
int demand = Integer.parseInt(tokens[4]);
double serviceTime = Double.parseDouble(tokens[3])*timeProjectionFactor;
if(counter == 3){
VehicleTypeImpl.Builder typeBuilder = VehicleTypeImpl.Builder.newInstance("solomonType").addCapacityDimension(0, vehicleCapacity);
typeBuilder.setCostPerDistance(1.0*variableCostProjectionFactor).setFixedCost(fixedCostPerVehicle);
VehicleTypeImpl vehicleType = typeBuilder.build();
double end = Double.parseDouble(tokens[8])*timeProjectionFactor;
for(int i=0;i<11;i++) {
VehicleImpl vehicle = VehicleImpl.Builder.newInstance("solomonVehicle"+(i+1)).setEarliestStart(0.).setLatestArrival(end)
.setStartLocation(Location.Builder.newInstance().setId(customerId)
.setCoordinate(coord).build()).setType(vehicleType).build();
vrpBuilder.addVehicle(vehicle);
}
}
else{
Service.Builder serviceBuilder = Service.Builder.newInstance(customerId);
serviceBuilder.addSizeDimension(0, demand).setLocation(Location.Builder.newInstance().setCoordinate(coord).setId(customerId).build()).setServiceTime(serviceTime);
int noTimeWindows = Integer.parseInt(tokens[7]);
for(int i=0;i<noTimeWindows*2;i=i+2){
double earliest = Double.parseDouble(tokens[8+i]);
double latest = Double.parseDouble(tokens[8+i+1]);
serviceBuilder.addTimeWindow(earliest,latest);
}
vrpBuilder.addJob(serviceBuilder.build());
}
}
}
close(reader);
}
public void setCoordProjectionFactor(double coordProjectionFactor) {
this.coordProjectionFactor = coordProjectionFactor;
}
private void close(BufferedReader reader) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
logger.error(e);
System.exit(1);
}
}
private String readLine(BufferedReader reader) {
try {
return reader.readLine();
} catch (IOException e) {
e.printStackTrace();
logger.error(e);
System.exit(1);
return null;
}
}
private Coordinate makeCoord(String xString, String yString) {
double x = Double.parseDouble(xString);
double y = Double.parseDouble(yString);
return new Coordinate(x*coordProjectionFactor,y*coordProjectionFactor);
}
private BufferedReader getReader(String solomonFile) {
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(solomonFile));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
logger.error(e1);
System.exit(1);
}
return reader;
}
public void setTimeProjectionFactor(double timeProjection) {
this.timeProjectionFactor=timeProjection;
}
}

View file

@ -0,0 +1,193 @@
/*******************************************************************************
* Copyright (C) 2013 Stefan Schroeder
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package jsprit.instance.reader;
import jsprit.core.algorithm.VehicleRoutingAlgorithm;
import jsprit.core.algorithm.box.Jsprit;
import jsprit.core.problem.VehicleRoutingProblem;
import jsprit.core.problem.VehicleRoutingProblem.FleetSize;
import jsprit.core.problem.job.Service;
import jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import jsprit.core.problem.solution.route.activity.TimeWindow;
import jsprit.core.problem.vehicle.Vehicle;
import jsprit.core.reporting.SolutionPrinter;
import jsprit.core.util.Solutions;
import org.junit.Test;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.assertEquals;
public class BelhaizaReaderTest {
@Test
public void whenReadingBelhaizaInstance_nuOfCustomersIsCorrect(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new BelhaizaReader(builder).read(getPath());
VehicleRoutingProblem vrp = builder.build();
assertEquals(100,vrp.getJobs().values().size());
}
private String getPath() {
URL resource = getClass().getClassLoader().getResource("cm101.txt");
if(resource == null) throw new IllegalStateException("file C101_solomon.txt does not exist");
return resource.getPath();
}
@Test
public void whenReadingBelhaizaInstance_fleetSizeIsInfinite(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new BelhaizaReader(builder).read(getPath());
VehicleRoutingProblem vrp = builder.build();
assertEquals(FleetSize.INFINITE,vrp.getFleetSize());
}
@Test
public void whenReadingBelhaizaInstance_vehicleCapacitiesAreCorrect(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new BelhaizaReader(builder).read(getPath());
VehicleRoutingProblem vrp = builder.build();
for(Vehicle v : vrp.getVehicles()){
assertEquals(200,v.getType().getCapacityDimensions().get(0));
}
}
@Test
public void whenReadingBelhaizaInstance_vehicleLocationsAreCorrect_and_correspondToDepotLocation(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new BelhaizaReader(builder).read(getPath());
VehicleRoutingProblem vrp = builder.build();
for(Vehicle v : vrp.getVehicles()){
assertEquals(40.0,v.getStartLocation().getCoordinate().getX(),0.01);
assertEquals(50.0,v.getStartLocation().getCoordinate().getY(),0.01);
}
}
@Test
public void whenReadingBelhaizaInstance_demandOfCustomerOneIsCorrect(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new BelhaizaReader(builder).read(getPath());
VehicleRoutingProblem vrp = builder.build();
assertEquals(10,vrp.getJobs().get("1").getSize().get(0));
}
@Test
public void whenReadingBelhaizaInstance_serviceDurationOfCustomerTwoIsCorrect(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new BelhaizaReader(builder).read(getPath());
VehicleRoutingProblem vrp = builder.build();
assertEquals(90,((Service)vrp.getJobs().get("2")).getServiceDuration(),0.1);
}
@Test
public void noTimeWindowsShouldBeCorrect(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new BelhaizaReader(builder).read(getPath());
VehicleRoutingProblem vrp = builder.build();
assertEquals(5,((Service)vrp.getJobs().get("1")).getTimeWindows(0.).size());
}
@Test
public void noTimeWindowsShouldBeCorrect2(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new BelhaizaReader(builder).read(getPath());
VehicleRoutingProblem vrp = builder.build();
assertEquals(10,((Service)vrp.getJobs().get("2")).getTimeWindows(0.).size());
}
@Test
public void firstTimeWindowShouldBeCorrect(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new BelhaizaReader(builder).read(getPath());
VehicleRoutingProblem vrp = builder.build();
assertEquals(20.,((Service)vrp.getJobs().get("1")).getTimeWindows(0.).iterator().next().getStart(),0.1);
assertEquals(31.,((Service)vrp.getJobs().get("1")).getTimeWindows(0.).iterator().next().getEnd(),0.1);
}
@Test
public void secondTimeWindowShouldBeCorrect(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new BelhaizaReader(builder).read(getPath());
VehicleRoutingProblem vrp = builder.build();
List<TimeWindow> timeWindows = new ArrayList<TimeWindow>(((Service)vrp.getJobs().get("1")).getTimeWindows(0.));
assertEquals(118.,timeWindows.get(1).getStart(),0.1);
assertEquals(148.,timeWindows.get(1).getEnd(),0.1);
}
@Test
public void thirdTimeWindowShouldBeCorrect(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new BelhaizaReader(builder).read(getPath());
VehicleRoutingProblem vrp = builder.build();
List<TimeWindow> timeWindows = new ArrayList<TimeWindow>(((Service)vrp.getJobs().get("1")).getTimeWindows(0.));
assertEquals(235.,timeWindows.get(2).getStart(),0.1);
assertEquals(258.,timeWindows.get(2).getEnd(),0.1);
}
@Test
public void fourthTimeWindowShouldBeCorrect(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new BelhaizaReader(builder).read(getPath());
VehicleRoutingProblem vrp = builder.build();
List<TimeWindow> timeWindows = new ArrayList<TimeWindow>(((Service)vrp.getJobs().get("1")).getTimeWindows(0.));
assertEquals(343.,timeWindows.get(3).getStart(),0.1);
assertEquals(355.,timeWindows.get(3).getEnd(),0.1);
}
@Test
public void fifthTimeWindowShouldBeCorrect(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new BelhaizaReader(builder).read(getPath());
VehicleRoutingProblem vrp = builder.build();
List<TimeWindow> timeWindows = new ArrayList<TimeWindow>(((Service)vrp.getJobs().get("1")).getTimeWindows(0.));
assertEquals(441.,timeWindows.get(4).getStart(),0.1);
assertEquals(457.,timeWindows.get(4).getEnd(),0.1);
}
@Test
public void testAlgo(){
VehicleRoutingProblem.Builder builder = VehicleRoutingProblem.Builder.newInstance();
new BelhaizaReader(builder).read(getPath());
builder.setFleetSize(FleetSize.FINITE);
VehicleRoutingProblem vrp = builder.build();
// VehicleRoutingAlgorithm vra = Jsprit.createAlgorithm(vrp);
// VehicleRoutingAlgorithm algorithm = new SchrimpfFactory().createAlgorithm(vrp);
Jsprit.Builder vraBuilder = Jsprit.Builder.newInstance(vrp);
vraBuilder.setProperty(Jsprit.Strategy.CLUSTER_REGRET, "0.25");
vraBuilder.setProperty(Jsprit.Strategy.RADIAL_REGRET, "0.25");
vraBuilder.setProperty(Jsprit.Strategy.RANDOM_REGRET, "0.");
vraBuilder.setProperty(Jsprit.Strategy.WORST_REGRET, "0.25");
vraBuilder.setProperty(Jsprit.Parameter.THRESHOLD_INI, "0.05");
VehicleRoutingAlgorithm algorithm = vraBuilder.buildAlgorithm();
algorithm.setMaxIterations(5000);
// VariationCoefficientTermination variation_coefficient = new VariationCoefficientTermination(200, 0.005);
// algorithm.setPrematureAlgorithmTermination(variation_coefficient);
// algorithm.addListener(variation_coefficient);
// vra.setMaxIterations(5000);
VehicleRoutingProblemSolution solution = Solutions.bestOf(algorithm.searchSolutions());
SolutionPrinter.print(vrp,solution, SolutionPrinter.Print.VERBOSE);
}
}

View file

@ -0,0 +1,103 @@
4 10 100 1
0 200
0 40 50 0 0 0 0 0 1236
1 45 68 90 10 1 1 5 20 31 118 148 235 258 343 355 441 457
2 45 70 90 30 1 1 10 61 94 163 187 238 252 313 350 410 439 498 527 616 631 698 744 803 844 920 939
3 42 66 90 10 1 1 8 76 88 187 221 288 303 371 403 469 514 587 618 683 694 760 791
4 42 68 90 10 1 1 7 64 110 168 201 253 281 333 357 415 463 540 580 644 668
5 42 65 90 10 1 1 7 7 36 129 144 202 222 289 328 391 403 477 514 574 592
6 40 69 90 20 1 1 7 122 153 247 288 362 392 446 483 536 561 629 665 744 784
7 40 66 90 20 1 1 7 37 68 152 162 248 286 373 422 476 490 554 587 665 697
8 38 68 90 20 1 1 8 34 73 127 152 209 250 312 322 389 407 494 514 600 629 686 717
9 38 70 90 10 1 1 5 106 133 193 221 305 331 414 430 498 515
10 35 66 90 10 1 1 7 82 116 172 198 256 290 344 388 466 510 568 601 691 706
11 35 69 90 10 1 1 7 55 72 157 187 237 276 337 348 445 488 569 605 683 707
12 25 85 90 20 1 1 7 87 105 202 212 307 335 391 424 503 519 608 642 722 752
13 22 75 90 30 1 1 8 55 78 132 167 248 271 325 355 443 464 546 568 631 653 706 746
14 22 85 90 10 1 1 5 100 147 234 276 343 391 444 470 533 574
15 20 80 90 40 1 1 5 110 155 241 275 344 379 451 479 551 569
16 20 85 90 40 1 1 6 4 16 73 88 170 206 267 278 349 392 451 465
17 18 75 90 20 1 1 10 122 162 257 289 366 407 496 508 586 609 697 741 814 842 900 918 972 1006 1094 1127
18 15 75 90 20 1 1 5 102 122 188 232 296 314 390 424 496 530
19 15 80 90 10 1 1 7 42 59 156 181 256 267 365 414 472 520 615 653 710 732
20 30 50 90 10 1 1 8 44 68 142 161 217 228 327 349 420 454 508 549 622 637 706 741
21 30 52 90 20 1 1 8 76 107 175 195 245 272 333 353 408 420 490 505 568 607 692 722
22 28 52 90 20 1 1 9 99 125 211 251 320 363 434 478 551 584 641 656 752 784 872 907 971 988
23 28 55 90 10 1 1 5 84 115 202 220 300 324 402 443 538 552
24 25 50 90 10 1 1 10 46 71 169 213 281 326 423 456 515 526 622 640 712 740 800 816 879 912 975 993
25 25 52 90 40 1 1 5 56 97 161 185 266 311 396 406 475 512
26 25 55 90 10 1 1 5 45 60 113 148 221 244 333 367 419 435
27 23 52 90 10 1 1 5 113 146 215 228 322 349 430 472 530 565
28 23 55 90 20 1 1 8 44 74 132 144 230 277 363 378 437 462 520 538 631 663 729 743
29 20 50 90 10 1 1 6 88 102 159 196 265 284 362 401 482 493 551 582
30 20 55 90 10 1 1 7 121 151 204 227 282 326 406 419 484 505 596 637 719 745
31 10 35 90 20 1 1 6 24 66 122 138 226 250 327 344 431 453 513 560
32 10 40 90 30 1 1 8 6 28 100 123 191 203 274 310 360 409 503 527 599 630 711 754
33 8 40 90 40 1 1 5 19 34 117 163 219 231 325 337 433 447
34 8 45 90 20 1 1 10 23 70 158 176 243 254 305 331 418 464 543 574 653 675 751 797 851 874 943 992
35 5 35 90 10 1 1 10 47 67 146 193 264 277 336 384 473 496 591 639 721 765 837 867 940 981 1036 1057
36 5 45 90 10 1 1 5 104 126 224 242 298 331 383 400 452 462
37 2 40 90 20 1 1 8 111 128 181 201 275 291 357 402 472 489 572 608 705 723 806 848
38 0 40 90 30 1 1 6 107 130 193 236 318 350 434 466 562 575 627 658
39 0 45 90 20 1 1 10 97 136 209 233 294 340 393 406 479 524 616 642 702 719 809 837 907 952 1034 1077
40 35 30 90 10 1 1 6 10 27 106 122 204 246 336 380 467 515 599 615
41 35 32 90 10 1 1 5 70 109 172 205 263 298 362 377 473 488
42 33 32 90 20 1 1 6 83 116 168 185 246 289 350 393 454 478 549 570
43 33 35 90 10 1 1 10 11 29 80 104 164 200 264 289 366 399 466 500 556 584 637 686 749 795 891 912
44 32 30 90 10 1 1 10 101 124 195 234 319 331 396 430 484 509 565 594 683 726 790 812 879 889 973 985
45 30 30 90 10 1 1 7 91 102 176 190 266 312 376 413 477 498 586 634 701 745
46 30 32 90 30 1 1 10 114 135 225 241 323 339 416 443 541 586 684 713 780 819 874 900 975 991 1042 1079
47 30 35 90 10 1 1 5 1 34 92 135 227 275 341 380 455 504
48 28 30 90 10 1 1 7 110 132 191 211 276 312 363 386 457 498 596 612 675 718
49 28 35 90 10 1 1 10 37 64 138 161 221 255 320 361 454 467 555 592 645 691 767 783 864 881 944 964
50 26 32 90 10 1 1 9 61 76 152 174 242 288 360 372 430 441 520 554 628 650 705 733 808 824
51 25 30 90 10 1 1 9 17 51 114 143 213 228 292 322 401 449 523 545 602 638 688 727 795 821
52 25 35 90 10 1 1 8 60 106 167 190 286 304 384 410 495 543 636 673 772 798 897 927
53 44 5 90 20 1 1 8 119 166 226 248 310 348 413 423 502 517 593 630 686 715 787 823
54 42 10 90 40 1 1 5 102 114 173 217 316 348 423 448 503 543
55 42 15 90 10 1 1 7 31 49 148 179 264 304 363 374 450 498 554 603 681 698
56 40 5 90 30 1 1 6 110 144 226 270 326 355 429 470 546 565 643 675
57 40 15 90 40 1 1 5 83 112 164 201 276 312 400 415 505 551
58 38 5 90 30 1 1 6 61 98 173 184 271 296 368 398 461 489 561 572
59 38 15 90 10 1 1 9 45 71 149 194 290 321 407 454 553 584 661 678 733 748 812 838 929 966
60 35 5 90 20 1 1 9 79 118 192 212 296 328 397 410 489 531 604 650 732 753 844 891 950 985
61 50 30 90 10 1 1 10 68 92 168 197 248 272 358 401 494 530 604 622 713 735 805 817 873 903 968 1008
62 50 35 90 20 1 1 7 29 77 169 201 272 313 378 424 515 553 640 685 736 753
63 50 40 90 50 1 1 7 0 14 103 126 223 265 359 391 442 458 532 575 656 699
64 48 30 90 10 1 1 8 8 33 85 124 192 232 295 314 388 398 461 495 578 608 697 712
65 48 40 90 10 1 1 5 70 98 172 209 306 336 404 442 537 564
66 47 35 90 10 1 1 7 44 64 155 189 284 330 391 418 491 507 588 620 703 720
67 47 40 90 10 1 1 9 65 103 202 226 279 300 367 403 496 518 582 631 707 737 818 849 914 955
68 45 30 90 10 1 1 8 110 147 234 270 340 389 451 466 555 594 657 697 783 827 911 936
69 45 35 90 10 1 1 7 60 107 180 192 275 324 399 416 480 521 610 620 719 735
70 95 30 90 30 1 1 9 22 49 125 164 243 284 356 400 499 540 636 654 720 750 809 833 888 932
71 95 35 90 20 1 1 8 73 91 163 212 266 302 394 410 490 520 590 610 688 732 810 859
72 53 30 90 10 1 1 7 28 68 141 160 230 269 340 366 462 496 548 574 624 642
73 92 30 90 10 1 1 9 117 156 234 280 360 396 479 500 588 633 707 727 813 831 919 948 1016 1047
74 53 35 90 50 1 1 5 45 56 109 145 228 256 323 357 414 438
75 45 65 90 20 1 1 5 105 148 211 242 298 341 422 435 509 545
76 90 35 90 10 1 1 6 74 105 159 205 295 331 401 422 503 538 631 672
77 88 30 90 10 1 1 8 92 138 214 252 343 385 443 491 542 575 665 698 750 768 857 885
78 88 35 90 20 1 1 8 63 86 148 185 251 268 364 377 456 481 546 559 626 665 755 797
79 87 30 90 10 1 1 10 111 154 210 257 321 357 436 456 524 535 634 678 763 812 888 921 996 1014 1089 1120
80 85 25 90 10 1 1 7 98 139 229 259 319 359 450 498 574 598 669 718 805 847
81 85 35 90 30 1 1 7 27 40 100 138 201 218 289 302 356 387 470 508 599 639
82 75 55 90 20 1 1 6 57 104 164 197 294 324 416 438 488 512 599 626
83 72 55 90 10 1 1 5 105 115 196 235 324 361 450 488 558 588
84 70 58 90 20 1 1 8 74 108 163 198 285 320 389 401 466 487 582 604 655 682 735 777
85 68 60 90 30 1 1 8 36 54 147 158 216 238 311 348 440 473 551 599 655 689 766 787
86 66 55 90 10 1 1 7 103 115 214 246 328 340 410 427 503 547 610 645 701 748
87 65 55 90 20 1 1 10 22 49 100 145 215 232 303 349 413 446 497 507 576 596 649 691 748 784 878 921
88 65 60 90 30 1 1 7 113 134 228 276 355 369 420 459 547 591 658 693 777 802
89 63 58 90 10 1 1 8 98 133 221 232 282 298 394 418 498 524 611 660 746 794 861 908
90 60 55 90 10 1 1 5 72 109 183 224 301 350 440 476 527 550
91 60 60 90 10 1 1 9 26 46 102 140 191 235 311 325 424 448 515 542 633 649 748 763 843 870
92 67 85 90 20 1 1 10 48 95 165 205 288 323 410 440 502 535 606 639 696 708 768 779 837 850 933 958
93 65 85 90 40 1 1 8 25 73 152 183 258 297 391 439 521 563 659 683 759 792 851 884
94 65 82 90 10 1 1 7 57 91 151 200 293 319 399 409 471 489 542 569 645 680
95 62 80 90 30 1 1 7 81 105 170 214 300 330 400 431 518 552 646 692 769 790
96 60 80 90 10 1 1 8 85 134 226 250 333 369 451 465 561 610 702 718 777 802 852 867
97 60 85 90 30 1 1 8 49 85 153 183 235 248 311 336 428 473 555 565 660 678 741 776
98 58 75 90 20 1 1 9 120 162 248 281 355 386 439 451 549 572 639 666 755 793 871 891 968 998
99 55 80 90 10 1 1 10 74 90 188 215 309 336 403 414 475 495 552 599 650 681 738 781 834 872 928 958
100 55 85 90 20 1 1 8 49 66 139 162 260 299 371 392 485 498 578 609 659 669 753 793