diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/.Rhistory b/ProyectoFinal/AlgoritmoGenetico/malva/.Rhistory new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/.cproject b/ProyectoFinal/AlgoritmoGenetico/malva/.cproject new file mode 100644 index 0000000000000000000000000000000000000000..4d31d90c5d30341f047854770a3b9d88675e97c9 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/.cproject @@ -0,0 +1,134 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<?fileVersion 4.0.0?> + +<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage"> + <storageModule moduleId="org.eclipse.cdt.core.settings"> + <cconfiguration id="cdt.managedbuild.toolchain.gnu.base.1028103499"> + <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.1028103499" moduleId="org.eclipse.cdt.core.settings" name="Default"> + <externalSettings/> + <extensions> + <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/> + <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + </extensions> + </storageModule> + <storageModule moduleId="cdtBuildSystem" version="4.0.0"> + <configuration artifactName="${ProjName}" buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.base.1028103499" name="Default" parent="org.eclipse.cdt.build.core.emptycfg"> + <folderInfo id="cdt.managedbuild.toolchain.gnu.base.1028103499.1127827476" name="/" resourcePath=""> + <toolChain id="cdt.managedbuild.toolchain.gnu.base.765753298" name="cdt.managedbuild.toolchain.gnu.base" superClass="cdt.managedbuild.toolchain.gnu.base"> + <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.1817766457" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/> + <builder id="cdt.managedbuild.target.gnu.builder.base.1493464269" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/> + <tool id="cdt.managedbuild.tool.gnu.archiver.base.1457471918" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1006777203" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base"> + <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.224865571" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/> + </tool> + <tool id="cdt.managedbuild.tool.gnu.c.compiler.base.2140176745" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base"> + <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.587099952" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> + </tool> + <tool id="cdt.managedbuild.tool.gnu.c.linker.base.1988570852" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.1956065400" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base"> + <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.507618374" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input"> + <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> + <additionalInput kind="additionalinput" paths="$(LIBS)"/> + </inputType> + </tool> + <tool id="cdt.managedbuild.tool.gnu.assembler.base.535458070" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base"> + <inputType id="cdt.managedbuild.tool.gnu.assembler.input.584095528" superClass="cdt.managedbuild.tool.gnu.assembler.input"/> + </tool> + </toolChain> + </folderInfo> + </configuration> + </storageModule> + <storageModule moduleId="scannerConfiguration"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + <profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="makefileGenerator"> + <runAction arguments="-E -P -v -dD" command="" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + </storageModule> + <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> + </cconfiguration> + </storageModule> + <storageModule moduleId="cdtBuildSystem" version="4.0.0"> + <project id="malva.null.2024921052" name="malva"/> + </storageModule> +</cproject> diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/.gitignore b/ProyectoFinal/AlgoritmoGenetico/malva/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..42fcba11cdc125b4add7382cc45c372d7f5839b3 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/.gitignore @@ -0,0 +1,6 @@ +.cproject/ +.project/ +.svn/ +.idea/ +.DS_Store + diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/.project b/ProyectoFinal/AlgoritmoGenetico/malva/.project new file mode 100644 index 0000000000000000000000000000000000000000..1bb914cafb7eb471ef782c892e428d4d182ddae0 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/.project @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>Malva</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name> + <triggers>clean,full,incremental,</triggers> + <arguments> + <dictionary> + <key>?name?</key> + <value></value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.append_environment</key> + <value>true</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.autoBuildTarget</key> + <value>all</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.buildArguments</key> + <value></value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.buildCommand</key> + <value>make</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.cleanBuildTarget</key> + <value>clean</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.contents</key> + <value>org.eclipse.cdt.make.core.activeConfigSettings</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.enableAutoBuild</key> + <value>false</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.enableCleanBuild</key> + <value>true</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.enableFullBuild</key> + <value>true</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.fullBuildTarget</key> + <value>all</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.stopOnError</key> + <value>true</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key> + <value>true</value> + </dictionary> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name> + <triggers>full,incremental,</triggers> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.cdt.core.cnature</nature> + <nature>org.eclipse.cdt.core.ccnature</nature> + <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature> + <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature> + </natures> +</projectDescription> diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/Makefile b/ProyectoFinal/AlgoritmoGenetico/malva/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..a662e76dd1a29fb21d5ef629333e0e5bd4e4c2cf --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/Makefile @@ -0,0 +1,24 @@ +default: + @echo "Make what? (all, libs, skeletons, clean)" + +all: + (cd inc ; rm -f Mallba) + (cd inc ; ./inc.env) + (cd src ; make all) + (cd lib ; make all) + (cd rep ; make all) + +libs: + (cd inc ; rm -f Mallba) + (cd inc ; ./inc.env) + (cd src ; make all) + (cd lib ; make all) + +skeletons: + (cd rep ; make all) + +clean: + (cd inc ; rm -f Mallba) + (cd src ; make clean) + (cd lib ; make clean) + (cd rep ; make clean) diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ATSP-instances/br17.atsp b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ATSP-instances/br17.atsp new file mode 100644 index 0000000000000000000000000000000000000000..37313b1fe39b7e174543156a59dabac8cb897506 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ATSP-instances/br17.atsp @@ -0,0 +1,42 @@ +NAME: br17 +TYPE: ATSP +COMMENT: 17 city problem (Repetto) +DIMENSION: 17 +EDGE_WEIGHT_TYPE: EXPLICIT +EDGE_WEIGHT_FORMAT: FULL_MATRIX +EDGE_WEIGHT_SECTION + 9999 3 5 48 48 8 8 5 5 3 3 0 3 5 8 8 + 5 + 3 9999 3 48 48 8 8 5 5 0 0 3 0 3 8 8 + 5 + 5 3 9999 72 72 48 48 24 24 3 3 5 3 0 48 48 + 24 + 48 48 74 9999 0 6 6 12 12 48 48 48 48 74 6 6 + 12 + 48 48 74 0 9999 6 6 12 12 48 48 48 48 74 6 6 + 12 + 8 8 50 6 6 9999 0 8 8 8 8 8 8 50 0 0 + 8 + 8 8 50 6 6 0 9999 8 8 8 8 8 8 50 0 0 + 8 + 5 5 26 12 12 8 8 9999 0 5 5 5 5 26 8 8 + 0 + 5 5 26 12 12 8 8 0 9999 5 5 5 5 26 8 8 + 0 + 3 0 3 48 48 8 8 5 5 9999 0 3 0 3 8 8 + 5 + 3 0 3 48 48 8 8 5 5 0 9999 3 0 3 8 8 + 5 + 0 3 5 48 48 8 8 5 5 3 3 9999 3 5 8 8 + 5 + 3 0 3 48 48 8 8 5 5 0 0 3 9999 3 8 8 + 5 + 5 3 0 72 72 48 48 24 24 3 3 5 3 9999 48 48 + 24 + 8 8 50 6 6 0 0 8 8 8 8 8 8 50 9999 0 + 8 + 8 8 50 6 6 0 0 8 8 8 8 8 8 50 0 9999 + 8 + 5 5 26 12 12 8 8 0 0 5 5 5 5 26 8 8 + 9999 +EOF diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ATSP-instances/ft53.atsp b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ATSP-instances/ft53.atsp new file mode 100644 index 0000000000000000000000000000000000000000..3f81c5bc3c7f5029423cd185473ac26a641fb5d0 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ATSP-instances/ft53.atsp @@ -0,0 +1,220 @@ +NAME: ft53 +TYPE: ATSP +COMMENT: Asymmetric TSP (Fischetti) +DIMENSION: 53 +EDGE_WEIGHT_TYPE: EXPLICIT +EDGE_WEIGHT_FORMAT: FULL_MATRIX +EDGE_WEIGHT_SECTION + 9999999 223 210 125 245 363 322 388 290 341 267 281 258 247 302 + 325 311 276 392 475 417 324 372 437 610 310 362 333 498 459 + 467 352 199 336 305 172 143 273 292 364 262 296 435 423 433 + 354 509 472 238 185 357 420 344 + 58 9999999 179 100 287 155 116 170 74 137 239 260 234 221 282 + 294 286 251 434 512 409 367 406 410 598 354 353 371 451 490 + 510 389 244 313 291 210 185 318 329 402 297 81 241 215 292 + 308 301 262 207 159 300 214 314 + 60 109 9999999 80 295 246 209 270 174 225 227 179 221 212 262 + 131 117 79 382 431 263 309 321 235 452 355 338 324 497 449 + 360 243 251 140 272 223 189 259 337 388 308 174 340 309 382 + 396 393 355 198 141 201 302 190 + 58 115 98 9999999 285 255 215 279 178 232 154 176 157 136 194 + 219 207 170 429 516 326 366 411 323 517 344 270 368 541 498 + 446 323 244 225 203 214 183 314 278 403 301 183 352 311 391 + 341 410 367 130 76 247 312 236 + 93 58 63 90 9999999 194 160 210 117 174 238 235 231 224 280 + 175 171 133 281 267 221 248 139 286 415 82 136 135 309 264 + 341 293 231 189 75 253 219 306 360 351 340 123 277 248 288 + 323 305 256 155 155 152 248 146 + 531 593 584 499 765 9999999 344 405 309 360 631 654 632 622 679 + 697 685 647 909 992 807 847 887 809 999 789 750 848 763 716 + 763 643 724 539 682 687 664 788 762 881 781 669 832 796 824 + 825 885 838 90 140 164 70 296 + 417 484 469 384 651 55 9999999 257 190 180 519 547 524 506 563 + 586 573 533 803 875 693 733 777 692 888 607 577 662 585 539 + 575 454 611 361 561 581 543 682 645 769 666 546 577 565 493 + 662 653 700 123 177 201 112 343 + 466 521 506 427 693 86 111 9999999 236 275 566 585 505 546 552 + 621 618 574 804 863 594 495 733 735 790 695 673 660 675 627 + 674 556 654 453 615 614 587 685 634 715 707 591 673 659 589 + 690 749 771 154 209 228 147 371 + 243 309 285 205 468 92 54 111 9999999 69 342 366 345 326 385 + 406 391 350 619 705 510 552 599 511 707 501 451 558 472 425 + 471 346 432 253 394 393 373 500 468 588 491 369 532 501 535 + 534 591 549 160 210 233 147 376 + 262 321 302 222 491 81 68 99 32 9999999 359 386 357 340 400 + 424 409 371 639 714 536 569 611 528 728 448 415 504 424 376 + 412 296 450 196 407 419 386 521 488 605 503 389 554 521 554 + 550 614 568 151 204 228 137 359 + 361 416 404 317 435 522 512 544 471 449 9999999 194 179 327 228 + 441 438 392 480 560 357 401 554 557 549 502 453 418 596 544 + 655 532 383 455 396 352 319 359 313 475 437 352 453 467 453 + 373 527 531 78 135 308 392 291 + 182 241 229 134 411 376 341 402 302 314 114 9999999 195 184 246 + 304 288 258 499 583 376 420 494 411 568 395 315 433 612 564 + 511 413 364 311 250 333 305 375 322 493 425 306 469 435 466 + 385 531 481 180 202 333 425 319 + 271 305 315 224 271 354 341 374 301 283 110 105 9999999 164 60 + 276 263 233 313 400 186 241 395 389 387 336 283 255 424 378 + 486 361 220 290 224 179 154 197 138 308 273 182 290 308 285 + 203 363 362 179 231 311 399 293 + 216 277 259 176 281 209 199 227 155 140 35 54 24 9999999 77 + 132 125 79 331 411 204 253 329 246 400 225 147 265 443 397 + 346 239 229 140 80 193 163 211 157 322 288 200 296 320 295 + 215 374 380 94 148 163 255 151 + 275 338 327 242 344 300 293 331 256 241 122 119 99 111 9999999 + 230 220 181 400 479 144 197 371 340 337 327 242 204 384 334 + 446 347 295 238 176 265 235 275 223 262 352 140 303 270 346 + 286 363 315 189 242 261 352 252 + 369 329 451 411 404 405 367 422 324 378 345 393 514 539 561 + 9999999 329 297 264 313 405 312 528 446 596 407 358 316 380 448 + 557 432 286 353 460 163 226 141 278 276 244 379 425 443 412 + 335 494 538 86 146 89 188 75 + 246 305 286 204 416 353 317 374 276 331 181 75 266 252 307 + 24 9999999 310 275 324 158 207 225 136 356 337 270 221 398 348 + 471 348 204 368 315 177 238 151 288 279 260 143 307 267 356 + 351 362 316 99 160 103 199 94 + 278 343 325 243 450 390 353 417 315 367 215 115 301 293 349 + 65 48 9999999 308 365 195 243 261 175 388 381 292 260 430 392 + 292 170 237 79 358 217 274 193 327 318 294 184 346 312 394 + 384 405 355 138 192 141 228 127 + 118 85 249 161 356 148 113 176 78 128 250 149 299 284 345 + 70 86 44 9999999 90 226 277 293 204 425 180 241 241 162 363 + 330 210 271 109 355 227 245 198 337 344 306 146 307 275 359 + 379 368 327 146 202 154 216 140 + 134 93 266 176 364 172 137 191 90 153 255 155 317 301 363 + 93 81 62 31 9999999 227 276 291 207 418 102 160 162 82 291 + 341 227 279 118 370 242 261 216 351 351 322 169 325 294 374 + 392 390 338 157 203 151 225 142 + 306 367 350 263 371 212 171 229 139 186 238 142 322 312 365 + 412 417 378 356 371 9999999 64 239 275 207 196 121 84 252 204 + 558 432 285 370 375 226 223 227 248 138 265 351 377 413 389 + 304 409 368 285 285 330 268 310 + 376 460 449 354 466 305 266 323 227 282 336 230 416 408 462 + 448 448 424 389 372 115 9999999 250 262 307 291 225 171 350 306 + 600 483 332 468 472 322 322 327 342 231 361 429 383 426 401 + 407 415 372 356 306 421 370 410 + 136 225 336 245 369 292 264 314 221 277 328 231 387 368 428 + 221 210 191 160 145 101 122 9999999 251 300 235 212 168 211 299 + 472 353 318 248 239 296 266 314 333 230 351 199 149 187 173 + 203 182 141 121 72 239 339 236 + 223 307 374 280 399 233 198 252 158 213 256 160 343 332 388 + 303 298 273 247 226 36 87 96 9999999 233 217 147 100 270 227 + 350 236 84 331 328 242 246 253 264 165 288 280 238 269 255 + 291 268 217 207 156 332 293 320 + 183 267 381 290 407 296 267 319 223 276 329 226 411 402 460 + 256 251 230 200 185 103 92 61 81 9999999 270 219 173 254 297 + 420 302 153 288 278 316 303 319 339 226 352 241 195 232 208 + 245 226 181 171 117 289 363 272 + 598 658 641 559 823 621 644 551 718 780 695 718 695 682 739 + 689 678 707 946 998 734 782 890 806 924 9999999 71 72 244 195 + 729 609 789 715 750 756 721 819 819 857 838 727 689 726 716 + 744 718 675 315 368 321 407 309 + 536 605 586 502 765 567 585 494 669 719 635 657 639 627 680 + 630 622 652 887 942 766 819 831 748 960 105 9999999 158 334 284 + 811 700 726 709 690 692 660 762 768 882 780 666 779 803 799 + 827 813 768 399 460 404 499 396 + 581 646 628 543 812 611 638 542 710 767 687 701 682 673 724 + 675 664 698 925 982 675 727 871 789 866 135 61 9999999 184 141 + 669 547 771 651 722 737 713 809 808 801 833 682 637 677 650 + 688 665 620 257 312 259 348 246 + 620 677 670 581 853 647 655 579 624 677 717 620 716 702 761 + 718 701 734 835 853 498 547 725 763 696 36 99 98 9999999 218 + 500 375 773 479 775 618 711 711 734 621 714 751 713 752 733 + 768 743 701 86 138 91 182 80 + 586 647 632 545 821 614 634 547 663 716 692 668 681 674 735 + 681 672 698 880 896 547 598 773 791 741 85 67 138 63 9999999 + 546 429 780 522 736 662 714 763 778 669 757 715 762 800 781 + 815 796 752 132 184 135 224 119 + 500 712 702 613 737 847 812 871 776 829 756 770 747 737 792 + 812 803 764 879 958 908 814 861 925 1103 797 782 822 987 943 + 9999999 653 691 559 793 659 628 764 774 849 753 784 927 911 917 + 838 998 963 724 677 843 911 833 + 619 720 707 621 850 685 705 614 723 772 764 725 756 746 807 + 758 739 766 883 862 596 502 740 747 791 220 134 281 447 407 + 136 9999999 485 118 815 775 752 815 830 717 853 673 700 620 795 + 721 778 815 520 573 528 621 514 + 768 870 853 766 1000 831 853 762 872 923 905 870 910 892 956 + 904 893 916 1032 1015 742 648 884 901 936 369 279 431 598 551 + 285 166 9999999 262 964 931 898 966 983 866 1000 819 854 775 946 + 870 926 964 669 725 676 766 664 + 722 816 801 722 951 786 805 710 820 873 860 820 859 848 901 + 858 847 875 978 959 702 600 837 852 894 322 232 376 554 510 + 235 119 381 9999999 915 879 852 912 931 825 950 773 797 722 902 + 821 871 923 625 678 621 712 611 + 730 693 861 768 883 538 493 738 678 664 619 759 779 894 825 + 678 689 652 619 706 838 784 898 818 1026 520 435 582 752 705 + 274 316 169 394 9999999 642 698 617 755 754 722 756 896 889 889 + 815 974 932 95 144 99 188 84 + 341 300 311 337 257 375 338 399 305 361 254 374 427 467 474 + 297 306 267 237 315 264 163 384 416 462 291 215 178 349 302 + 461 345 194 332 324 9999999 135 116 137 210 109 238 275 296 272 + 199 358 396 124 73 243 335 231 + 371 325 341 374 292 403 360 425 331 382 139 312 308 451 352 + 323 335 303 266 345 297 195 413 442 485 315 246 204 373 333 + 341 222 81 329 351 48 9999999 142 158 231 133 260 307 322 301 + 226 386 423 152 102 271 366 264 + 247 200 330 286 276 274 236 300 203 257 218 273 383 410 434 + 192 207 168 139 218 282 179 395 324 472 303 231 185 280 321 + 428 309 157 230 334 40 93 9999999 154 158 120 254 293 311 291 + 216 367 408 148 98 269 337 261 + 225 179 195 223 140 320 280 337 249 301 147 321 321 346 367 + 250 264 221 188 268 301 214 265 382 499 203 265 214 337 345 + 361 241 88 277 202 61 23 67 9999999 207 147 117 157 174 152 + 76 238 271 168 116 279 371 268 + 331 288 305 330 253 178 139 379 292 304 221 360 395 459 433 + 289 301 261 227 311 304 206 374 415 491 311 255 215 370 335 + 433 315 166 317 315 96 98 110 125 9999999 144 225 267 285 265 + 188 341 383 215 162 329 241 317 + 250 214 223 255 174 287 245 305 209 262 165 283 335 373 385 + 211 218 177 152 226 170 79 297 331 365 204 132 85 260 207 + 373 256 109 243 234 54 47 26 48 118 9999999 143 188 205 181 + 108 260 306 167 116 279 341 271 + 529 587 576 488 738 428 456 355 574 613 548 618 623 605 669 + 593 602 569 537 613 494 548 561 477 693 403 454 461 380 590 + 556 594 445 628 289 509 566 476 613 616 586 9999999 172 144 227 + 241 232 189 257 204 370 466 358 + 412 441 461 373 592 269 287 194 421 448 495 512 509 497 556 + 437 447 406 373 454 427 480 490 410 628 339 400 398 322 530 + 496 532 381 464 229 360 418 335 464 470 436 61 9999999 107 158 + 135 84 131 212 168 309 323 297 + 393 453 440 353 622 347 370 272 497 527 498 519 495 478 544 + 516 527 488 452 537 459 515 520 442 659 426 478 475 399 606 + 528 560 413 547 261 433 497 410 551 553 515 67 94 9999999 190 + 115 163 211 128 74 245 338 239 + 464 520 508 421 648 353 370 275 401 464 505 407 558 546 605 + 520 533 489 457 478 282 334 346 262 483 425 398 353 401 479 + 343 387 234 464 86 447 497 415 518 408 528 65 98 76 9999999 + 181 170 221 161 147 167 260 152 + 296 360 344 258 527 348 375 276 427 477 394 415 398 385 440 + 462 449 406 459 534 360 410 430 338 552 422 475 426 398 551 + 426 463 315 465 162 442 423 422 526 491 523 50 94 112 94 + 9999999 173 213 226 178 240 330 232 + 339 403 387 301 524 359 387 286 443 495 435 462 436 426 479 + 443 453 409 377 457 354 412 422 331 554 387 443 420 364 546 + 423 456 310 473 160 283 338 264 394 397 369 31 110 29 88 + 58 9999999 184 144 97 240 329 221 + 364 426 411 320 564 276 299 211 425 461 379 445 465 453 511 + 448 460 423 386 469 314 364 378 295 510 220 278 282 203 410 + 383 414 272 478 113 327 383 306 434 443 406 76 26 67 47 + 86 61 9999999 177 134 193 294 184 + 1551 1527 1596 1509 1784 1572 1562 1504 1522 1513 1653 1593 1650 1634 1695 + 1512 1530 1489 1455 1532 1512 1560 1549 1582 1505 1050 1026 1104 1028 978 + 1419 1297 1562 1197 1678 1635 1678 1643 1747 1637 1717 1578 1617 1634 1614 + 1534 1693 1672 9999999 73 233 330 224 + 1599 1569 1649 1566 1834 1527 1515 1543 1478 1463 1706 1641 1621 1687 1673 + 1571 1578 1543 1504 1585 1548 1530 1496 1520 1458 1102 1078 1154 1079 1027 + 1360 1248 1506 1144 1628 1682 1727 1689 1754 1666 1775 1517 1568 1582 1557 + 1486 1638 1621 60 9999999 188 274 169 + 1504 1464 1629 1541 1713 1598 1564 1542 1528 1543 1552 1549 1454 1603 1497 + 1550 1557 1526 1490 1566 1539 1566 1579 1609 1534 1080 1062 1144 1060 1010 + 1192 1071 1343 977 1621 1627 1593 1632 1577 1663 1715 1514 1553 1578 1548 + 1477 1627 1670 44 100 9999999 272 159 + 1505 1534 1545 1464 1705 1550 1572 1487 1533 1523 1607 1601 1548 1586 1590 + 1532 1543 1503 1470 1547 1519 1573 1563 1549 1517 1057 1045 1120 1040 993 + 1280 1168 1432 1060 1366 1462 1581 1563 1584 1648 1551 1255 1302 1319 1298 + 1224 1380 1412 24 79 106 9999999 240 + 1520 1472 1612 1526 1722 1589 1574 1517 1528 1520 1559 1558 1466 1616 1513 + 1530 1536 1501 1466 1544 1517 1573 1562 1593 1518 1056 1044 1116 1036 992 + 1206 1088 1352 986 1469 1571 1607 1642 1595 1643 1658 1362 1411 1429 1401 + 1325 1479 1516 21 80 29 118 9999999 +EOF diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ATSP-instances/ft70.atsp b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ATSP-instances/ft70.atsp new file mode 100644 index 0000000000000000000000000000000000000000..75cacb6f328537a583263bfb878737db59505a68 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ATSP-instances/ft70.atsp @@ -0,0 +1,358 @@ +NAME: ft70 +TYPE: ATSP +COMMENT: Asymmetric TSP (Fischetti) +DIMENSION: 70 +EDGE_WEIGHT_TYPE: EXPLICIT +EDGE_WEIGHT_FORMAT: FULL_MATRIX +EDGE_WEIGHT_SECTION + 9999999 375 1000 1011 853 950 936 1027 1101 1235 1279 1109 1141 976 1389 + 858 1368 1110 1263 1435 1091 936 1047 962 1079 1083 826 926 1004 1203 + 1037 1105 1229 986 1227 1096 1235 973 753 1165 1518 1064 1285 1149 1312 + 914 1161 1349 1418 1515 1170 966 1112 1049 1064 912 901 1040 1086 1177 + 1118 1239 1103 1203 1094 1237 1143 1195 1293 1229 + 609 9999999 1068 980 1029 976 1068 1144 1100 1342 1262 1097 1304 1217 1494 + 960 1214 1233 1040 1175 1122 1237 1133 1031 1192 1004 1005 1087 1119 1109 + 1019 1087 1248 1257 1196 1061 1284 1142 951 1117 1329 1320 1284 1340 1282 + 934 1207 1200 1559 1717 1190 1168 1213 1144 1196 1317 1112 1048 1259 1008 + 871 1326 1455 977 1139 1335 974 1352 1468 1057 + 669 419 9999999 888 528 955 989 989 794 1185 1055 987 933 1009 1022 + 709 1124 1137 1203 1048 984 845 657 600 880 998 874 739 603 1042 + 939 1024 986 813 1136 872 963 1013 710 801 1189 1126 977 1102 1069 + 683 1102 1253 1316 1373 978 1046 881 998 1001 948 751 982 1092 881 + 829 1335 1082 1071 1053 941 889 1100 1164 970 + 665 645 664 9999999 559 491 528 592 505 769 680 576 793 724 996 + 796 898 755 525 1002 639 629 676 635 694 854 562 543 524 790 + 495 632 968 715 923 665 809 811 496 794 1031 759 714 829 764 + 609 504 1040 903 986 544 703 543 942 814 712 794 546 741 737 + 430 926 1047 660 686 558 632 944 808 890 + 632 606 506 676 9999999 659 742 781 582 926 778 865 868 620 798 + 499 996 787 883 792 858 615 438 483 671 523 527 557 562 661 + 544 609 871 587 837 541 787 571 558 594 1038 910 761 873 765 + 648 651 970 1026 1307 811 669 749 621 548 748 649 697 923 652 + 707 879 968 617 879 706 773 1035 944 863 + 712 373 621 441 416 9999999 441 666 565 524 541 507 803 574 680 + 613 739 875 860 1018 699 697 576 691 801 761 606 511 597 805 + 619 790 808 798 965 654 698 636 676 842 986 886 910 690 897 + 464 556 1062 1178 1097 697 830 869 627 821 661 784 848 868 562 + 623 927 823 544 475 852 674 803 814 786 + 412 702 566 534 473 744 9999999 623 690 765 770 526 699 752 986 + 492 577 596 733 746 598 672 681 715 676 762 608 590 522 782 + 694 769 976 723 700 704 923 692 467 751 964 813 806 818 538 + 485 700 865 996 1234 548 645 766 800 759 606 786 681 651 549 + 482 901 792 702 544 726 456 902 925 827 + 826 666 682 535 668 660 705 9999999 688 861 755 706 766 495 693 + 913 1001 768 727 1046 724 894 748 927 1051 816 863 743 654 822 + 872 952 1094 786 839 968 1126 1039 662 789 1152 1080 798 884 852 + 986 622 1202 1255 1072 813 980 841 984 929 872 868 893 810 876 + 791 1090 1030 708 822 879 577 1058 896 1107 + 874 915 804 786 736 873 725 491 9999999 729 749 578 641 757 747 + 942 943 1023 937 1170 746 1066 943 808 943 893 1064 909 1005 1095 + 803 1046 1041 1079 933 958 1078 1100 820 845 1225 975 971 755 1020 + 956 690 1241 1129 939 820 922 981 1105 961 1136 922 905 956 1001 + 785 1087 1012 905 839 921 753 913 755 981 + 806 919 992 826 940 683 913 470 456 9999999 728 555 653 586 802 + 962 896 1137 811 950 972 1005 797 934 1070 975 857 887 791 1055 + 852 946 1049 983 1037 1094 1111 1122 807 1019 1342 1160 883 814 1119 + 870 932 1124 1364 910 782 1104 1072 1063 938 929 939 926 1084 831 + 864 1151 1137 618 757 828 481 786 740 980 + 773 960 1030 780 702 970 966 697 559 472 9999999 803 609 743 612 + 1100 974 970 970 1162 825 989 910 954 1156 1107 974 1092 1059 908 + 944 1118 1050 1023 1062 975 1172 1154 833 988 1312 1045 1154 592 1182 + 879 815 1097 1368 1193 1001 1106 1003 1026 1130 1007 967 1085 973 922 + 1006 1271 1285 505 737 875 689 1027 842 1123 + 805 663 762 640 787 632 870 475 381 585 501 9999999 628 577 806 + 846 909 1021 880 1087 1009 934 1024 932 905 990 1032 994 847 1121 + 830 911 1138 1018 1134 745 854 851 740 818 965 740 868 514 883 + 968 735 1046 1307 948 694 847 1014 1023 1016 949 1047 882 1138 744 + 844 1307 1154 657 721 856 664 927 730 954 + 910 777 916 662 851 937 745 695 527 528 402 533 9999999 909 669 + 911 1044 1129 938 1099 873 1187 888 956 1193 1126 1172 1026 800 979 + 1119 1041 1235 1154 1195 981 1185 1111 858 1143 1435 1001 1012 833 1205 + 1129 1027 1087 1332 1057 968 1110 849 1089 1207 1026 1111 993 902 1075 + 893 1112 1073 474 624 684 773 1074 750 1060 + 1058 766 1030 850 962 822 865 655 471 625 580 655 608 9999999 703 + 975 1238 1063 991 1213 885 987 1023 942 1137 956 889 923 935 1214 + 1023 1063 1339 983 1046 1040 1025 1180 956 932 1412 906 1006 853 1155 + 871 836 1155 1480 1172 1011 1157 1050 1274 1125 975 950 1092 1001 858 + 795 1295 1039 615 856 948 721 886 799 1149 + 935 773 823 884 766 684 735 663 571 613 479 685 682 643 9999999 + 901 1005 902 877 1117 842 878 963 1038 1156 914 984 1052 999 1176 + 963 1175 1245 942 1114 997 1091 1096 802 990 1247 1022 876 799 949 + 948 890 1137 1274 912 759 898 1094 1040 1175 969 1116 1076 1045 808 + 837 1244 1071 398 656 762 757 998 786 1207 + 647 593 614 715 510 570 622 492 696 670 681 532 710 716 1007 + 9999999 1025 786 989 812 936 662 825 588 842 916 765 563 573 985 + 908 794 825 759 1062 882 1084 794 743 918 1318 931 1050 611 913 + 809 582 742 1357 1068 731 839 816 718 828 975 707 743 830 869 + 897 1194 1054 918 832 723 785 942 910 985 + 675 703 683 693 611 725 910 776 662 870 943 557 856 907 878 + 375 9999999 699 582 560 728 970 601 719 799 831 843 696 625 848 + 718 681 907 695 1005 688 946 811 699 969 1136 716 788 958 656 + 802 709 627 1002 1098 690 559 685 752 689 784 926 790 864 776 + 936 1195 1008 699 845 833 687 940 972 688 + 852 654 736 652 626 608 767 795 635 851 827 876 673 663 692 + 567 555 9999999 760 648 682 734 458 790 645 480 679 676 665 805 + 767 812 845 861 1080 723 838 713 675 777 1154 830 628 974 706 + 608 855 783 976 1245 920 684 781 727 678 600 809 806 817 766 + 871 1144 1058 616 862 762 836 1124 979 729 + 676 602 822 793 723 660 862 636 719 828 885 742 942 880 967 + 492 606 587 9999999 551 710 955 743 877 672 582 785 746 707 821 + 477 502 898 734 958 782 853 577 621 666 1088 883 770 921 868 + 973 877 626 1113 1233 654 709 888 781 941 740 1006 685 675 864 + 902 926 677 808 800 874 931 991 1050 781 + 820 868 737 766 816 800 744 861 631 819 966 775 1015 755 855 + 709 774 617 494 9999999 854 677 563 725 799 482 799 770 742 816 + 506 755 866 710 997 639 856 556 800 771 879 492 692 931 626 + 779 553 526 1047 1112 528 455 754 744 755 483 843 527 636 725 + 836 837 800 932 917 650 831 1038 864 836 + 844 767 714 878 815 561 758 717 752 704 821 642 944 600 808 + 651 662 398 377 793 9999999 780 726 868 582 686 768 937 914 680 + 628 688 762 749 931 745 890 786 747 555 902 872 694 975 763 + 699 816 756 1192 1166 912 868 809 929 994 917 819 654 871 691 + 921 906 796 568 558 711 688 1092 990 912 + 894 676 988 739 891 721 818 957 878 880 788 849 981 721 828 + 806 1065 982 793 913 824 9999999 797 747 545 706 498 582 690 912 + 904 985 972 680 969 620 937 763 775 755 1315 1000 787 988 1119 + 645 770 1092 1354 1337 784 713 829 888 704 664 712 824 932 872 + 707 1022 922 611 867 553 749 1007 773 932 + 721 892 856 716 760 758 739 640 635 787 908 803 876 716 717 + 727 1099 1018 1015 1038 798 492 9999999 574 651 395 666 707 827 927 + 674 995 1005 811 870 544 932 926 914 738 1173 918 984 1028 1123 + 885 685 1145 1252 1354 954 954 765 748 755 742 738 895 836 869 + 975 1179 961 644 737 691 666 1073 743 1067 + 811 753 647 617 776 593 724 835 588 768 645 641 601 745 927 + 434 997 749 658 990 798 550 777 9999999 632 594 483 744 646 644 + 519 609 787 674 909 646 758 609 701 740 1067 657 780 852 788 + 773 612 1035 1194 1225 586 644 514 633 625 505 581 728 848 725 + 917 771 644 536 707 754 640 793 848 876 + 678 604 575 573 490 579 453 828 776 847 727 786 622 630 925 + 672 757 817 646 794 700 630 627 515 9999999 652 611 486 514 598 + 468 775 798 501 727 793 827 811 726 802 1006 692 697 696 943 + 586 675 922 1063 1286 579 707 717 737 682 559 456 710 923 515 + 621 894 792 556 683 409 512 751 647 847 + 731 732 725 489 589 589 680 626 799 712 803 556 656 438 737 + 666 872 817 972 1107 711 656 552 602 514 9999999 765 697 666 670 + 595 745 834 849 855 432 1002 871 869 682 1258 747 712 946 993 + 563 846 1123 1189 1187 835 860 688 846 856 780 678 809 878 712 + 871 1082 1030 756 798 668 589 839 642 790 + 772 738 682 764 816 664 570 905 717 697 860 848 948 547 1005 + 756 991 1006 723 900 799 666 656 646 624 610 9999999 775 651 764 + 687 734 833 626 1018 519 1110 936 871 695 1008 913 950 969 1059 + 776 615 1105 1347 1195 622 733 632 741 717 581 724 762 772 788 + 764 948 879 738 841 774 827 1001 663 938 + 910 887 809 662 731 716 593 859 803 630 677 712 760 547 708 + 628 1054 891 742 867 856 515 331 512 470 531 496 9999999 669 660 + 795 662 777 783 801 656 996 716 750 724 1176 908 752 872 770 + 600 712 882 1081 1311 616 698 615 799 760 764 676 643 640 545 + 858 1006 901 542 685 582 663 1021 936 702 + 908 545 674 582 724 560 725 639 563 628 676 630 602 733 902 + 440 949 750 837 902 801 497 619 561 750 630 492 616 9999999 804 + 476 746 844 730 781 512 864 683 834 623 1008 800 712 703 822 + 452 805 986 977 1197 633 616 575 690 463 555 588 608 675 596 + 978 1029 696 670 782 846 884 838 730 616 + 1085 780 885 770 888 874 926 884 638 611 717 693 577 669 766 + 852 1054 1168 1098 1000 1039 613 663 612 673 748 758 622 712 9999999 + 787 986 879 775 928 787 1129 823 987 775 1338 1010 997 845 862 + 892 916 1174 1191 1161 879 720 973 841 680 698 888 907 801 827 + 998 998 986 519 624 615 780 628 575 596 + 878 696 874 663 770 717 884 655 731 732 732 902 803 960 869 + 500 778 784 861 857 792 885 630 762 761 613 752 690 885 590 + 9999999 838 742 805 716 519 574 406 632 501 925 509 627 924 671 + 716 547 874 1240 1251 516 662 700 809 812 852 788 1006 882 842 + 881 1154 849 557 899 756 683 906 745 646 + 813 784 877 869 876 781 1000 859 706 634 754 805 707 746 843 + 553 822 959 704 833 949 938 822 920 966 816 808 793 784 648 + 370 9999999 670 692 782 511 626 580 693 589 991 506 698 870 649 + 842 557 1083 945 1276 576 587 698 957 904 1055 972 744 529 728 + 644 854 526 676 903 695 669 858 668 701 + 651 673 934 789 845 801 764 715 548 747 612 704 451 772 786 + 642 1139 871 941 960 797 811 566 708 687 632 597 458 945 437 + 530 661 9999999 633 664 617 743 643 636 596 960 572 791 635 543 + 830 621 957 801 1228 802 802 874 825 886 944 873 728 593 677 + 976 922 664 742 608 676 755 600 693 421 + 929 854 813 724 841 643 752 877 605 730 710 834 647 690 1005 + 492 1060 804 895 938 718 972 667 849 704 740 877 645 746 514 + 475 423 475 9999999 589 543 730 578 609 667 978 586 662 795 697 + 778 750 982 886 1100 759 535 802 813 871 921 1022 809 605 602 + 707 873 678 732 903 753 683 683 656 671 + 755 447 1127 804 1000 723 994 736 822 832 875 733 776 786 766 + 778 957 916 992 1118 932 801 826 680 994 749 756 787 999 623 + 636 564 458 684 9999999 824 757 611 868 726 1103 815 615 992 711 + 845 768 1137 853 1159 891 792 862 842 834 895 875 962 788 602 + 850 810 801 778 879 898 664 874 878 686 + 1858 1976 1887 1686 1781 1843 1899 1634 1777 1688 1743 1598 1732 1402 1622 + 1612 2196 2109 2183 2035 1905 2180 1912 1921 1990 2028 2069 1981 1926 1987 + 2098 2050 1948 2016 1931 9999999 1262 1205 1130 1200 1605 1232 1167 1689 1926 + 2031 1923 2276 2160 2197 1858 1820 1924 1965 1932 1846 2129 1716 1877 1731 + 1769 2022 2157 1179 1230 1366 1386 1452 1320 1302 + 1023 1198 1259 1228 1416 1113 1340 1334 1089 1213 1244 1135 1397 914 1167 + 1038 1399 1487 1368 1555 1444 1164 1179 1341 1207 1362 1318 1267 1166 1195 + 1360 1142 1318 1300 1313 642 9999999 570 692 492 845 626 451 1350 1235 + 1232 1202 1404 1647 1647 1182 1040 1242 1281 1253 1205 1376 1280 1191 1120 + 1173 1432 1339 727 734 847 820 822 718 557 + 1203 1180 1235 1260 1198 1296 1196 1297 1266 1350 1316 1346 1498 1353 1361 + 1120 1501 1386 1508 1532 1483 1369 1348 1271 1430 1305 1405 1210 1393 1494 + 1353 1596 1381 1423 1319 742 864 9999999 786 711 1009 841 876 1334 1284 + 1408 1321 1587 1572 1730 1453 1323 1424 1514 1339 1376 1518 1095 1103 1095 + 947 1540 1562 515 819 601 716 649 648 526 + 1137 1280 1415 1140 1466 1182 1287 1125 1146 1204 1134 1012 1215 788 1310 + 1290 1483 1543 1527 1605 1548 1426 1418 1461 1494 1605 1516 1484 1438 1644 + 1347 1455 1452 1311 1481 530 787 731 9999999 558 1148 886 719 1126 1300 + 1458 1332 1705 1571 1622 1521 1289 1388 1339 1421 1326 1425 1185 1349 1149 + 1148 1646 1506 874 974 697 789 812 965 653 + 1044 962 1287 1247 1101 1285 1134 1081 1249 1282 1241 1225 1197 1129 1382 + 1128 1326 1264 1422 1308 1409 1197 1215 1096 1038 1190 1330 1210 1147 1424 + 1229 1126 1325 1315 1466 650 702 332 576 9999999 712 403 448 1354 1125 + 1256 1268 1409 1514 1535 1239 1018 1029 1219 1127 1140 1347 1217 1202 1277 + 944 1469 1354 614 648 572 675 754 838 514 + 1071 1028 1447 1400 1224 1301 1366 1154 1187 1060 1056 1278 1224 1152 1141 + 1110 1471 1481 1432 1546 1213 1158 1123 1050 1148 1047 1159 1127 1214 959 + 1067 1112 925 1170 1050 671 548 682 583 547 9999999 747 650 1060 861 + 708 1233 1670 1196 1380 1110 1214 1230 1144 1313 1159 1207 1138 1069 1158 + 1045 1409 1022 645 951 700 897 718 810 751 + 1050 882 1342 1161 1325 1217 1275 1168 1197 1192 1178 1299 1322 1062 1302 + 1131 1501 1478 1236 1330 1422 1063 1244 931 954 1228 1073 1092 1210 1338 + 1333 1161 1191 1241 1280 811 515 464 601 721 673 9999999 580 1322 1111 + 1156 1295 1583 1473 1836 1096 1289 1372 1242 1128 1113 1277 1091 1258 1215 + 928 1601 1381 553 604 827 763 752 607 602 + 1118 1166 1415 1307 1108 1232 1357 1272 1258 1393 1412 1346 1249 1158 1211 + 1082 1498 1420 1245 1451 1139 1208 1146 1007 965 1377 1144 1251 1092 1159 + 1167 1169 1378 1072 1209 569 648 652 700 699 722 349 9999999 1288 1274 + 1108 1056 1375 1471 1755 1239 1157 1095 1104 1176 1096 1378 1110 1231 1050 + 1253 1566 1279 684 600 690 753 896 824 490 + 1120 1026 1104 1029 1039 1144 875 1148 1176 1140 1117 944 1065 1279 1132 + 1079 1329 1250 1270 1470 1094 1095 973 1079 1243 1148 1235 988 1039 807 + 953 912 1069 1152 879 989 1326 1181 1080 1152 1508 1097 1254 9999999 1029 + 1282 967 1259 1103 762 1172 1106 1289 1155 1229 1137 1257 1157 1211 1087 + 1035 1381 1100 713 582 646 679 705 638 814 + 1369 1236 1472 1205 1340 1223 1195 1303 1266 1524 1284 1353 1294 1243 1534 + 1132 1252 1399 1376 1400 1504 1185 1081 1080 1336 1235 1127 965 1366 1145 + 1379 1342 1244 1257 1159 1023 1543 1256 1457 1439 1619 1341 1464 765 9999999 + 1251 937 1100 770 937 1185 1213 1297 1468 1344 1258 1387 1377 1352 1221 + 1439 1551 1341 783 794 837 971 896 818 1223 + 1562 1364 1372 1207 1311 1293 1237 1450 1295 1368 1284 1359 1349 1471 1459 + 1602 1502 1487 1531 1802 1496 1493 1363 1448 1562 1356 1530 1300 1568 1290 + 1311 1225 1346 1614 1272 1113 1509 1429 1372 1459 1608 1528 1451 821 1126 + 9999999 1261 1616 1183 1039 1341 1539 1586 1500 1561 1585 1420 1221 1005 1231 + 1323 1135 1045 883 937 1058 981 1022 842 1098 + 1663 1689 1725 1516 1698 1648 1597 1522 1702 1575 1471 1725 1775 1839 1556 + 1778 1900 1901 1845 1982 1753 1932 1593 1793 1768 1808 1694 1732 1700 1705 + 1616 1638 1589 1964 1692 1593 1727 1624 1691 1833 1787 1547 1663 935 1285 + 639 9999999 1559 1194 1452 1645 1659 1879 1792 1793 1757 1775 1413 1283 1377 + 1409 1456 1211 1301 1260 1246 1203 1182 1215 1502 + 1207 1142 1416 1333 1350 1096 1469 1331 1341 1332 1410 1418 1320 1257 1638 + 1404 1293 1419 1272 1332 1318 1518 1288 1272 1403 1328 1482 1452 1402 1086 + 1186 1338 1364 978 1246 1238 1384 1239 1298 1172 1521 1398 1248 967 1429 + 1175 1042 9999999 1055 1124 1039 1181 1235 1126 1238 971 1373 1390 1259 1411 + 1277 1448 1192 1210 1120 1181 1138 1335 1176 1215 + 1080 1222 1165 1152 1249 1021 974 1077 1082 1231 1338 1172 1072 1394 1483 + 1154 915 1295 1308 1203 1272 1143 1187 1058 1309 1164 1058 1304 1248 1046 + 1127 1034 1160 1227 1127 931 1474 1106 1127 1234 1597 1225 1238 398 1065 + 906 791 1011 9999999 841 1112 1254 1240 1325 1411 1294 1387 1147 1209 1187 + 1076 1350 1169 829 685 838 634 827 601 1021 + 1220 1228 1212 1160 1249 1025 1072 943 843 1070 913 1120 1022 1014 857 + 1410 1417 1291 1131 1561 1193 1271 1241 1199 1450 1411 1352 1226 1209 986 + 1194 1152 1041 1327 1072 550 1437 1123 1260 1166 1555 1361 1309 571 1249 + 1292 1123 765 791 9999999 1043 1133 1215 1467 1472 1387 1274 1205 1152 1302 + 1155 1467 1234 839 531 806 698 680 720 1023 + 885 859 1096 981 946 697 832 762 749 852 779 875 995 769 838 + 781 697 536 491 743 655 870 615 796 746 719 891 983 881 947 + 847 700 1057 627 1040 606 785 628 672 821 1151 777 781 1053 945 + 939 799 880 1149 1217 9999999 734 612 641 787 762 731 787 939 995 + 830 1077 821 579 903 717 875 1145 870 684 + 1035 921 1037 989 943 922 1038 886 858 1008 1056 852 1085 931 1017 + 725 863 857 642 877 723 996 781 970 926 850 977 935 1041 855 + 973 806 880 731 1173 786 988 844 765 951 1120 936 831 1147 1073 + 709 513 1082 1269 1397 455 9999999 761 682 911 859 822 1071 949 914 + 1180 928 992 866 810 891 685 1151 1144 785 + 769 779 788 757 686 749 800 793 930 793 913 690 965 526 837 + 679 953 882 639 983 847 587 624 657 708 503 807 888 738 929 + 676 888 859 798 818 703 931 594 631 866 1043 984 669 996 976 + 753 578 1144 1078 1291 535 525 9999999 716 586 573 600 810 813 776 + 927 1135 916 831 811 864 958 1063 835 578 + 723 663 638 515 582 691 689 738 744 828 936 626 842 698 1059 + 598 829 756 656 981 636 640 627 606 774 550 601 554 784 745 + 610 873 974 648 893 618 866 585 471 807 1138 803 742 684 1011 + 779 707 938 1154 1056 617 540 506 9999999 686 788 914 877 965 762 + 831 1078 997 752 856 694 717 898 908 690 + 753 653 755 855 820 700 852 884 903 878 562 874 759 772 759 + 960 848 930 839 1024 661 873 664 707 629 764 954 943 691 939 + 839 861 1012 748 907 853 891 792 660 741 1217 1039 912 945 591 + 868 773 1071 994 1228 605 566 381 563 9999999 759 686 482 736 513 + 752 999 810 851 957 967 725 1131 909 685 + 649 622 595 759 775 682 844 678 630 823 826 676 898 573 1009 + 761 669 738 681 888 641 840 580 710 777 511 688 716 808 523 + 433 658 742 641 899 662 727 656 690 648 824 707 642 954 653 + 907 676 818 936 1102 407 390 645 482 560 9999999 865 701 774 776 + 911 746 846 672 626 794 693 805 829 585 + 739 602 661 823 656 690 849 719 676 486 494 695 487 755 758 + 562 719 687 789 756 635 743 648 762 765 562 779 833 788 637 + 490 661 641 395 724 711 673 754 619 568 1014 559 536 802 656 + 647 654 986 867 1145 360 545 561 408 457 417 9999999 669 678 637 + 866 901 713 466 590 890 546 945 772 572 + 807 776 908 1020 667 1005 973 912 861 1184 1074 989 1111 1025 1102 + 833 1235 1076 1128 1235 1068 959 677 682 981 952 977 660 793 882 + 758 867 1157 946 1085 956 1118 984 715 892 1172 1190 1005 713 476 + 873 1042 1351 790 1078 1069 783 978 1030 1009 798 764 9999999 675 992 + 1150 1146 1048 859 997 947 789 978 798 1035 + 1047 1017 869 1092 940 1142 985 1163 1165 1249 1064 1303 1003 857 1263 + 843 1229 1183 1188 1192 1164 917 847 861 898 840 862 801 834 1051 + 1035 961 1283 1104 1152 1047 1259 1083 1020 971 1529 1078 1268 889 760 + 1074 1244 1282 939 1191 1053 1097 1154 1020 1117 1191 897 676 9999999 909 + 1120 1207 1040 937 965 927 965 1041 871 1276 + 1081 904 825 949 716 1083 990 847 762 760 496 877 949 1036 930 + 838 909 1029 844 1127 1095 825 914 1019 977 1011 881 861 880 1128 + 1026 833 977 1025 887 1122 1063 1136 939 918 1408 911 1040 800 621 + 1072 1012 1237 1070 1103 914 934 990 1063 900 1165 1056 496 584 9999999 + 698 963 854 749 800 797 695 1126 906 1063 + 1006 952 726 975 904 1099 970 718 724 717 792 865 1091 947 799 + 1019 986 1153 817 962 1142 821 753 947 1049 854 1037 771 990 849 + 997 762 876 887 706 1021 1048 951 815 1010 1139 945 849 735 540 + 830 1132 1224 873 1185 1030 1111 914 997 1145 1084 1019 657 701 503 + 9999999 778 818 489 568 766 516 1044 925 782 + 1050 835 996 835 678 941 962 816 678 689 674 941 1082 1102 939 + 940 806 980 730 1033 897 948 938 744 874 771 851 887 816 1099 + 854 946 871 890 877 921 763 792 777 763 974 649 786 836 649 + 926 988 1233 1064 1136 964 878 911 720 668 945 1075 536 538 521 + 718 9999999 890 679 736 761 574 1004 940 774 + 962 1085 996 1061 875 1138 910 891 667 805 532 810 936 1081 835 + 872 885 1005 724 1038 1104 932 725 961 1082 869 985 773 796 1099 + 1085 877 1078 1011 778 957 867 762 795 935 1018 826 816 782 577 + 1090 1033 1010 839 1271 1019 1040 1051 968 862 1025 967 433 389 404 + 679 498 9999999 686 850 801 816 1138 902 821 + 1927 1983 1997 1959 2157 2170 2045 2221 2159 2159 2264 2231 2046 1910 2335 + 2056 1966 1987 2199 1989 2150 1950 2147 2255 2087 1995 2160 2226 2154 2039 + 2188 2019 1977 2218 2043 1606 1494 1604 1558 1461 1832 1398 1580 1490 1921 + 1875 1859 1955 1418 1962 1990 2011 2198 2146 2312 2146 2251 2255 2335 2273 + 1991 2373 2181 9999999 486 752 415 1018 923 916 + 2129 2282 2240 2197 2273 2185 2270 2203 2402 2253 2413 2255 2321 2107 2259 + 2100 2034 2205 2269 2219 2272 1814 2239 2166 2161 2217 2002 2092 1996 2253 + 2289 2170 2251 2071 2307 1728 1627 1569 1622 1533 1960 1795 1579 1787 2181 + 2233 1937 1875 1408 1993 2240 2289 2217 2316 2263 2346 2263 2179 2266 2332 + 2320 2588 2275 691 9999999 978 787 1209 881 963 + 1923 1990 2082 1882 1829 2080 1929 1977 2138 2100 2001 1977 2120 1947 2141 + 1944 1927 1964 2176 2114 2267 1893 1869 2108 2138 1996 1960 1994 2081 2130 + 2058 1978 2068 2200 2045 1592 1451 1525 1531 1474 1911 1520 1660 1526 2080 + 1956 1578 1999 1565 1918 2259 2279 2017 2238 2231 2088 2038 2067 1866 2106 + 2195 2452 2069 471 566 9999999 433 645 552 719 + 2271 2110 2196 2019 2099 2085 2033 2056 2015 2050 2189 2107 1949 2157 2134 + 2041 2197 2053 2072 1750 2205 2042 2120 2107 1977 1940 2022 2106 2040 1906 + 1854 2049 1808 2076 2052 1577 1404 1441 1507 1539 1976 1675 1460 1687 2010 + 2212 1746 1956 1659 2021 1959 1995 1995 1916 2095 1960 2185 1916 1993 2040 + 2181 2270 2134 463 443 618 9999999 909 816 871 + 2170 2021 2292 1997 2202 2012 2037 2216 2244 2226 2018 2067 2008 2096 2295 + 2040 2053 2053 2003 2067 1978 2182 2142 2157 2151 2089 2183 1900 2175 1963 + 2121 2044 2065 1883 2122 1473 1527 1532 1468 1613 1794 1644 1634 1441 1840 + 2122 1932 2006 1403 1761 1915 1889 1926 1994 1983 1999 2031 1926 1662 2008 + 2318 2310 2285 386 627 627 759 9999999 712 749 + 2243 2278 2112 2059 2217 2099 2293 2166 2311 2106 2136 2348 1952 1959 2380 + 2041 2253 1954 2053 1801 2215 2009 2104 2283 2228 2008 1935 2167 2264 2064 + 2026 2138 1856 2037 1875 1612 1581 1757 1682 1713 1918 1738 1632 1726 2061 + 2041 1934 2100 1601 2052 2200 2048 2068 1979 2066 1989 2081 1967 1715 2213 + 2352 2395 2113 588 640 641 461 682 9999999 757 + 2058 2030 2049 2062 2021 2048 2033 2126 2328 2299 2170 2276 2164 1985 2236 + 2245 2137 1972 2182 1902 2327 2130 2046 2237 2246 2273 2163 2031 2267 1981 + 2073 2057 1955 2224 2130 1673 1669 1563 1658 1645 1853 1785 1729 1714 1988 + 2230 1766 1910 1507 1817 2175 2111 2024 2289 2177 2214 2080 1984 1770 2042 + 2173 2271 2101 689 522 613 514 589 663 9999999 +EOF diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ATSP-instances/ftv170.atsp b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ATSP-instances/ftv170.atsp new file mode 100644 index 0000000000000000000000000000000000000000..22a978b5242dc0e3787933e17da2bd2553dc3af7 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ATSP-instances/ftv170.atsp @@ -0,0 +1,4882 @@ +NAME: ftv170 +TYPE: ATSP +COMMENT: Asymmetric TSP (Fischetti) +DIMENSION: 171 +EDGE_WEIGHT_TYPE: EXPLICIT +EDGE_WEIGHT_FORMAT: FULL_MATRIX +EDGE_WEIGHT_SECTION + 100000000 9 15 19 39 50 + 67 55 75 58 67 85 + 99 100 95 111 125 110 + 103 91 100 109 123 134 + 156 130 143 153 140 126 + 144 132 122 121 111 99 + 112 84 78 88 100 134 + 159 119 125 115 126 137 + 150 51 65 80 91 105 + 148 127 167 180 167 98 + 85 100 188 134 153 132 + 119 117 104 115 140 67 + 47 35 49 68 79 22 + 35 29 22 13 40 82 + 94 133 140 127 141 123 + 130 106 97 85 115 131 + 128 95 114 109 127 143 + 131 143 89 82 74 61 + 67 49 29 21 39 58 + 72 77 90 101 109 127 + 137 136 152 165 111 96 + 85 78 140 131 91 91 + 46 59 69 106 128 138 + 118 132 134 85 86 111 + 122 176 159 128 142 115 + 140 106 91 153 112 127 + 107 114 117 115 123 147 + 158 122 67 109 76 124 + 60 68 45 9 100000000 6 + 26 46 57 74 62 82 + 65 74 76 90 104 102 + 118 132 114 94 82 91 + 100 114 125 147 137 134 + 144 131 117 135 123 113 + 112 102 90 103 75 69 + 79 91 125 150 110 116 + 106 117 128 141 42 56 + 71 82 96 139 118 158 + 171 158 89 76 91 179 + 125 144 123 110 108 95 + 118 131 58 38 26 40 + 59 86 13 26 38 31 + 22 34 91 103 136 143 + 136 150 132 139 115 106 + 94 124 140 137 104 123 + 118 136 152 140 152 98 + 91 83 70 76 58 38 + 30 48 67 81 86 99 + 110 118 136 146 145 161 + 174 120 105 94 87 149 + 140 100 100 55 68 78 + 115 137 147 127 141 141 + 94 93 118 129 185 168 + 135 149 122 147 113 98 + 162 121 118 98 105 108 + 122 130 154 167 131 76 + 118 85 115 51 75 36 + 15 6 100000000 20 40 51 + 68 56 76 59 68 82 + 96 101 96 112 126 111 + 100 88 97 106 120 131 + 153 131 140 150 137 123 + 141 129 119 118 108 96 + 109 81 75 85 97 131 + 156 116 122 112 123 134 + 147 48 62 77 88 102 + 145 124 164 177 164 95 + 82 97 185 131 150 129 + 116 114 101 124 137 64 + 44 32 46 65 80 19 + 32 44 37 28 40 97 + 109 142 149 142 156 138 + 145 121 112 100 130 146 + 143 110 129 124 142 158 + 146 158 104 97 89 76 + 82 64 44 36 54 73 + 87 92 105 116 124 142 + 152 151 167 180 126 111 + 100 93 155 146 106 100 + 61 68 78 121 143 151 + 133 147 135 94 87 112 + 123 191 174 129 143 116 + 141 107 92 168 127 124 + 104 111 114 116 124 148 + 173 137 82 124 91 121 + 57 69 42 75 66 60 + 100000000 20 31 48 36 56 + 39 48 112 126 81 76 + 92 106 91 102 112 118 + 109 123 134 156 111 140 + 153 140 126 144 149 126 + 160 168 156 144 141 135 + 145 157 190 215 176 182 + 172 183 194 207 108 122 + 137 148 162 205 184 224 + 237 224 155 142 157 245 + 190 209 188 175 161 161 + 151 177 124 104 92 76 + 95 60 79 92 104 97 + 88 100 118 130 169 176 + 163 177 159 166 142 133 + 121 151 167 164 131 150 + 145 163 179 167 179 125 + 118 110 97 103 85 65 + 57 75 94 108 113 126 + 137 145 163 173 172 188 + 201 147 132 121 114 160 + 151 127 80 82 48 58 + 142 141 131 148 162 115 + 74 67 92 103 196 179 + 109 123 96 121 87 72 + 189 148 184 164 161 131 + 96 104 128 194 158 103 + 145 112 168 117 49 102 + 55 46 40 53 100000000 11 + 28 16 36 19 28 92 + 106 61 56 72 86 71 + 82 92 98 89 103 114 + 136 91 120 133 120 106 + 124 129 106 140 148 136 + 124 121 115 125 137 170 + 195 156 162 152 163 174 + 187 88 102 117 128 142 + 185 164 204 217 204 135 + 122 137 225 170 189 168 + 155 141 141 131 157 104 + 84 72 56 75 40 59 + 72 84 77 68 80 98 + 110 149 156 143 157 139 + 146 122 113 101 131 147 + 144 111 130 125 143 159 + 147 159 105 98 90 77 + 83 65 45 37 55 74 + 88 93 106 117 125 143 + 153 152 168 181 127 112 + 101 94 140 131 107 60 + 62 28 38 122 121 111 + 128 142 95 54 47 72 + 83 176 159 89 103 76 + 101 67 52 169 128 164 + 144 141 111 76 84 108 + 174 138 83 125 92 148 + 97 29 82 47 56 62 + 42 62 100000000 56 66 86 + 81 90 132 146 111 106 + 122 136 121 132 138 147 + 139 153 164 186 141 170 + 183 170 156 174 179 156 + 168 158 146 159 131 125 + 135 147 181 206 166 172 + 162 173 184 197 98 112 + 127 138 152 195 174 193 + 215 214 145 132 147 223 + 159 178 157 144 130 151 + 120 146 114 94 82 96 + 115 102 69 82 76 69 + 60 87 87 99 138 145 + 132 146 128 135 111 102 + 90 120 136 133 100 119 + 114 132 148 136 148 94 + 87 79 66 72 54 34 + 26 44 63 77 82 95 + 106 114 132 142 141 157 + 170 116 101 90 83 145 + 136 96 49 51 17 27 + 111 133 139 123 137 123 + 43 75 100 111 181 164 + 117 131 104 129 95 80 + 158 117 174 154 161 161 + 126 112 136 163 127 72 + 114 81 137 107 18 92 + 82 73 67 87 72 83 + 100000000 10 30 46 55 119 + 133 55 50 66 80 65 + 76 86 92 83 97 108 + 130 85 114 127 114 100 + 118 123 100 134 155 158 + 118 117 137 147 159 164 + 189 183 184 174 185 196 + 209 115 129 144 155 169 + 212 191 231 244 231 162 + 149 164 252 198 217 196 + 183 181 168 191 204 131 + 111 99 83 102 67 86 + 99 111 104 95 107 164 + 176 209 216 209 223 205 + 212 188 179 167 197 212 + 210 176 195 190 208 224 + 182 194 140 163 156 143 + 149 131 111 103 121 109 + 151 128 141 152 160 178 + 188 187 203 216 162 147 + 136 129 131 122 142 94 + 113 100 72 131 112 102 + 119 133 86 56 38 63 + 74 167 150 80 94 67 + 73 39 24 235 194 176 + 165 135 105 70 56 99 + 209 203 118 190 158 188 + 124 101 109 72 63 57 + 77 62 73 90 100000000 20 + 36 45 109 123 45 40 + 56 70 55 66 76 82 + 73 87 98 120 75 104 + 117 104 90 108 113 90 + 124 145 148 108 107 127 + 137 149 154 179 173 174 + 164 175 186 199 105 119 + 134 145 159 202 181 221 + 234 221 152 139 154 242 + 188 207 186 173 171 158 + 181 194 121 101 89 73 + 92 57 76 89 101 94 + 85 97 154 166 199 206 + 199 213 195 202 178 169 + 157 187 203 200 167 186 + 181 199 215 203 215 161 + 154 146 133 139 121 101 + 93 111 130 144 149 162 + 173 181 199 209 208 224 + 237 183 168 157 150 184 + 175 163 122 118 90 100 + 178 165 155 172 186 139 + 109 91 116 127 220 203 + 133 147 120 96 62 77 + 225 184 166 155 125 95 + 60 79 129 230 194 139 + 181 148 178 114 91 99 + 52 43 37 57 42 53 + 70 58 100000000 16 25 89 + 103 25 20 36 50 35 + 46 56 62 53 67 78 + 100 55 84 97 84 70 + 88 93 70 104 125 128 + 88 87 107 117 129 134 + 159 153 154 144 155 166 + 179 85 99 114 125 139 + 182 161 201 214 201 132 + 119 134 222 168 187 166 + 153 151 138 161 174 101 + 81 69 53 72 37 56 + 69 81 74 65 77 134 + 146 179 186 179 193 175 + 182 158 149 137 167 183 + 180 147 166 161 179 195 + 183 195 141 134 126 113 + 119 101 81 73 91 110 + 124 129 142 153 161 179 + 189 188 204 217 163 148 + 137 130 164 155 143 102 + 98 70 80 158 145 135 + 152 166 119 89 71 96 + 107 200 183 113 127 100 + 76 42 57 205 164 146 + 135 105 75 40 59 109 + 210 174 119 161 128 158 + 94 71 79 36 27 21 + 41 26 37 54 42 62 + 100000000 9 73 87 87 82 + 98 112 97 91 79 88 + 97 111 122 144 117 131 + 141 128 114 132 133 110 + 139 129 117 118 102 96 + 106 118 152 177 137 143 + 133 144 155 168 69 83 + 98 109 123 166 145 185 + 198 185 116 103 118 206 + 152 171 150 137 135 122 + 145 158 85 65 53 37 + 56 21 40 53 65 58 + 49 61 118 130 163 170 + 163 177 159 166 142 133 + 121 151 167 164 131 150 + 145 163 179 167 179 125 + 118 110 97 103 85 65 + 57 75 94 108 113 126 + 137 145 163 173 172 188 + 201 147 132 121 114 166 + 157 127 86 82 54 64 + 142 147 137 154 168 121 + 80 73 98 109 202 185 + 115 129 102 127 93 78 + 189 148 145 125 132 105 + 102 110 134 194 158 103 + 145 112 142 78 55 63 + 188 179 185 205 225 236 + 253 229 249 244 100000000 64 + 78 92 230 149 120 102 + 82 70 79 88 102 113 + 135 146 122 132 119 105 + 123 124 101 133 154 145 + 109 104 124 134 146 163 + 188 188 171 161 172 183 + 196 137 151 166 177 191 + 217 196 236 249 236 184 + 196 211 257 245 251 243 + 230 228 215 238 251 187 + 167 153 28 47 12 166 + 179 198 205 201 187 270 + 268 256 263 265 293 311 + 318 294 285 273 303 319 + 316 283 302 297 315 331 + 319 331 277 270 262 249 + 255 237 217 209 227 246 + 260 265 278 289 297 315 + 325 324 340 353 299 284 + 273 266 310 301 279 279 + 234 247 257 294 291 281 + 298 312 273 254 236 261 + 261 346 329 259 232 205 + 174 208 222 305 300 173 + 153 126 96 153 191 207 + 346 310 255 297 264 235 + 158 254 143 146 137 143 + 163 183 194 211 187 207 + 202 10 100000000 14 28 188 + 107 78 38 18 28 37 + 46 60 71 93 104 80 + 90 77 63 81 82 59 + 91 112 103 67 62 82 + 92 104 121 146 146 129 + 119 130 141 154 95 109 + 124 135 149 175 154 194 + 207 194 142 154 169 215 + 203 209 201 188 186 173 + 196 209 145 125 111 38 + 57 22 124 137 156 163 + 159 145 228 226 214 221 + 223 251 269 276 252 243 + 231 261 277 274 241 260 + 255 273 289 277 289 235 + 228 220 207 213 195 175 + 167 185 204 218 223 236 + 247 255 273 283 282 298 + 311 257 242 231 224 268 + 259 237 237 192 205 215 + 252 249 239 256 270 231 + 212 194 219 219 304 287 + 217 190 163 132 166 180 + 263 258 131 111 84 54 + 111 149 165 304 268 213 + 255 222 193 116 212 101 + 138 129 135 155 175 186 + 203 179 199 194 92 82 + 100000000 14 180 99 70 24 + 10 20 29 38 52 63 + 85 96 72 82 69 55 + 73 74 51 83 104 95 + 59 54 74 84 96 113 + 138 138 121 111 122 133 + 146 87 101 116 127 141 + 167 146 186 199 186 134 + 146 161 207 195 201 193 + 180 178 165 188 201 137 + 117 103 117 65 104 116 + 129 148 155 151 137 220 + 218 206 213 215 243 261 + 268 244 235 223 253 269 + 266 233 252 247 265 281 + 269 281 227 220 212 199 + 205 187 167 159 177 196 + 210 215 228 239 247 265 + 275 274 290 303 249 234 + 223 216 260 251 229 229 + 184 197 207 244 241 231 + 248 262 223 204 186 211 + 211 296 279 209 182 155 + 124 158 172 255 250 123 + 103 76 46 103 141 157 + 296 260 205 247 214 185 + 108 204 93 146 137 143 + 163 183 194 211 169 189 + 202 100 90 104 100000000 170 + 89 60 10 21 31 37 + 28 42 53 75 86 62 + 72 59 45 63 68 45 + 79 100 103 63 62 82 + 92 104 109 134 146 129 + 119 130 141 154 95 109 + 124 135 149 175 154 194 + 207 194 142 154 169 215 + 203 209 201 188 186 173 + 196 209 145 125 111 125 + 73 112 124 137 156 163 + 159 145 228 226 214 221 + 223 251 269 276 252 243 + 231 261 277 274 241 260 + 255 273 289 277 289 235 + 228 220 207 213 195 175 + 167 185 204 218 223 236 + 247 255 273 283 282 298 + 311 257 242 231 224 250 + 241 237 232 192 205 210 + 250 231 221 238 252 213 + 194 176 201 201 286 269 + 199 172 145 114 148 162 + 263 258 121 110 80 50 + 93 131 147 304 268 213 + 255 222 193 116 212 101 + 115 106 100 120 105 116 + 91 43 63 79 88 95 + 109 5 100000000 16 30 15 + 26 36 42 33 47 58 + 80 35 64 77 64 50 + 68 73 50 84 105 108 + 68 67 87 97 109 114 + 139 151 134 124 135 146 + 159 100 114 129 140 154 + 180 159 199 212 199 147 + 159 174 220 208 214 206 + 193 191 178 201 214 150 + 130 116 116 78 100 119 + 132 144 137 128 140 197 + 209 219 226 228 256 238 + 245 221 212 200 230 225 + 238 189 208 203 221 237 + 195 207 153 176 189 176 + 182 164 144 136 154 122 + 164 141 154 165 173 191 + 201 200 216 229 175 160 + 149 142 144 135 155 107 + 126 133 85 144 125 115 + 132 146 99 69 51 76 + 87 180 163 93 107 80 + 56 22 37 268 227 126 + 115 85 55 20 39 89 + 222 216 131 203 191 198 + 121 134 106 164 155 159 + 179 164 175 149 102 122 + 138 118 108 122 20 103 + 100000000 14 28 39 49 55 + 46 60 57 79 19 48 + 61 74 63 81 86 63 + 97 118 121 81 80 100 + 110 122 127 152 164 147 + 137 148 159 172 113 127 + 142 153 167 193 172 212 + 225 212 160 172 187 233 + 221 227 219 206 204 191 + 214 227 163 143 129 143 + 91 130 142 155 174 181 + 177 163 246 244 232 239 + 241 269 287 294 270 261 + 249 279 283 292 247 266 + 261 279 295 253 265 211 + 234 238 225 231 213 193 + 185 203 180 222 199 212 + 223 231 249 247 240 256 + 273 215 218 207 200 183 + 174 198 165 184 192 143 + 183 164 154 171 185 146 + 127 109 134 134 219 202 + 132 105 78 47 81 95 + 281 276 139 128 98 68 + 4 64 80 280 274 189 + 261 240 211 134 193 119 + 150 141 147 167 187 198 + 215 173 193 206 104 94 + 108 113 174 93 100000000 14 + 25 35 41 32 46 57 + 79 90 66 76 63 49 + 67 72 49 83 104 107 + 67 66 86 96 108 113 + 138 150 133 123 134 145 + 158 99 113 128 139 153 + 179 158 198 211 198 146 + 158 173 219 207 213 205 + 192 190 177 200 213 149 + 129 115 129 77 116 128 + 141 160 167 163 149 232 + 230 218 225 227 255 273 + 280 256 247 235 265 281 + 278 245 264 259 277 293 + 281 293 239 232 224 211 + 217 199 179 171 189 208 + 222 227 240 251 259 277 + 287 286 302 315 261 246 + 235 228 254 245 241 236 + 196 209 214 254 235 225 + 242 256 217 198 180 205 + 205 290 273 203 176 149 + 118 152 166 267 262 125 + 114 84 54 97 135 151 + 308 272 217 259 226 197 + 120 216 105 136 127 133 + 153 173 184 201 159 179 + 192 90 80 94 99 160 + 79 50 100000000 11 21 27 + 18 32 43 65 76 52 + 62 49 35 53 58 35 + 69 90 93 53 52 72 + 82 94 99 124 136 119 + 109 120 131 144 85 99 + 114 125 139 165 144 184 + 197 184 132 144 159 205 + 193 199 191 178 176 163 + 186 199 135 115 101 115 + 63 102 114 127 146 153 + 149 135 218 216 204 211 + 213 241 259 266 242 233 + 221 251 267 264 231 250 + 245 263 279 267 279 225 + 218 210 197 203 185 165 + 157 175 194 208 213 226 + 237 245 263 273 272 288 + 301 247 232 221 214 240 + 231 227 222 182 195 200 + 240 221 211 228 242 203 + 184 166 191 191 276 259 + 189 162 135 104 138 152 + 253 248 111 100 70 40 + 83 121 137 294 258 203 + 245 212 183 106 202 91 + 128 119 125 145 165 176 + 193 169 189 184 82 72 + 86 100 170 89 60 46 + 100000000 10 19 28 42 53 + 75 86 62 72 59 45 + 63 64 41 73 94 85 + 49 44 64 74 86 103 + 128 128 111 101 112 123 + 136 77 91 106 117 131 + 157 136 176 189 176 124 + 136 151 197 185 191 183 + 170 168 155 178 191 127 + 107 93 107 55 94 106 + 119 138 145 141 127 210 + 208 196 203 205 233 251 + 258 234 225 213 243 259 + 256 223 242 237 255 271 + 259 271 217 210 202 189 + 195 177 157 149 167 186 + 200 205 218 229 237 255 + 265 264 280 293 239 224 + 213 206 250 241 219 219 + 174 187 197 234 231 221 + 238 252 213 194 176 201 + 201 286 269 199 172 145 + 114 148 162 245 240 113 + 93 66 36 93 131 147 + 286 250 195 237 204 175 + 98 194 83 118 109 115 + 135 155 166 183 159 179 + 174 72 62 76 90 160 + 79 50 36 47 100000000 9 + 18 32 43 65 76 52 + 62 49 35 53 54 31 + 63 84 75 39 34 54 + 64 76 93 118 118 101 + 91 102 113 126 67 81 + 96 107 121 147 126 166 + 179 166 114 126 141 187 + 175 181 173 160 158 145 + 168 181 117 97 83 97 + 45 84 96 109 128 135 + 131 117 200 198 186 193 + 195 223 241 248 224 215 + 203 233 249 246 213 232 + 227 245 261 249 261 207 + 200 192 179 185 167 147 + 139 157 176 190 195 208 + 219 227 245 255 254 270 + 283 229 214 203 196 240 + 231 209 209 164 177 187 + 224 221 211 228 242 203 + 184 166 191 191 276 259 + 189 162 135 104 138 152 + 235 230 103 83 56 26 + 83 121 137 276 240 185 + 227 194 165 88 184 73 + 109 100 106 126 146 157 + 174 150 170 165 63 53 + 67 81 151 70 41 27 + 38 48 100000000 9 23 34 + 56 67 43 53 40 26 + 44 45 22 54 75 66 + 30 25 45 55 67 84 + 109 109 92 82 93 104 + 117 58 72 87 98 112 + 138 117 157 170 157 105 + 117 132 178 166 172 164 + 151 149 136 159 172 108 + 88 74 88 36 75 87 + 100 119 126 122 108 191 + 189 177 184 186 214 232 + 239 215 206 194 224 240 + 237 204 223 218 236 252 + 240 252 198 191 183 170 + 176 158 138 130 148 167 + 181 186 199 210 218 236 + 246 245 261 274 220 205 + 194 187 231 222 200 200 + 155 168 178 215 212 202 + 219 233 194 175 157 182 + 182 267 250 180 153 126 + 95 129 143 226 221 94 + 74 47 17 74 112 128 + 267 231 176 218 185 156 + 79 175 64 118 109 115 + 135 155 166 183 141 161 + 174 72 62 76 81 142 + 61 32 18 29 39 9 + 100000000 14 25 47 58 34 + 44 31 17 35 40 17 + 51 72 75 35 34 54 + 64 76 81 106 118 101 + 91 102 113 126 67 81 + 96 107 121 147 126 166 + 179 166 114 126 141 187 + 175 181 173 160 158 145 + 168 181 117 97 83 97 + 45 84 96 109 128 135 + 131 117 200 198 186 193 + 195 223 241 248 224 215 + 203 233 249 246 213 232 + 227 245 261 249 261 207 + 200 192 179 185 167 147 + 139 157 176 190 195 208 + 219 227 245 255 254 270 + 283 229 214 203 196 222 + 213 209 204 164 177 182 + 222 203 193 210 224 185 + 166 148 173 173 258 241 + 171 144 117 86 120 134 + 235 230 93 82 52 22 + 65 103 119 276 240 185 + 227 194 165 88 184 73 + 132 123 129 149 169 180 + 174 127 147 163 86 76 + 90 67 128 47 18 32 + 43 53 23 14 100000000 11 + 33 44 20 33 45 31 + 49 54 31 65 86 89 + 49 48 68 78 90 95 + 120 132 115 105 116 127 + 140 81 95 110 121 135 + 161 140 180 193 180 128 + 140 155 201 189 195 187 + 174 172 159 182 195 131 + 111 97 111 59 98 110 + 123 142 149 145 131 214 + 212 200 207 209 237 255 + 262 238 229 217 247 263 + 260 227 246 241 259 275 + 263 275 221 214 206 193 + 199 181 161 153 171 190 + 204 209 222 233 241 259 + 269 265 281 297 240 228 + 217 210 208 199 223 190 + 178 191 168 208 189 179 + 196 210 171 152 134 159 + 159 244 227 157 130 103 + 72 106 120 249 244 107 + 96 66 36 51 89 105 + 290 254 199 241 208 179 + 102 198 87 143 134 140 + 160 178 189 163 116 136 + 152 97 87 101 56 117 + 36 29 43 54 64 34 + 25 11 100000000 22 33 9 + 22 35 42 50 65 42 + 76 97 100 60 59 79 + 89 101 106 131 143 126 + 116 127 138 151 92 106 + 121 132 146 172 151 191 + 204 191 139 151 166 212 + 200 206 198 185 183 170 + 193 206 142 122 108 122 + 70 109 121 134 153 160 + 156 142 225 223 211 218 + 220 248 266 273 249 240 + 228 258 274 271 238 257 + 252 270 286 267 279 225 + 225 217 204 210 192 172 + 164 182 194 215 213 226 + 237 245 263 261 254 270 + 287 229 232 221 214 197 + 188 212 179 189 202 157 + 197 178 168 185 199 160 + 141 123 148 148 233 216 + 146 119 92 61 95 109 + 260 255 118 107 77 47 + 40 78 94 294 265 203 + 252 219 190 113 207 98 + 166 157 151 171 156 167 + 141 94 114 130 132 122 + 136 34 95 14 28 42 + 53 63 69 60 60 49 + 100000000 11 40 53 66 77 + 81 98 77 109 130 135 + 95 94 114 124 136 139 + 164 178 161 151 162 173 + 186 127 141 156 167 181 + 207 186 226 239 226 174 + 186 201 247 235 241 233 + 220 218 205 228 241 177 + 157 143 157 105 144 156 + 169 188 188 179 177 248 + 258 246 253 255 283 289 + 296 272 263 251 281 275 + 288 239 258 253 271 287 + 245 257 203 226 240 227 + 233 215 195 187 205 172 + 214 191 204 215 223 241 + 239 232 248 265 207 210 + 199 192 175 166 190 157 + 176 184 135 175 156 146 + 163 177 138 119 101 126 + 126 211 194 124 97 70 + 39 73 87 295 278 151 + 140 112 82 18 56 72 + 272 266 181 253 242 225 + 148 185 133 155 146 140 + 160 145 156 130 83 103 + 119 128 125 139 89 84 + 74 67 81 92 102 72 + 63 49 38 60 100000000 29 + 42 55 69 70 87 80 + 98 119 131 98 97 117 + 127 136 128 153 178 161 + 151 162 173 186 130 144 + 159 170 184 207 186 226 + 239 226 177 189 204 247 + 238 241 236 223 221 208 + 231 244 180 160 146 156 + 108 140 159 172 184 177 + 168 180 237 249 249 256 + 258 286 278 285 261 252 + 240 270 264 277 228 247 + 242 260 276 234 246 192 + 215 229 216 222 204 184 + 176 194 161 203 180 193 + 204 212 230 228 221 237 + 254 196 199 188 181 164 + 155 179 146 165 173 124 + 164 145 135 152 166 127 + 108 90 115 115 200 183 + 113 86 59 28 62 76 + 298 267 140 129 115 85 + 78 45 61 261 255 170 + 242 231 228 151 174 136 + 152 143 149 169 174 185 + 159 112 132 148 106 96 + 110 65 113 45 38 52 + 63 73 43 34 20 9 + 31 29 100000000 13 26 40 + 41 58 51 69 90 102 + 69 68 88 98 107 99 + 124 149 132 122 133 144 + 157 101 115 130 141 155 + 178 157 197 210 197 148 + 160 175 218 209 212 207 + 194 192 179 202 215 151 + 131 117 131 79 118 130 + 143 162 169 165 151 234 + 232 220 227 229 257 275 + 282 258 249 237 267 283 + 280 247 266 261 279 295 + 263 275 221 234 226 213 + 219 201 181 173 191 190 + 224 209 222 233 241 259 + 257 250 266 283 225 228 + 217 210 193 184 208 175 + 194 202 153 193 174 164 + 181 195 156 137 119 144 + 144 229 212 142 115 88 + 57 91 105 269 264 111 + 100 86 56 49 74 90 + 290 274 199 261 228 199 + 122 203 107 162 153 159 + 179 187 198 172 125 145 + 161 116 106 120 78 126 + 58 51 62 73 83 53 + 44 33 22 44 42 13 + 100000000 13 27 28 45 61 + 56 77 89 79 78 98 + 106 94 86 111 136 119 + 109 120 131 144 111 125 + 140 147 161 165 144 184 + 197 184 158 170 185 205 + 219 199 217 204 202 189 + 212 225 161 141 127 141 + 89 128 140 153 172 179 + 175 161 244 242 230 237 + 239 267 285 292 268 259 + 247 277 293 290 257 276 + 271 289 305 276 288 234 + 244 236 223 229 211 191 + 183 201 203 234 222 235 + 246 254 272 270 263 279 + 296 238 241 230 223 206 + 197 221 188 207 215 166 + 206 187 177 194 208 169 + 150 132 157 157 242 225 + 155 128 101 70 104 118 + 279 274 98 87 96 66 + 62 87 103 303 284 212 + 271 238 209 132 216 117 + 149 140 146 166 186 197 + 185 138 158 174 103 93 + 107 78 139 58 43 49 + 60 70 40 31 25 22 + 44 55 26 13 100000000 14 + 15 32 48 43 64 76 + 66 65 85 93 81 73 + 98 123 106 96 107 118 + 131 98 112 127 134 148 + 152 131 171 184 171 145 + 157 172 192 206 186 204 + 191 189 176 199 212 148 + 128 114 128 76 115 127 + 140 159 166 162 148 231 + 229 217 224 226 254 272 + 279 255 246 234 264 280 + 277 244 263 258 276 292 + 280 292 238 231 223 210 + 216 198 178 170 188 207 + 221 226 239 250 258 276 + 283 276 292 309 251 245 + 234 227 219 210 234 201 + 195 208 179 219 200 190 + 207 221 182 163 145 170 + 170 255 238 168 141 114 + 83 117 131 266 261 85 + 74 83 53 62 100 116 + 307 271 216 258 225 196 + 119 215 104 135 126 132 + 152 172 183 185 138 158 + 174 89 79 93 78 139 + 58 29 35 46 56 26 + 17 11 22 44 55 31 + 27 14 100000000 18 35 34 + 46 67 79 52 51 71 + 81 84 76 101 126 109 + 99 110 121 134 84 98 + 113 124 138 155 134 174 + 187 174 131 143 158 195 + 192 189 190 177 175 162 + 185 198 134 114 100 114 + 62 101 113 126 145 152 + 148 134 217 215 203 210 + 212 240 258 265 241 232 + 220 250 266 263 230 249 + 244 262 278 266 278 224 + 217 209 196 202 184 164 + 156 174 193 207 212 225 + 236 244 262 272 271 287 + 300 246 231 220 213 219 + 210 226 201 181 194 179 + 219 200 190 207 221 182 + 163 145 170 170 255 238 + 168 141 114 83 117 131 + 252 247 88 77 69 39 + 62 100 116 293 257 202 + 244 211 182 105 201 90 + 164 155 161 181 201 212 + 200 153 173 189 118 108 + 122 93 154 73 58 64 + 75 85 55 46 40 37 + 59 70 41 28 15 29 + 100000000 17 40 28 49 61 + 58 80 88 78 66 58 + 83 108 91 81 92 103 + 116 113 127 127 119 133 + 137 116 156 169 156 145 + 157 172 177 202 171 203 + 191 189 176 199 212 163 + 143 129 143 91 130 142 + 155 174 181 177 163 239 + 229 217 224 226 253 271 + 278 257 248 241 266 295 + 279 259 278 273 291 307 + 295 307 253 246 238 225 + 231 213 193 185 203 222 + 236 241 254 265 273 291 + 298 291 307 324 266 260 + 249 242 234 225 249 216 + 210 223 194 234 215 205 + 222 236 197 178 160 185 + 185 270 253 183 156 129 + 98 132 146 265 263 70 + 59 75 45 77 115 131 + 322 286 231 273 240 196 + 134 230 119 154 145 151 + 171 191 202 217 170 190 + 206 108 98 112 110 171 + 90 72 58 69 79 49 + 40 54 54 76 87 58 + 45 32 46 17 100000000 23 + 11 32 44 41 70 71 + 61 49 41 66 91 74 + 64 75 86 99 103 117 + 110 102 116 120 99 139 + 152 139 128 140 155 160 + 185 154 186 174 172 159 + 182 195 153 133 119 133 + 81 120 132 145 164 171 + 167 153 222 212 200 207 + 209 236 254 261 240 231 + 224 249 285 262 249 268 + 263 281 297 285 297 243 + 236 228 215 221 203 183 + 175 193 212 226 231 244 + 255 263 281 291 290 306 + 319 265 250 239 232 251 + 242 245 233 200 213 211 + 251 232 222 239 253 214 + 195 177 202 202 287 270 + 200 173 146 115 149 163 + 248 246 53 42 58 28 + 94 132 148 312 276 221 + 263 230 179 124 220 109 + 131 122 128 148 168 179 + 196 158 178 187 85 75 + 89 98 159 78 49 35 + 46 56 26 17 31 42 + 64 75 51 61 48 34 + 40 23 100000000 34 55 67 + 18 47 67 77 72 64 + 89 114 97 87 98 109 + 122 80 94 109 120 134 + 143 122 162 175 162 127 + 139 154 183 188 177 186 + 173 171 158 181 194 130 + 110 96 110 58 97 109 + 122 141 148 144 130 213 + 211 199 206 208 236 254 + 261 237 228 216 246 262 + 259 226 245 240 258 274 + 262 274 220 213 205 192 + 198 180 160 152 170 189 + 203 208 221 232 240 258 + 268 267 283 296 242 227 + 216 209 239 230 222 221 + 177 190 199 237 220 210 + 227 241 202 183 165 190 + 190 275 258 188 161 134 + 103 137 151 248 243 76 + 65 35 5 82 120 136 + 289 253 198 240 207 178 + 101 197 86 152 143 149 + 169 189 200 217 181 201 + 208 113 103 117 121 182 + 101 83 69 80 90 60 + 51 65 65 87 98 69 + 56 43 57 28 11 34 + 100000000 21 33 46 75 60 + 50 38 30 55 80 63 + 53 64 75 88 101 115 + 99 91 105 109 88 128 + 141 128 117 129 144 149 + 174 143 175 163 161 148 + 171 184 151 131 117 131 + 86 125 130 143 162 169 + 165 151 211 201 189 196 + 198 225 243 250 229 220 + 213 238 283 251 247 266 + 261 279 295 283 295 241 + 234 226 213 219 201 181 + 173 191 210 224 229 242 + 253 261 279 289 288 304 + 317 263 248 237 230 262 + 253 243 243 198 211 221 + 258 243 233 250 264 225 + 206 188 213 213 298 281 + 211 184 157 126 160 174 + 237 235 42 31 48 39 + 105 143 159 310 274 219 + 261 222 168 122 218 107 + 131 122 128 148 168 179 + 196 184 204 187 92 82 + 96 110 203 122 104 90 + 100 88 79 72 86 86 + 108 119 90 77 64 78 + 49 32 55 21 100000000 12 + 25 54 39 29 17 23 + 48 59 42 32 43 54 + 67 80 94 78 70 84 + 88 67 107 120 107 96 + 108 123 128 153 122 154 + 142 140 127 150 163 130 + 110 96 110 65 104 109 + 122 141 148 144 130 190 + 180 168 175 177 204 222 + 229 208 199 192 217 262 + 230 226 245 240 258 274 + 262 274 220 213 205 192 + 198 180 160 152 170 189 + 203 208 221 232 240 258 + 268 267 283 296 242 227 + 216 209 271 262 222 222 + 177 190 200 237 259 254 + 249 263 246 216 209 234 + 234 307 290 232 205 178 + 147 181 195 216 214 30 + 10 27 60 126 164 180 + 289 253 198 240 201 147 + 101 197 86 126 117 123 + 143 163 174 191 179 199 + 182 80 70 84 98 204 + 123 105 91 88 76 67 + 73 87 87 109 120 91 + 78 65 79 50 33 56 + 22 12 100000000 13 42 51 + 41 29 35 60 71 54 + 44 55 66 79 75 89 + 90 82 96 100 79 119 + 132 119 108 120 135 140 + 165 134 166 154 152 139 + 162 175 125 105 91 105 + 53 92 104 117 136 143 + 139 125 202 192 180 187 + 189 216 234 241 220 211 + 204 229 257 242 221 240 + 235 253 269 257 269 215 + 208 200 187 193 175 155 + 147 165 184 198 203 216 + 227 235 253 263 262 278 + 291 237 222 211 204 266 + 257 217 217 172 185 195 + 232 254 255 244 258 247 + 211 210 235 235 302 285 + 233 206 179 148 182 196 + 228 226 42 22 15 61 + 127 165 181 284 248 193 + 235 202 159 96 192 81 + 113 104 110 130 150 161 + 178 166 186 169 67 57 + 71 85 192 111 93 79 + 75 63 54 61 75 75 + 97 108 79 66 53 67 + 38 21 44 24 45 57 + 100000000 29 49 59 62 54 + 79 104 87 77 88 99 + 112 62 76 91 102 116 + 133 112 152 165 152 109 + 121 136 173 170 167 168 + 155 153 140 163 176 112 + 92 78 92 40 79 91 + 104 123 130 126 112 195 + 193 181 188 190 218 236 + 243 219 210 198 228 244 + 241 208 227 222 240 256 + 244 256 202 195 187 174 + 180 162 142 134 152 171 + 185 190 203 214 222 240 + 250 249 265 278 224 209 + 198 191 253 244 204 204 + 159 172 182 219 241 243 + 231 245 235 198 197 222 + 223 289 272 221 194 167 + 136 170 184 230 225 66 + 55 17 49 115 153 169 + 271 235 180 222 189 160 + 83 179 68 84 75 81 + 101 121 132 149 137 157 + 140 38 28 42 56 176 + 95 66 52 46 34 25 + 34 48 59 81 92 68 + 78 65 51 69 70 47 + 63 53 41 54 100000000 20 + 30 42 76 101 84 67 + 57 68 79 92 33 47 + 62 73 87 113 92 132 + 145 132 80 92 107 153 + 141 147 139 126 124 111 + 134 147 83 63 49 63 + 11 50 62 75 94 101 + 97 83 166 164 152 159 + 161 189 207 214 190 181 + 169 199 215 212 179 198 + 193 211 227 215 227 173 + 166 158 145 151 133 113 + 105 123 142 156 161 174 + 185 193 211 221 220 236 + 249 195 180 169 162 224 + 215 175 175 130 143 153 + 190 212 222 202 216 216 + 169 168 193 204 260 243 + 205 178 151 120 154 168 + 201 196 69 49 56 42 + 99 137 153 242 206 151 + 193 160 131 54 150 39 + 104 95 101 121 141 152 + 169 157 177 160 58 48 + 62 76 196 115 86 72 + 66 54 45 54 68 79 + 101 112 88 98 85 71 + 71 54 67 43 33 21 + 34 20 100000000 10 22 56 + 81 64 47 37 48 59 + 72 53 67 82 75 89 + 93 72 112 125 112 100 + 112 127 133 158 127 159 + 146 144 131 154 167 103 + 83 69 83 31 70 82 + 95 114 121 117 103 186 + 184 172 179 181 209 227 + 234 210 201 189 219 235 + 232 199 218 213 231 247 + 235 247 193 186 178 165 + 171 153 133 125 143 162 + 176 181 194 205 213 231 + 241 240 256 269 215 200 + 189 182 244 235 195 195 + 150 163 173 210 232 242 + 222 236 236 189 188 213 + 224 280 263 225 198 171 + 140 174 188 221 216 49 + 29 36 62 119 157 173 + 262 226 171 213 180 151 + 74 170 59 114 105 111 + 131 151 162 179 167 187 + 170 68 58 72 86 206 + 125 96 82 76 64 55 + 64 78 89 111 122 98 + 106 93 81 78 61 77 + 50 29 31 44 30 10 + 100000000 12 51 76 54 37 + 27 38 49 62 63 77 + 73 65 79 83 62 102 + 115 102 91 103 118 123 + 148 117 149 137 135 122 + 145 158 113 93 79 93 + 41 80 92 105 124 131 + 127 113 185 175 163 170 + 172 199 217 224 203 194 + 187 212 245 225 209 228 + 223 241 257 245 257 203 + 196 188 175 181 163 143 + 135 153 172 186 191 204 + 215 223 241 251 250 266 + 279 225 210 199 192 254 + 245 205 205 160 173 183 + 220 242 252 232 246 246 + 199 198 223 234 290 273 + 235 208 181 150 184 198 + 211 209 39 19 46 72 + 129 167 183 272 236 181 + 223 190 142 84 180 69 + 114 105 111 131 151 162 + 179 167 187 170 80 70 + 84 98 207 137 108 94 + 88 76 67 76 90 101 + 123 134 107 94 81 93 + 66 49 72 38 17 29 + 42 42 22 12 100000000 39 + 64 42 25 15 26 37 + 50 63 77 61 53 67 + 71 50 90 103 90 79 + 91 106 111 136 105 137 + 125 123 110 133 146 113 + 93 79 93 53 92 92 + 105 124 131 127 113 173 + 163 151 158 160 187 205 + 212 191 182 175 200 245 + 213 209 228 223 241 257 + 245 257 203 196 188 175 + 181 163 143 135 153 172 + 186 191 204 215 223 241 + 251 250 266 279 225 210 + 199 192 254 245 205 205 + 160 173 183 220 242 252 + 232 246 246 199 198 223 + 234 290 273 240 220 193 + 162 196 203 199 197 27 + 7 44 77 141 179 195 + 272 236 181 223 184 130 + 84 180 69 153 144 150 + 170 190 201 218 206 226 + 209 115 105 119 133 212 + 131 113 99 110 111 90 + 81 95 95 117 128 99 + 86 73 87 58 41 64 + 30 23 35 48 77 61 + 51 39 100000000 25 81 64 + 54 65 76 89 102 116 + 100 92 94 85 64 104 + 117 104 113 125 140 125 + 150 119 151 159 157 144 + 167 180 152 132 118 132 + 88 127 131 144 163 170 + 166 152 207 197 185 192 + 194 201 219 226 225 216 + 209 234 282 247 248 265 + 262 280 296 284 296 242 + 235 227 214 220 202 182 + 174 192 211 225 230 243 + 254 262 280 290 289 305 + 318 264 249 238 231 292 + 283 244 244 199 212 222 + 259 273 263 271 285 255 + 236 218 243 243 328 311 + 241 214 187 156 190 204 + 213 231 12 32 50 69 + 135 173 189 311 275 220 + 262 218 164 123 219 108 + 133 124 130 150 170 181 + 198 186 206 189 129 119 + 133 147 226 156 138 124 + 135 125 115 106 120 120 + 142 153 124 111 98 112 + 83 66 89 55 48 60 + 73 91 71 61 49 25 + 100000000 61 44 34 45 56 + 69 82 96 80 72 69 + 60 39 79 92 79 88 + 100 115 100 125 94 126 + 134 132 119 142 155 132 + 112 98 112 102 141 111 + 124 143 150 146 132 182 + 172 160 167 169 176 194 + 201 200 191 184 209 257 + 222 228 240 242 260 276 + 264 276 222 215 207 194 + 200 182 162 154 172 191 + 205 210 223 234 242 260 + 270 269 285 298 244 229 + 218 211 273 264 224 224 + 179 192 202 239 261 271 + 251 265 265 218 217 242 + 253 309 292 259 239 212 + 181 215 222 188 206 37 + 56 75 94 160 198 214 + 291 255 200 242 193 139 + 103 199 88 129 120 126 + 146 166 177 194 182 202 + 185 125 115 129 143 222 + 182 153 139 133 121 112 + 121 135 146 168 179 152 + 139 126 138 111 94 117 + 83 62 74 87 87 67 + 57 45 72 47 100000000 20 + 30 41 52 65 78 84 + 76 68 38 29 8 48 + 61 48 57 69 84 69 + 94 63 95 103 101 88 + 111 124 128 108 94 108 + 98 137 107 120 139 146 + 142 128 151 141 129 136 + 138 145 163 170 169 160 + 153 178 226 191 201 209 + 215 233 246 247 259 218 + 204 196 183 171 178 158 + 150 168 187 201 206 219 + 230 238 256 266 265 281 + 268 240 225 214 207 269 + 260 220 220 175 188 198 + 235 257 267 247 261 261 + 214 213 238 249 305 288 + 255 265 238 207 233 218 + 157 175 72 52 89 122 + 186 224 240 274 228 196 + 215 162 108 99 195 84 + 109 100 106 126 146 157 + 174 162 182 165 105 95 + 109 123 202 162 133 119 + 113 101 92 101 115 126 + 148 159 132 119 106 118 + 91 74 97 63 42 54 + 67 67 47 37 25 64 + 84 37 100000000 10 21 32 + 45 58 72 56 48 62 + 66 45 85 98 85 74 + 86 101 106 131 100 132 + 120 118 105 128 141 108 + 88 74 88 78 117 87 + 100 119 126 122 108 168 + 158 146 153 155 182 200 + 207 186 177 170 195 240 + 208 204 223 218 236 252 + 240 252 198 191 183 170 + 176 158 138 130 148 167 + 181 186 199 210 218 236 + 246 245 261 274 220 205 + 194 187 249 240 200 200 + 155 168 178 215 237 247 + 227 241 241 194 193 218 + 229 285 268 235 245 218 + 187 213 198 194 192 52 + 32 69 102 166 204 220 + 267 231 176 218 179 125 + 79 175 64 99 90 96 + 116 136 147 164 152 172 + 155 95 85 99 113 192 + 152 123 109 103 91 82 + 91 105 116 138 149 122 + 109 96 108 81 64 87 + 53 32 44 57 57 37 + 27 15 54 74 27 10 + 100000000 11 22 35 48 62 + 46 38 52 56 35 75 + 88 75 64 76 91 96 + 121 90 122 110 108 95 + 118 131 98 78 64 78 + 68 107 77 90 109 116 + 112 98 158 148 136 143 + 145 172 190 197 176 167 + 160 185 230 198 194 213 + 208 226 242 230 242 188 + 181 173 160 166 148 128 + 120 138 157 171 176 189 + 200 208 226 236 235 251 + 264 210 195 184 177 239 + 230 190 190 145 158 168 + 205 227 237 217 231 231 + 184 183 208 219 275 258 + 225 235 208 177 203 188 + 184 182 42 22 59 92 + 156 194 210 257 221 166 + 208 169 115 69 165 54 + 88 79 85 105 125 136 + 153 141 161 144 95 85 + 99 113 181 152 123 109 + 103 91 82 91 105 116 + 138 149 125 133 120 108 + 105 88 104 77 56 58 + 71 57 37 27 39 78 + 102 55 64 54 100000000 11 + 24 37 51 35 27 41 + 84 63 103 116 103 53 + 65 80 124 114 118 112 + 99 97 84 107 120 87 + 67 53 67 68 107 66 + 79 98 105 101 87 147 + 137 125 132 134 162 180 + 187 165 156 149 174 219 + 187 183 202 197 215 231 + 219 231 177 170 162 149 + 155 137 117 109 127 146 + 160 165 178 189 197 215 + 225 224 240 253 199 184 + 173 166 228 219 179 179 + 134 147 157 194 216 226 + 206 220 220 173 172 197 + 208 264 247 214 228 201 + 177 192 177 174 171 66 + 46 73 99 156 194 210 + 246 210 155 197 158 104 + 58 154 43 77 68 74 + 94 114 125 142 130 150 + 133 84 74 88 102 170 + 141 112 98 92 80 71 + 80 94 105 127 138 114 + 122 109 97 94 77 93 + 66 45 47 60 46 26 + 16 28 67 91 44 53 + 43 51 100000000 13 26 40 + 24 16 30 73 52 92 + 105 92 42 54 69 113 + 103 107 101 88 86 73 + 96 109 76 56 42 56 + 57 96 55 68 87 94 + 90 76 136 126 114 121 + 123 151 169 176 154 145 + 138 163 208 176 172 191 + 186 204 220 208 220 166 + 159 151 138 144 126 106 + 98 116 135 149 154 167 + 178 186 204 214 213 229 + 242 188 173 162 155 217 + 208 168 168 123 136 146 + 183 205 215 195 209 209 + 162 161 186 197 253 236 + 203 217 190 166 181 166 + 163 160 55 35 62 88 + 145 183 199 235 199 144 + 186 147 93 47 143 32 + 64 55 61 81 101 112 + 129 117 137 120 84 74 + 88 102 157 141 112 98 + 92 80 71 80 94 105 + 127 138 114 124 111 97 + 111 94 93 83 73 61 + 74 46 40 50 62 96 + 97 50 70 77 57 68 + 100000000 13 27 11 22 36 + 79 58 98 111 98 29 + 41 56 119 90 109 88 + 75 73 60 83 96 63 + 43 29 43 57 96 42 + 55 74 81 77 63 123 + 113 101 108 110 138 156 + 163 141 132 125 150 195 + 163 159 178 173 191 207 + 195 207 153 146 138 125 + 131 113 93 85 103 122 + 136 141 154 165 173 191 + 201 200 216 229 175 160 + 149 142 204 195 155 155 + 110 123 133 170 192 202 + 182 196 196 149 148 173 + 184 240 223 190 204 177 + 166 168 153 150 147 89 + 69 76 88 145 183 199 + 222 186 131 173 134 80 + 34 130 19 51 42 48 + 68 88 99 116 104 124 + 107 71 61 75 89 144 + 128 99 85 79 67 58 + 67 81 92 114 125 101 + 111 98 84 98 81 80 + 70 60 48 61 33 27 + 37 49 83 108 68 74 + 64 75 86 99 100000000 14 + 29 40 54 97 76 116 + 129 116 47 59 74 137 + 108 127 106 93 91 78 + 101 114 50 30 16 30 + 44 83 29 42 61 68 + 64 50 133 131 119 126 + 128 156 174 181 157 148 + 136 166 182 179 146 165 + 160 178 194 182 194 140 + 133 125 112 118 100 80 + 72 90 109 123 128 141 + 152 160 178 188 187 203 + 216 162 147 136 129 191 + 182 142 142 97 110 120 + 157 179 189 169 183 183 + 136 135 160 171 227 210 + 177 191 164 153 155 140 + 168 163 76 56 63 75 + 132 170 186 209 173 118 + 160 127 98 21 117 6 + 65 56 62 82 102 113 + 130 118 138 121 85 75 + 89 103 158 142 113 99 + 93 81 72 81 95 106 + 128 139 115 125 112 98 + 112 95 94 84 74 62 + 75 47 41 51 63 97 + 101 54 74 78 61 72 + 85 14 100000000 15 26 40 + 83 62 102 115 102 33 + 45 60 123 94 113 92 + 79 77 64 87 100 64 + 44 30 44 58 97 43 + 56 75 82 78 64 127 + 117 105 112 114 142 160 + 167 145 136 129 154 196 + 167 160 179 174 192 208 + 196 208 154 147 139 126 + 132 114 94 86 104 123 + 137 142 155 166 174 192 + 202 201 217 230 176 161 + 150 143 205 196 156 156 + 111 124 134 171 193 203 + 183 197 197 150 149 174 + 185 241 224 191 205 178 + 167 169 154 154 151 90 + 70 77 89 146 184 200 + 223 187 132 174 138 84 + 35 131 20 110 101 107 + 127 147 158 175 163 183 + 166 130 120 134 148 203 + 187 158 144 138 126 117 + 126 140 151 173 184 160 + 170 157 143 150 133 139 + 122 101 104 117 92 83 + 73 84 111 86 39 59 + 69 46 57 70 59 45 + 100000000 11 25 68 47 87 + 100 87 18 30 45 108 + 79 98 77 64 62 49 + 72 85 109 89 75 89 + 103 142 88 101 120 127 + 123 109 112 102 90 97 + 99 127 145 152 130 121 + 114 139 198 152 162 181 + 176 194 210 208 220 193 + 165 157 144 132 159 139 + 131 149 168 182 187 200 + 211 219 237 235 242 249 + 232 221 206 195 188 250 + 241 201 201 156 169 179 + 216 238 248 228 242 242 + 195 194 219 230 286 269 + 236 250 223 212 214 199 + 139 136 111 91 119 134 + 191 229 245 235 189 177 + 176 123 69 80 176 65 + 123 114 120 140 160 171 + 188 176 196 179 130 120 + 134 148 216 187 158 144 + 138 126 117 126 140 151 + 173 184 160 167 154 143 + 139 122 139 111 90 93 + 106 92 72 62 73 100 + 75 28 48 58 35 46 + 59 72 86 70 100000000 14 + 57 36 76 89 76 85 + 97 112 97 122 91 123 + 131 129 116 139 152 122 + 102 88 102 103 142 101 + 114 133 140 136 122 179 + 169 157 164 166 173 191 + 198 197 188 181 206 254 + 219 218 237 232 250 266 + 254 266 212 205 197 184 + 190 172 152 144 162 181 + 195 200 213 224 232 250 + 260 259 275 288 234 219 + 208 201 263 254 214 214 + 169 182 192 229 251 261 + 241 255 255 208 207 232 + 243 299 282 249 263 236 + 212 227 212 185 203 100 + 80 108 134 191 229 245 + 281 245 190 232 190 136 + 93 189 78 109 100 106 + 126 146 157 174 162 182 + 165 116 106 120 134 202 + 173 144 130 124 112 103 + 112 126 137 159 170 146 + 153 140 129 125 108 125 + 97 76 79 92 78 58 + 48 59 86 61 14 34 + 44 21 32 45 58 72 + 56 48 100000000 43 22 62 + 75 62 71 83 98 83 + 108 77 109 117 115 102 + 125 138 108 88 74 88 + 89 128 87 100 119 126 + 122 108 165 155 143 150 + 152 159 177 184 183 174 + 167 192 240 205 204 223 + 218 236 252 240 252 198 + 191 183 170 176 158 138 + 130 148 167 181 186 199 + 210 218 236 246 245 261 + 274 220 205 194 187 249 + 240 200 200 155 168 178 + 215 237 247 227 241 241 + 194 193 218 229 285 268 + 235 249 222 198 213 198 + 171 189 86 66 94 120 + 177 215 231 267 231 176 + 218 176 122 79 175 64 + 118 109 115 135 155 166 + 183 171 191 174 125 115 + 129 143 211 182 153 139 + 133 121 112 121 135 146 + 168 179 155 162 149 138 + 134 117 134 106 85 88 + 101 87 67 57 68 95 + 70 23 43 53 30 41 + 54 67 55 65 57 9 + 100000000 31 71 32 19 28 + 40 55 40 65 60 87 + 74 72 59 82 95 117 + 97 83 97 98 137 96 + 109 128 135 131 117 122 + 112 100 107 109 137 155 + 162 140 131 124 149 208 + 162 172 191 186 204 220 + 218 230 203 175 167 154 + 142 167 147 139 157 176 + 190 195 208 219 227 245 + 245 252 259 242 229 214 + 203 196 258 249 209 209 + 164 177 187 224 246 256 + 236 250 250 203 202 227 + 238 294 277 244 258 231 + 207 222 207 149 146 95 + 75 103 129 186 224 240 + 245 199 185 186 133 79 + 88 184 73 139 130 136 + 156 176 187 204 192 212 + 195 146 136 150 164 232 + 195 174 160 154 142 133 + 142 156 159 181 192 163 + 150 137 151 122 105 128 + 94 87 99 112 108 88 + 78 88 64 39 44 64 + 73 51 62 75 88 76 + 86 78 30 21 100000000 40 + 53 40 49 61 76 61 + 86 55 87 95 93 80 + 103 116 138 118 104 118 + 119 158 117 130 149 156 + 152 138 143 133 121 128 + 130 137 155 162 161 152 + 145 170 218 183 193 201 + 207 225 238 239 251 224 + 196 188 175 163 188 168 + 160 178 197 211 216 229 + 240 248 266 266 273 277 + 260 250 235 224 217 279 + 270 230 230 185 198 208 + 245 267 277 257 271 271 + 224 223 248 259 315 298 + 265 278 251 220 243 228 + 149 167 76 95 114 133 + 199 237 253 266 220 206 + 207 154 100 109 205 94 + 179 170 176 196 216 227 + 244 232 252 235 186 176 + 190 204 272 235 214 200 + 194 182 173 182 196 199 + 221 232 203 190 177 191 + 162 145 168 134 127 139 + 152 148 128 118 128 104 + 79 84 104 113 91 102 + 115 128 116 126 118 70 + 61 40 100000000 22 80 89 + 101 46 30 55 15 47 + 65 70 57 80 93 129 + 158 144 158 159 198 157 + 170 189 196 192 178 120 + 110 98 105 107 97 115 + 122 138 129 122 147 178 + 160 170 161 184 202 198 + 216 228 201 173 165 152 + 140 228 208 200 218 237 + 212 256 269 245 253 271 + 243 250 237 220 275 275 + 264 257 319 310 270 270 + 225 238 248 285 307 317 + 297 311 311 264 263 288 + 299 355 338 305 318 291 + 260 283 268 109 128 116 + 135 154 173 239 277 293 + 227 197 246 184 131 77 + 149 245 134 205 196 202 + 222 242 253 270 258 278 + 261 225 215 229 243 298 + 278 253 239 233 221 212 + 221 235 242 264 275 246 + 233 220 234 205 188 211 + 177 170 182 195 187 171 + 161 171 147 122 127 147 + 156 134 145 158 154 140 + 155 161 113 104 83 43 + 100000000 123 132 125 24 8 + 33 28 56 43 48 35 + 58 71 107 184 170 184 + 198 237 183 196 215 222 + 218 204 98 88 76 83 + 85 106 124 131 116 107 + 100 125 184 138 148 167 + 162 180 196 194 206 179 + 151 143 130 118 213 226 + 226 244 215 190 234 247 + 223 231 249 221 228 235 + 218 253 253 242 235 297 + 288 248 261 251 264 274 + 263 285 295 275 289 298 + 290 289 314 325 333 316 + 317 344 318 303 309 294 + 118 122 159 178 197 216 + 282 320 336 221 175 224 + 162 109 55 175 271 160 + 101 92 98 118 138 149 + 166 154 174 157 121 111 + 125 139 194 178 149 135 + 129 117 108 117 131 142 + 164 175 151 161 148 134 + 148 131 130 120 110 98 + 111 83 77 87 99 133 + 135 90 110 114 97 108 + 121 50 36 51 62 76 + 117 96 56 13 100000000 9 + 21 36 21 46 41 68 + 55 53 40 63 76 100 + 80 66 80 94 133 79 + 92 111 118 114 100 103 + 93 81 88 90 118 136 + 143 121 112 105 130 189 + 143 153 172 167 185 201 + 199 211 184 156 148 135 + 123 150 130 122 140 159 + 173 178 191 202 210 228 + 226 233 240 223 212 197 + 186 179 241 232 192 192 + 147 160 170 207 229 239 + 219 233 233 186 185 210 + 221 277 260 227 241 214 + 203 205 190 130 127 126 + 106 113 125 182 220 236 + 226 180 168 167 114 60 + 71 167 56 92 83 89 + 109 129 140 157 145 165 + 148 112 102 116 130 185 + 169 140 126 120 108 99 + 108 122 133 155 166 142 + 152 139 125 139 122 121 + 111 101 89 102 74 68 + 78 90 124 128 81 101 + 105 88 99 112 41 27 + 42 53 67 110 89 95 + 117 129 100000000 12 27 125 + 61 80 59 46 44 31 + 54 67 91 71 57 71 + 85 124 70 83 102 109 + 105 91 94 84 72 79 + 81 109 127 134 112 103 + 96 121 180 134 144 163 + 158 176 192 190 202 175 + 147 139 126 114 141 121 + 113 131 150 164 169 182 + 193 201 219 217 224 231 + 214 203 188 177 170 232 + 223 183 183 138 151 161 + 198 220 230 210 224 224 + 177 176 201 212 268 251 + 218 232 205 194 196 181 + 121 118 117 97 104 116 + 173 211 227 217 171 159 + 158 105 51 62 158 47 + 80 71 77 97 117 128 + 145 133 153 136 100 90 + 104 118 173 157 128 114 + 108 96 87 96 110 121 + 143 154 130 140 127 113 + 127 110 109 99 89 77 + 90 62 56 66 78 112 + 116 69 89 93 76 87 + 100 29 15 30 41 55 + 98 77 83 105 117 48 + 100000000 15 113 49 68 47 + 34 32 19 42 55 79 + 59 45 59 73 112 58 + 71 90 97 93 79 82 + 72 60 67 69 97 115 + 122 100 91 84 109 168 + 122 132 151 146 164 180 + 178 190 163 135 127 114 + 102 129 109 101 119 138 + 152 157 170 181 189 207 + 205 212 219 202 191 176 + 165 158 220 211 171 171 + 126 139 149 186 208 218 + 198 212 212 165 164 189 + 200 256 239 206 220 193 + 182 184 169 109 106 105 + 85 92 104 161 199 215 + 205 159 147 146 93 39 + 50 146 35 181 172 178 + 198 218 229 246 234 254 + 237 201 191 205 219 274 + 258 229 215 209 197 188 + 197 211 222 244 255 231 + 241 228 214 228 211 210 + 200 190 178 191 163 157 + 167 179 172 147 152 172 + 181 159 170 183 130 116 + 131 142 138 129 108 68 + 90 148 149 101 100000000 98 + 34 53 32 19 24 11 + 34 47 83 160 146 160 + 174 213 159 172 191 198 + 194 180 74 64 52 59 + 61 82 100 107 92 83 + 76 101 160 114 124 143 + 138 156 172 170 182 155 + 127 119 106 94 189 202 + 202 220 191 166 210 223 + 199 207 225 197 204 211 + 194 229 229 218 211 273 + 264 224 237 227 240 250 + 239 261 271 251 265 274 + 266 265 290 301 309 292 + 293 320 294 283 285 270 + 94 98 184 186 193 205 + 262 300 316 197 151 200 + 138 85 31 151 247 136 + 197 188 194 214 234 245 + 262 250 270 253 217 207 + 221 235 290 274 245 231 + 225 213 204 213 227 238 + 260 271 247 249 236 230 + 221 204 226 193 186 194 + 207 179 173 177 187 163 + 138 143 163 172 150 161 + 174 146 132 147 158 129 + 120 99 59 81 139 148 + 117 16 100000000 25 44 48 + 35 40 27 50 63 99 + 176 162 176 190 229 175 + 188 207 214 210 196 90 + 80 68 75 77 98 116 + 123 108 99 92 117 176 + 130 140 159 154 172 188 + 186 198 171 143 135 122 + 110 205 218 218 236 207 + 182 226 239 215 223 241 + 213 220 227 210 245 245 + 234 227 289 280 240 253 + 243 256 266 255 277 287 + 267 281 290 282 281 306 + 317 325 308 309 336 310 + 299 301 286 110 114 175 + 194 209 221 278 316 332 + 213 167 216 154 101 47 + 167 263 152 213 204 210 + 230 250 261 278 266 286 + 269 220 210 224 238 306 + 269 248 234 228 216 207 + 216 230 233 255 266 237 + 224 211 225 196 179 202 + 168 161 173 186 182 162 + 152 162 138 113 118 138 + 147 125 136 149 162 150 + 160 152 104 95 74 34 + 56 114 123 135 80 64 + 100000000 19 51 99 104 91 + 114 127 163 192 178 192 + 193 232 191 204 223 230 + 226 212 154 144 132 139 + 125 101 119 126 144 147 + 156 161 182 174 184 165 + 198 216 202 230 242 215 + 195 187 186 174 249 242 + 234 252 251 226 270 283 + 259 267 285 254 257 241 + 224 282 289 278 271 332 + 323 284 297 259 272 282 + 299 321 331 311 325 334 + 298 297 322 333 368 351 + 339 352 325 294 317 302 + 113 132 150 169 188 207 + 273 311 327 231 211 260 + 198 165 111 183 279 168 + 194 185 191 211 231 242 + 259 247 267 250 201 191 + 205 219 287 250 229 215 + 209 197 188 197 211 214 + 236 247 218 205 192 206 + 177 160 183 149 142 154 + 167 163 143 133 143 119 + 94 99 119 128 106 117 + 130 143 131 141 133 85 + 76 55 15 37 95 104 + 116 61 45 70 100000000 32 + 80 85 72 95 108 144 + 173 159 173 174 213 172 + 185 204 211 207 193 135 + 125 113 120 106 82 100 + 107 125 128 137 142 163 + 155 165 146 179 197 183 + 211 223 196 176 168 167 + 155 230 223 215 233 232 + 207 251 264 240 248 266 + 235 238 222 205 263 270 + 259 252 313 304 265 278 + 240 253 263 280 302 312 + 292 306 315 279 278 303 + 314 349 332 320 333 306 + 275 298 283 94 113 131 + 150 169 188 254 292 308 + 212 192 241 179 146 92 + 164 260 149 217 208 214 + 234 254 265 282 270 290 + 273 233 223 237 251 310 + 282 261 247 241 229 220 + 229 243 246 268 279 250 + 237 224 238 209 192 215 + 181 174 186 199 195 175 + 165 175 151 126 131 151 + 160 138 149 162 166 152 + 167 165 117 108 87 47 + 69 127 136 137 93 77 + 102 32 100000000 112 113 104 + 103 88 119 196 182 196 + 206 245 195 208 227 234 + 230 216 104 100 88 89 + 74 50 68 75 93 96 + 106 110 131 123 133 114 + 147 165 151 179 191 164 + 144 136 136 124 198 211 + 238 256 200 175 219 232 + 208 216 234 203 206 190 + 173 231 238 227 220 281 + 272 233 246 263 276 273 + 248 270 280 260 274 283 + 289 301 326 337 317 300 + 302 329 330 307 321 306 + 62 81 163 182 201 220 + 286 324 340 180 160 209 + 147 115 120 187 283 172 + 228 219 225 245 265 276 + 293 281 301 284 235 225 + 239 253 321 284 263 249 + 243 231 222 231 245 248 + 270 281 252 239 226 240 + 211 194 217 183 176 188 + 201 197 177 167 177 153 + 128 133 153 162 140 151 + 164 177 165 175 167 119 + 110 89 49 71 129 138 + 150 95 79 15 34 13 + 100000000 119 106 116 101 132 + 207 193 207 208 247 206 + 219 238 245 241 227 117 + 113 101 102 87 63 81 + 88 106 109 119 123 144 + 136 146 127 160 178 164 + 192 204 177 157 149 149 + 137 211 224 249 267 213 + 188 232 245 221 229 247 + 216 219 203 186 244 251 + 240 233 294 285 246 259 + 274 287 286 261 283 293 + 273 287 296 302 312 337 + 348 330 313 315 342 340 + 309 332 317 75 94 165 + 184 203 222 288 326 342 + 193 173 222 160 128 126 + 198 294 183 157 148 154 + 174 194 205 222 210 230 + 213 177 167 181 195 250 + 234 205 191 185 173 164 + 173 187 198 220 231 207 + 217 204 190 204 187 186 + 176 166 154 167 139 133 + 143 155 167 142 146 166 + 170 153 164 177 106 92 + 107 118 132 124 103 63 + 85 143 125 77 92 93 + 29 48 27 14 100000000 96 + 10 23 59 136 122 136 + 150 189 135 148 167 174 + 170 156 50 40 28 35 + 37 77 85 92 68 59 + 52 77 136 90 100 119 + 114 132 148 146 158 131 + 103 95 82 70 165 178 + 178 196 167 142 186 199 + 175 183 201 173 180 187 + 170 205 205 194 187 249 + 240 200 213 203 216 226 + 215 237 247 227 241 250 + 242 241 266 277 285 268 + 269 296 270 259 261 246 + 89 74 179 162 169 181 + 238 276 292 173 127 176 + 114 61 7 127 223 112 + 170 161 167 187 207 218 + 235 223 243 226 190 180 + 194 208 263 247 218 204 + 198 186 177 186 200 211 + 233 244 220 230 217 203 + 217 200 199 189 179 167 + 180 152 146 156 168 180 + 155 159 179 183 166 177 + 190 119 105 120 131 145 + 137 116 76 98 156 138 + 90 105 106 42 61 40 + 27 13 100000000 23 36 72 + 149 135 149 163 202 148 + 161 180 187 183 169 63 + 53 41 48 50 90 98 + 105 81 72 65 90 149 + 103 113 132 127 145 161 + 159 171 144 116 108 95 + 83 178 191 191 209 180 + 155 199 212 188 196 214 + 186 193 200 183 218 218 + 207 200 262 253 213 226 + 216 229 239 228 250 260 + 240 254 263 255 254 279 + 290 298 281 282 309 283 + 272 274 259 102 87 192 + 175 182 194 251 289 305 + 186 140 189 127 74 20 + 140 236 125 147 138 144 + 164 184 195 212 200 220 + 203 167 157 171 185 240 + 224 195 181 175 163 154 + 163 177 188 210 221 197 + 207 194 180 194 177 176 + 166 156 144 157 129 123 + 133 145 177 152 136 156 + 160 143 154 167 96 82 + 97 108 122 134 113 73 + 95 153 115 67 82 103 + 39 58 37 24 10 86 + 100000000 33 49 126 112 126 + 140 179 125 138 157 164 + 160 146 40 30 18 25 + 47 87 80 87 63 54 + 42 72 131 85 95 114 + 109 127 143 141 153 126 + 93 85 72 60 160 173 + 168 186 162 137 181 194 + 170 178 196 168 175 182 + 165 200 200 189 182 244 + 235 195 208 193 206 216 + 210 232 242 222 236 245 + 232 231 256 267 280 263 + 264 287 260 249 251 236 + 99 69 172 152 159 171 + 228 266 282 168 122 171 + 109 51 17 117 213 102 + 157 148 154 174 194 205 + 222 210 230 213 177 167 + 181 195 250 234 205 191 + 185 173 164 173 187 198 + 220 231 207 217 204 190 + 204 187 186 176 166 154 + 167 139 133 143 155 189 + 167 146 166 170 153 164 + 177 106 92 107 118 132 + 149 128 88 110 168 125 + 77 92 118 54 73 52 + 39 25 96 15 100000000 59 + 136 122 136 150 189 135 + 148 167 174 170 156 44 + 40 28 29 14 80 62 + 69 45 36 46 54 113 + 67 77 96 91 109 125 + 123 135 108 88 80 76 + 64 142 155 178 196 144 + 119 163 176 152 160 178 + 150 157 164 147 182 182 + 171 164 226 217 177 190 + 203 216 217 192 214 224 + 204 218 227 233 241 266 + 277 262 245 246 273 270 + 259 261 246 92 51 182 + 162 169 181 238 276 292 + 150 104 153 91 55 32 + 127 223 112 98 89 95 + 115 135 146 163 151 171 + 154 118 108 122 136 191 + 175 146 132 126 114 105 + 114 128 139 161 172 148 + 158 145 131 145 128 127 + 117 107 95 108 80 74 + 84 96 130 134 87 107 + 111 94 105 118 47 33 + 48 59 73 116 95 101 + 123 135 66 18 33 131 + 67 86 65 52 50 37 + 60 73 100000000 77 63 77 + 91 130 76 89 108 115 + 111 97 100 90 78 85 + 87 115 133 140 118 109 + 102 127 186 140 150 169 + 164 182 198 196 208 181 + 153 145 132 120 147 127 + 119 137 156 170 175 188 + 199 207 225 223 230 237 + 220 209 194 183 176 238 + 229 189 189 144 157 167 + 204 226 236 216 230 230 + 183 182 207 218 274 257 + 224 238 211 200 202 187 + 127 124 123 103 110 122 + 179 217 233 223 177 165 + 164 111 57 68 164 53 + 47 38 44 64 84 95 + 112 100 120 103 74 64 + 78 92 140 149 120 102 + 82 70 79 88 102 113 + 135 146 122 132 119 105 + 123 111 101 100 90 78 + 91 63 57 67 79 113 + 138 98 104 94 105 116 + 129 30 44 59 70 84 + 127 106 121 143 146 77 + 38 53 151 87 106 85 + 72 70 57 80 93 20 + 100000000 14 28 47 86 25 + 12 31 38 47 20 120 + 110 98 105 107 135 153 + 160 138 129 122 147 178 + 160 142 161 156 174 190 + 178 190 136 129 121 108 + 114 96 76 68 86 105 + 119 124 137 148 156 174 + 184 183 199 212 158 143 + 132 125 187 178 138 138 + 93 106 116 153 175 185 + 165 179 179 132 131 156 + 167 223 206 173 187 160 + 174 151 136 147 144 106 + 86 93 96 153 168 192 + 205 169 114 156 123 77 + 39 113 24 35 26 32 + 52 72 83 100 88 108 + 91 60 50 64 78 128 + 135 106 88 68 56 65 + 74 88 99 121 132 108 + 118 105 91 109 97 87 + 86 76 64 77 49 43 + 53 65 99 124 84 90 + 80 91 102 115 16 30 + 45 56 70 113 92 132 + 145 132 63 72 87 153 + 121 140 119 106 104 91 + 114 127 54 34 100000000 14 + 33 72 13 26 45 52 + 48 34 117 129 132 139 + 141 169 158 165 141 132 + 120 150 166 163 130 149 + 144 162 178 166 178 124 + 117 109 96 102 84 64 + 56 74 93 107 112 125 + 136 144 162 172 171 187 + 200 146 131 120 113 175 + 166 126 126 81 94 104 + 141 163 173 153 167 167 + 120 119 144 155 211 194 + 161 175 148 160 139 124 + 181 147 92 72 79 82 + 139 156 180 193 157 102 + 144 111 111 25 101 10 + 160 151 157 177 197 208 + 225 201 221 216 46 36 + 50 64 202 121 92 74 + 54 42 51 60 74 85 + 107 118 94 104 91 77 + 95 96 73 105 126 117 + 81 76 96 106 118 135 + 160 160 143 133 144 155 + 168 109 123 138 149 163 + 189 168 208 221 208 156 + 168 183 229 217 223 215 + 202 200 187 210 223 159 + 139 125 100000000 19 58 138 + 151 170 177 173 159 242 + 240 228 235 237 265 283 + 290 266 257 245 275 291 + 288 255 274 269 287 303 + 291 303 249 242 234 221 + 227 209 189 181 199 218 + 232 237 250 261 269 287 + 297 296 312 325 271 256 + 245 238 282 273 251 251 + 206 219 229 266 263 253 + 270 284 245 226 208 233 + 233 318 301 231 204 177 + 146 180 194 277 272 145 + 125 98 68 125 163 179 + 318 282 227 269 236 207 + 130 226 115 141 132 138 + 158 178 189 206 182 202 + 197 27 17 31 45 183 + 102 73 55 35 23 32 + 41 55 66 88 99 75 + 85 72 58 76 77 54 + 86 107 98 62 57 77 + 87 99 116 141 141 124 + 114 125 136 149 90 104 + 119 130 144 170 149 189 + 202 189 137 149 164 210 + 198 204 196 183 181 168 + 191 204 140 120 106 55 + 100000000 39 119 132 151 158 + 154 140 223 221 209 216 + 218 246 264 271 247 238 + 226 256 272 269 236 255 + 250 268 284 272 284 230 + 223 215 202 208 190 170 + 162 180 199 213 218 231 + 242 250 268 278 277 293 + 306 252 237 226 219 263 + 254 232 232 187 200 210 + 247 244 234 251 265 226 + 207 189 214 214 299 282 + 212 185 158 127 161 175 + 258 253 126 106 79 49 + 106 144 160 299 263 208 + 250 217 188 111 207 96 + 176 167 173 193 213 224 + 241 217 237 232 62 52 + 66 80 218 137 108 90 + 70 58 67 76 90 101 + 123 134 110 120 107 93 + 111 112 89 121 142 133 + 97 92 112 122 134 151 + 176 176 159 149 160 171 + 184 125 139 154 165 179 + 205 184 224 237 224 172 + 184 199 245 233 239 231 + 218 216 203 226 239 175 + 155 141 16 35 100000000 154 + 167 186 193 189 175 258 + 256 244 251 253 281 299 + 306 282 273 261 291 307 + 304 271 290 285 303 319 + 307 319 265 258 250 237 + 243 225 205 197 215 234 + 248 253 266 277 285 303 + 313 312 328 341 287 272 + 261 254 298 289 267 267 + 222 235 245 282 279 269 + 286 300 261 242 224 249 + 249 334 317 247 220 193 + 162 196 210 293 288 161 + 141 114 84 141 179 195 + 334 298 243 285 252 223 + 146 242 131 22 13 19 + 39 59 70 87 75 95 + 78 73 63 77 91 115 + 131 119 101 81 69 78 + 87 101 112 134 145 121 + 131 118 104 122 110 100 + 99 89 77 90 62 56 + 66 78 112 137 97 103 + 93 104 115 128 29 43 + 58 69 83 126 105 145 + 158 145 76 63 78 166 + 112 131 110 97 95 82 + 105 118 45 25 13 27 + 46 85 100000000 13 32 39 + 35 21 104 116 123 130 + 132 160 145 152 128 119 + 107 137 153 150 117 136 + 131 149 165 153 165 111 + 104 96 83 89 71 51 + 43 61 80 94 99 112 + 123 131 149 159 158 174 + 187 133 118 107 100 162 + 153 113 113 68 81 91 + 128 150 160 140 154 154 + 107 106 131 142 198 181 + 148 162 135 160 126 111 + 172 134 105 85 92 95 + 135 143 167 180 144 89 + 131 98 102 38 88 23 + 35 26 32 52 72 83 + 100 88 108 91 86 76 + 90 104 128 144 132 114 + 94 82 91 100 114 125 + 147 158 134 144 131 117 + 135 123 113 112 102 90 + 103 75 69 79 91 125 + 150 110 116 106 117 128 + 141 42 56 71 82 96 + 139 118 133 155 158 89 + 50 65 163 99 118 97 + 84 82 69 92 105 32 + 12 26 40 59 98 13 + 100000000 19 26 35 8 117 + 122 110 117 119 147 158 + 165 141 132 120 150 166 + 163 130 149 144 162 178 + 166 178 124 117 109 96 + 102 84 64 56 74 93 + 107 112 125 136 144 162 + 172 171 187 200 146 131 + 120 113 175 166 126 126 + 81 94 104 141 163 173 + 153 167 167 120 119 144 + 155 211 194 161 175 148 + 173 139 124 159 147 118 + 98 105 108 148 156 180 + 193 157 102 144 111 89 + 51 101 36 29 38 44 + 48 68 79 96 84 104 + 87 96 95 109 123 124 + 140 151 133 113 101 110 + 119 133 144 166 159 153 + 163 150 136 154 142 132 + 131 121 109 122 94 88 + 98 110 144 169 129 135 + 125 136 147 160 61 75 + 90 101 115 158 137 152 + 174 177 108 69 84 182 + 118 137 116 103 101 88 + 111 124 51 31 45 59 + 78 108 32 19 100000000 7 + 16 11 111 123 129 136 + 138 166 152 159 135 126 + 114 144 160 157 124 143 + 138 156 172 160 172 118 + 111 103 90 96 78 58 + 50 68 87 101 106 119 + 130 138 156 166 165 181 + 194 140 125 114 107 169 + 160 120 120 75 88 98 + 135 157 167 147 161 163 + 114 115 140 151 205 188 + 157 171 144 169 135 120 + 178 141 137 117 124 127 + 144 152 176 187 151 96 + 138 105 108 70 97 55 + 22 31 37 41 61 72 + 89 77 97 80 89 91 + 105 119 117 133 147 129 + 109 97 106 115 129 140 + 162 152 149 159 146 132 + 150 138 128 127 117 105 + 118 90 84 94 106 140 + 165 125 131 121 132 143 + 156 57 71 86 97 111 + 154 133 148 170 173 104 + 65 80 178 114 133 112 + 99 97 84 107 120 47 + 27 41 55 74 101 28 + 15 7 100000000 9 18 104 + 116 125 132 134 162 145 + 152 128 119 107 137 153 + 150 117 136 131 149 165 + 153 165 111 104 96 83 + 89 71 51 43 61 80 + 94 99 112 123 131 149 + 159 158 174 187 133 118 + 107 100 162 153 113 113 + 68 81 91 128 150 160 + 140 154 156 107 108 133 + 144 198 181 150 164 137 + 162 128 113 174 134 133 + 113 120 123 137 145 169 + 180 144 89 131 98 104 + 66 90 51 13 22 28 + 32 52 63 80 68 88 + 71 80 98 112 113 108 + 124 138 123 116 104 113 + 122 136 147 169 143 156 + 166 153 139 157 145 135 + 134 124 112 125 97 91 + 101 113 147 172 132 138 + 128 139 150 163 64 78 + 93 104 118 161 140 157 + 179 180 111 74 89 187 + 123 142 121 108 106 93 + 116 129 56 36 48 62 + 81 92 35 24 16 9 + 100000000 27 95 107 134 141 + 140 154 136 143 119 110 + 98 128 144 141 108 127 + 122 140 156 144 156 102 + 95 87 74 80 62 42 + 34 52 71 85 90 103 + 114 122 140 150 149 165 + 178 124 109 98 91 153 + 144 104 104 59 72 82 + 119 141 151 131 145 147 + 98 99 124 135 189 172 + 141 155 128 153 119 104 + 166 125 140 120 127 130 + 128 136 160 171 135 80 + 122 89 113 73 81 58 + 40 34 40 59 79 90 + 107 95 115 98 94 84 + 98 112 135 151 140 122 + 102 90 99 108 122 133 + 155 166 142 152 139 125 + 143 131 121 120 110 98 + 111 83 77 87 99 133 + 158 118 124 114 125 136 + 149 50 64 79 90 104 + 147 126 141 163 166 97 + 58 73 171 107 126 105 + 92 90 77 100 113 40 + 20 34 48 67 106 21 + 8 11 18 27 100000000 122 + 130 118 125 127 155 163 + 170 146 137 125 155 171 + 168 135 154 149 167 183 + 171 183 129 122 114 101 + 107 89 69 61 79 98 + 112 117 130 141 149 167 + 177 176 192 205 151 136 + 125 118 180 171 131 131 + 86 99 109 146 168 178 + 158 172 174 125 126 151 + 162 216 199 168 182 155 + 180 146 131 167 152 126 + 106 113 116 155 163 187 + 198 162 107 149 116 97 + 59 108 44 129 120 126 + 146 166 177 194 182 202 + 185 149 139 153 167 222 + 206 177 163 157 145 136 + 145 159 170 192 203 179 + 189 176 162 176 159 158 + 148 138 126 139 111 105 + 115 127 161 165 118 138 + 142 125 136 149 78 64 + 79 90 104 147 126 106 + 128 166 97 49 64 136 + 72 91 70 57 43 68 + 33 66 31 108 94 108 + 122 161 107 120 139 146 + 142 128 100000000 12 51 58 + 80 120 113 120 96 87 + 75 105 164 118 128 147 + 142 160 176 174 186 159 + 126 118 105 93 178 158 + 150 168 187 170 206 219 + 203 211 229 201 208 215 + 198 233 225 214 207 269 + 260 220 220 175 188 198 + 235 257 267 247 261 261 + 214 213 238 249 305 288 + 255 269 242 231 233 218 + 132 102 154 134 141 153 + 210 248 264 201 155 196 + 142 84 50 99 195 84 + 117 108 114 134 154 165 + 182 170 190 173 137 127 + 141 155 210 194 165 151 + 145 133 124 133 147 158 + 180 191 167 177 164 150 + 164 147 146 136 126 114 + 127 99 93 103 115 149 + 153 106 126 130 113 124 + 137 66 52 67 78 92 + 135 114 94 116 154 85 + 37 52 124 60 79 58 + 45 31 56 21 54 19 + 96 82 96 110 149 95 + 108 127 134 130 116 61 + 100000000 39 46 68 108 101 + 108 84 75 63 93 152 + 106 116 135 130 148 164 + 162 174 147 114 106 93 + 81 166 146 138 156 175 + 158 194 207 191 199 217 + 189 196 203 186 221 213 + 202 195 257 248 208 208 + 163 176 186 223 245 255 + 235 249 249 202 201 226 + 237 293 276 243 257 230 + 219 221 206 120 90 142 + 122 129 141 198 236 252 + 189 143 184 130 72 38 + 87 183 72 129 120 126 + 146 166 177 194 182 202 + 185 149 139 153 167 222 + 206 177 163 157 145 136 + 145 159 170 192 203 179 + 189 176 162 176 159 158 + 148 138 126 139 111 105 + 115 127 161 165 118 138 + 142 125 136 149 78 64 + 79 90 104 147 126 106 + 128 166 97 49 64 136 + 72 91 70 57 43 68 + 33 66 31 108 94 108 + 122 161 107 120 139 146 + 142 128 22 12 100000000 7 + 66 80 62 69 45 36 + 24 54 113 67 77 96 + 91 109 125 123 135 108 + 75 67 54 42 142 155 + 150 168 144 119 163 176 + 152 160 178 150 157 164 + 147 182 182 171 164 226 + 217 177 190 175 188 198 + 192 214 224 204 218 227 + 214 213 238 249 262 245 + 246 269 242 231 233 218 + 92 51 154 134 141 153 + 210 248 264 150 104 153 + 91 33 50 99 195 84 + 136 127 133 153 173 184 + 201 189 209 192 156 146 + 160 174 229 213 184 170 + 164 152 143 152 166 177 + 199 210 186 196 183 169 + 183 166 165 155 145 133 + 146 118 112 122 134 168 + 172 125 145 149 132 143 + 156 85 71 86 97 111 + 154 133 113 135 173 104 + 56 71 143 79 98 77 + 64 50 75 40 73 38 + 115 101 115 129 168 114 + 127 146 153 149 135 15 + 19 7 100000000 59 73 55 + 62 38 29 17 47 106 + 60 70 89 84 102 118 + 116 128 101 68 60 47 + 35 135 148 157 175 137 + 112 156 169 145 153 171 + 143 150 157 140 175 175 + 164 157 219 210 170 183 + 182 195 205 185 207 217 + 197 211 220 221 220 245 + 256 255 238 239 266 249 + 238 240 225 85 44 161 + 141 148 160 217 255 271 + 143 97 146 84 26 57 + 106 202 91 143 134 140 + 160 180 191 208 196 216 + 199 163 153 167 181 236 + 220 191 177 171 159 150 + 159 173 184 206 217 193 + 203 190 176 190 173 172 + 162 152 140 153 125 119 + 129 141 175 179 132 152 + 156 139 150 163 92 78 + 93 104 118 161 140 102 + 124 180 111 63 78 132 + 68 87 66 53 39 82 + 29 14 45 122 108 122 + 136 175 121 134 153 160 + 156 142 30 26 14 15 + 100000000 66 48 55 31 22 + 32 40 99 53 63 82 + 77 95 111 109 121 94 + 74 66 62 50 128 141 + 164 182 130 105 149 162 + 138 146 164 136 143 150 + 133 168 168 157 150 212 + 203 163 176 189 202 203 + 178 200 210 190 204 213 + 219 227 252 263 248 231 + 232 259 256 245 247 232 + 78 37 168 148 155 167 + 224 262 278 136 90 139 + 77 41 46 113 209 98 + 167 158 164 184 204 215 + 232 220 240 223 187 177 + 191 205 260 244 215 201 + 195 183 174 183 197 208 + 230 241 217 227 214 200 + 214 197 196 186 176 164 + 177 149 143 153 165 199 + 176 156 176 180 163 174 + 187 116 102 117 128 142 + 158 137 97 119 177 135 + 87 102 127 92 82 50 + 77 63 106 53 38 69 + 146 132 146 160 199 145 + 158 177 184 180 166 54 + 50 38 39 24 100000000 18 + 25 43 46 56 60 81 + 73 83 64 97 115 101 + 129 141 114 94 86 86 + 74 148 161 188 206 150 + 125 169 182 158 166 184 + 153 156 140 123 181 188 + 177 170 231 222 183 196 + 213 226 223 198 220 230 + 210 224 233 239 251 276 + 287 267 250 252 279 280 + 269 271 256 12 31 192 + 172 179 191 248 286 302 + 130 110 159 97 65 70 + 137 233 122 185 176 182 + 202 222 233 234 238 258 + 241 205 195 209 223 278 + 262 233 219 213 201 192 + 201 215 226 248 259 235 + 245 232 218 232 215 214 + 204 194 182 195 167 161 + 171 183 217 194 174 194 + 198 181 192 205 134 120 + 135 146 160 176 155 115 + 137 195 153 105 120 145 + 110 100 68 95 81 124 + 71 56 87 164 150 164 + 178 217 163 176 195 202 + 198 184 72 68 56 57 + 42 18 100000000 7 25 60 + 72 42 63 55 65 46 + 79 97 83 111 123 96 + 76 68 102 90 130 143 + 206 224 132 107 151 164 + 140 148 166 135 138 122 + 105 163 170 159 152 213 + 204 165 178 197 210 205 + 180 202 212 192 206 215 + 221 253 278 274 249 232 + 234 261 282 287 273 258 + 30 31 210 190 197 209 + 266 290 314 112 92 141 + 79 81 88 155 225 140 + 182 173 179 199 219 230 + 227 235 255 238 202 192 + 206 220 275 259 230 216 + 210 198 189 198 212 223 + 245 256 232 242 229 215 + 229 212 211 201 191 179 + 192 164 158 168 180 214 + 201 171 191 195 178 189 + 202 131 117 132 143 157 + 183 162 122 144 202 150 + 102 117 152 107 107 75 + 92 78 121 68 53 84 + 161 147 161 175 214 160 + 173 192 199 195 181 69 + 65 53 54 39 25 7 + 100000000 18 53 65 35 56 + 48 58 39 72 90 76 + 104 116 89 69 61 95 + 83 123 136 203 221 125 + 100 144 157 133 141 159 + 128 131 115 98 156 163 + 152 145 206 197 158 171 + 190 203 198 173 195 205 + 185 199 208 214 246 271 + 267 242 225 227 254 275 + 284 266 251 37 24 207 + 187 194 206 263 283 307 + 105 85 134 72 74 85 + 152 218 137 164 155 161 + 181 201 212 209 217 237 + 220 184 174 188 202 257 + 241 212 198 192 180 171 + 180 194 205 227 238 214 + 224 211 197 211 194 193 + 183 173 161 174 146 140 + 150 162 196 200 153 173 + 177 160 171 184 113 99 + 114 125 139 182 161 123 + 145 201 132 84 99 153 + 89 108 85 74 60 103 + 50 35 66 143 129 143 + 157 196 142 155 174 181 + 177 163 51 47 35 36 + 21 35 17 24 100000000 35 + 47 17 76 30 40 59 + 54 72 88 86 98 71 + 51 43 77 65 105 118 + 185 203 107 82 126 139 + 115 123 141 113 120 127 + 110 145 145 134 127 189 + 180 140 153 172 185 180 + 155 177 187 167 181 190 + 196 228 253 250 225 208 + 209 236 257 266 248 233 + 47 6 189 169 176 188 + 245 265 289 113 67 116 + 54 56 67 134 200 119 + 173 164 170 190 210 221 + 210 220 240 229 193 183 + 197 211 260 250 221 207 + 201 189 180 189 203 214 + 236 247 223 233 220 206 + 220 203 202 192 182 170 + 183 155 149 159 171 205 + 209 162 182 186 169 180 + 193 122 108 123 134 148 + 191 170 132 154 210 141 + 93 108 162 98 117 94 + 83 69 112 59 44 75 + 152 138 152 166 205 151 + 164 183 190 186 172 45 + 56 44 45 30 44 26 + 33 9 100000000 12 18 77 + 31 41 60 55 73 89 + 87 99 72 52 44 42 + 30 106 119 190 208 108 + 83 127 140 116 124 142 + 114 121 128 111 146 146 + 135 128 190 181 141 154 + 173 186 181 156 178 188 + 168 182 191 197 229 254 + 251 226 209 210 237 258 + 275 249 234 56 15 198 + 178 185 197 254 266 290 + 114 68 117 55 21 76 + 143 201 128 162 153 159 + 179 199 210 222 215 235 + 218 182 172 186 200 255 + 239 210 196 190 178 169 + 178 192 203 225 236 212 + 222 209 195 209 192 191 + 181 171 159 172 144 138 + 148 160 194 198 151 171 + 175 158 169 182 111 97 + 112 123 137 180 159 139 + 161 199 130 82 97 169 + 105 124 103 90 76 101 + 66 56 64 141 127 141 + 155 194 140 153 172 179 + 175 161 33 45 56 57 + 42 56 38 45 21 12 + 100000000 30 89 43 53 72 + 67 85 101 99 111 84 + 51 43 30 18 118 131 + 183 201 120 95 139 152 + 128 136 154 126 133 140 + 123 158 158 147 140 202 + 193 153 166 185 198 193 + 168 190 200 180 194 203 + 209 241 266 263 238 221 + 222 249 270 264 261 246 + 68 27 187 167 174 186 + 243 278 297 126 80 129 + 67 9 83 132 213 117 + 191 182 188 188 208 219 + 192 202 222 227 211 201 + 215 229 242 258 239 225 + 219 207 198 207 221 232 + 254 265 241 251 238 224 + 238 221 220 210 200 188 + 201 173 167 177 189 223 + 227 180 200 204 187 198 + 211 140 126 141 152 166 + 209 188 150 172 228 159 + 111 126 180 116 135 112 + 101 87 130 77 62 93 + 170 156 170 184 223 169 + 182 201 208 204 190 63 + 74 62 63 48 62 44 + 51 27 18 30 100000000 59 + 13 23 42 37 55 71 + 69 81 54 34 26 60 + 48 88 101 172 190 90 + 65 109 122 98 106 124 + 96 103 110 93 128 128 + 117 110 172 163 123 136 + 155 168 163 138 160 170 + 150 164 173 179 211 236 + 233 208 191 192 219 240 + 265 231 216 74 33 216 + 196 203 215 262 248 272 + 96 50 99 37 39 94 + 161 183 146 193 198 204 + 188 208 219 192 202 222 + 227 227 217 231 245 242 + 258 255 241 235 223 214 + 223 237 248 270 277 257 + 267 254 240 254 237 236 + 226 216 204 217 189 183 + 193 205 239 243 196 216 + 220 203 214 227 156 142 + 157 168 182 225 204 166 + 188 244 175 127 142 196 + 132 151 128 117 103 146 + 93 78 109 186 172 186 + 200 239 185 198 217 215 + 206 206 79 90 78 79 + 64 78 60 67 43 34 + 46 16 100000000 13 23 42 + 37 55 71 69 81 54 + 50 42 76 64 88 101 + 172 190 90 65 109 122 + 98 106 124 96 103 110 + 93 128 128 117 110 172 + 163 123 136 155 168 163 + 138 160 170 150 164 173 + 179 211 236 233 208 191 + 192 219 240 265 231 216 + 90 49 232 212 219 231 + 262 248 272 96 50 99 + 37 55 110 177 183 162 + 180 189 195 175 195 206 + 179 189 209 214 223 247 + 261 234 229 245 259 244 + 255 253 244 253 267 278 + 300 264 287 297 284 270 + 284 267 266 256 246 234 + 247 219 213 223 235 269 + 269 226 246 250 233 244 + 257 186 172 187 198 212 + 251 230 190 212 270 205 + 157 172 220 175 175 143 + 160 146 176 136 121 139 + 216 202 216 230 235 202 + 215 209 202 193 220 108 + 120 121 122 107 93 75 + 68 86 80 92 62 46 + 100000000 10 29 24 42 58 + 56 68 41 64 88 87 + 93 75 88 159 177 77 + 52 96 109 85 93 111 + 83 90 97 80 115 115 + 104 97 159 150 110 123 + 142 155 150 125 147 157 + 137 151 160 166 198 223 + 220 195 178 179 206 227 + 252 218 203 105 92 262 + 242 249 261 249 235 259 + 83 37 86 24 101 153 + 207 170 192 170 179 185 + 165 185 196 169 179 199 + 204 213 237 251 224 219 + 235 249 234 245 243 234 + 243 257 268 290 254 277 + 287 274 260 274 257 256 + 246 236 224 237 209 203 + 213 225 259 259 216 236 + 240 223 234 247 176 162 + 177 188 202 241 220 180 + 202 260 195 147 162 210 + 165 165 133 150 136 166 + 126 111 129 206 192 206 + 220 225 192 205 199 192 + 183 210 98 110 111 112 + 97 83 65 58 76 70 + 82 52 36 49 100000000 19 + 14 32 48 46 58 31 + 54 78 77 83 65 78 + 149 167 67 42 86 99 + 75 83 101 73 80 87 + 70 105 105 94 87 149 + 140 100 113 132 145 140 + 115 137 147 127 141 150 + 156 188 213 210 185 168 + 169 196 217 242 208 193 + 95 82 252 232 239 251 + 239 225 249 73 27 76 + 14 91 143 197 160 182 + 210 212 218 205 225 236 + 209 219 239 244 241 231 + 245 259 259 275 269 255 + 249 237 228 237 251 262 + 284 294 271 281 268 254 + 268 251 250 240 230 218 + 231 203 197 207 219 253 + 240 210 230 234 217 228 + 241 170 156 171 182 196 + 222 201 161 183 241 189 + 141 156 191 146 146 114 + 131 117 160 107 92 123 + 200 186 200 214 253 199 + 212 231 232 223 220 96 + 104 92 93 78 64 46 + 39 57 51 63 33 17 + 30 40 100000000 54 53 37 + 67 79 71 67 59 93 + 81 105 118 189 207 107 + 82 126 139 96 104 122 + 89 92 76 59 117 145 + 134 127 167 158 140 153 + 172 185 180 155 168 178 + 167 181 190 196 228 239 + 228 203 186 200 227 254 + 282 248 233 76 63 246 + 226 233 245 279 265 286 + 66 67 116 54 72 124 + 191 200 176 207 216 222 + 202 222 233 206 216 236 + 241 250 249 263 261 256 + 272 286 271 267 255 246 + 255 269 280 302 287 289 + 299 286 272 286 269 268 + 258 248 236 249 221 215 + 225 237 271 258 228 248 + 252 235 246 259 188 174 + 189 200 214 240 219 179 + 201 259 207 159 174 209 + 164 164 132 149 135 178 + 125 110 141 218 204 218 + 232 262 217 230 236 229 + 220 238 114 122 110 111 + 96 82 64 57 75 69 + 81 51 35 48 58 18 + 100000000 18 34 32 44 68 + 85 77 111 99 102 115 + 186 204 104 79 123 136 + 61 69 87 59 66 73 + 56 91 142 131 124 141 + 132 137 150 169 182 177 + 152 142 152 164 178 187 + 193 225 213 202 177 160 + 174 201 228 259 245 230 + 94 81 264 244 251 263 + 276 262 260 59 63 113 + 72 90 142 209 197 194 + 189 198 204 184 204 215 + 188 198 218 223 232 256 + 270 243 238 254 268 253 + 264 262 253 262 276 287 + 309 269 296 306 293 279 + 293 276 275 265 255 243 + 256 228 222 232 244 278 + 282 235 255 259 242 253 + 266 195 181 196 207 221 + 264 243 214 236 283 214 + 166 181 244 189 199 167 + 174 160 185 150 145 148 + 225 211 225 239 244 211 + 224 218 211 202 229 117 + 129 145 146 131 117 99 + 92 110 104 116 86 70 + 83 86 53 53 100000000 16 + 14 26 50 73 109 96 + 102 84 97 168 186 86 + 61 105 118 43 51 69 + 41 48 55 38 73 124 + 113 106 123 114 119 132 + 151 164 159 134 124 134 + 146 160 169 175 207 195 + 184 159 142 156 183 210 + 241 227 212 129 116 271 + 251 258 270 258 244 242 + 41 45 95 100 111 167 + 216 179 201 205 214 220 + 200 220 231 204 214 234 + 239 248 268 282 259 254 + 270 284 269 280 274 265 + 274 288 299 321 276 305 + 318 305 291 305 288 287 + 277 267 255 268 240 234 + 244 256 290 277 247 267 + 271 254 265 278 207 193 + 208 219 233 259 238 198 + 220 278 226 178 193 228 + 183 183 151 168 154 197 + 144 129 160 237 223 237 + 251 260 227 240 234 227 + 218 245 133 141 129 130 + 115 101 83 76 94 88 + 100 70 54 67 77 37 + 69 16 100000000 30 42 66 + 89 96 112 118 100 113 + 184 202 102 77 121 134 + 59 67 85 52 55 39 + 22 80 140 129 122 130 + 121 135 148 167 180 175 + 150 131 141 158 172 181 + 191 223 202 191 166 149 + 163 190 217 248 243 228 + 113 100 283 263 270 282 + 274 260 249 29 61 111 + 91 109 161 228 195 213 + 175 184 190 170 190 201 + 174 184 204 209 218 242 + 256 229 224 240 254 239 + 250 248 239 248 262 273 + 295 255 282 292 279 265 + 279 262 261 251 241 229 + 242 214 208 218 230 264 + 268 221 241 245 228 239 + 252 181 167 182 193 207 + 250 229 209 231 269 200 + 152 167 239 175 194 171 + 160 146 171 136 149 134 + 211 197 211 225 230 197 + 210 204 197 188 215 103 + 115 149 150 135 121 103 + 96 114 108 106 90 74 + 87 72 57 39 33 49 + 100000000 12 36 59 95 82 + 88 70 83 154 172 72 + 47 91 104 29 37 55 + 27 34 50 34 59 110 + 99 92 109 100 105 118 + 137 150 145 120 110 120 + 132 146 155 161 193 181 + 170 145 128 142 169 196 + 227 213 198 133 120 257 + 237 244 256 244 230 228 + 27 31 81 86 97 153 + 202 165 187 163 172 178 + 158 178 189 162 172 192 + 197 206 230 244 217 212 + 228 242 227 238 236 227 + 236 250 261 283 247 270 + 280 267 253 267 250 249 + 239 229 217 230 202 196 + 206 218 252 256 209 229 + 233 216 227 240 169 155 + 170 181 195 238 217 197 + 219 257 188 140 155 227 + 163 182 159 148 134 159 + 124 137 122 199 185 199 + 213 218 185 198 192 185 + 176 203 91 103 137 138 + 123 109 91 84 102 96 + 94 78 62 75 60 45 + 27 21 37 35 100000000 24 + 47 83 70 76 58 71 + 142 160 60 35 79 92 + 17 25 43 53 60 76 + 59 59 98 87 80 109 + 100 93 106 125 138 133 + 108 110 120 120 134 143 + 149 181 181 170 145 128 + 142 169 196 227 201 186 + 121 108 245 225 232 244 + 232 218 228 62 19 69 + 74 85 141 190 153 175 + 139 148 154 134 154 165 + 138 148 168 173 182 206 + 220 193 188 204 218 203 + 214 212 203 212 226 237 + 259 223 246 256 243 229 + 243 226 225 215 205 193 + 206 178 172 182 194 228 + 232 185 205 209 192 203 + 216 145 131 146 157 171 + 214 193 173 195 233 164 + 116 131 203 139 158 137 + 124 110 135 100 126 98 + 175 161 175 189 194 161 + 174 168 161 152 179 67 + 79 118 125 112 119 101 + 94 91 82 70 88 72 + 85 36 55 50 68 84 + 82 94 100000000 23 59 46 + 52 34 47 118 136 36 + 11 55 68 79 87 105 + 109 114 123 106 89 74 + 63 56 118 109 69 82 + 101 114 109 84 106 116 + 96 110 119 125 157 182 + 179 154 137 138 165 186 + 211 177 162 131 97 221 + 201 208 220 208 194 218 + 109 63 45 50 61 117 + 166 129 151 183 192 198 + 178 198 209 182 192 212 + 217 226 250 264 237 232 + 248 262 247 258 256 247 + 256 270 281 303 267 290 + 300 287 273 287 270 269 + 259 249 237 250 222 216 + 226 238 272 272 229 249 + 253 236 247 260 189 175 + 190 201 215 254 233 193 + 215 273 208 160 175 223 + 178 178 146 163 149 179 + 139 124 142 219 205 219 + 233 238 205 218 212 205 + 196 223 111 123 124 125 + 110 96 78 71 89 83 + 95 65 49 62 13 32 + 27 45 61 59 71 44 + 100000000 91 90 96 78 91 + 162 180 80 55 99 112 + 88 96 114 86 93 100 + 83 118 118 107 100 162 + 153 113 126 145 158 153 + 128 150 160 140 154 163 + 169 201 226 223 198 181 + 182 209 230 255 221 206 + 108 95 265 245 252 264 + 252 238 262 86 40 89 + 27 104 156 210 173 195 + 191 200 206 186 206 217 + 190 200 220 225 234 258 + 272 245 240 256 270 255 + 266 264 255 264 278 289 + 311 275 298 308 295 281 + 295 278 277 267 257 245 + 258 230 224 234 246 280 + 280 237 257 261 244 255 + 268 197 183 198 209 223 + 262 241 201 223 281 216 + 168 183 231 186 186 154 + 171 157 187 147 132 150 + 227 213 227 241 246 213 + 226 220 213 204 231 119 + 131 132 133 118 104 86 + 79 97 91 103 73 57 + 70 21 40 35 53 69 + 67 79 52 8 100000000 98 + 104 86 99 170 188 88 + 63 107 120 96 104 122 + 94 101 108 91 126 126 + 115 108 170 161 121 134 + 153 166 161 136 158 168 + 148 162 171 177 209 234 + 231 206 189 190 217 238 + 263 229 214 116 103 273 + 253 260 272 260 246 270 + 94 48 97 35 112 164 + 218 181 203 204 213 219 + 199 219 230 203 213 233 + 238 247 271 285 258 253 + 269 283 268 279 277 268 + 277 291 302 324 288 311 + 321 308 294 308 291 290 + 280 270 258 271 243 237 + 247 259 293 293 250 270 + 274 257 268 281 210 196 + 211 222 236 275 254 214 + 236 294 229 181 196 244 + 199 199 167 184 170 200 + 160 145 163 240 226 240 + 254 259 226 239 233 226 + 217 244 132 144 145 146 + 131 117 99 92 110 104 + 116 86 70 83 34 53 + 48 66 82 80 92 65 + 21 13 100000000 117 99 112 + 183 201 101 76 120 133 + 109 117 135 107 114 121 + 104 139 139 128 121 183 + 174 134 147 166 179 174 + 149 171 181 161 175 184 + 190 222 247 244 219 202 + 203 230 251 276 242 227 + 129 116 286 266 273 285 + 273 259 283 107 61 110 + 48 125 177 231 194 216 + 144 135 141 161 181 192 + 209 197 217 200 164 154 + 168 182 237 221 192 178 + 172 160 151 160 174 185 + 207 218 194 204 191 177 + 191 174 173 163 153 141 + 154 126 120 130 142 176 + 180 133 153 157 140 151 + 164 93 79 94 105 119 + 162 141 121 143 181 112 + 64 79 151 87 106 85 + 72 58 83 48 74 46 + 123 109 123 137 176 122 + 135 154 161 157 143 15 + 27 66 73 60 74 56 + 63 39 30 18 48 100 + 61 64 83 78 96 112 + 110 122 95 51 43 30 + 100000000 129 142 165 183 131 + 106 150 163 139 147 165 + 137 144 151 134 169 169 + 158 151 213 204 164 177 + 190 203 204 179 201 211 + 191 205 214 220 228 253 + 264 249 232 233 260 257 + 246 248 233 86 45 169 + 149 156 168 225 263 279 + 137 91 140 78 9 65 + 114 210 99 151 153 159 + 146 166 177 150 160 180 + 185 182 172 186 200 200 + 216 210 196 190 178 169 + 178 192 203 225 235 212 + 222 209 195 209 192 191 + 181 171 159 172 144 138 + 148 160 194 198 151 171 + 175 158 169 182 111 97 + 112 123 137 180 159 139 + 161 199 130 82 97 169 + 105 124 103 90 76 101 + 66 92 64 141 127 141 + 155 194 140 153 172 173 + 164 161 33 45 84 91 + 78 92 74 81 57 48 + 36 66 82 79 46 65 + 60 78 94 92 104 77 + 33 25 12 18 100000000 59 + 130 148 48 23 67 80 + 91 99 117 119 126 133 + 116 101 86 75 68 130 + 121 81 94 113 126 121 + 96 118 128 108 122 131 + 137 169 194 191 166 149 + 150 177 198 223 189 174 + 104 63 187 167 174 186 + 220 206 230 119 73 57 + 60 27 83 132 141 117 + 171 173 179 166 186 197 + 170 180 200 205 202 192 + 206 220 220 236 230 216 + 210 198 189 198 212 223 + 245 255 232 242 229 215 + 229 212 211 201 191 179 + 192 164 158 168 180 214 + 218 171 191 195 178 189 + 202 131 117 132 143 157 + 200 179 159 181 219 150 + 102 117 189 125 144 123 + 110 96 121 86 112 84 + 161 147 161 175 214 160 + 173 192 193 184 181 53 + 65 104 111 98 112 94 + 101 77 68 56 86 102 + 99 66 85 80 98 114 + 112 124 97 53 45 32 + 38 20 100000000 150 168 68 + 43 87 100 111 119 137 + 139 146 153 136 121 106 + 95 88 150 141 101 114 + 133 146 141 116 138 148 + 128 142 151 157 189 214 + 211 186 169 170 197 218 + 243 209 194 124 83 207 + 187 194 206 240 226 250 + 139 93 77 80 47 103 + 152 161 137 21 30 36 + 16 36 47 64 52 72 + 55 64 106 120 97 92 + 108 122 107 118 112 121 + 125 139 150 172 127 156 + 169 156 142 160 153 142 + 142 132 120 133 105 99 + 109 121 155 180 140 146 + 136 147 158 171 72 86 + 101 112 126 169 148 167 + 189 188 119 106 121 197 + 133 152 131 118 104 125 + 94 120 88 68 56 70 + 89 76 43 56 50 43 + 34 61 61 73 112 119 + 106 120 102 109 85 76 + 64 94 110 107 74 93 + 88 106 122 110 122 68 + 61 53 40 46 28 8 + 100000000 18 37 51 56 69 + 80 88 106 116 115 131 + 144 90 75 64 57 119 + 110 70 70 25 38 48 + 85 107 117 97 111 120 + 64 83 108 119 155 138 + 125 139 112 137 103 88 + 132 91 148 128 135 138 + 112 120 144 137 101 46 + 88 55 111 81 53 66 + 45 54 60 40 60 71 + 59 69 89 79 88 130 + 144 114 109 125 139 124 + 135 136 145 142 156 167 + 189 144 173 186 173 159 + 177 177 159 166 156 144 + 157 129 123 133 145 179 + 204 164 170 160 171 182 + 195 96 110 125 136 150 + 193 172 191 213 212 143 + 130 145 221 157 176 155 + 142 128 149 118 144 112 + 92 80 94 113 100 67 + 80 74 67 58 85 85 + 97 136 143 130 144 126 + 133 109 100 88 118 122 + 131 86 105 100 118 134 + 92 104 50 73 77 64 + 70 52 32 24 100000000 19 + 61 38 51 62 70 88 + 98 97 113 126 72 57 + 46 39 101 92 52 52 + 7 20 30 67 89 99 + 79 93 102 46 78 103 + 114 137 120 120 134 107 + 132 98 83 156 115 172 + 152 159 162 129 115 139 + 119 113 28 100 79 135 + 105 35 90 103 112 118 + 98 118 129 102 112 132 + 137 146 188 202 157 152 + 168 182 167 178 188 194 + 185 199 210 232 187 216 + 229 216 202 220 225 202 + 224 214 202 215 187 181 + 191 203 237 262 216 228 + 218 223 234 247 154 162 + 177 188 202 245 224 204 + 226 264 195 147 162 234 + 170 189 168 155 141 166 + 131 157 129 150 138 152 + 171 158 125 138 132 125 + 116 143 98 110 149 156 + 143 150 132 125 122 113 + 101 119 103 116 67 86 + 81 99 115 73 85 31 + 54 90 77 83 65 78 + 82 100 100000000 42 19 32 + 43 51 69 79 78 94 + 107 53 38 27 20 82 + 73 33 46 65 78 73 + 48 70 80 60 74 83 + 89 121 146 143 118 101 + 102 129 150 175 141 126 + 162 128 230 210 217 207 + 172 158 182 100 94 9 + 81 92 148 163 93 148 + 128 137 143 123 143 154 + 127 137 157 162 171 195 + 209 182 177 193 207 192 + 203 201 192 201 215 226 + 248 212 235 245 232 218 + 232 215 214 204 194 182 + 195 167 161 171 183 217 + 221 174 194 198 181 192 + 205 134 120 135 146 160 + 203 182 162 184 222 153 + 105 120 192 128 147 126 + 113 99 124 89 115 87 + 164 150 164 178 183 150 + 163 157 150 141 168 56 + 68 107 114 101 115 97 + 104 80 71 59 89 105 + 102 69 88 83 101 117 + 98 110 56 56 48 35 + 41 23 36 107 125 25 + 100000000 44 57 68 76 94 + 104 103 119 132 78 63 + 52 45 107 98 58 71 + 90 103 98 73 95 105 + 85 99 108 114 146 171 + 168 143 126 127 154 175 + 200 166 151 127 86 210 + 190 197 209 197 183 207 + 125 96 34 83 50 106 + 155 118 140 151 160 166 + 146 166 177 150 160 180 + 185 194 218 232 205 200 + 216 230 215 226 224 215 + 224 238 249 271 235 258 + 268 255 241 255 238 237 + 227 217 205 218 190 184 + 194 206 240 244 197 217 + 221 204 215 228 157 143 + 158 169 183 226 205 185 + 207 245 176 128 143 215 + 151 170 149 136 122 147 + 112 138 110 187 173 187 + 201 206 173 186 180 173 + 164 191 79 91 130 137 + 124 131 113 106 103 94 + 82 100 84 97 48 67 + 62 80 96 54 66 12 + 35 71 58 64 46 59 + 130 148 48 23 100000000 13 + 24 32 50 60 67 83 + 88 66 86 75 68 116 + 107 81 94 113 126 121 + 96 117 127 108 122 131 + 137 169 188 177 152 135 + 149 176 198 223 189 174 + 143 109 233 213 220 232 + 220 206 230 81 75 57 + 62 73 129 178 141 163 + 188 197 203 183 203 214 + 187 197 217 222 231 273 + 287 242 237 253 267 252 + 263 273 279 270 284 287 + 309 249 278 291 301 287 + 305 303 287 292 282 270 + 283 255 249 259 271 305 + 309 262 282 286 269 280 + 293 222 208 223 234 248 + 291 270 250 272 310 241 + 193 208 280 216 235 212 + 201 187 212 177 190 175 + 235 223 237 256 243 210 + 223 217 210 201 228 144 + 156 190 191 176 162 144 + 137 155 149 147 131 115 + 128 113 98 80 74 90 + 41 53 77 100 136 123 + 129 111 124 167 185 113 + 88 132 100000000 11 19 37 + 47 54 70 75 53 145 + 134 133 103 94 118 131 + 150 163 158 133 104 114 + 131 145 154 174 200 175 + 164 139 122 136 163 190 + 221 226 211 174 161 298 + 278 285 292 257 237 222 + 68 72 122 127 138 194 + 243 178 228 177 186 192 + 172 192 203 176 186 206 + 211 220 262 276 231 226 + 242 256 241 252 262 268 + 259 273 276 298 238 267 + 280 290 276 294 292 276 + 281 271 259 272 244 238 + 248 260 294 298 251 271 + 275 258 269 282 211 197 + 212 223 237 280 259 239 + 261 299 230 182 197 269 + 205 224 201 190 176 201 + 166 179 164 224 212 226 + 245 232 199 212 206 199 + 190 217 133 145 179 180 + 165 151 133 126 144 138 + 136 120 104 117 102 87 + 69 63 79 30 42 66 + 89 125 112 118 100 113 + 156 174 102 77 121 134 + 100000000 8 26 36 43 59 + 64 42 134 123 122 92 + 83 107 120 139 152 147 + 122 93 103 120 134 143 + 163 189 164 153 128 111 + 125 152 179 210 215 200 + 163 150 287 267 274 281 + 246 226 211 57 61 111 + 116 127 183 232 167 217 + 169 178 184 164 184 195 + 168 178 198 203 212 254 + 268 223 218 234 248 233 + 244 254 260 251 265 268 + 290 230 259 272 282 268 + 286 284 268 273 263 251 + 264 236 230 240 252 286 + 290 243 263 267 250 261 + 274 203 189 204 215 229 + 272 251 231 253 291 222 + 174 189 261 197 216 193 + 182 168 193 158 171 156 + 216 204 218 237 224 191 + 204 198 191 182 209 125 + 137 171 172 157 143 125 + 118 136 130 128 112 96 + 109 94 79 61 55 71 + 22 34 58 81 117 104 + 110 92 105 148 166 94 + 69 113 126 51 100000000 18 + 28 35 51 56 34 126 + 115 114 84 75 99 112 + 131 144 139 114 85 95 + 112 126 135 155 181 156 + 145 120 103 117 144 171 + 202 207 192 155 142 279 + 259 266 273 238 218 203 + 49 53 103 108 119 175 + 224 159 209 151 160 166 + 146 166 177 150 160 180 + 185 194 236 250 205 200 + 216 230 215 226 236 242 + 233 247 250 272 212 241 + 254 264 250 268 273 250 + 272 262 250 263 235 229 + 239 251 285 305 258 276 + 266 265 276 289 202 204 + 219 230 244 287 266 246 + 268 306 237 189 204 276 + 212 231 208 197 183 208 + 173 186 171 198 186 200 + 219 206 173 186 180 173 + 164 191 140 152 186 187 + 172 158 140 133 151 145 + 143 127 111 124 109 94 + 76 70 72 37 49 73 + 96 132 119 125 107 120 + 130 148 109 84 128 141 + 66 74 100000000 10 17 33 + 50 16 108 97 129 66 + 57 81 94 113 126 121 + 96 67 77 94 108 117 + 137 163 138 127 102 85 + 99 126 153 184 189 174 + 170 157 278 258 265 255 + 220 200 185 57 68 118 + 123 134 190 211 141 196 + 167 176 182 162 182 193 + 166 176 196 201 210 252 + 266 221 216 232 246 231 + 242 252 258 249 263 266 + 288 228 257 270 280 266 + 284 289 266 278 268 256 + 269 241 235 245 257 291 + 295 248 268 272 255 266 + 279 208 194 209 220 234 + 277 256 236 258 296 227 + 179 194 266 202 221 198 + 187 173 198 163 176 161 + 214 202 216 235 222 189 + 202 196 189 180 207 130 + 142 176 177 162 148 130 + 123 141 135 133 117 101 + 114 99 84 66 60 62 + 27 39 63 86 122 109 + 115 97 110 146 164 99 + 74 118 131 56 64 82 + 100000000 7 23 40 32 124 + 113 119 82 73 97 110 + 129 142 137 112 83 93 + 110 124 133 153 179 154 + 143 118 101 115 142 169 + 200 205 190 160 147 284 + 264 271 271 236 216 201 + 47 58 108 113 124 180 + 227 157 212 160 169 175 + 155 175 186 159 169 189 + 194 203 245 259 214 209 + 225 239 224 235 245 251 + 242 256 259 281 221 250 + 263 273 259 277 282 259 + 281 271 259 272 244 238 + 248 260 294 302 255 275 + 275 262 273 286 211 201 + 216 227 241 284 263 243 + 265 303 234 186 201 273 + 209 228 205 194 180 205 + 170 183 168 207 195 209 + 228 215 182 195 189 182 + 173 200 137 149 183 184 + 169 155 137 130 148 142 + 140 124 108 121 106 91 + 73 67 55 34 46 70 + 93 129 116 122 104 117 + 139 157 106 81 125 138 + 63 71 89 7 100000000 16 + 33 25 117 106 126 75 + 66 90 103 122 135 130 + 105 76 86 103 117 126 + 146 172 147 136 111 94 + 108 135 162 193 198 183 + 167 154 287 267 274 264 + 229 209 194 40 65 115 + 120 131 187 220 150 205 + 176 185 191 171 191 202 + 175 185 205 210 219 261 + 275 230 225 241 255 240 + 251 261 267 258 272 275 + 297 237 266 279 289 275 + 293 298 275 297 287 275 + 288 260 254 264 276 310 + 316 271 291 291 278 289 + 302 227 217 232 243 257 + 298 277 237 259 317 250 + 202 217 267 222 222 190 + 207 193 221 183 168 184 + 223 211 225 244 231 198 + 211 205 198 189 216 153 + 165 168 169 154 140 122 + 115 133 127 139 109 93 + 106 116 76 89 55 39 + 50 62 86 109 135 132 + 138 120 133 155 173 122 + 97 141 154 79 87 105 + 23 16 100000000 17 41 133 + 122 142 91 82 106 119 + 138 151 146 121 92 102 + 119 133 142 162 188 163 + 152 127 110 124 151 178 + 209 214 199 152 139 303 + 283 290 280 245 225 210 + 24 81 131 130 147 200 + 236 166 221 193 202 208 + 188 208 219 192 202 222 + 227 236 276 290 247 242 + 258 272 257 268 278 273 + 275 289 292 314 254 283 + 296 306 292 310 296 292 + 285 275 263 276 248 242 + 252 264 298 299 255 275 + 279 262 273 286 215 201 + 216 227 241 281 260 220 + 242 300 234 186 201 250 + 205 205 173 190 176 205 + 166 151 168 240 228 242 + 259 248 215 228 222 215 + 206 233 137 149 151 152 + 137 123 105 98 116 110 + 122 92 76 89 99 59 + 73 38 22 34 46 70 + 93 118 116 122 104 117 + 172 190 106 81 125 138 + 63 71 89 30 33 17 + 100000000 58 144 133 126 108 + 99 123 136 155 168 163 + 138 109 119 136 150 159 + 179 205 180 169 144 127 + 141 168 195 226 231 216 + 135 122 291 271 278 290 + 262 242 227 7 65 115 + 113 131 183 236 183 221 + 135 144 150 130 150 161 + 134 144 164 169 178 220 + 234 189 184 200 214 199 + 210 220 226 217 231 234 + 256 196 225 238 248 234 + 252 257 234 256 246 234 + 247 219 213 223 235 269 + 294 254 260 250 261 272 + 285 186 200 215 226 240 + 283 262 268 290 302 233 + 211 226 298 234 253 230 + 219 205 230 195 208 193 + 182 170 184 203 190 157 + 170 164 157 148 175 162 + 174 208 209 194 180 162 + 155 173 167 165 149 133 + 146 131 116 98 92 80 + 59 71 95 118 154 141 + 147 129 122 114 132 93 + 106 112 125 88 96 114 + 32 25 41 58 100000000 92 + 81 113 50 41 65 78 + 97 110 105 80 51 61 + 78 92 101 121 147 122 + 111 86 69 83 110 137 + 168 173 158 192 179 262 + 242 249 239 204 184 169 + 65 90 102 145 156 212 + 195 125 180 129 138 144 + 124 144 155 128 138 158 + 163 172 214 228 183 178 + 194 208 193 204 214 220 + 211 225 228 250 190 219 + 232 242 228 246 251 228 + 250 240 228 241 213 207 + 217 229 263 288 248 254 + 244 255 266 279 180 194 + 209 220 234 277 256 248 + 270 296 227 191 206 278 + 214 233 210 199 185 210 + 175 188 173 176 164 178 + 197 184 151 164 158 151 + 142 169 142 154 188 189 + 174 160 142 135 153 147 + 145 129 113 126 111 96 + 78 72 88 39 51 75 + 98 134 121 127 109 116 + 108 126 87 86 106 119 + 68 17 35 45 40 56 + 73 15 100000000 75 107 44 + 35 59 72 91 104 99 + 74 45 55 72 86 95 + 115 141 116 105 80 63 + 77 104 131 162 167 152 + 172 159 256 236 243 233 + 198 178 163 66 70 96 + 125 136 192 189 119 174 + 140 149 155 135 155 166 + 139 149 169 174 183 225 + 239 194 189 205 219 204 + 215 225 231 222 236 239 + 261 201 230 243 253 239 + 257 262 239 261 251 239 + 252 224 218 228 240 274 + 299 259 265 255 266 277 + 290 191 205 220 231 245 + 288 267 259 281 307 238 + 202 217 289 225 244 221 + 210 196 221 186 199 184 + 187 175 189 208 195 162 + 175 169 162 153 180 153 + 165 199 200 185 171 153 + 146 164 158 156 140 124 + 137 122 107 89 83 99 + 50 62 86 109 145 132 + 138 120 127 119 137 98 + 97 117 130 79 28 46 + 56 51 67 84 26 11 + 100000000 118 55 46 70 83 + 102 115 110 85 56 66 + 83 97 106 126 152 127 + 116 91 74 88 115 142 + 173 178 163 183 170 267 + 247 254 244 209 189 174 + 77 81 107 136 147 203 + 200 130 185 147 156 162 + 142 162 173 146 156 176 + 181 190 232 246 201 196 + 212 226 211 222 232 238 + 229 243 246 268 208 237 + 250 260 246 264 269 246 + 268 258 246 259 231 225 + 235 247 281 306 266 272 + 262 273 284 297 198 212 + 227 238 252 295 274 264 + 286 314 245 207 222 294 + 230 249 226 215 201 226 + 191 204 189 194 182 196 + 215 202 169 182 176 169 + 160 187 158 170 204 205 + 190 176 158 151 169 163 + 161 145 129 142 127 112 + 94 88 104 55 67 91 + 114 150 137 143 125 134 + 126 144 105 102 124 14 + 25 33 51 61 58 74 + 89 33 18 7 100000000 62 + 53 77 90 109 122 117 + 92 63 73 90 104 113 + 133 159 134 123 98 81 + 95 122 149 180 185 170 + 188 175 274 254 261 251 + 216 196 181 82 86 114 + 141 152 208 207 137 192 + 85 94 100 80 100 111 + 84 94 114 119 128 170 + 184 139 134 150 164 149 + 160 170 176 167 181 192 + 214 169 198 211 198 184 + 202 207 184 206 196 184 + 197 169 163 173 185 219 + 244 204 210 200 211 222 + 235 136 150 165 176 190 + 233 212 231 253 252 183 + 170 185 261 197 216 195 + 182 168 189 158 184 152 + 132 120 134 153 140 107 + 120 114 107 98 125 125 + 137 176 183 170 184 166 + 168 149 140 128 158 146 + 159 110 129 120 114 130 + 81 93 74 97 117 104 + 110 92 72 64 82 43 + 85 62 75 86 59 77 + 87 82 98 115 57 42 + 31 63 100000000 62 15 28 + 47 60 55 30 52 62 + 42 56 65 71 103 128 + 132 107 90 84 111 132 + 157 123 108 196 155 212 + 192 199 189 154 140 164 + 108 112 52 124 119 175 + 145 75 130 94 103 109 + 89 109 120 93 103 123 + 128 137 179 193 148 143 + 159 173 158 169 179 185 + 176 190 193 215 155 184 + 197 207 193 211 216 193 + 215 205 193 206 178 172 + 182 194 228 253 213 219 + 209 220 231 244 145 159 + 174 185 199 242 221 240 + 262 261 192 179 194 270 + 206 225 204 191 177 198 + 167 193 161 141 129 143 + 162 149 116 129 123 116 + 107 134 134 146 185 192 + 179 193 175 177 158 149 + 137 167 155 168 119 138 + 129 123 121 90 102 83 + 106 126 113 119 101 81 + 73 91 52 94 71 84 + 95 68 86 73 66 82 + 99 41 51 40 72 9 + 100000000 24 37 56 69 64 + 39 10 20 37 51 60 + 80 106 81 70 45 28 + 42 69 96 127 132 117 + 205 164 221 201 208 198 + 163 143 128 106 121 61 + 133 128 184 154 84 139 + 70 79 85 65 85 96 + 69 79 99 104 113 155 + 169 124 119 135 149 134 + 145 155 161 152 166 177 + 199 154 183 196 183 169 + 187 192 169 191 181 169 + 182 154 148 158 170 204 + 229 189 195 185 196 207 + 220 121 135 150 161 175 + 218 197 216 238 237 168 + 155 170 246 182 201 180 + 167 153 174 143 169 137 + 117 105 119 138 125 92 + 105 99 92 83 110 110 + 122 161 168 155 169 151 + 153 134 125 113 143 131 + 144 95 114 109 127 143 + 101 113 59 82 102 89 + 95 77 57 49 67 28 + 70 47 60 71 79 97 + 107 106 122 135 81 66 + 55 48 56 47 100000000 13 + 32 45 40 15 37 47 + 27 41 50 56 88 113 + 117 92 75 69 96 117 + 142 108 93 181 140 197 + 177 184 174 139 125 149 + 128 122 37 109 104 160 + 130 60 115 57 66 72 + 52 72 83 71 81 101 + 91 100 142 156 126 121 + 137 151 136 147 148 157 + 154 168 179 201 156 185 + 198 185 171 189 189 171 + 178 168 156 169 141 135 + 145 157 191 216 176 182 + 172 183 194 207 108 122 + 137 148 162 205 184 203 + 225 224 155 142 157 233 + 169 188 167 154 140 161 + 130 156 124 104 92 106 + 125 112 79 92 86 79 + 70 97 97 109 148 155 + 142 156 138 140 121 112 + 100 130 118 131 82 101 + 96 114 130 88 100 46 + 69 89 76 82 64 44 + 36 54 15 57 34 47 + 58 66 84 94 93 109 + 122 68 53 42 35 97 + 88 48 100000000 19 32 42 + 63 85 95 75 89 98 + 58 90 115 126 133 116 + 117 144 119 144 110 95 + 168 127 184 164 171 174 + 141 127 151 115 109 24 + 96 91 147 117 47 102 + 38 47 53 33 53 64 + 52 62 82 72 81 123 + 137 107 102 118 132 117 + 128 129 138 135 149 160 + 182 137 166 179 166 152 + 170 170 152 159 149 137 + 150 122 116 126 138 172 + 197 157 163 153 164 175 + 188 89 103 118 129 143 + 186 165 184 206 205 136 + 123 138 214 150 169 148 + 135 121 142 111 137 105 + 85 73 87 106 93 60 + 73 67 60 51 78 78 + 90 129 136 123 137 119 + 126 102 93 81 111 127 + 124 91 110 105 123 139 + 127 139 85 78 70 57 + 63 45 25 17 35 54 + 68 73 86 97 105 123 + 133 132 148 161 107 92 + 81 74 136 127 87 45 + 100000000 13 23 102 124 134 + 114 128 119 39 71 96 + 107 172 155 113 127 100 + 125 91 76 149 108 165 + 145 152 155 122 108 132 + 154 118 63 105 72 128 + 98 28 83 44 53 59 + 39 59 70 39 49 69 + 78 87 129 143 94 89 + 105 119 104 115 125 131 + 122 136 147 169 124 153 + 166 153 139 157 162 139 + 165 155 143 156 128 122 + 132 144 178 203 163 169 + 159 170 181 194 95 109 + 124 135 149 192 171 190 + 212 211 142 129 144 220 + 156 175 154 141 127 148 + 117 143 111 91 79 93 + 112 99 66 79 73 66 + 57 84 84 96 135 142 + 129 143 125 132 108 99 + 87 117 133 130 97 116 + 111 129 145 120 132 78 + 84 76 63 69 51 31 + 23 41 47 74 66 79 + 90 98 116 126 125 141 + 154 100 85 74 67 129 + 120 80 32 48 100000000 10 + 95 117 122 107 121 106 + 26 58 83 94 165 148 + 100 114 87 112 78 63 + 155 114 171 151 158 144 + 109 95 119 147 124 56 + 111 78 134 104 15 89 + 79 88 94 74 94 105 + 29 39 59 75 84 148 + 162 84 79 95 109 94 + 105 115 121 112 126 137 + 159 114 143 156 143 129 + 147 152 129 163 184 178 + 147 146 157 167 179 193 + 218 198 204 194 205 216 + 229 130 144 159 170 184 + 227 206 225 247 246 177 + 164 179 255 191 210 189 + 176 162 183 152 178 146 + 126 114 112 131 96 101 + 114 108 101 92 119 119 + 131 170 177 164 178 160 + 162 143 134 122 152 140 + 153 104 123 118 136 152 + 110 122 68 91 111 98 + 104 86 66 58 76 37 + 79 56 69 80 88 106 + 116 115 131 144 90 75 + 64 57 119 110 70 22 + 41 54 100000000 85 107 112 + 97 111 96 16 48 73 + 84 155 138 90 104 77 + 102 68 53 190 149 205 + 186 164 134 99 85 109 + 137 131 46 118 113 169 + 139 69 124 104 113 119 + 99 119 130 54 64 84 + 100 109 173 187 109 104 + 120 134 119 130 140 146 + 137 151 162 184 139 168 + 181 168 154 172 177 154 + 188 209 203 172 171 182 + 192 204 218 243 223 229 + 219 230 241 254 155 169 + 184 195 209 252 231 250 + 272 271 202 189 204 280 + 216 235 214 201 187 208 + 177 203 171 151 139 137 + 156 121 126 139 133 126 + 117 144 144 156 195 202 + 189 203 185 187 168 159 + 147 177 165 178 129 148 + 143 155 153 122 134 93 + 116 136 123 129 111 91 + 83 101 62 104 81 94 + 105 100 118 105 98 114 + 131 73 83 72 82 41 + 32 56 47 66 79 25 + 100000000 22 32 12 26 35 + 41 73 98 102 77 60 + 54 81 102 127 93 78 + 215 174 230 211 189 159 + 124 110 134 138 153 71 + 143 138 194 164 94 149 + 104 113 119 99 119 130 + 93 103 123 138 147 189 + 203 148 143 159 173 158 + 169 179 185 176 190 183 + 205 145 174 187 200 193 + 211 216 193 225 215 203 + 211 188 182 192 204 238 + 263 223 229 219 230 241 + 254 155 169 184 195 209 + 252 231 250 272 271 202 + 189 204 280 216 235 214 + 201 187 208 177 203 171 + 151 139 153 172 159 126 + 139 133 126 117 144 144 + 156 195 202 189 203 185 + 187 168 159 147 177 165 + 178 129 148 139 133 131 + 100 112 93 116 136 123 + 129 111 91 83 101 62 + 104 81 94 105 78 96 + 83 76 92 109 51 61 + 50 82 19 10 34 47 + 66 79 64 39 100000000 10 + 27 41 50 75 112 91 + 80 55 38 32 59 86 + 117 132 117 215 174 231 + 211 218 198 163 133 118 + 116 131 71 143 138 194 + 164 94 149 114 123 129 + 109 129 140 83 93 113 + 129 138 199 213 138 133 + 149 163 148 159 169 175 + 166 180 173 195 135 164 + 177 190 183 201 206 183 + 217 225 213 201 198 192 + 202 214 247 272 233 239 + 229 240 251 264 165 179 + 194 205 219 262 241 260 + 282 281 212 199 214 290 + 226 245 224 211 197 218 + 187 213 181 161 149 163 + 182 150 136 149 143 136 + 127 154 154 166 205 212 + 199 213 195 197 178 169 + 157 187 175 188 139 158 + 149 143 141 110 122 103 + 126 146 133 139 121 101 + 93 111 72 114 91 104 + 115 88 106 93 86 102 + 119 61 71 60 92 29 + 20 44 57 76 89 54 + 29 10 100000000 17 31 40 + 65 102 89 78 65 48 + 22 49 76 107 122 107 + 225 184 241 221 218 188 + 153 123 108 126 141 81 + 153 148 204 174 104 159 + 116 125 131 111 131 142 + 66 76 96 112 121 185 + 199 121 116 132 146 131 + 142 152 158 149 163 174 + 196 151 180 193 180 166 + 184 189 166 200 221 215 + 184 183 194 204 216 230 + 255 235 241 231 242 253 + 266 167 181 196 207 221 + 264 243 262 284 283 214 + 201 216 292 228 247 226 + 213 199 220 189 215 183 + 163 151 149 168 133 138 + 151 145 138 129 156 156 + 168 207 214 201 215 197 + 199 180 171 159 189 177 + 190 141 160 155 167 165 + 134 146 105 128 148 135 + 141 123 103 95 113 74 + 116 93 106 117 112 130 + 117 110 126 143 85 95 + 84 94 53 44 68 59 + 78 91 37 12 34 44 + 100000000 14 23 48 85 110 + 114 89 72 66 93 114 + 139 105 90 227 186 242 + 223 201 171 136 122 146 + 150 165 83 155 150 206 + 176 106 161 129 129 123 + 124 128 139 56 66 86 + 102 111 175 189 111 106 + 122 136 121 132 142 148 + 139 153 164 186 141 170 + 183 170 156 174 179 156 + 190 211 214 174 173 193 + 203 215 220 245 239 240 + 230 241 252 265 171 185 + 200 211 225 268 247 275 + 297 287 218 205 220 305 + 241 260 239 226 212 224 + 202 228 187 167 155 139 + 158 123 142 155 158 151 + 142 163 169 181 220 227 + 214 228 210 212 193 184 + 172 202 190 203 154 173 + 168 186 202 160 172 118 + 141 161 148 154 136 116 + 108 126 87 129 106 119 + 130 138 156 166 165 181 + 194 140 125 114 107 168 + 159 120 72 91 104 50 + 135 149 139 147 100000000 9 + 34 75 100 111 204 187 + 117 131 104 129 95 80 + 240 199 232 221 191 161 + 126 112 136 187 181 96 + 168 163 219 180 119 165 + 120 120 114 115 119 130 + 47 57 77 93 102 166 + 180 102 97 113 127 112 + 123 133 139 130 144 155 + 177 132 161 174 161 147 + 165 170 147 181 202 205 + 165 164 184 194 206 211 + 236 230 231 221 232 243 + 256 162 176 191 202 216 + 259 238 266 288 278 209 + 196 211 296 232 251 230 + 217 203 215 193 219 178 + 158 146 130 149 114 133 + 146 149 142 133 154 160 + 172 211 218 205 219 201 + 203 184 175 163 193 181 + 194 145 164 159 177 193 + 151 163 109 132 152 139 + 145 127 107 99 117 78 + 120 97 110 121 129 147 + 157 156 172 185 131 116 + 105 98 159 150 111 63 + 82 95 41 126 140 130 + 138 152 100000000 25 66 91 + 102 195 178 108 122 95 + 120 86 71 231 190 223 + 212 182 152 117 103 127 + 178 172 87 159 154 210 + 171 110 156 95 95 89 + 90 94 105 22 32 52 + 68 77 141 155 77 72 + 88 102 87 98 108 114 + 105 119 130 152 107 136 + 149 136 122 140 145 122 + 156 177 180 140 139 159 + 169 181 186 211 205 206 + 196 207 218 231 137 151 + 166 177 191 234 213 241 + 263 253 184 171 186 271 + 207 226 205 192 178 190 + 168 194 153 133 121 105 + 124 89 108 121 124 117 + 108 129 135 147 186 193 + 180 194 176 178 159 150 + 138 168 156 169 120 139 + 134 152 168 126 138 84 + 107 127 114 120 102 82 + 74 92 53 95 72 85 + 96 104 122 132 131 147 + 160 106 91 80 73 134 + 125 86 38 57 70 16 + 101 115 105 113 127 89 + 100000000 41 66 77 170 153 + 83 97 70 95 61 46 + 206 165 198 187 157 127 + 92 78 102 153 147 62 + 134 129 185 146 85 131 + 113 113 107 108 112 123 + 40 50 70 86 95 146 + 160 56 51 67 81 66 + 77 87 93 84 98 109 + 131 86 115 128 115 101 + 119 124 101 135 156 159 + 119 118 138 148 160 165 + 190 202 185 175 186 197 + 210 151 165 180 191 205 + 231 210 250 263 250 198 + 189 204 271 225 244 223 + 210 196 208 186 212 171 + 151 139 123 129 107 126 + 139 142 135 126 147 153 + 165 204 211 198 212 194 + 196 177 168 156 186 174 + 187 138 157 152 170 186 + 144 156 102 125 145 132 + 138 120 100 92 110 71 + 113 90 103 114 122 140 + 150 149 165 178 124 109 + 98 91 93 84 104 56 + 75 88 34 93 74 64 + 81 95 48 18 100000000 25 + 36 129 112 42 56 29 + 60 29 14 224 183 177 + 166 136 106 71 46 61 + 171 165 80 152 147 203 + 164 103 149 138 138 132 + 133 137 148 65 75 95 + 111 120 171 185 81 76 + 92 106 91 102 112 118 + 109 123 134 156 111 140 + 153 140 126 144 149 126 + 160 181 184 144 143 163 + 173 185 190 215 227 210 + 200 211 222 235 176 190 + 205 216 230 256 235 275 + 288 275 223 214 229 296 + 250 269 248 235 221 233 + 211 237 196 176 164 148 + 154 132 151 164 167 160 + 151 172 178 190 229 236 + 223 237 219 221 202 193 + 181 211 199 212 163 182 + 177 182 180 149 161 127 + 150 170 157 163 145 125 + 117 135 96 138 115 128 + 139 127 145 132 125 141 + 158 100 110 99 116 68 + 59 83 81 100 113 59 + 68 49 39 56 70 23 + 43 25 100000000 11 104 87 + 17 44 54 85 54 39 + 249 208 202 191 161 131 + 96 71 86 165 180 105 + 177 172 228 189 128 174 + 132 132 126 127 131 142 + 59 69 89 105 114 178 + 192 92 87 103 117 102 + 113 123 129 120 134 145 + 167 122 151 164 151 137 + 155 160 137 171 192 195 + 155 154 174 184 196 201 + 226 238 221 211 222 233 + 246 174 188 203 214 228 + 267 246 278 299 286 221 + 208 223 307 244 263 242 + 229 215 227 205 231 190 + 170 158 142 161 126 145 + 158 161 154 145 166 172 + 184 223 230 217 231 213 + 215 196 187 175 205 193 + 206 157 176 171 189 191 + 160 172 121 144 164 151 + 157 139 119 111 129 90 + 132 109 122 133 138 156 + 143 136 152 169 111 121 + 110 110 79 70 94 75 + 94 107 53 79 60 50 + 67 81 12 37 36 11 + 100000000 115 98 28 55 65 + 96 65 50 243 202 213 + 202 172 142 107 82 97 + 176 184 99 171 166 222 + 183 122 168 157 157 151 + 152 156 167 84 94 114 + 130 139 203 217 117 112 + 128 142 127 138 148 154 + 145 159 170 192 147 176 + 189 176 162 180 185 162 + 196 217 220 180 179 199 + 209 221 226 251 263 246 + 236 247 258 271 199 213 + 228 239 253 292 271 303 + 324 311 246 233 248 332 + 269 288 267 254 240 252 + 230 256 215 195 183 167 + 186 151 170 183 186 179 + 170 191 197 209 248 255 + 242 256 238 240 221 212 + 200 230 218 231 182 201 + 196 214 216 185 197 146 + 169 189 176 182 164 144 + 136 154 115 157 134 147 + 158 163 181 168 161 177 + 194 136 146 135 135 104 + 95 119 100 119 132 78 + 104 85 75 92 106 37 + 62 61 36 25 100000000 123 + 53 80 90 121 90 75 + 268 227 238 227 197 167 + 132 107 122 201 209 124 + 196 191 247 208 147 193 + 174 174 168 169 173 184 + 101 111 131 147 156 220 + 234 134 129 145 159 144 + 155 165 171 162 176 187 + 209 164 193 206 193 179 + 197 202 179 213 234 237 + 197 196 216 226 238 243 + 268 280 263 253 264 275 + 288 216 230 245 256 270 + 309 288 320 341 328 263 + 250 265 349 286 305 284 + 271 257 269 247 273 232 + 212 200 184 203 168 187 + 200 203 196 187 208 214 + 226 265 272 259 273 255 + 257 238 229 217 247 235 + 248 199 218 213 231 233 + 202 214 163 186 206 193 + 199 181 161 153 171 132 + 174 151 164 175 180 198 + 185 178 194 211 153 163 + 152 152 121 112 136 117 + 136 149 95 121 102 92 + 109 123 54 79 78 53 + 42 17 100000000 70 97 107 + 138 107 92 285 244 255 + 244 214 184 149 124 139 + 218 226 141 213 208 264 + 225 164 210 136 145 151 + 131 151 162 105 115 135 + 151 160 221 235 143 138 + 154 168 153 164 174 180 + 171 162 151 173 113 142 + 155 168 182 183 200 188 + 211 232 235 206 205 214 + 224 236 241 266 255 261 + 251 262 273 286 187 201 + 216 227 241 284 263 282 + 304 303 234 221 236 312 + 248 267 246 233 219 240 + 209 235 203 183 171 185 + 204 172 158 171 165 158 + 149 176 176 188 227 234 + 221 235 217 219 200 191 + 179 209 197 210 161 180 + 171 165 163 132 144 125 + 148 168 155 161 143 123 + 115 133 94 136 113 126 + 137 110 128 115 108 124 + 141 83 93 82 114 51 + 42 66 79 98 111 76 + 51 32 22 39 53 62 + 87 92 67 56 87 70 + 100000000 27 54 85 116 101 + 247 206 253 242 223 193 + 158 101 86 148 163 103 + 175 170 226 196 126 181 + 161 161 155 156 160 171 + 88 98 118 134 143 206 + 220 116 111 127 141 126 + 137 147 153 144 135 124 + 146 86 115 128 141 155 + 156 173 161 184 205 217 + 179 178 198 208 220 214 + 239 262 245 235 246 257 + 270 203 217 232 243 257 + 291 270 307 323 310 250 + 237 252 331 273 292 271 + 258 244 256 234 260 219 + 199 187 171 189 155 174 + 187 190 183 174 195 201 + 213 252 259 246 260 242 + 244 225 216 204 234 222 + 235 186 205 198 192 190 + 159 171 150 173 193 180 + 186 168 148 140 158 119 + 161 138 151 162 137 155 + 142 135 151 168 110 120 + 109 139 78 69 93 104 + 123 136 82 78 59 49 + 66 80 41 66 65 40 + 29 114 97 27 100000000 27 + 58 89 74 272 231 226 + 215 196 166 131 74 59 + 175 190 128 200 195 251 + 212 151 197 155 146 140 + 160 145 156 101 83 103 + 119 128 179 193 89 84 + 100 114 99 110 120 126 + 117 108 97 119 59 88 + 101 114 128 129 146 134 + 157 178 190 152 151 171 + 181 193 187 212 235 218 + 208 219 230 243 184 198 + 213 224 238 264 243 283 + 296 283 231 222 237 304 + 271 290 269 256 254 241 + 247 273 204 184 172 156 + 162 140 159 172 184 177 + 168 180 214 226 265 272 + 259 273 255 257 238 229 + 217 247 235 248 199 218 + 213 219 217 186 198 163 + 186 206 193 199 181 161 + 153 171 132 174 151 164 + 175 164 182 169 162 178 + 195 137 147 136 152 105 + 96 120 117 136 149 95 + 105 86 76 93 107 68 + 79 61 67 56 141 124 + 54 27 100000000 31 62 47 + 285 244 199 188 169 139 + 104 47 32 202 217 141 + 213 208 261 197 164 182 + 127 118 112 132 117 128 + 102 55 75 91 100 151 + 165 61 56 72 86 71 + 82 92 98 89 77 66 + 88 28 57 70 83 97 + 98 115 106 126 147 159 + 124 123 143 153 164 156 + 181 206 189 179 190 201 + 214 156 170 185 196 210 + 235 214 254 267 254 203 + 194 209 275 243 262 241 + 228 226 213 236 249 176 + 156 144 128 134 112 131 + 144 156 149 140 152 209 + 221 254 261 254 268 250 + 257 233 224 212 242 236 + 249 200 219 214 232 248 + 206 218 164 187 201 188 + 194 176 156 148 166 133 + 175 152 165 176 184 202 + 200 193 209 226 168 171 + 160 153 136 127 151 118 + 137 145 96 136 117 107 + 124 138 99 80 62 87 + 87 172 155 85 58 31 + 100000000 34 48 280 239 168 + 157 141 111 76 17 33 + 233 227 142 214 203 233 + 169 146 154 93 84 78 + 98 83 94 69 21 41 + 57 66 117 131 27 22 + 38 52 37 48 58 64 + 55 69 80 102 57 86 + 99 86 72 90 95 72 + 106 127 130 90 89 109 + 119 131 136 161 173 156 + 146 157 168 181 122 136 + 151 162 176 202 181 221 + 234 221 169 160 175 242 + 209 228 207 194 192 179 + 202 215 142 122 110 94 + 100 78 97 110 122 115 + 106 118 175 187 220 227 + 220 234 216 223 199 190 + 178 208 203 216 167 186 + 181 199 215 173 185 131 + 154 167 154 160 142 122 + 114 132 100 142 119 132 + 143 151 169 179 178 194 + 207 153 138 127 120 122 + 113 133 85 104 111 63 + 122 103 93 110 124 77 + 47 29 54 65 158 141 + 71 85 58 34 100000000 15 + 246 205 148 137 107 77 + 42 17 67 200 194 109 + 181 169 199 135 112 120 + 108 99 93 113 98 109 + 54 36 56 72 81 132 + 146 42 37 53 67 52 + 63 73 79 70 84 95 + 117 72 101 114 101 87 + 105 110 87 121 142 145 + 105 104 124 134 146 151 + 176 188 171 161 172 183 + 196 137 151 166 177 191 + 217 196 236 249 236 184 + 175 190 257 224 243 222 + 209 207 194 200 226 157 + 137 125 109 115 93 112 + 125 137 130 121 133 167 + 179 218 225 212 226 208 + 210 191 182 170 200 188 + 201 152 171 166 184 200 + 158 170 116 139 159 146 + 152 134 114 106 124 85 + 127 104 117 128 136 154 + 164 163 179 192 138 123 + 112 105 107 98 118 70 + 89 102 48 107 88 78 + 95 109 62 32 14 39 + 50 143 126 56 70 43 + 49 15 100000000 238 197 163 + 152 122 92 57 32 75 + 185 179 94 166 161 214 + 150 117 135 155 146 152 + 172 192 203 220 208 228 + 211 175 165 179 193 248 + 232 203 189 183 171 162 + 171 185 196 218 229 205 + 215 202 188 202 185 184 + 174 164 152 165 137 131 + 141 153 187 191 144 164 + 168 151 162 175 104 90 + 105 116 130 173 152 114 + 136 192 123 75 90 144 + 80 99 78 65 51 94 + 41 26 57 134 120 134 + 148 187 133 146 165 172 + 168 154 42 38 26 27 + 12 48 30 37 43 34 + 44 52 93 65 75 76 + 89 107 113 121 133 106 + 86 78 74 62 140 153 + 176 194 142 117 161 174 + 150 158 176 148 155 152 + 135 180 180 169 162 224 + 215 175 188 201 214 215 + 190 212 222 202 216 225 + 231 239 264 275 260 243 + 244 271 268 257 259 244 + 100000000 19 180 160 167 179 + 236 274 290 142 102 151 + 89 53 58 125 221 110 + 196 187 193 213 233 244 + 245 249 269 252 216 206 + 220 234 289 273 244 230 + 224 212 203 212 226 237 + 259 270 246 256 243 229 + 243 226 225 215 205 193 + 206 178 172 182 194 228 + 205 185 205 209 192 203 + 216 145 131 146 157 171 + 187 166 126 148 206 164 + 116 131 156 121 111 79 + 106 92 135 82 67 98 + 175 161 175 189 228 174 + 187 206 213 209 195 83 + 79 67 68 53 29 11 + 18 36 71 83 53 74 + 66 76 57 90 108 94 + 122 134 107 87 79 113 + 101 141 154 217 235 143 + 118 162 175 151 159 177 + 146 149 133 116 174 181 + 170 163 224 215 176 189 + 208 221 216 191 213 223 + 203 217 226 232 264 289 + 285 260 243 245 272 293 + 298 284 269 41 100000000 221 + 201 208 220 277 301 325 + 123 103 152 90 92 99 + 166 236 151 141 132 138 + 158 178 189 206 194 214 + 197 107 97 111 125 224 + 143 125 111 115 103 94 + 93 107 107 129 140 111 + 98 85 99 70 53 76 + 42 30 42 55 69 49 + 39 27 12 37 69 52 + 42 53 64 77 90 104 + 88 80 94 97 76 116 + 129 116 106 118 133 137 + 162 131 163 152 150 137 + 160 173 140 120 106 120 + 80 119 119 132 151 158 + 154 140 200 190 178 185 + 187 213 231 238 218 209 + 202 227 272 240 236 255 + 250 268 284 272 284 230 + 223 215 202 208 190 170 + 162 180 199 213 218 231 + 242 250 268 278 277 293 + 306 252 237 226 219 281 + 272 232 232 187 200 210 + 247 269 275 259 273 267 + 226 225 250 255 317 300 + 253 226 199 168 202 216 + 225 224 100000000 20 57 81 + 147 185 201 299 263 208 + 250 211 157 111 207 96 + 121 112 118 138 158 169 + 186 174 194 177 87 77 + 91 105 213 132 114 100 + 95 83 74 82 96 96 + 118 129 100 87 74 88 + 59 42 65 31 10 22 + 35 49 29 19 7 32 + 57 49 32 22 33 44 + 57 70 84 68 60 74 + 78 57 97 110 97 86 + 98 113 118 143 112 144 + 132 130 117 140 153 120 + 100 86 100 60 99 99 + 112 131 138 134 120 180 + 170 158 165 167 194 212 + 219 198 189 182 207 252 + 220 216 235 230 248 264 + 252 264 210 203 195 182 + 188 170 150 142 160 179 + 193 198 211 222 230 248 + 258 257 273 286 232 217 + 206 199 261 252 212 212 + 167 180 190 227 249 259 + 239 253 253 206 205 230 + 241 297 280 242 215 188 + 157 191 205 206 204 20 + 100000000 37 70 136 174 190 + 279 243 188 230 191 137 + 91 187 76 159 150 156 + 176 196 207 224 188 208 + 215 120 110 124 128 189 + 108 90 76 87 97 67 + 58 72 72 94 105 76 + 63 50 64 35 18 41 + 7 28 40 53 82 67 + 57 45 37 62 87 70 + 60 71 82 95 108 122 + 106 98 112 116 95 135 + 148 135 124 136 151 156 + 181 150 182 170 168 155 + 178 191 158 138 124 138 + 93 132 137 150 169 176 + 172 158 218 208 196 203 + 205 232 250 257 236 227 + 220 245 290 258 254 273 + 268 286 302 290 302 248 + 241 233 220 226 208 188 + 180 198 217 231 236 249 + 260 268 286 296 295 311 + 324 270 255 244 237 269 + 260 250 250 205 218 228 + 265 250 240 257 271 232 + 213 195 220 220 305 288 + 218 191 164 133 167 181 + 244 242 49 38 100000000 46 + 112 150 166 317 281 226 + 268 229 175 129 225 114 + 126 117 123 143 163 174 + 191 163 183 182 80 70 + 84 98 164 83 54 40 + 51 61 31 22 36 47 + 69 80 56 66 53 39 + 45 28 5 37 58 70 + 13 42 62 72 75 67 + 92 117 100 90 101 112 + 125 75 89 104 115 129 + 146 125 165 178 165 122 + 134 149 186 183 180 181 + 168 166 153 176 189 125 + 105 91 105 53 92 104 + 117 136 143 139 125 208 + 206 194 201 203 231 249 + 256 232 223 211 241 257 + 254 221 240 235 253 269 + 257 269 215 208 200 187 + 193 175 155 147 165 184 + 198 203 216 227 235 253 + 263 262 278 291 237 222 + 211 204 244 235 217 217 + 172 185 195 232 225 215 + 232 246 207 188 170 195 + 195 280 263 193 166 139 + 108 142 156 243 238 79 + 68 30 100000000 87 125 141 + 284 248 193 235 202 173 + 96 192 81 160 151 157 + 177 197 208 225 183 203 + 216 114 104 118 16 184 + 103 10 24 35 45 51 + 42 56 67 89 100 76 + 86 73 59 77 82 59 + 93 114 117 77 76 96 + 106 118 123 148 160 143 + 133 144 155 168 109 123 + 138 149 163 189 168 208 + 221 208 156 168 183 229 + 217 223 215 202 200 187 + 210 223 159 139 125 139 + 87 126 138 151 170 177 + 173 159 242 240 228 235 + 237 265 283 290 266 257 + 245 275 291 288 255 274 + 269 287 303 291 303 249 + 242 234 221 227 209 189 + 181 199 218 232 237 250 + 261 269 287 297 296 312 + 325 271 256 245 238 264 + 255 251 246 206 219 224 + 264 245 235 252 266 227 + 208 190 215 215 300 283 + 213 186 159 128 162 176 + 277 272 135 124 94 64 + 100000000 145 161 318 282 227 + 269 236 207 130 226 115 + 110 101 95 115 100 111 + 86 38 58 74 83 134 + 148 44 39 55 69 54 + 65 75 81 72 86 83 + 105 45 74 87 100 89 + 107 112 89 123 144 147 + 107 106 126 136 148 153 + 178 190 173 163 174 185 + 198 139 153 168 179 193 + 219 198 238 251 238 186 + 177 192 259 226 245 224 + 211 209 196 219 232 159 + 139 127 111 117 95 114 + 127 139 132 123 135 192 + 204 237 244 237 251 233 + 240 216 207 195 225 220 + 233 184 203 198 216 232 + 190 202 148 171 184 171 + 177 159 139 131 149 117 + 159 136 149 160 168 186 + 196 195 211 224 170 155 + 144 137 139 130 150 102 + 121 128 80 139 120 110 + 127 141 94 64 46 71 + 82 175 158 88 75 48 + 17 17 32 263 222 165 + 154 124 94 59 100000000 50 + 217 211 126 198 186 216 + 152 129 137 123 114 108 + 128 113 124 69 51 71 + 87 96 147 161 57 52 + 68 82 67 78 88 94 + 85 99 98 120 60 89 + 102 115 102 120 125 102 + 136 157 160 120 119 139 + 149 161 166 191 203 186 + 176 187 198 211 152 166 + 181 192 206 232 211 251 + 264 251 199 190 205 272 + 239 258 237 224 222 209 + 215 241 172 152 140 124 + 130 108 127 140 152 145 + 136 148 182 194 233 240 + 227 241 223 225 206 197 + 185 215 203 216 167 186 + 181 199 215 173 185 131 + 154 174 161 167 149 129 + 121 139 100 142 119 132 + 143 151 169 179 178 194 + 207 153 138 127 120 122 + 113 133 85 104 117 63 + 122 103 93 110 124 77 + 47 29 54 65 158 141 + 71 85 58 32 30 15 + 253 212 178 167 137 107 + 72 15 100000000 200 194 109 + 181 176 229 165 132 150 + 190 199 205 185 205 216 + 189 199 219 224 233 269 + 283 244 239 255 269 254 + 265 275 266 272 286 289 + 311 251 280 293 303 289 + 306 289 288 278 268 256 + 269 241 235 245 257 291 + 295 248 268 272 255 266 + 279 208 194 209 220 234 + 277 256 227 249 296 227 + 179 194 257 202 212 180 + 187 173 198 163 158 161 + 237 224 238 252 245 212 + 225 219 212 203 230 130 + 142 158 159 144 130 112 + 105 123 117 129 99 83 + 96 99 66 66 45 29 + 27 39 63 86 122 109 + 115 97 110 169 187 99 + 74 118 131 56 64 82 + 23 30 24 7 55 137 + 126 119 105 96 120 133 + 152 165 160 135 106 116 + 133 147 156 176 202 177 + 166 141 124 138 165 192 + 223 228 213 142 129 284 + 264 271 283 259 239 224 + 100000000 58 108 113 124 180 + 229 180 214 215 224 230 + 210 230 241 214 224 244 + 249 258 257 271 269 264 + 280 294 279 275 263 254 + 263 277 288 310 295 297 + 307 294 280 294 277 276 + 266 256 244 257 229 223 + 233 245 279 266 236 256 + 260 243 254 267 196 182 + 197 208 222 248 227 187 + 209 267 215 167 182 217 + 172 172 140 157 143 186 + 133 118 149 226 212 226 + 240 270 225 238 244 237 + 228 246 122 130 118 119 + 104 90 72 65 83 77 + 89 59 43 56 66 26 + 8 26 42 40 52 76 + 93 85 119 107 110 123 + 194 212 112 87 131 144 + 69 77 95 67 74 81 + 64 99 150 139 132 149 + 140 145 158 177 190 185 + 160 150 160 172 186 195 + 201 233 221 210 185 168 + 182 209 236 267 253 238 + 102 89 272 252 259 271 + 284 270 268 67 100000000 121 + 80 98 150 217 205 202 + 94 103 109 89 109 120 + 93 103 123 128 137 179 + 193 148 143 159 173 158 + 169 179 185 176 190 201 + 223 178 207 220 207 193 + 211 216 193 215 205 193 + 206 178 172 182 194 228 + 253 213 219 209 220 231 + 244 145 159 174 185 199 + 242 221 240 262 261 192 + 179 194 270 206 225 204 + 191 177 198 167 193 161 + 141 129 143 162 149 116 + 129 123 116 107 134 134 + 146 185 192 179 187 169 + 162 158 149 137 156 140 + 153 119 123 105 99 115 + 66 78 83 106 126 113 + 119 101 81 73 91 52 + 94 71 25 36 44 62 + 72 69 85 100 44 29 + 18 11 73 64 24 37 + 56 69 64 39 61 71 + 51 65 74 80 112 137 + 134 109 92 93 120 141 + 166 132 117 199 164 221 + 201 208 198 163 149 173 + 93 97 100000000 133 128 184 + 154 84 139 156 165 171 + 151 171 182 155 165 185 + 190 199 223 237 210 205 + 221 235 220 231 229 220 + 229 243 254 276 240 263 + 273 260 246 260 243 242 + 232 222 210 223 195 189 + 199 211 245 249 202 222 + 226 209 220 233 162 148 + 163 174 188 231 210 190 + 212 250 181 133 148 220 + 156 175 153 141 127 152 + 117 131 115 192 178 192 + 206 211 178 191 185 178 + 169 196 84 96 131 132 + 117 103 85 78 96 90 + 87 72 56 69 53 39 + 21 39 55 53 65 17 + 40 76 63 69 51 64 + 135 153 53 28 72 85 + 82 90 108 80 87 94 + 77 106 91 80 73 135 + 126 86 99 118 131 126 + 101 123 133 113 127 136 + 142 174 199 196 171 154 + 155 182 203 228 194 179 + 115 102 238 218 225 237 + 225 211 235 80 13 62 + 100000000 78 134 183 146 168 + 153 144 150 170 190 201 + 218 206 226 209 173 163 + 177 191 246 230 201 187 + 181 169 160 169 183 194 + 216 227 203 213 200 186 + 200 183 182 172 162 150 + 163 135 129 139 151 185 + 189 142 162 166 149 160 + 173 102 88 103 114 128 + 171 150 130 152 190 121 + 73 88 160 96 115 94 + 81 67 92 57 65 55 + 132 118 132 146 185 131 + 144 163 170 166 152 24 + 36 65 66 51 65 47 + 54 30 21 9 39 91 + 52 55 74 69 87 103 + 101 113 86 42 34 21 + 9 120 133 174 192 122 + 97 141 154 130 138 156 + 128 135 142 125 160 160 + 149 142 204 195 155 168 + 187 200 195 170 192 202 + 182 196 205 211 237 262 + 265 240 223 224 251 266 + 255 257 242 77 36 178 + 158 165 177 234 272 288 + 128 82 131 69 100000000 74 + 123 215 108 173 164 170 + 190 210 221 238 226 246 + 229 193 183 197 211 266 + 250 221 207 201 189 180 + 189 203 214 236 247 223 + 233 220 206 220 203 202 + 192 182 170 183 155 149 + 159 171 205 183 162 182 + 186 169 180 193 122 108 + 123 134 148 165 144 104 + 126 184 141 93 108 134 + 70 89 68 55 41 112 + 31 16 75 152 138 152 + 166 205 151 164 183 190 + 186 172 60 56 44 45 + 30 96 78 85 61 52 + 62 70 129 83 93 112 + 107 125 141 139 151 124 + 104 96 92 80 158 171 + 194 212 160 135 179 192 + 168 176 194 166 173 180 + 163 198 198 187 180 242 + 233 193 206 219 232 233 + 208 230 240 220 234 243 + 249 257 282 293 278 261 + 262 289 286 275 277 262 + 108 67 198 178 185 197 + 254 292 308 166 120 169 + 107 71 100000000 143 239 128 + 56 47 53 73 93 104 + 121 109 129 112 83 73 + 87 101 149 158 129 111 + 91 79 88 97 111 122 + 144 155 131 141 128 114 + 132 120 110 109 99 87 + 100 72 66 76 88 122 + 147 107 113 103 114 125 + 138 39 53 68 79 93 + 136 115 130 152 155 86 + 47 62 160 96 115 94 + 81 79 66 89 102 29 + 9 23 37 56 95 34 + 21 40 47 56 29 129 + 119 107 114 116 144 162 + 169 147 138 131 156 187 + 169 151 170 165 183 199 + 187 199 145 138 130 117 + 123 105 85 77 95 114 + 128 133 146 157 165 183 + 193 192 208 221 167 152 + 141 134 196 187 147 147 + 102 115 125 162 184 194 + 174 188 188 141 140 165 + 176 232 215 182 196 169 + 183 160 145 156 153 115 + 95 102 105 162 177 201 + 214 178 123 165 132 86 + 100000000 122 33 29 38 44 + 24 44 55 72 60 80 + 63 72 114 128 105 100 + 116 130 115 126 120 129 + 133 147 158 180 135 164 + 177 164 150 168 161 150 + 150 140 128 141 113 107 + 117 129 163 188 148 154 + 144 155 166 179 80 94 + 109 120 134 177 156 175 + 197 196 127 114 129 205 + 141 160 139 126 112 133 + 102 128 96 76 64 78 + 97 84 51 64 58 51 + 42 69 69 81 120 127 + 114 128 110 117 93 84 + 72 102 118 115 82 101 + 96 114 130 118 130 76 + 69 61 48 54 36 16 + 8 26 45 59 64 77 + 88 96 114 124 123 139 + 152 98 83 72 65 127 + 118 78 78 33 46 56 + 93 115 125 105 119 128 + 72 91 116 127 163 146 + 133 147 120 145 111 96 + 140 99 156 136 143 146 + 120 128 152 145 109 54 + 96 63 119 89 100000000 74 + 45 36 42 62 82 93 + 110 98 118 101 70 60 + 74 88 138 134 105 91 + 78 66 64 73 87 98 + 120 131 107 117 104 90 + 104 87 86 76 66 54 + 67 39 33 43 55 89 + 114 74 80 70 81 92 + 105 6 20 35 46 60 + 103 82 122 135 122 53 + 62 77 143 111 130 109 + 96 94 81 104 117 44 + 24 10 24 43 82 23 + 36 55 62 58 44 127 + 134 122 129 131 159 168 + 175 151 142 130 160 176 + 173 140 159 154 172 188 + 176 188 134 127 119 106 + 112 94 74 66 84 103 + 117 122 135 146 154 172 + 182 181 197 210 156 141 + 130 123 185 176 136 136 + 91 104 114 151 173 183 + 163 177 177 130 129 154 + 165 221 204 171 185 158 + 159 149 134 171 157 82 + 62 69 81 138 166 190 + 203 167 112 154 121 101 + 15 111 100000000 +EOF diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ATSP-instances/ftv70.atsp b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ATSP-instances/ftv70.atsp new file mode 100644 index 0000000000000000000000000000000000000000..a966e4930c1e78bad7ec1f7e9e9745792f5b332e --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ATSP-instances/ftv70.atsp @@ -0,0 +1,849 @@ +NAME: ftv70 +TYPE: ATSP +COMMENT: Asymmetric TSP (Fischetti) +DIMENSION: 71 +EDGE_WEIGHT_TYPE: EXPLICIT +EDGE_WEIGHT_FORMAT: FULL_MATRIX +EDGE_WEIGHT_SECTION + 100000000 26 46 74 82 65 + 90 104 102 100 147 134 + 90 75 69 106 117 42 + 71 96 158 89 76 125 + 38 40 58 59 13 38 + 31 22 103 143 106 94 + 137 104 123 140 98 70 + 58 38 30 48 67 118 + 120 105 149 140 100 55 + 115 141 94 93 122 113 + 162 154 76 118 36 21 + 62 165 92 94 66 66 + 100000000 20 48 56 39 126 + 81 76 109 156 140 156 + 141 135 172 183 108 137 + 162 224 155 142 190 104 + 76 124 95 79 104 97 + 88 130 176 133 121 164 + 131 150 167 125 97 85 + 65 57 75 94 145 147 + 132 160 151 80 82 142 + 162 74 67 96 87 189 + 128 103 145 102 66 128 + 176 119 121 40 46 53 + 100000000 28 36 19 106 61 + 56 89 136 120 136 121 + 115 152 163 88 117 142 + 204 135 122 170 84 56 + 104 75 59 84 77 68 + 110 156 113 101 144 111 + 130 147 105 77 65 45 + 37 55 74 125 127 112 + 140 131 60 62 122 142 + 54 47 76 67 169 108 + 83 125 82 46 108 156 + 99 101 20 73 87 72 + 100000000 30 46 133 55 50 + 83 130 114 158 117 137 + 174 185 115 144 169 231 + 162 149 198 111 83 131 + 102 86 111 104 95 176 + 216 179 167 210 176 195 + 182 140 143 131 111 103 + 121 109 160 162 147 131 + 122 94 113 131 133 56 + 38 67 39 235 99 118 + 190 109 94 135 147 162 + 167 70 43 57 42 70 + 100000000 16 103 25 20 53 + 100 84 128 87 107 144 + 155 85 114 139 201 132 + 119 168 81 53 101 72 + 56 81 74 65 146 186 + 149 137 180 147 166 183 + 141 113 101 81 73 91 + 110 161 163 148 164 155 + 102 98 158 166 89 71 + 100 42 205 109 119 161 + 79 64 105 180 135 137 + 62 27 41 26 54 62 + 100000000 87 87 82 97 144 + 131 117 102 96 133 144 + 69 98 123 185 116 103 + 152 65 37 85 56 40 + 65 58 49 130 170 133 + 121 164 131 150 167 125 + 97 85 65 57 75 94 + 145 147 132 166 157 86 + 82 142 168 80 73 102 + 93 189 134 103 145 63 + 48 89 182 119 121 46 + 129 155 175 203 199 194 + 100000000 14 180 38 85 72 + 95 54 74 111 122 87 + 116 141 186 134 146 195 + 117 117 137 65 116 148 + 155 151 218 213 235 223 + 266 233 252 269 227 199 + 187 167 159 177 196 247 + 249 234 260 251 229 184 + 244 262 204 186 155 158 + 255 157 205 247 93 150 + 80 276 221 223 195 137 + 163 183 211 189 202 104 + 100000000 170 28 75 62 103 + 62 82 119 130 95 124 + 149 194 142 154 203 125 + 125 145 73 124 156 163 + 159 226 221 243 231 274 + 241 260 277 235 207 195 + 175 167 185 204 255 257 + 242 250 241 232 192 250 + 252 194 176 145 148 263 + 147 213 255 101 158 88 + 266 229 231 203 106 120 + 105 91 63 79 109 5 + 100000000 33 80 64 108 67 + 87 124 135 100 129 154 + 199 147 159 208 130 116 + 150 78 119 144 137 128 + 209 226 212 200 238 189 + 208 195 153 176 164 144 + 136 154 122 173 175 160 + 144 135 107 126 144 146 + 69 51 80 22 268 89 + 131 203 106 127 93 160 + 175 200 83 109 135 155 + 183 161 174 76 81 142 + 100000000 47 34 75 34 54 + 91 102 67 96 121 166 + 114 126 175 97 97 117 + 45 96 128 135 131 198 + 193 215 203 246 213 232 + 249 207 179 167 147 139 + 157 176 227 229 214 222 + 213 204 164 222 224 166 + 148 117 120 235 119 185 + 227 73 130 60 238 201 + 203 175 157 171 156 141 + 114 130 136 34 95 60 + 100000000 40 135 94 114 151 + 162 127 156 181 226 174 + 186 235 157 157 177 105 + 156 188 188 179 258 253 + 263 251 288 239 258 245 + 203 227 215 195 187 205 + 172 223 207 210 175 166 + 157 176 175 177 119 101 + 70 73 295 72 181 253 + 133 178 120 191 225 251 + 133 143 169 174 159 132 + 148 110 65 113 34 31 + 100000000 102 68 88 122 133 + 101 130 155 197 148 160 + 209 131 131 151 79 130 + 162 169 165 232 227 249 + 237 280 247 266 263 221 + 213 201 181 173 191 190 + 241 225 228 193 184 175 + 194 193 195 137 119 88 + 91 269 90 199 261 107 + 164 94 209 235 237 151 + 117 143 163 191 199 182 + 84 98 204 73 109 91 + 100000000 42 51 44 55 75 + 90 96 119 108 120 165 + 105 105 125 53 104 136 + 143 139 192 187 211 204 + 242 221 240 257 215 187 + 175 155 147 165 184 235 + 237 222 266 257 217 172 + 232 258 211 210 179 182 + 228 181 193 235 81 138 + 68 282 209 211 183 75 + 101 121 149 157 140 42 + 56 176 34 81 68 41 + 100000000 20 57 68 33 62 + 87 132 80 92 141 63 + 63 83 11 62 94 101 + 97 164 159 181 169 212 + 179 198 215 173 145 133 + 113 105 123 142 193 195 + 180 224 215 175 130 190 + 216 169 168 151 154 201 + 153 151 193 39 96 26 + 240 167 169 141 95 121 + 141 169 177 160 62 76 + 196 54 101 88 21 20 + 100000000 37 48 53 82 89 + 112 100 112 158 83 83 + 103 31 82 114 121 117 + 184 179 201 189 232 199 + 218 235 193 165 153 133 + 125 143 162 213 215 200 + 244 235 195 150 210 236 + 189 188 171 174 221 173 + 171 213 59 116 46 260 + 187 189 161 90 116 136 + 164 172 155 99 113 192 + 91 138 122 44 57 37 + 100000000 11 48 46 52 75 + 64 76 121 78 78 98 + 68 77 109 116 112 148 + 143 167 160 198 194 213 + 230 188 160 148 128 120 + 138 157 208 210 195 239 + 230 190 145 205 231 184 + 183 208 203 184 210 166 + 208 54 111 68 255 182 + 178 156 79 105 125 153 + 161 144 99 113 181 91 + 138 125 58 57 37 54 + 100000000 37 35 41 103 53 + 65 114 67 67 87 68 + 66 98 105 101 137 132 + 156 149 187 183 202 219 + 177 149 137 117 109 127 + 146 197 199 184 228 219 + 179 134 194 220 173 172 + 201 192 174 210 155 197 + 43 100 57 244 171 167 + 145 42 68 88 116 124 + 107 75 89 144 67 114 + 101 48 33 27 64 75 + 100000000 29 54 116 47 59 + 108 30 30 50 44 29 + 61 68 64 131 126 148 + 136 179 146 165 182 140 + 112 100 80 72 90 109 + 160 162 147 191 182 142 + 97 157 183 136 135 164 + 155 168 186 118 160 6 + 63 20 207 134 136 108 + 101 127 147 175 183 166 + 134 148 203 126 173 160 + 104 92 83 69 46 59 + 100000000 25 87 18 30 79 + 89 89 109 103 88 120 + 127 123 102 97 121 114 + 152 162 181 208 193 144 + 159 139 131 149 168 219 + 221 206 250 241 201 156 + 216 242 195 194 223 214 + 139 245 177 176 65 122 + 79 266 193 132 167 100 + 126 146 174 182 165 120 + 134 202 112 159 146 79 + 78 58 44 21 58 56 + 100000000 62 71 83 108 88 + 88 108 89 87 119 126 + 122 155 150 174 167 205 + 204 223 240 198 170 158 + 138 130 148 167 218 220 + 205 249 240 200 155 215 + 241 194 193 222 213 171 + 231 176 218 64 121 78 + 265 192 185 166 92 118 + 138 166 174 157 125 139 + 194 117 164 151 98 83 + 77 114 97 50 51 76 + 100000000 9 21 46 80 80 + 100 94 79 111 118 114 + 93 88 112 105 143 153 + 172 199 184 135 150 130 + 122 140 159 210 212 197 + 241 232 192 147 207 233 + 186 185 214 205 130 236 + 168 167 56 113 70 257 + 184 123 158 83 109 129 + 157 165 148 116 130 185 + 108 155 142 89 74 68 + 105 88 41 42 67 129 + 100000000 12 61 71 71 91 + 85 70 102 109 105 84 + 79 103 96 134 144 163 + 190 175 126 141 121 113 + 131 150 201 203 188 232 + 223 183 138 198 224 177 + 176 205 196 121 227 159 + 158 47 104 61 248 175 + 114 149 71 97 117 145 + 153 136 104 118 173 96 + 143 130 77 62 56 93 + 76 29 30 55 117 48 + 100000000 49 59 59 79 73 + 58 90 97 93 72 67 + 91 84 122 132 151 178 + 163 114 129 109 101 119 + 138 189 191 176 220 211 + 171 126 186 212 165 164 + 193 184 109 215 147 146 + 35 92 49 236 163 102 + 137 204 230 250 278 286 + 269 224 238 306 216 255 + 237 173 182 162 147 125 + 162 160 104 114 123 135 + 100000000 192 192 163 193 191 + 223 230 226 144 139 147 + 156 174 184 165 230 215 + 186 249 242 234 252 251 + 267 282 289 332 323 297 + 259 299 325 298 297 325 + 317 113 327 260 198 168 + 225 182 348 237 174 270 + 38 64 84 112 120 103 + 78 92 140 88 135 122 + 78 63 57 94 105 30 + 59 84 146 77 38 87 + 100000000 28 20 47 25 31 + 38 47 110 105 129 122 + 160 142 161 178 136 108 + 96 76 68 86 105 156 + 158 143 187 178 138 93 + 153 179 132 131 160 151 + 147 192 114 156 24 59 + 50 203 130 132 104 151 + 177 197 225 221 216 50 + 64 202 60 107 94 117 + 76 96 133 144 109 138 + 163 208 156 168 217 139 + 100000000 159 19 138 170 177 + 173 240 235 257 245 288 + 255 274 291 249 221 209 + 189 181 199 218 269 271 + 256 282 273 251 206 266 + 284 226 208 177 180 277 + 179 227 269 115 172 102 + 298 243 245 217 89 115 + 135 163 171 154 122 136 + 191 114 161 148 95 80 + 74 111 94 47 48 73 + 135 66 18 67 77 77 + 100000000 91 76 108 115 111 + 90 85 109 102 140 150 + 169 196 181 132 147 127 + 119 137 156 207 209 194 + 238 229 189 144 204 230 + 183 182 211 202 127 233 + 165 164 53 110 67 254 + 181 120 155 132 158 178 + 206 202 197 31 45 183 + 41 88 75 98 57 77 + 114 125 90 119 144 189 + 137 149 198 120 55 140 + 100000000 119 151 158 154 221 + 216 238 226 269 236 255 + 272 230 202 190 170 162 + 180 199 250 252 237 263 + 254 232 187 247 265 207 + 189 158 161 258 160 208 + 250 96 153 83 279 224 + 226 198 13 39 59 87 + 95 78 77 91 115 87 + 134 121 77 62 56 93 + 104 29 58 83 145 76 + 63 112 25 27 45 46 + 100000000 32 39 35 116 130 + 119 107 150 117 136 153 + 111 83 71 51 43 61 + 80 131 133 118 162 153 + 113 68 128 154 107 106 + 135 126 172 167 89 131 + 23 34 49 178 105 107 + 79 38 48 68 96 104 + 87 109 123 124 119 166 + 153 109 94 88 125 136 + 61 90 115 177 108 69 + 118 31 59 51 78 32 + 100000000 7 16 123 136 126 + 114 157 124 143 160 118 + 90 78 58 50 68 87 + 138 140 125 169 160 120 + 75 135 161 114 115 144 + 135 178 176 96 138 55 + 41 81 185 112 114 88 + 31 41 61 89 97 80 + 105 119 117 115 162 149 + 105 90 84 121 132 57 + 86 111 173 104 65 114 + 27 55 47 74 28 7 + 100000000 9 116 132 119 107 + 150 117 136 153 111 83 + 71 51 43 61 80 131 + 133 118 162 153 113 68 + 128 154 107 108 137 128 + 174 169 89 131 51 34 + 77 178 105 107 81 22 + 32 52 80 88 71 112 + 113 108 122 169 156 112 + 97 91 128 139 64 93 + 118 180 111 74 123 36 + 62 56 81 35 16 9 + 100000000 107 141 110 98 141 + 108 127 144 102 74 62 + 42 34 52 71 122 124 + 109 153 144 104 59 119 + 145 98 99 128 119 166 + 160 80 122 58 25 84 + 169 96 98 72 108 134 + 154 182 190 173 141 155 + 210 133 180 167 114 99 + 93 130 113 66 67 92 + 154 85 37 60 96 96 + 19 110 95 127 134 130 + 100000000 46 75 63 106 116 + 135 162 147 93 166 146 + 138 156 175 199 221 213 + 257 248 208 163 223 249 + 202 201 230 221 120 252 + 184 130 72 129 86 273 + 169 81 174 127 153 173 + 201 209 192 160 174 229 + 152 199 186 133 118 112 + 149 132 85 86 111 173 + 104 56 79 115 115 38 + 129 114 146 153 149 19 + 100000000 29 17 60 70 89 + 116 101 47 135 148 157 + 175 137 153 175 175 219 + 210 183 182 185 211 221 + 220 249 240 85 271 146 + 84 91 148 105 235 123 + 35 193 164 190 210 210 + 240 229 197 211 260 189 + 236 223 170 155 149 186 + 169 122 123 148 210 141 + 93 98 152 152 75 166 + 151 183 190 186 56 45 + 100000000 12 31 41 60 87 + 72 42 106 119 190 208 + 108 124 146 146 190 181 + 154 173 156 182 197 229 + 258 249 56 290 117 55 + 128 185 142 206 94 30 + 202 153 179 199 222 235 + 218 186 200 255 178 225 + 212 159 144 138 175 158 + 111 112 137 199 130 82 + 105 141 141 64 155 140 + 172 179 175 45 57 12 + 100000000 43 53 72 99 84 + 30 118 131 183 201 120 + 136 158 158 202 193 166 + 185 168 194 209 241 270 + 261 68 297 129 67 117 + 174 131 218 106 18 214 + 189 175 195 179 209 214 + 261 234 229 253 300 287 + 234 219 213 250 233 186 + 187 212 270 205 157 175 + 216 216 139 230 202 209 + 202 193 120 122 80 92 + 100000000 10 29 56 41 87 + 75 88 159 177 77 93 + 115 115 159 150 123 142 + 125 151 166 198 227 218 + 105 259 86 24 192 168 + 206 175 63 110 171 179 + 165 185 169 199 204 251 + 224 219 243 290 277 224 + 209 203 240 223 176 177 + 202 260 195 147 165 206 + 206 129 220 192 199 192 + 183 110 112 70 82 49 + 100000000 19 46 31 77 65 + 78 149 167 67 83 105 + 105 149 140 113 132 115 + 141 156 188 217 208 95 + 249 76 14 182 158 196 + 165 53 100 161 212 205 + 225 209 239 244 245 259 + 259 237 284 271 218 203 + 197 234 217 170 171 196 + 241 189 141 146 200 200 + 123 214 199 231 232 223 + 104 93 51 63 30 40 + 100000000 67 71 93 105 118 + 189 207 107 104 117 145 + 167 158 153 172 155 181 + 196 228 254 248 76 286 + 116 54 176 198 190 183 + 93 81 201 184 170 190 + 174 204 209 256 229 224 + 248 295 282 229 214 208 + 245 228 181 182 207 269 + 200 152 175 211 211 134 + 225 197 204 197 188 115 + 150 108 106 87 72 57 + 100000000 36 82 70 83 154 + 172 72 37 59 110 109 + 100 118 137 120 146 161 + 193 196 213 133 228 81 + 86 187 163 201 125 58 + 106 166 148 134 154 138 + 168 173 220 193 188 212 + 259 246 193 178 172 209 + 192 145 146 171 233 164 + 116 139 175 175 98 189 + 161 168 161 152 79 125 + 82 70 85 36 55 82 + 100000000 46 34 47 118 136 + 36 87 89 74 118 109 + 82 101 84 110 125 157 + 186 177 131 218 45 50 + 151 127 165 134 22 70 + 130 213 199 219 203 233 + 238 285 258 253 277 324 + 311 258 243 237 274 257 + 210 211 236 294 229 181 + 199 240 240 163 254 226 + 233 226 217 144 146 104 + 116 83 34 53 80 65 + 100000000 99 112 183 201 101 + 117 139 139 183 174 147 + 166 149 175 190 222 251 + 242 129 283 110 48 216 + 192 230 199 87 134 195 + 153 146 166 150 180 185 + 186 200 200 178 225 212 + 159 144 138 175 158 111 + 112 137 199 130 82 105 + 141 141 64 155 140 172 + 173 164 45 91 48 36 + 79 46 65 92 77 12 + 100000000 59 130 148 48 99 + 101 86 130 121 94 113 + 96 122 137 169 198 189 + 104 230 57 60 117 139 + 131 146 34 36 142 173 + 166 186 170 200 205 206 + 220 220 198 245 232 179 + 164 158 195 178 131 132 + 157 219 150 102 125 161 + 161 84 175 160 192 193 + 184 65 111 68 56 99 + 66 85 112 97 32 20 + 100000000 150 168 68 119 121 + 106 150 141 114 133 116 + 142 157 189 218 209 124 + 250 77 80 137 159 151 + 166 54 56 162 30 16 + 36 64 72 55 120 97 + 92 125 172 156 120 105 + 99 136 147 72 101 126 + 188 119 106 133 68 70 + 88 89 43 50 43 34 + 73 119 76 64 107 74 + 93 110 68 40 28 8 + 100000000 18 37 88 90 75 + 119 110 70 25 85 111 + 64 83 112 103 132 144 + 46 88 66 9 92 135 + 62 64 56 54 40 60 + 59 89 79 144 114 109 + 142 189 173 144 129 123 + 160 171 96 125 150 212 + 143 130 157 92 94 112 + 113 67 74 67 58 97 + 143 100 88 131 86 105 + 92 50 64 52 32 24 + 100000000 19 70 72 57 101 + 92 52 7 67 93 46 + 78 107 98 156 139 28 + 100 90 33 116 117 72 + 88 51 112 98 118 102 + 132 137 202 157 152 185 + 232 216 202 187 181 218 + 223 154 177 202 264 195 + 147 170 150 152 129 171 + 125 132 125 116 110 156 + 113 101 116 67 86 73 + 31 77 65 78 82 100 + 100000000 51 53 38 82 73 + 46 65 48 74 89 121 + 150 141 162 182 9 81 + 148 91 174 98 53 101 + 94 178 164 184 168 198 + 203 268 223 218 251 290 + 259 251 236 230 267 250 + 203 204 229 291 222 174 + 197 216 218 156 237 191 + 198 191 182 137 172 130 + 128 109 94 79 22 58 + 104 92 105 148 166 94 + 100000000 34 126 84 75 112 + 131 114 126 155 181 171 + 207 155 203 103 108 209 + 157 223 100 80 128 160 + 144 130 150 134 164 169 + 234 189 184 217 256 225 + 234 219 213 250 261 186 + 215 240 302 233 211 234 + 182 184 193 203 157 164 + 157 148 174 209 167 165 + 146 131 116 59 95 141 + 129 122 114 132 93 96 + 100000000 92 50 41 78 97 + 80 92 121 147 137 173 + 192 169 102 145 180 123 + 206 66 117 165 126 138 + 124 144 128 158 163 228 + 183 178 211 250 219 228 + 213 207 244 255 180 209 + 234 296 227 191 214 176 + 178 173 197 151 158 151 + 142 154 189 147 145 126 + 111 96 39 75 121 109 + 116 108 126 87 17 15 + 100000000 44 35 72 91 74 + 86 115 141 131 167 172 + 163 96 125 174 117 200 + 60 97 145 120 94 80 + 100 84 114 119 184 139 + 134 167 214 198 184 169 + 163 200 211 136 165 190 + 252 183 170 197 132 134 + 152 153 107 114 107 98 + 137 183 140 128 159 110 + 129 81 74 104 92 72 + 64 82 43 59 57 42 + 100000000 62 28 47 30 56 + 71 103 132 123 196 164 + 52 124 130 73 156 16 + 96 128 76 103 89 109 + 93 123 128 193 148 143 + 176 215 184 193 178 172 + 209 220 145 174 199 261 + 192 179 206 141 143 161 + 162 116 123 116 107 146 + 192 149 137 168 119 138 + 90 83 113 101 81 73 + 91 52 68 41 51 9 + 100000000 37 56 39 51 80 + 106 96 132 205 128 61 + 133 139 82 165 25 105 + 137 85 66 52 72 71 + 101 91 156 126 121 154 + 201 185 156 141 135 172 + 183 108 137 162 224 155 + 142 169 104 106 124 125 + 79 86 79 70 109 155 + 112 100 131 82 101 88 + 46 76 64 44 36 54 + 15 66 68 53 97 88 + 100000000 19 63 89 58 90 + 119 110 168 151 24 96 + 102 45 128 113 68 100 + 63 47 33 53 52 82 + 72 137 107 102 135 182 + 166 137 122 116 153 164 + 89 118 143 205 136 123 + 150 85 87 105 106 60 + 67 60 51 90 136 93 + 81 124 91 110 127 85 + 57 45 25 17 35 54 + 105 107 92 136 127 45 + 100000000 102 128 39 71 100 + 91 149 132 63 105 83 + 26 109 152 79 81 44 + 113 99 119 54 84 100 + 187 109 104 137 184 168 + 203 171 182 219 230 155 + 184 209 271 202 189 216 + 151 137 171 156 126 133 + 126 117 156 202 159 147 + 178 129 148 122 93 123 + 111 91 83 101 62 100 + 73 83 41 32 47 66 + 100000000 26 41 73 102 93 + 215 134 71 143 149 92 + 175 57 115 147 46 129 + 124 128 56 86 102 189 + 111 106 139 186 170 214 + 173 193 230 241 171 200 + 225 287 218 205 241 167 + 139 187 158 142 158 151 + 142 181 227 184 172 203 + 154 173 160 118 148 136 + 116 108 126 87 138 140 + 125 168 159 72 91 135 + 100000000 34 75 104 95 240 + 136 96 168 165 117 191 + 184 140 172 48 95 90 + 94 22 52 68 155 77 + 72 105 152 136 180 139 + 159 196 207 137 166 191 + 253 184 171 207 133 105 + 153 124 108 124 117 108 + 147 193 150 138 169 120 + 139 126 84 114 102 82 + 74 92 53 104 106 91 + 134 125 38 57 101 127 + 100000000 41 70 61 206 102 + 62 134 131 83 157 150 + 106 138 14 113 108 112 + 40 70 86 160 56 51 + 84 131 115 159 118 138 + 175 186 151 180 205 250 + 198 189 225 151 123 171 + 129 126 142 135 126 165 + 211 168 156 187 138 157 + 144 102 132 120 100 92 + 110 71 122 124 109 93 + 84 56 75 93 95 18 + 100000000 29 29 224 61 80 + 152 149 101 144 109 124 + 156 32 146 160 145 101 + 103 119 193 89 84 117 + 119 88 190 151 171 208 + 219 184 213 238 283 231 + 222 271 184 156 204 162 + 159 184 177 168 226 272 + 229 217 248 199 218 186 + 163 193 181 161 153 171 + 132 164 137 147 105 96 + 117 136 105 107 79 61 + 100000000 62 285 32 141 213 + 182 162 177 121 185 217 + 93 84 98 83 69 41 + 57 131 27 22 55 102 + 86 130 89 109 146 157 + 122 151 176 221 169 160 + 209 122 94 142 100 97 + 122 115 106 187 227 190 + 178 216 167 186 173 131 + 154 142 122 114 132 100 + 151 153 138 122 113 85 + 104 122 124 47 29 58 + 100000000 246 67 109 181 120 + 105 115 138 153 178 61 + 146 172 192 220 228 211 + 179 193 248 171 218 205 + 152 137 131 168 151 104 + 105 130 192 123 75 80 + 134 134 57 148 133 165 + 172 168 38 27 34 44 + 65 75 76 121 106 74 + 140 153 176 194 142 158 + 180 180 224 215 188 201 + 190 216 231 239 268 259 + 100000000 290 151 89 110 167 + 124 240 128 62 212 114 + 128 113 69 71 87 161 + 57 52 85 120 89 160 + 119 139 176 187 152 181 + 206 251 199 190 239 152 + 124 172 130 127 152 145 + 136 194 240 197 185 216 + 167 186 173 131 161 149 + 129 121 139 100 151 153 + 138 122 113 85 104 122 + 124 47 29 58 30 253 + 100000000 109 181 150 130 145 + 138 153 185 61 103 89 + 109 93 123 128 193 148 + 143 176 223 207 193 178 + 172 209 220 145 174 199 + 261 192 179 206 141 143 + 161 162 116 123 116 107 + 146 192 149 137 153 119 + 123 66 83 113 101 81 + 73 91 52 44 44 29 + 73 64 37 56 39 65 + 80 112 141 132 199 173 + 100000000 133 139 82 165 89 + 105 137 85 165 151 171 + 155 185 190 237 210 205 + 229 276 263 210 195 189 + 226 209 162 163 188 250 + 181 133 156 192 192 115 + 206 178 185 178 169 96 + 132 90 87 69 53 39 + 53 17 63 51 64 135 + 153 53 90 106 91 135 + 126 99 118 101 127 142 + 174 203 194 115 235 62 + 100000000 168 144 182 151 39 + 87 147 36 62 82 110 + 118 101 74 88 138 73 + 120 107 54 39 33 70 + 81 6 35 60 122 53 + 62 111 24 24 44 43 + 23 55 62 58 134 129 + 142 130 173 140 159 176 + 134 106 94 74 66 84 + 103 154 156 141 185 176 + 136 91 151 177 130 129 + 158 149 171 190 112 154 + 100000000 57 26 201 128 130 + 102 21 7 27 55 63 + 46 111 88 83 116 163 + 147 111 96 90 127 138 + 63 92 117 179 110 97 + 142 59 61 79 80 34 + 41 34 25 82 128 85 + 73 116 83 102 119 77 + 49 37 17 9 27 46 + 97 99 84 128 119 79 + 34 94 120 73 74 103 + 94 141 135 55 97 57 + 100000000 83 144 71 73 47 + 102 128 148 176 184 167 + 69 83 203 61 108 95 + 28 27 7 44 55 60 + 89 96 119 107 119 165 + 90 90 110 38 89 121 + 128 124 191 186 208 196 + 239 206 225 242 200 172 + 160 140 132 150 169 220 + 222 207 251 242 202 157 + 217 243 196 195 178 181 + 228 180 178 220 66 123 + 100000000 267 194 196 168 164 + 150 170 154 184 189 254 + 209 204 237 276 245 254 + 239 233 270 281 206 235 + 260 322 253 217 240 202 + 204 199 223 177 184 177 + 168 180 215 173 171 152 + 137 122 65 101 147 135 + 142 134 152 113 43 41 + 26 70 61 98 117 100 + 112 141 167 157 193 198 + 189 122 151 200 143 226 + 100000000 123 171 146 126 112 + 132 116 146 151 216 171 + 166 199 246 230 216 201 + 195 232 237 168 191 216 + 278 209 161 184 164 166 + 143 185 139 146 139 130 + 124 170 127 115 130 81 + 100 87 45 91 79 92 + 96 114 14 65 67 52 + 96 87 60 79 62 88 + 103 135 164 155 176 196 + 23 95 162 105 188 112 + 100000000 115 108 225 211 231 + 215 245 250 297 270 265 + 289 336 323 270 255 249 + 286 269 222 223 248 306 + 241 193 211 252 252 175 + 266 238 245 238 229 156 + 158 116 128 95 46 65 + 92 77 12 111 124 195 + 213 113 129 151 151 195 + 186 159 178 161 187 202 + 234 263 254 141 295 122 + 60 228 204 242 211 99 + 100000000 207 81 95 80 8 + 38 54 141 63 58 91 + 138 122 166 125 145 182 + 193 123 152 177 239 170 + 157 206 119 91 139 110 + 94 119 112 103 184 224 + 187 175 214 165 184 171 + 129 151 139 119 111 129 + 98 149 151 136 120 111 + 83 102 120 122 45 27 + 56 47 243 88 107 179 + 117 102 143 136 151 175 + 0 +EOF diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ATSP-instances/rbg323.atsp b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ATSP-instances/rbg323.atsp new file mode 100644 index 0000000000000000000000000000000000000000..c19aa72c455db30b9d4c75672b2e085cd4d5f268 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ATSP-instances/rbg323.atsp @@ -0,0 +1,6467 @@ +NAME: rbg323 +TYPE: ATSP +COMMENT: Stacker crane application (Ascheuer) +DIMENSION: 323 +EDGE_WEIGHT_TYPE: EXPLICIT +EDGE_WEIGHT_FORMAT: FULL_MATRIX +EDGE_WEIGHT_SECTION + 0 18 20 18 27 18 7 20 22 14 11 10 14 14 23 10 24 + 16 12 12 15 12 12 16 24 18 18 18 14 18 14 23 23 18 + 18 18 19 18 18 21 18 18 18 15 18 21 11 18 24 21 11 + 12 23 12 5 27 16 18 11 18 18 4 15 27 16 23 24 15 + 18 18 14 20 18 18 22 10 18 10 18 27 18 25 18 18 18 + 18 18 18 18 18 18 18 15 18 18 18 18 16 7 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 18 18 18 12 + 18 18 24 18 18 18 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 12 12 16 15 13 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 20 24 27 + 18 25 23 16 11 27 23 27 13 18 14 18 23 10 24 11 27 + 15 14 18 23 27 18 16 18 15 23 20 23 16 27 16 24 18 + 21 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 18 + 21 18 14 11 12 24 12 27 12 18 23 10 23 21 24 23 13 + 18 23 23 23 14 18 23 27 14 27 18 21 18 16 26 18 10 + 26 27 24 12 14 9 15 20 20 24 16 11 20 27 12 18 13 + 24 15 16 15 13 24 13 24 16 24 7 12 18 20 15 16 24 + 12 23 23 27 14 18 11 18 16 13 10 20 23 14 24 23 11 + 27 18 15 14 26 10 14 10 16 24 14 18 16 12 10 27 24 + + 18 0 20 18 27 18 7 20 22 14 11 10 14 14 23 10 24 + 16 12 12 15 12 12 16 24 18 18 18 14 18 14 23 23 18 + 18 18 19 18 18 21 18 18 18 15 18 21 11 18 24 21 11 + 12 23 12 5 27 16 18 11 18 18 4 15 27 16 23 24 15 + 18 18 14 20 18 18 22 10 18 10 18 27 18 25 18 18 18 + 18 18 18 18 18 18 18 15 18 18 18 18 16 7 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 18 18 18 12 + 18 18 24 18 18 18 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 12 12 16 15 13 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 20 24 27 + 18 25 23 16 11 27 23 27 13 18 14 18 23 10 24 11 27 + 15 14 18 23 27 18 16 18 15 23 20 23 16 27 16 24 18 + 21 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 18 + 21 18 14 11 12 24 12 27 12 18 23 10 23 21 24 23 13 + 18 23 23 23 14 18 23 27 14 27 18 21 18 16 26 18 10 + 26 27 24 12 14 9 15 20 20 24 16 11 20 27 12 18 13 + 24 15 16 15 13 24 13 24 16 24 7 12 18 20 15 16 24 + 12 23 23 27 14 18 11 18 16 13 10 20 23 14 24 23 11 + 27 18 15 14 26 10 14 10 16 24 14 18 16 12 10 27 24 + + 15 10 0 25 23 25 20 11 22 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 18 25 25 24 25 12 11 12 25 + 25 25 19 25 25 21 25 25 25 24 25 10 23 25 14 21 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 13 16 24 + 25 25 13 9 25 25 22 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 9 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 18 16 24 16 23 10 + 18 12 12 11 12 14 18 24 15 23 24 24 23 14 24 24 10 + 4 7 15 23 23 12 12 12 24 20 21 12 12 12 20 15 23 + 10 20 12 24 21 23 12 23 23 18 24 24 11 21 18 23 23 + 12 24 23 11 23 10 13 25 24 12 9 12 11 23 24 14 11 + 21 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 18 24 16 23 14 15 23 16 24 13 21 12 10 14 12 14 + 25 12 11 12 24 15 13 23 24 23 24 10 18 11 21 13 21 + 21 23 14 14 12 20 24 7 5 15 24 23 4 23 23 18 23 + 18 24 24 24 23 15 23 18 24 18 20 23 18 6 24 24 14 + 23 12 18 23 12 10 23 10 24 23 21 7 12 24 14 13 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 20 20 21 0 27 16 10 21 24 15 11 11 15 15 24 0 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 21 16 16 23 16 16 16 14 16 23 10 16 24 23 10 + 14 23 12 10 27 15 19 10 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 24 11 16 11 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 20 16 16 16 18 10 16 21 12 + 6 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 5 9 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 14 11 15 14 15 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 22 24 27 + 20 26 24 15 12 27 24 27 15 19 12 19 23 0 24 10 27 + 16 15 19 23 27 20 18 19 14 23 21 24 18 27 15 24 20 + 23 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 19 + 23 20 12 12 12 24 12 27 14 19 23 6 24 23 24 23 15 + 19 23 23 23 12 20 24 28 15 28 19 23 19 18 27 20 10 + 27 27 24 14 15 10 14 21 21 24 15 10 21 27 11 19 15 + 25 14 15 14 15 24 15 25 15 24 10 12 19 21 14 15 24 + 11 23 23 27 15 20 10 20 15 15 9 21 23 12 24 23 10 + 27 19 15 12 27 8 12 6 15 25 15 19 15 12 11 28 24 + + 23 23 23 33 0 33 27 23 24 24 28 27 24 24 18 28 14 + 31 25 25 31 25 30 31 14 23 33 33 31 33 24 21 20 33 + 33 33 23 33 33 23 33 33 33 31 33 23 28 33 16 23 28 + 25 20 25 27 10 31 29 28 33 33 27 31 6 31 20 15 31 + 33 33 24 23 33 33 24 27 33 27 33 10 33 12 33 33 33 + 33 33 33 33 33 23 33 31 23 33 33 33 24 27 33 23 26 + 28 31 24 25 24 25 24 20 33 33 33 33 33 33 33 33 25 + 33 33 15 33 33 33 33 23 15 28 28 19 26 31 26 10 23 + 15 18 20 21 24 16 19 31 25 29 31 31 29 23 31 31 23 + 23 23 23 10 6 20 18 18 31 12 15 18 18 18 23 15 10 + 23 12 18 31 28 10 18 10 30 24 31 31 21 28 19 28 19 + 24 31 30 21 10 23 24 33 31 20 23 18 24 10 31 16 23 + 23 23 23 10 15 31 26 25 12 23 14 24 20 15 31 25 27 + 23 23 31 26 30 16 25 10 26 31 20 28 18 23 16 20 25 + 33 20 21 20 31 23 18 10 31 10 31 23 25 24 11 23 28 + 15 10 16 25 24 27 31 23 23 15 31 28 23 10 29 25 30 + 19 31 31 31 29 15 28 19 31 19 27 30 26 23 31 31 16 + 29 20 21 10 24 23 28 23 31 29 28 23 20 31 16 20 28 + 10 31 31 31 15 28 31 28 31 15 24 31 31 25 27 15 16 + + 17 14 12 27 16 0 23 12 24 18 24 23 18 18 0 24 12 + 27 21 21 26 20 25 27 12 19 27 27 25 27 18 11 10 27 + 27 27 21 27 27 23 27 27 27 26 27 12 24 27 10 23 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 15 15 26 + 27 27 18 12 27 27 24 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 19 23 27 23 16 14 + 15 0 10 11 18 15 19 27 21 24 27 26 24 16 27 27 14 + 12 12 17 16 18 10 10 10 26 14 15 12 10 0 22 11 16 + 14 14 5 27 24 16 12 16 25 19 25 26 11 24 19 24 19 + 16 25 25 11 16 14 15 27 26 10 12 0 15 16 27 10 14 + 23 14 12 16 16 26 23 20 14 14 12 16 10 15 27 20 23 + 12 19 25 23 25 15 21 16 23 25 15 24 10 12 15 10 20 + 27 10 11 10 25 17 15 18 25 18 26 12 21 15 15 15 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 19 26 27 26 24 11 24 19 27 19 23 25 23 12 26 27 10 + 24 10 19 16 18 14 24 14 27 24 24 12 10 25 10 15 24 + 16 25 26 25 15 24 25 24 27 15 18 25 27 21 23 18 10 + + 18 18 20 18 27 18 0 20 22 14 11 10 14 14 23 10 24 + 16 12 12 15 12 12 16 24 18 18 18 14 18 14 23 23 18 + 18 18 19 18 18 21 18 18 18 15 18 21 11 18 24 21 11 + 12 23 12 5 27 16 18 11 18 18 4 15 27 16 23 24 15 + 18 18 14 20 18 18 22 10 18 10 18 27 18 25 18 18 18 + 18 18 18 18 18 18 18 15 18 18 18 18 16 7 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 18 18 18 12 + 18 18 24 18 18 18 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 12 12 16 15 13 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 20 24 27 + 18 25 23 16 11 27 23 27 13 18 14 18 23 10 24 11 27 + 15 14 18 23 27 18 16 18 15 23 20 23 16 27 16 24 18 + 21 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 18 + 21 18 14 11 12 24 12 27 12 18 23 10 23 21 24 23 13 + 18 23 23 23 14 18 23 27 14 27 18 21 18 16 26 18 10 + 26 27 24 12 14 9 15 20 20 24 16 11 20 27 12 18 13 + 24 15 16 15 13 24 13 24 16 24 7 12 18 20 15 16 24 + 12 23 23 27 14 18 11 18 16 13 10 20 23 14 24 23 11 + 27 18 15 14 26 10 14 10 16 24 14 18 16 12 10 27 24 + + 17 10 11 25 23 25 20 0 24 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 19 25 25 24 25 12 11 12 25 + 25 25 21 25 25 23 25 25 25 24 25 10 23 25 14 23 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 15 16 24 + 25 25 15 10 25 25 24 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 10 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 19 16 24 16 23 10 + 18 12 12 11 12 15 19 24 15 23 24 24 23 16 24 24 10 + 5 9 17 23 23 12 12 12 24 20 21 12 12 12 22 15 23 + 10 20 12 24 21 23 12 23 23 19 24 24 11 21 19 23 23 + 12 24 23 11 23 10 15 25 24 12 10 12 11 23 24 14 12 + 23 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 19 + 10 19 24 16 23 15 15 23 16 24 15 21 12 10 15 12 15 + 25 12 11 12 24 17 15 23 24 23 24 10 19 11 21 15 21 + 21 23 14 14 12 20 24 9 6 15 24 23 5 23 23 19 23 + 19 24 24 24 23 15 23 19 24 19 20 23 19 8 24 24 14 + 23 12 19 23 14 10 23 10 24 23 21 9 12 24 14 15 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 14 10 8 25 23 25 20 9 0 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 16 25 25 24 25 12 11 12 25 + 25 25 18 25 25 20 25 25 25 24 25 10 23 25 14 20 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 12 16 24 + 25 25 12 7 25 25 21 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 7 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 16 16 24 16 23 10 + 18 12 12 11 12 14 16 24 15 23 24 24 23 13 24 24 10 + 2 6 14 23 23 12 12 12 24 20 21 12 12 12 19 15 23 + 10 20 12 24 21 23 12 23 23 16 24 24 11 21 16 23 23 + 12 24 23 11 23 10 12 25 24 12 7 12 11 23 24 14 10 + 20 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 16 24 16 23 14 15 23 16 24 12 21 12 10 14 12 14 + 25 12 11 12 24 14 12 23 24 23 24 10 16 11 21 12 21 + 21 23 14 14 12 20 24 6 3 15 24 23 2 23 23 16 23 + 16 24 24 24 23 15 23 16 24 16 20 23 16 5 24 24 14 + 23 12 16 23 12 10 23 10 24 23 21 6 12 24 14 12 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 17 14 15 23 25 23 12 15 24 0 14 11 11 11 21 12 23 + 21 6 11 20 10 16 21 23 19 23 23 18 23 11 18 20 23 + 23 23 21 23 23 23 23 23 23 20 23 16 14 23 23 23 14 + 10 20 8 12 25 21 19 14 23 23 12 20 25 21 20 23 20 + 23 23 15 15 23 23 24 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 8 12 5 12 20 23 23 23 23 23 23 23 23 11 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 14 15 21 20 15 16 21 21 14 + 15 15 17 25 25 20 21 21 20 24 24 21 21 21 22 23 25 + 14 24 21 21 12 25 21 25 16 19 18 20 18 12 23 14 25 + 12 18 19 18 25 14 15 23 20 20 15 21 12 25 21 23 14 + 23 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 19 + 16 19 18 10 16 23 11 25 14 19 20 12 21 16 23 20 15 + 23 20 18 20 18 17 21 25 18 25 20 16 19 12 24 15 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 19 16 + 23 20 21 20 15 23 15 23 21 23 12 16 19 15 20 21 23 + 15 20 19 25 14 14 14 14 21 15 12 15 20 18 23 20 14 + 25 19 20 18 24 12 18 12 21 23 11 19 21 0 11 25 23 + + 21 21 23 15 28 15 11 23 22 16 0 12 16 16 24 10 25 + 14 14 14 12 15 11 14 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 21 15 15 15 12 15 23 1 15 24 21 7 + 15 24 14 11 28 14 18 9 15 15 11 12 28 14 24 25 12 + 15 15 16 23 15 15 22 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 10 14 12 13 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 21 25 28 + 21 27 24 14 11 28 24 28 13 18 12 18 23 10 25 5 28 + 18 13 18 23 28 21 20 18 12 24 23 24 20 28 14 24 21 + 21 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 18 + 23 21 12 12 11 24 14 28 12 18 24 10 24 23 24 24 15 + 18 24 23 24 12 21 24 28 13 28 18 23 18 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 7 23 28 10 18 13 + 25 12 14 12 13 25 13 25 14 24 11 11 18 23 12 14 24 + 10 24 23 28 16 21 7 21 14 13 10 23 24 12 24 24 1 + 28 18 13 12 27 10 12 10 14 25 16 18 14 14 12 28 24 + + 24 24 25 0 31 0 18 25 24 23 15 0 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 17 14 15 23 25 23 12 15 24 11 14 11 0 11 21 12 23 + 21 6 11 20 10 16 21 23 19 23 23 18 23 11 18 20 23 + 23 23 21 23 23 23 23 23 23 20 23 16 14 23 23 23 14 + 10 20 8 12 25 21 19 14 23 23 12 20 25 21 20 23 20 + 23 23 15 15 23 23 24 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 8 12 5 12 20 23 23 23 23 23 23 23 23 11 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 14 15 21 20 15 16 21 21 14 + 15 15 17 25 25 20 21 21 20 24 24 21 21 21 22 23 25 + 14 24 21 21 12 25 21 25 16 19 18 20 18 12 23 14 25 + 12 18 19 18 25 14 15 23 20 20 15 21 12 25 21 23 14 + 23 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 19 + 16 19 18 10 16 23 11 25 14 19 20 12 21 16 23 20 15 + 23 20 18 20 18 17 21 25 18 25 20 16 19 12 24 15 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 19 16 + 23 20 21 20 15 23 15 23 21 23 12 16 19 15 20 21 23 + 15 20 19 25 14 14 14 14 21 15 12 15 20 18 23 20 14 + 25 19 20 18 24 12 18 12 21 23 11 19 21 0 11 25 23 + + 17 14 15 23 25 23 12 15 24 11 14 11 11 0 21 12 23 + 21 6 11 20 10 16 21 23 19 23 23 18 23 11 18 20 23 + 23 23 21 23 23 23 23 23 23 20 23 16 14 23 23 23 14 + 10 20 8 12 25 21 19 14 23 23 12 20 25 21 20 23 20 + 23 23 15 15 23 23 24 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 8 12 5 12 20 23 23 23 23 23 23 23 23 11 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 14 15 21 20 15 16 21 21 14 + 15 15 17 25 25 20 21 21 20 24 24 21 21 21 22 23 25 + 14 24 21 21 12 25 21 25 16 19 18 20 18 12 23 14 25 + 12 18 19 18 25 14 15 23 20 20 15 21 12 25 21 23 14 + 23 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 19 + 16 19 18 10 16 23 11 25 14 19 20 12 21 16 23 20 15 + 23 20 18 20 18 17 21 25 18 25 20 16 19 12 24 15 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 19 16 + 23 20 21 20 15 23 15 23 21 23 12 16 19 15 20 21 23 + 15 20 19 25 14 14 14 14 21 15 12 15 20 18 23 20 14 + 25 19 20 18 24 12 18 12 21 23 11 19 21 0 11 25 23 + + 15 15 14 28 15 28 24 14 15 20 24 23 20 20 0 24 15 + 27 23 23 27 21 25 27 11 15 28 28 26 28 20 15 11 28 + 28 28 15 28 28 15 28 28 28 27 28 15 24 28 15 15 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 11 11 27 + 28 28 20 14 28 28 15 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 28 27 15 28 28 28 16 24 28 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 15 24 24 10 23 27 23 15 15 + 12 15 15 15 20 0 4 27 23 25 27 27 25 15 27 27 15 + 14 14 15 15 16 15 10 10 27 15 14 10 10 15 15 15 15 + 15 12 10 27 24 15 10 15 25 18 26 27 12 24 10 24 15 + 18 26 25 15 15 15 16 28 27 15 14 15 16 15 27 9 15 + 15 15 15 15 15 27 23 21 15 15 15 18 15 12 27 21 23 + 15 15 26 23 25 0 23 15 23 26 11 24 10 12 0 11 21 + 28 15 15 11 26 15 10 16 26 16 27 12 23 16 14 15 24 + 14 15 15 21 20 24 27 14 14 15 27 24 14 15 25 21 25 + 11 27 27 27 25 15 24 11 27 4 24 25 23 14 27 27 15 + 25 15 12 15 20 15 24 15 27 25 24 14 15 26 15 11 24 + 15 26 27 26 14 24 26 24 27 11 20 26 27 23 23 16 4 + + 23 23 23 14 29 14 12 23 23 20 11 15 20 20 25 0 27 + 15 16 16 15 18 4 12 27 23 14 14 15 14 20 24 24 14 + 14 14 23 14 14 23 14 14 14 15 14 24 15 14 25 23 11 + 18 24 16 12 29 15 10 11 14 14 12 15 30 12 24 27 11 + 14 14 20 23 14 14 23 14 14 12 14 29 14 27 14 14 14 + 14 14 14 14 14 23 14 15 23 14 14 14 23 12 14 23 15 + 12 15 23 16 23 16 21 24 14 14 14 14 14 14 14 14 16 + 14 14 26 14 14 14 14 23 26 12 12 26 15 15 15 29 23 + 27 25 24 24 20 25 25 15 16 15 15 15 10 23 15 12 23 + 23 23 23 29 30 24 25 25 15 28 28 25 25 25 23 26 29 + 23 28 25 15 12 29 25 29 0 21 10 11 24 15 26 11 29 + 21 10 4 24 29 23 23 12 15 24 23 25 23 29 15 25 23 + 23 23 24 29 29 15 15 18 28 23 27 21 24 27 15 18 14 + 24 23 15 15 15 25 16 29 15 10 24 12 25 24 25 24 18 + 12 24 24 24 15 23 25 30 10 30 11 24 16 23 28 23 12 + 28 29 25 18 20 12 15 23 23 26 15 11 23 29 10 18 0 + 27 11 12 15 10 26 11 27 15 25 12 15 15 23 15 12 25 + 10 24 24 29 20 23 11 23 15 10 12 23 24 10 25 24 15 + 29 10 11 15 28 12 15 12 15 27 20 10 15 16 15 30 25 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 0 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 0 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 17 14 15 23 25 23 12 15 24 11 14 11 11 11 21 12 23 + 21 0 11 20 10 16 21 23 19 23 23 18 23 11 18 20 23 + 23 23 21 23 23 23 23 23 23 20 23 16 14 23 23 23 14 + 10 20 8 12 25 21 19 14 23 23 12 20 25 21 20 23 20 + 23 23 15 15 23 23 24 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 8 12 5 12 20 23 23 23 23 23 23 23 23 11 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 14 15 21 20 15 16 21 21 14 + 15 15 17 25 25 20 21 21 20 24 24 21 21 21 22 23 25 + 14 24 21 21 12 25 21 25 16 19 18 20 18 12 23 14 25 + 12 18 19 18 25 14 15 23 20 20 15 21 12 25 21 23 14 + 23 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 19 + 16 19 18 10 16 23 11 25 14 19 20 12 21 16 23 20 15 + 23 20 18 20 18 17 21 25 18 25 20 16 19 12 24 15 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 19 16 + 23 20 21 20 15 23 15 23 21 23 12 16 19 15 20 21 23 + 15 20 19 25 14 14 14 14 21 15 12 15 20 18 23 20 14 + 25 19 20 18 24 12 18 12 21 23 11 19 21 0 11 25 23 + + 17 14 15 23 25 23 12 15 24 11 14 11 11 11 21 12 23 + 21 6 0 20 10 16 21 23 19 23 23 18 23 11 18 20 23 + 23 23 21 23 23 23 23 23 23 20 23 16 14 23 23 23 14 + 10 20 8 12 25 21 19 14 23 23 12 20 25 21 20 23 20 + 23 23 15 15 23 23 24 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 8 12 5 12 20 23 23 23 23 23 23 23 23 11 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 14 15 21 20 15 16 21 21 14 + 15 15 17 25 25 20 21 21 20 24 24 21 21 21 22 23 25 + 14 24 21 21 12 25 21 25 16 19 18 20 18 12 23 14 25 + 12 18 19 18 25 14 15 23 20 20 15 21 12 25 21 23 14 + 23 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 19 + 16 19 18 10 16 23 11 25 14 19 20 12 21 16 23 20 15 + 23 20 18 20 18 17 21 25 18 25 20 16 19 12 24 15 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 19 16 + 23 20 21 20 15 23 15 23 21 23 12 16 19 15 20 21 23 + 15 20 19 25 14 14 14 14 21 15 12 15 20 18 23 20 14 + 25 19 20 18 24 12 18 12 21 23 11 19 21 0 11 25 23 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 0 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 17 16 18 20 26 20 10 18 24 12 12 0 12 12 23 11 24 + 18 11 11 16 0 14 18 24 19 20 20 15 20 12 21 23 20 + 20 20 21 20 20 23 20 20 20 16 20 20 12 20 23 23 12 + 12 23 11 10 26 18 19 12 20 20 10 16 27 18 23 24 16 + 20 20 15 18 20 20 24 8 20 11 20 26 20 24 20 20 20 + 20 20 20 20 20 16 20 16 16 20 20 20 15 10 20 18 10 + 11 18 15 11 15 11 14 23 20 20 20 20 20 20 20 20 11 + 20 20 24 20 20 20 20 16 24 11 11 24 10 18 10 26 16 + 24 23 23 21 12 23 23 18 14 12 18 16 15 16 18 18 16 + 18 18 17 26 27 23 23 23 16 25 25 23 23 23 22 24 26 + 16 25 23 18 12 26 23 26 15 19 15 19 21 11 24 12 26 + 14 15 19 21 26 16 15 20 16 23 18 23 15 26 18 23 16 + 23 16 20 26 26 16 10 12 25 16 24 14 23 24 18 12 19 + 20 19 15 10 14 23 11 26 14 19 23 11 23 20 23 23 15 + 20 23 21 23 15 17 23 27 15 27 19 20 19 15 25 16 11 + 25 26 23 12 12 10 16 18 18 24 18 12 18 26 12 19 15 + 24 16 18 16 15 24 15 24 18 23 10 14 19 18 16 18 23 + 12 23 21 26 14 16 12 16 18 15 11 18 23 15 23 23 12 + 26 19 16 15 25 11 15 11 18 24 12 19 18 11 0 27 23 + + 18 18 16 29 15 29 24 16 24 23 25 24 23 23 12 25 0 + 28 23 23 28 23 0 28 10 19 29 29 27 29 23 14 12 29 + 29 29 21 29 29 23 29 29 29 28 29 15 25 29 11 23 25 + 23 12 23 24 12 28 26 25 29 29 24 28 14 28 15 15 28 + 29 29 23 16 29 29 24 24 29 24 29 12 29 10 29 29 29 + 29 29 29 29 29 18 29 28 18 29 29 29 20 24 29 16 24 + 25 28 20 23 20 23 21 12 29 29 29 29 29 29 29 29 23 + 29 29 10 29 29 29 29 18 10 25 25 19 24 28 24 12 18 + 15 12 12 14 23 15 19 28 23 26 28 28 26 18 28 28 18 + 16 16 18 12 14 12 12 12 28 11 15 12 12 12 22 10 12 + 18 11 12 28 25 12 12 12 27 21 27 28 14 25 19 25 19 + 21 27 27 14 12 18 20 29 28 12 16 12 20 12 28 11 18 + 23 18 15 12 15 28 24 23 11 18 0 21 12 15 28 23 24 + 15 19 27 24 27 15 23 12 24 27 15 25 12 15 15 12 23 + 29 12 14 12 27 18 15 14 27 14 28 15 23 20 12 18 25 + 15 12 11 23 23 24 28 16 16 10 28 25 16 12 26 23 27 + 19 28 28 28 26 10 25 19 28 19 24 27 24 16 28 28 11 + 26 12 19 12 23 18 25 18 28 26 25 16 12 27 11 15 25 + 12 27 28 27 15 25 27 25 28 15 23 27 28 23 24 15 11 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 0 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 0 21 11 15 0 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 0 11 24 12 11 27 24 12 + 21 25 20 15 31 10 19 12 11 11 15 0 31 15 25 28 6 + 11 11 23 24 11 11 24 16 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 0 24 11 11 11 23 15 11 24 18 + 14 10 23 20 23 20 23 25 11 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 0 15 24 10 10 24 + 24 24 24 31 31 25 26 26 0 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 15 23 10 19 25 14 27 12 31 + 23 15 19 25 31 24 23 19 0 25 24 26 23 31 10 27 24 + 24 24 24 31 31 0 18 21 29 24 28 23 25 28 10 21 19 + 24 24 10 18 11 27 20 31 18 19 25 14 26 24 27 25 21 + 19 25 25 25 10 24 26 31 15 31 19 24 20 23 30 24 14 + 30 31 27 21 23 15 0 24 24 27 10 12 24 31 12 21 15 + 28 10 10 0 15 27 15 28 10 27 15 11 19 24 0 15 27 + 12 25 25 31 23 24 12 24 10 15 14 24 25 10 27 25 12 + 31 19 15 10 30 14 10 14 10 28 23 19 10 20 16 31 27 + + 15 10 10 25 23 25 20 11 22 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 0 25 25 24 25 12 11 12 25 + 25 25 19 25 25 21 25 25 25 24 25 10 23 25 14 21 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 13 16 24 + 25 25 13 9 25 25 22 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 9 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 18 16 24 16 23 10 + 18 12 12 11 12 14 18 24 15 23 24 24 23 14 24 24 10 + 4 7 15 23 23 12 12 12 24 20 21 12 12 12 20 15 23 + 10 20 12 24 21 23 12 23 23 18 24 24 11 21 18 23 23 + 12 24 23 11 23 10 13 25 24 12 9 12 11 23 24 14 11 + 21 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 18 24 16 23 14 15 23 16 24 13 21 12 10 14 12 14 + 25 12 11 12 24 15 13 23 24 23 24 10 18 11 21 13 21 + 21 23 14 14 12 20 24 7 5 15 24 23 4 23 23 18 23 + 18 24 24 24 23 15 23 18 24 18 20 23 18 6 24 24 14 + 23 12 18 23 12 10 23 10 24 23 21 7 12 24 14 13 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 24 24 24 14 31 14 16 24 24 23 14 18 23 23 27 15 28 + 15 21 21 15 23 12 0 28 24 0 14 15 14 23 25 26 14 + 14 14 24 14 14 24 14 14 14 15 14 25 15 14 27 24 14 + 23 26 21 16 31 15 12 14 14 14 16 15 31 0 26 28 10 + 14 14 23 24 14 14 24 18 14 16 14 31 14 29 14 14 14 + 14 14 14 14 14 24 14 15 24 14 14 14 24 16 14 24 20 + 15 15 24 21 24 21 23 26 14 14 14 14 14 14 14 14 21 + 14 14 28 14 14 14 14 24 28 15 15 28 20 15 20 31 24 + 29 27 26 25 23 27 27 15 21 15 15 15 12 24 15 9 24 + 24 24 24 31 31 26 27 27 15 30 31 27 27 27 24 28 31 + 24 30 27 15 15 31 27 31 12 23 11 10 25 15 28 14 31 + 23 11 12 25 31 24 24 10 15 26 24 27 24 31 15 27 24 + 24 24 25 31 31 15 20 23 30 24 28 23 26 29 15 23 18 + 25 24 15 20 15 27 21 31 20 11 26 15 27 25 27 26 23 + 10 26 25 26 15 24 27 31 11 31 10 25 21 24 31 24 15 + 31 31 27 23 23 16 15 24 24 28 15 14 24 31 12 23 12 + 28 10 9 15 12 28 14 28 15 27 16 15 20 24 15 0 27 + 12 26 25 31 23 24 14 24 15 12 15 24 26 11 27 26 15 + 31 11 10 15 31 15 15 15 15 28 23 11 15 21 18 31 27 + + 23 23 23 12 29 12 12 23 23 20 11 14 20 20 25 12 27 + 12 16 16 11 18 0 12 27 23 12 0 10 12 20 24 24 12 + 12 12 23 12 12 23 12 12 12 11 12 24 11 12 25 23 11 + 18 24 16 12 29 12 10 11 12 12 12 11 30 12 24 27 11 + 12 12 20 23 12 12 23 14 12 12 12 29 12 27 12 12 12 + 12 12 12 12 12 23 12 11 23 12 12 12 23 12 12 23 15 + 12 12 23 16 23 16 21 24 12 12 12 12 12 12 12 12 16 + 12 12 26 12 12 12 12 23 26 12 12 26 15 12 15 29 23 + 27 25 24 24 20 25 25 12 16 10 12 11 10 23 12 12 23 + 23 23 23 29 30 24 25 25 11 28 28 25 25 25 23 26 29 + 23 28 25 12 12 29 25 29 4 21 10 11 24 12 26 11 29 + 21 10 9 24 29 23 23 12 11 24 23 25 23 29 12 25 23 + 23 23 24 29 29 11 15 18 28 23 27 21 24 27 12 18 14 + 24 23 10 15 10 25 16 29 15 10 24 12 25 24 25 24 18 + 12 24 24 24 10 23 25 30 10 30 11 24 16 23 28 23 12 + 28 29 25 18 20 12 11 23 23 26 12 11 23 29 10 18 4 + 27 11 12 11 10 26 11 27 12 25 12 10 15 23 11 12 25 + 10 24 24 29 20 23 11 23 12 10 12 23 24 10 25 24 11 + 29 10 11 10 28 12 10 12 12 27 20 10 12 16 14 30 25 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 0 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 12 12 14 23 24 23 12 14 14 10 15 12 10 10 20 14 23 + 23 10 10 21 0 18 23 23 12 23 23 20 0 10 16 18 23 + 23 23 12 23 23 12 23 23 23 21 23 15 15 23 21 12 15 + 4 18 10 12 24 23 16 15 23 23 12 21 25 23 18 23 21 + 23 23 10 14 23 23 14 12 23 12 23 24 23 23 23 23 23 + 23 23 23 23 23 12 23 21 12 23 23 23 12 12 23 14 11 + 14 23 12 10 12 10 11 18 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 12 23 14 14 23 11 23 11 24 12 + 23 20 18 16 10 21 21 23 10 16 23 21 16 12 23 23 12 + 14 14 12 24 25 18 20 20 21 24 24 20 20 20 12 23 24 + 12 24 20 23 14 24 20 24 18 11 20 21 16 14 23 15 24 + 11 20 18 16 24 12 12 23 21 18 14 20 12 24 23 21 12 + 12 12 15 24 24 21 11 3 24 12 23 11 18 23 23 10 12 + 15 12 20 11 18 21 10 24 11 20 18 14 20 15 21 18 4 + 23 18 16 18 20 12 20 25 20 25 21 15 10 12 24 12 14 + 24 24 21 10 10 12 21 14 14 23 23 15 14 24 16 9 18 + 23 21 23 21 16 23 15 23 23 21 12 18 11 14 21 23 21 + 16 18 16 24 10 12 15 12 23 16 14 14 18 20 21 18 15 + 24 20 21 20 24 14 20 14 23 23 10 20 23 10 12 25 21 + + 23 23 24 12 30 12 14 24 24 21 12 15 21 21 25 12 27 + 11 18 18 10 20 10 15 27 23 12 12 0 12 0 24 25 12 + 12 12 23 12 12 23 12 12 12 10 12 24 12 12 26 23 12 + 20 25 18 14 30 11 19 12 12 12 14 10 31 15 25 27 10 + 12 12 21 24 12 12 24 15 12 14 12 30 12 28 12 12 12 + 12 12 12 12 12 23 12 10 23 12 12 12 23 14 12 24 16 + 12 11 23 18 23 18 23 25 12 12 12 12 12 12 12 12 18 + 12 12 27 12 12 12 12 23 27 12 12 27 16 11 16 30 23 + 28 25 25 24 21 26 26 11 18 11 11 10 15 23 11 11 23 + 24 24 23 30 31 25 25 25 10 28 29 25 25 25 23 27 30 + 23 28 25 11 12 30 25 30 15 23 10 19 24 12 27 12 30 + 23 15 19 24 30 23 23 19 10 25 24 25 23 30 11 26 23 + 23 23 24 30 30 10 16 20 28 23 27 23 25 28 11 20 19 + 24 23 0 16 10 26 18 30 16 19 25 12 25 24 26 25 20 + 19 25 24 25 0 23 25 31 15 31 19 24 19 23 29 23 12 + 29 30 26 20 21 14 10 24 24 27 11 12 24 30 11 20 15 + 27 10 11 10 15 27 15 27 11 26 14 10 19 24 10 15 26 + 11 25 24 30 21 23 12 23 11 15 12 24 25 6 26 25 12 + 30 19 15 0 29 12 0 12 11 27 21 19 11 18 15 31 26 + + 12 12 12 27 18 27 23 12 12 16 24 23 16 16 15 23 15 + 26 20 20 25 18 24 26 12 12 27 27 25 27 16 0 9 27 + 27 27 12 27 27 12 27 27 27 25 27 15 24 27 15 12 24 + 18 9 20 23 18 26 24 24 27 27 23 25 20 26 0 12 25 + 27 27 16 12 27 27 12 23 27 23 27 18 27 14 27 27 27 + 27 27 27 27 27 12 27 25 12 27 27 27 15 23 27 12 21 + 23 26 14 20 14 20 15 9 27 27 27 27 27 27 27 27 20 + 27 27 12 27 27 27 27 12 15 23 23 12 21 26 21 18 12 + 14 15 15 15 16 11 11 26 20 24 26 25 24 12 26 26 12 + 12 12 12 18 20 15 10 10 25 15 16 10 10 15 12 15 18 + 15 15 10 26 23 18 10 18 24 15 25 25 10 23 12 24 18 + 15 25 24 15 18 12 14 27 25 15 12 15 15 18 26 11 12 + 12 15 15 18 18 25 21 18 15 15 15 15 15 14 26 18 23 + 15 12 25 21 24 11 20 18 21 25 0 23 10 11 11 9 18 + 27 15 15 9 25 12 10 20 25 20 25 11 20 14 16 12 23 + 16 18 15 18 16 23 25 12 12 15 26 24 12 18 24 18 24 + 12 25 26 25 24 15 24 12 26 11 23 24 21 12 25 26 15 + 24 15 10 18 16 12 24 12 26 24 23 12 15 25 15 0 24 + 18 25 25 25 16 23 25 23 26 12 16 25 26 20 23 20 11 + + 17 12 11 26 20 26 23 12 24 15 23 21 15 15 11 23 14 + 25 18 18 25 16 24 25 14 19 26 26 24 26 15 0 0 26 + 26 26 21 26 26 23 26 26 26 25 26 10 23 26 12 23 23 + 16 10 18 23 20 25 24 23 26 26 23 25 21 25 15 15 25 + 26 26 15 11 26 26 24 21 26 23 26 20 26 15 26 26 26 + 26 26 26 26 26 12 26 25 12 26 26 26 12 23 26 11 20 + 23 25 12 18 12 18 14 10 26 26 26 26 26 26 26 26 18 + 26 26 12 26 26 26 26 12 12 23 23 19 20 25 20 20 12 + 15 11 10 0 15 15 19 25 18 24 25 25 24 16 25 25 12 + 11 11 17 20 21 10 11 11 25 16 18 12 11 11 22 12 20 + 12 16 11 25 23 20 12 20 24 19 24 25 10 23 19 23 20 + 14 24 24 0 20 12 15 26 25 10 11 11 12 20 25 12 12 + 23 12 10 20 20 25 20 16 16 12 14 14 10 15 25 16 21 + 10 19 24 20 24 15 18 20 20 24 15 23 11 10 15 10 16 + 26 10 0 10 24 17 15 21 24 21 25 10 19 12 18 15 23 + 18 20 12 16 15 23 25 11 11 12 25 23 11 20 24 19 24 + 19 25 25 25 24 12 23 19 25 19 23 24 20 11 25 25 12 + 24 10 19 20 15 12 23 12 25 24 23 11 10 24 12 15 23 + 20 24 25 24 18 23 24 23 25 15 15 24 25 18 21 21 12 + + 18 18 20 18 27 18 7 20 22 14 11 10 14 14 23 10 24 + 16 12 12 15 12 12 16 24 18 18 18 14 18 14 23 23 0 + 18 18 19 18 18 21 18 18 18 15 18 21 11 18 24 21 11 + 12 23 12 5 27 16 18 11 18 18 4 15 27 16 23 24 15 + 18 18 14 20 18 18 22 10 18 10 18 27 18 25 18 18 18 + 18 18 18 18 18 18 18 15 18 18 18 18 16 7 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 18 18 18 12 + 18 18 24 18 18 18 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 12 12 16 15 13 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 20 24 27 + 18 25 23 16 11 27 23 27 13 18 14 18 23 10 24 11 27 + 15 14 18 23 27 18 16 18 15 23 20 23 16 27 16 24 18 + 21 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 18 + 21 18 14 11 12 24 12 27 12 18 23 10 23 21 24 23 13 + 18 23 23 23 14 18 23 27 14 27 18 21 18 16 26 18 10 + 26 27 24 12 14 9 15 20 20 24 16 11 20 27 12 18 13 + 24 15 16 15 13 24 13 24 16 24 7 12 18 20 15 16 24 + 12 23 23 27 14 18 11 18 16 13 10 20 23 14 24 23 11 + 27 18 15 14 26 10 14 10 16 24 14 18 16 12 10 27 24 + + 11 0 10 24 23 24 18 10 18 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 14 24 24 23 24 12 12 12 24 + 0 24 15 24 24 17 24 24 24 24 24 11 21 24 15 17 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 12 18 24 + 24 24 12 10 24 24 18 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 1 24 24 4 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 0 16 20 20 16 15 24 15 23 3 + 20 14 12 12 12 15 15 24 14 23 24 24 23 10 24 24 0 + 10 10 11 23 23 12 14 14 24 21 23 14 14 14 16 16 23 + 5 21 14 24 20 23 14 23 23 14 23 24 12 20 16 21 23 + 11 23 23 12 23 4 10 24 24 12 10 14 10 23 24 15 7 + 17 5 11 23 23 24 15 12 21 5 18 11 12 20 24 12 16 + 11 14 23 15 23 15 14 23 15 23 12 20 14 11 15 12 12 + 24 12 12 12 23 11 14 23 23 23 24 11 14 10 23 9 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 14 23 + 18 24 24 24 23 16 21 18 24 15 18 23 15 10 24 24 15 + 23 12 14 23 12 3 21 1 24 23 20 10 12 23 15 12 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 14 2 10 24 23 24 18 10 21 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 16 24 24 23 24 12 12 12 24 + 24 0 18 24 24 20 24 24 24 24 24 11 21 24 15 20 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 12 18 24 + 24 24 12 10 24 24 21 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 3 24 24 7 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 2 16 20 20 16 15 24 15 23 6 + 20 14 12 12 12 15 16 24 14 23 24 24 23 13 24 24 2 + 10 10 14 23 23 12 14 14 24 21 23 14 14 14 19 16 23 + 3 21 14 24 20 23 14 23 23 16 23 24 12 20 16 21 23 + 11 23 23 12 23 7 12 24 24 12 10 14 10 23 24 15 9 + 20 3 11 23 23 24 15 12 21 3 18 11 12 20 24 12 16 + 11 16 23 15 23 15 14 23 15 23 12 20 14 11 15 12 12 + 24 12 12 12 23 14 14 23 23 23 24 11 16 10 23 12 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 16 23 + 18 24 24 24 23 16 21 18 24 16 18 23 16 10 24 24 15 + 23 12 16 23 12 6 21 3 24 23 20 10 12 23 15 12 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 17 10 11 25 23 25 20 12 24 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 19 25 25 24 25 12 11 12 25 + 25 25 0 25 25 23 25 25 25 24 25 10 23 25 14 23 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 15 16 24 + 25 25 15 10 25 25 24 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 10 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 19 16 24 16 23 10 + 18 12 12 11 12 15 19 24 15 23 24 24 23 16 24 24 10 + 5 9 17 23 23 12 12 12 24 20 21 12 12 12 22 15 23 + 10 20 12 24 21 23 12 23 23 19 24 24 11 21 19 23 23 + 12 24 23 11 23 10 15 25 24 12 10 12 11 23 24 14 12 + 23 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 19 + 10 19 24 16 23 15 15 23 16 24 15 21 12 10 15 12 15 + 25 12 11 12 24 17 15 23 24 23 24 10 19 11 21 15 21 + 21 23 14 14 12 20 24 9 6 15 24 23 5 23 23 19 23 + 19 24 24 24 23 15 23 19 24 19 20 23 19 8 24 24 14 + 23 12 19 23 14 10 23 10 24 23 21 9 12 24 14 15 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 14 14 15 23 25 23 12 15 17 11 14 11 11 11 21 12 23 + 21 0 4 20 10 16 21 23 14 23 23 18 23 11 18 20 23 + 23 23 14 0 23 16 23 23 23 20 23 16 14 23 23 16 14 + 10 20 1 12 25 21 15 14 23 23 12 20 25 21 20 23 20 + 23 23 11 15 23 23 17 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 1 12 1 12 20 23 23 23 23 23 23 23 23 4 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 7 15 21 20 15 14 21 21 14 + 15 15 14 25 25 20 21 21 20 24 24 21 21 21 15 23 25 + 14 24 21 21 12 25 21 25 16 12 18 20 18 12 23 14 25 + 12 18 16 18 25 14 12 23 20 20 15 21 12 25 21 23 14 + 16 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 12 + 16 14 18 10 16 23 4 25 10 18 20 12 21 16 23 20 10 + 23 20 18 20 18 14 21 25 18 25 20 16 12 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 12 16 + 23 20 21 20 15 23 14 23 21 23 12 16 12 15 20 21 23 + 15 20 18 25 11 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 6 11 25 23 + + 10 10 4 25 23 25 20 6 17 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 12 25 25 24 25 12 11 12 25 + 25 25 14 25 0 16 25 25 25 24 25 10 23 25 14 16 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 12 16 24 + 25 25 12 3 25 25 17 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 3 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 15 16 24 16 23 10 + 18 12 12 11 12 14 14 24 15 23 24 24 23 10 24 24 10 + 1 2 10 23 23 12 12 12 24 20 21 12 12 12 15 15 23 + 10 20 12 24 21 23 12 23 23 12 24 24 11 21 15 23 23 + 12 24 23 11 23 10 11 25 24 12 3 12 11 23 24 14 10 + 16 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 12 24 16 23 14 15 23 16 24 12 21 12 10 14 12 14 + 25 12 11 12 24 10 12 23 24 23 24 10 15 11 21 10 21 + 21 23 14 14 12 20 24 2 0 15 24 23 1 23 23 14 23 + 16 24 24 24 23 15 23 16 24 14 20 23 16 1 24 24 14 + 23 12 12 23 12 10 23 10 24 23 21 2 12 24 14 12 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 14 10 8 25 23 25 20 9 21 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 16 25 25 24 25 12 11 12 25 + 25 25 18 25 25 0 25 25 25 24 25 10 23 25 14 20 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 12 16 24 + 25 25 12 7 25 25 21 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 7 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 16 16 24 16 23 10 + 18 12 12 11 12 14 16 24 15 23 24 24 23 13 24 24 10 + 2 6 14 23 23 12 12 12 24 20 21 12 12 12 19 15 23 + 10 20 12 24 21 23 12 23 23 16 24 24 11 21 16 23 23 + 12 24 23 11 23 10 12 25 24 12 7 12 11 23 24 14 10 + 20 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 16 24 16 23 14 15 23 16 24 12 21 12 10 14 12 14 + 25 12 11 12 24 14 12 23 24 23 24 10 16 11 21 12 21 + 21 23 14 14 12 20 24 6 3 15 24 23 2 23 23 16 23 + 16 24 24 24 23 15 23 16 24 16 20 23 16 5 24 24 14 + 23 12 16 23 12 10 23 10 24 23 21 6 12 24 14 12 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 10 10 0 25 23 25 20 1 12 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 10 25 25 24 25 12 11 12 25 + 25 25 10 25 25 11 0 25 25 24 25 11 23 25 14 11 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 12 16 24 + 25 25 12 1 25 25 12 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 1 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 15 16 24 16 23 10 + 18 12 12 11 12 14 14 24 15 23 24 24 23 10 24 24 10 + 6 2 10 23 23 12 12 12 24 20 21 12 12 12 10 15 23 + 11 20 12 24 21 23 12 23 23 12 24 24 11 21 15 23 23 + 12 24 23 11 23 10 11 25 24 12 1 12 11 23 24 14 10 + 11 11 11 23 23 24 16 14 20 11 16 12 12 18 24 14 18 + 11 10 24 16 23 14 15 23 16 24 12 21 12 10 14 12 14 + 25 12 11 12 24 10 12 23 24 23 24 10 15 11 21 10 21 + 21 23 14 14 12 20 24 2 4 15 24 23 6 23 23 14 23 + 16 24 24 24 23 15 23 16 24 14 20 23 16 3 24 24 14 + 23 12 11 23 12 10 23 10 24 23 21 2 12 24 14 12 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 9 2 10 24 23 24 18 10 16 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 11 24 24 23 24 12 12 12 24 + 24 24 12 24 24 15 24 0 24 24 24 11 21 24 15 15 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 12 18 24 + 24 24 12 10 24 24 16 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 1 24 24 2 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 2 16 20 20 16 15 24 15 23 1 + 20 14 12 12 12 15 15 24 14 23 24 24 23 8 24 24 2 + 10 10 9 23 23 12 14 14 24 21 23 14 14 14 14 16 23 + 8 21 14 24 20 23 14 23 23 11 23 24 12 20 16 21 23 + 11 23 23 12 23 2 10 24 24 12 10 14 10 23 24 15 4 + 15 8 11 23 23 24 15 12 21 8 18 11 12 20 24 12 16 + 11 11 23 15 23 15 14 23 15 23 12 20 14 11 15 12 12 + 24 12 12 12 23 9 14 23 23 23 24 11 14 10 23 7 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 12 23 + 18 24 24 24 23 16 21 18 24 15 18 23 15 10 24 24 15 + 23 12 12 23 12 1 21 1 24 23 20 10 12 23 15 12 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 10 10 1 25 23 25 20 0 11 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 10 25 25 24 25 12 12 12 25 + 25 25 10 25 25 10 25 25 0 24 25 12 23 25 14 10 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 12 16 24 + 25 25 12 2 25 25 11 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 12 20 25 2 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 15 16 24 16 23 10 + 18 12 12 12 12 14 14 24 15 23 24 24 23 10 24 24 10 + 7 3 10 23 23 12 12 12 24 20 21 12 12 12 10 15 23 + 12 20 12 24 21 23 12 23 23 12 24 24 11 21 15 23 23 + 12 24 23 12 23 10 11 25 24 12 2 12 12 23 24 14 10 + 10 12 12 23 23 24 16 14 20 12 16 12 12 18 24 14 18 + 12 10 24 16 23 14 15 23 16 24 12 21 12 10 14 12 14 + 25 12 12 12 24 10 12 23 24 23 24 10 15 11 21 10 21 + 21 23 14 14 12 20 24 3 6 15 24 23 7 23 23 14 23 + 16 24 24 24 23 15 23 16 24 14 20 23 16 4 24 24 14 + 23 12 11 23 12 10 23 10 24 23 21 3 12 24 14 12 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 0 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 10 10 1 25 23 25 20 0 11 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 10 25 25 24 25 12 12 12 25 + 25 25 10 25 25 10 25 25 25 24 0 12 23 25 14 10 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 12 16 24 + 25 25 12 2 25 25 11 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 12 20 25 2 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 15 16 24 16 23 10 + 18 12 12 12 12 14 14 24 15 23 24 24 23 10 24 24 10 + 7 3 10 23 23 12 12 12 24 20 21 12 12 12 10 15 23 + 12 20 12 24 21 23 12 23 23 12 24 24 11 21 15 23 23 + 12 24 23 12 23 10 11 25 24 12 2 12 12 23 24 14 10 + 10 12 12 23 23 24 16 14 20 12 16 12 12 18 24 14 18 + 12 10 24 16 23 14 15 23 16 24 12 21 12 10 14 12 14 + 25 12 12 12 24 10 12 23 24 23 24 10 15 11 21 10 21 + 21 23 14 14 12 20 24 3 6 15 24 23 7 23 23 14 23 + 16 24 24 24 23 15 23 16 24 14 20 23 16 4 24 24 14 + 23 12 11 23 12 10 23 10 24 23 21 3 12 24 14 12 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 0 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 0 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 6 4 10 24 23 24 18 10 13 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 9 24 24 23 24 12 12 12 24 + 24 24 10 24 24 12 24 24 24 24 24 11 21 0 15 12 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 12 18 24 + 24 24 12 10 24 24 13 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 3 24 24 0 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 4 16 20 20 16 15 24 15 23 1 + 20 14 12 12 12 15 15 24 14 23 24 24 23 5 24 24 4 + 10 10 6 23 23 12 14 14 24 21 23 14 14 14 11 16 23 + 10 21 14 24 20 23 14 23 23 11 23 24 12 20 16 21 23 + 11 23 23 12 23 0 10 24 24 12 10 14 10 23 24 15 2 + 12 10 11 23 23 24 15 12 21 10 18 11 12 20 24 12 16 + 11 9 23 15 23 15 14 23 15 23 12 20 14 11 15 12 12 + 24 12 12 12 23 6 14 23 23 23 24 11 14 10 23 4 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 12 23 + 18 24 24 24 23 16 21 18 24 15 18 23 15 10 24 24 15 + 23 12 12 23 12 1 21 3 24 23 20 10 12 23 15 12 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 0 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 17 10 11 25 23 25 20 12 24 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 19 25 25 24 25 12 11 12 25 + 25 25 21 25 25 23 25 25 25 24 25 10 23 25 14 0 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 15 16 24 + 25 25 15 10 25 25 24 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 10 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 19 16 24 16 23 10 + 18 12 12 11 12 15 19 24 15 23 24 24 23 16 24 24 10 + 5 9 17 23 23 12 12 12 24 20 21 12 12 12 22 15 23 + 10 20 12 24 21 23 12 23 23 19 24 24 11 21 19 23 23 + 12 24 23 11 23 10 15 25 24 12 10 12 11 23 24 14 12 + 23 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 19 + 10 19 24 16 23 15 15 23 16 24 15 21 12 10 15 12 15 + 25 12 11 12 24 17 15 23 24 23 24 10 19 11 21 15 21 + 21 23 14 14 12 20 24 9 6 15 24 23 5 23 23 19 23 + 19 24 24 24 23 15 23 19 24 19 20 23 19 8 24 24 14 + 23 12 19 23 14 10 23 10 24 23 21 9 12 24 14 15 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 21 21 23 15 28 15 11 23 22 16 10 12 16 16 24 10 25 + 14 14 14 12 15 11 14 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 21 15 15 15 12 15 23 1 15 24 21 0 + 15 24 14 11 28 14 18 9 15 15 11 12 28 14 24 25 12 + 15 15 16 23 15 15 22 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 10 14 12 13 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 21 25 28 + 21 27 24 14 11 28 24 28 13 18 12 18 23 10 25 5 28 + 18 13 18 23 28 21 20 18 12 24 23 24 20 28 14 24 21 + 21 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 18 + 23 21 12 12 11 24 14 28 12 18 24 10 24 23 24 24 15 + 18 24 23 24 12 21 24 28 13 28 18 23 18 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 7 23 28 10 18 13 + 25 12 14 12 13 25 13 25 14 24 11 11 18 23 12 14 24 + 10 24 23 28 16 21 7 21 14 13 10 23 24 12 24 24 1 + 28 18 13 12 27 10 12 10 14 25 16 18 14 14 12 28 24 + + 21 21 23 15 28 15 11 23 24 16 11 12 16 16 24 10 25 + 14 14 14 12 15 11 15 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 23 15 15 15 12 15 23 0 15 24 23 9 + 0 24 14 11 28 14 19 10 15 15 11 12 28 15 24 25 12 + 15 15 16 23 15 15 24 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 10 14 12 15 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 22 25 28 + 21 27 24 14 12 28 24 28 15 19 12 19 23 10 25 6 28 + 18 15 19 23 28 21 20 19 12 24 23 24 20 28 14 24 21 + 23 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 19 + 23 21 12 12 11 24 14 28 14 19 24 10 24 23 24 24 15 + 19 24 23 24 12 21 24 28 15 28 19 23 19 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 9 23 28 10 19 15 + 25 12 14 12 15 25 15 25 14 24 11 11 19 23 12 15 24 + 10 24 23 28 16 21 9 21 14 15 10 23 24 12 24 24 0 + 28 19 15 12 27 10 12 10 14 25 16 19 14 14 12 28 24 + + 17 11 12 24 24 24 15 12 24 10 18 14 10 10 16 16 21 + 23 12 12 23 11 21 23 21 19 24 24 23 24 10 14 15 24 + 24 24 21 24 24 23 24 24 24 23 24 12 18 24 18 23 18 + 11 0 12 15 24 23 20 18 24 24 15 23 24 23 15 21 23 + 24 24 15 12 24 24 24 14 24 15 24 24 24 23 24 24 24 + 24 24 24 24 24 11 24 23 11 24 24 24 10 15 24 12 12 + 16 23 10 12 10 12 0 15 24 24 24 24 24 24 24 24 12 + 24 24 20 24 24 24 24 11 20 16 16 20 12 23 12 24 11 + 23 16 15 14 10 18 19 23 14 20 23 23 20 16 23 23 11 + 12 12 17 24 24 15 16 16 23 23 23 16 16 16 22 20 24 + 11 23 16 23 16 24 16 24 21 19 23 23 14 16 20 18 24 + 10 23 21 14 24 11 15 24 23 15 12 16 10 24 23 18 12 + 23 11 12 24 24 23 12 11 23 11 21 0 15 23 23 11 19 + 12 19 23 12 21 18 12 24 14 23 15 16 16 12 18 15 15 + 24 15 14 15 23 17 16 24 23 24 23 12 19 10 23 15 16 + 23 24 18 11 10 15 23 12 12 20 23 18 12 24 20 19 21 + 21 23 23 23 20 20 18 21 23 19 15 21 19 12 23 23 18 + 20 15 19 24 14 11 18 11 23 20 16 12 15 23 18 15 18 + 24 23 23 23 23 16 23 16 23 21 10 23 23 12 14 24 18 + + 15 14 15 23 25 23 12 15 22 11 14 11 11 11 21 12 23 + 21 5 10 20 10 16 21 23 18 23 23 18 23 11 18 20 23 + 23 23 19 23 23 21 23 23 23 20 23 16 14 23 23 21 14 + 10 20 0 12 25 21 18 14 23 23 12 20 25 21 20 23 20 + 23 23 13 15 23 23 22 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 6 12 4 12 20 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 12 15 21 20 15 14 21 21 14 + 15 15 15 25 25 20 21 21 20 24 24 21 21 21 20 23 25 + 14 24 21 21 12 25 21 25 16 18 18 20 18 12 23 14 25 + 12 18 18 18 25 14 13 23 20 20 15 21 12 25 21 23 14 + 21 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 18 + 16 18 18 10 16 23 10 25 12 18 20 12 21 16 23 20 13 + 23 20 18 20 18 15 21 25 18 25 20 16 18 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 18 16 + 23 20 21 20 15 23 14 23 21 23 12 16 18 15 20 21 23 + 15 20 18 25 12 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 1 11 25 23 + + 15 14 15 23 25 23 12 15 22 11 14 11 11 11 21 12 23 + 21 5 10 20 10 16 21 23 18 23 23 18 23 11 18 20 23 + 23 23 19 23 23 21 23 23 23 20 23 16 14 23 23 21 14 + 10 20 6 0 25 21 18 14 23 23 12 20 25 21 20 23 20 + 23 23 13 15 23 23 22 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 6 12 4 12 20 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 12 15 21 20 15 14 21 21 14 + 15 15 15 25 25 20 21 21 20 24 24 21 21 21 20 23 25 + 14 24 21 21 12 25 21 25 16 18 18 20 18 12 23 14 25 + 12 18 18 18 25 14 13 23 20 20 15 21 12 25 21 23 14 + 21 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 18 + 16 18 18 10 16 23 10 25 12 18 20 12 21 16 23 20 13 + 23 20 18 20 18 15 21 25 18 25 20 16 18 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 18 16 + 23 20 21 20 15 23 14 23 21 23 12 16 18 15 20 21 23 + 15 20 18 25 12 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 1 11 25 23 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 0 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 24 14 31 14 16 24 24 23 14 18 23 23 27 15 28 + 15 21 21 15 23 12 0 28 24 14 14 15 14 23 25 26 14 + 14 14 24 14 14 24 14 14 14 15 14 25 15 14 27 24 14 + 23 26 21 16 31 0 12 14 14 14 16 15 31 0 26 28 10 + 14 14 23 24 14 14 24 18 14 16 14 31 14 29 14 14 14 + 14 14 14 14 14 24 14 15 24 14 14 14 24 16 14 24 20 + 15 15 24 21 24 21 23 26 14 14 14 14 14 14 14 14 21 + 14 14 28 14 14 14 14 24 28 15 15 28 20 15 20 31 24 + 29 27 26 25 23 27 27 15 21 15 15 15 12 24 15 9 24 + 24 24 24 31 31 26 27 27 15 30 31 27 27 27 24 28 31 + 24 30 27 15 15 31 27 31 12 23 11 10 25 15 28 14 31 + 23 11 12 25 31 24 24 10 15 26 24 27 24 31 15 27 24 + 24 24 25 31 31 15 20 23 30 24 28 23 26 29 15 23 18 + 25 24 15 20 15 27 21 31 20 11 26 15 27 25 27 26 23 + 10 26 25 26 15 24 27 31 11 31 10 25 21 24 31 24 15 + 31 31 27 23 23 16 15 24 24 28 15 14 24 31 12 23 12 + 28 10 9 15 12 28 14 28 15 27 16 15 20 24 15 0 27 + 12 26 25 31 23 24 14 24 15 12 15 24 26 11 27 26 15 + 31 11 10 15 31 15 15 15 15 28 23 11 15 21 18 31 27 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 0 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 20 20 21 16 27 16 10 21 24 15 11 11 15 15 24 0 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 21 16 16 23 16 16 16 14 16 23 10 16 24 23 10 + 14 23 12 10 27 15 19 0 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 24 11 16 11 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 20 16 16 16 18 10 16 21 12 + 6 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 5 9 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 14 11 15 14 15 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 22 24 27 + 20 26 24 15 12 27 24 27 15 19 12 19 23 0 24 10 27 + 16 15 19 23 27 20 18 19 14 23 21 24 18 27 15 24 20 + 23 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 19 + 23 20 12 12 12 24 12 27 14 19 23 6 24 23 24 23 15 + 19 23 23 23 12 20 24 28 15 28 19 23 19 18 27 20 10 + 27 27 24 14 15 10 14 21 21 24 15 10 21 27 11 19 15 + 25 14 15 14 15 24 15 25 15 24 10 12 19 21 14 15 24 + 11 23 23 27 15 20 10 20 15 15 9 21 23 12 24 23 10 + 27 19 15 12 27 8 12 6 15 25 15 19 15 12 11 28 24 + + 21 21 23 15 28 15 11 23 21 16 2 12 16 16 24 10 25 + 14 14 14 12 15 11 14 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 21 15 15 15 12 15 23 9 15 24 21 0 + 15 24 14 11 28 14 10 1 0 15 11 12 28 14 24 25 12 + 15 15 16 23 15 15 21 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 10 14 12 10 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 21 25 28 + 21 27 24 14 10 28 24 28 11 18 12 12 23 10 25 2 28 + 18 12 11 23 28 21 20 15 12 24 23 24 20 28 14 24 21 + 21 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 12 + 23 21 12 12 11 24 14 28 12 12 24 10 24 23 24 24 15 + 15 24 23 24 12 21 24 28 12 28 12 23 14 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 0 23 28 10 15 11 + 25 12 14 12 10 25 5 25 14 24 11 11 12 23 12 14 24 + 10 24 23 28 16 21 0 21 14 10 10 23 24 12 24 24 9 + 28 12 12 12 27 10 12 10 14 25 16 12 14 14 12 28 24 + + 14 14 12 27 16 27 23 12 17 18 24 23 18 18 6 24 12 + 27 21 21 26 20 25 27 12 14 27 27 25 27 18 11 10 27 + 27 27 14 27 27 16 27 27 27 26 27 12 24 27 10 16 24 + 20 10 21 23 16 27 24 24 27 0 23 26 18 27 10 12 26 + 27 27 18 12 27 27 17 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 12 23 27 23 16 14 + 12 6 10 11 18 10 12 27 21 24 27 26 24 14 27 27 14 + 12 12 14 16 18 10 3 3 26 14 15 6 3 6 15 11 16 + 14 14 1 27 24 16 6 16 25 16 25 26 11 24 12 24 16 + 16 25 25 11 16 14 15 27 26 10 12 6 15 16 27 10 14 + 16 14 12 16 16 26 23 20 14 14 12 16 10 12 27 20 23 + 12 14 25 23 25 10 21 16 23 25 10 24 3 12 10 10 20 + 27 10 11 10 25 14 8 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 12 26 27 26 24 11 24 12 27 12 23 25 23 12 26 27 10 + 24 10 12 16 18 14 24 14 27 24 24 12 10 25 10 10 24 + 16 25 26 25 15 24 25 24 27 12 18 25 27 21 23 18 10 + + 15 15 16 21 25 21 11 16 22 12 12 10 12 12 23 12 24 + 20 10 10 18 11 15 20 24 18 21 21 16 21 12 20 21 21 + 21 21 19 21 21 21 21 21 21 18 21 18 12 21 23 21 12 + 11 21 10 11 25 20 18 12 21 21 0 18 26 20 21 24 18 + 21 21 13 16 21 21 22 10 21 11 21 25 21 24 21 21 21 + 21 21 21 21 21 15 21 18 15 21 21 21 14 11 21 16 5 + 12 20 14 10 14 10 12 21 21 21 21 21 21 21 21 21 10 + 21 21 23 21 21 21 21 15 23 12 12 23 5 20 6 25 15 + 24 23 21 20 12 23 23 20 12 14 20 18 14 15 20 20 15 + 16 16 15 25 26 21 23 23 18 24 25 23 23 23 20 23 25 + 15 24 23 20 12 25 23 25 15 18 16 18 20 12 23 12 25 + 12 16 18 20 25 15 14 21 18 21 16 23 14 25 20 23 15 + 21 15 18 25 25 18 6 11 24 15 24 12 21 24 20 11 18 + 18 18 16 4 15 23 10 25 12 18 21 12 23 18 23 21 13 + 21 21 20 21 16 15 23 26 16 26 18 18 18 14 25 15 12 + 25 25 23 11 12 11 18 16 16 23 20 12 16 25 14 18 15 + 24 18 20 18 14 23 13 24 20 23 11 15 18 16 18 20 23 + 14 21 20 25 12 15 12 15 20 14 12 16 21 16 23 21 12 + 25 18 18 16 25 12 16 12 20 24 12 18 20 10 10 26 23 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 0 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 23 23 23 33 15 33 27 23 24 24 28 27 24 24 18 28 14 + 31 25 25 31 25 30 31 14 23 33 33 31 33 24 21 20 33 + 33 33 23 33 33 23 33 33 33 31 33 23 28 33 16 23 28 + 25 20 25 27 10 31 29 28 33 33 27 31 0 31 20 15 31 + 33 33 24 23 33 33 24 27 33 27 33 10 33 12 33 33 33 + 33 33 33 33 33 23 33 31 23 33 33 33 24 27 33 23 26 + 28 31 24 25 24 25 24 20 33 33 33 33 33 33 33 33 25 + 33 33 15 33 33 33 33 23 15 28 28 19 26 31 26 10 23 + 15 18 20 21 24 16 19 31 25 29 31 31 29 23 31 31 23 + 23 23 23 10 6 20 18 18 31 12 15 18 18 18 23 15 10 + 23 12 18 31 28 10 18 10 30 24 31 31 21 28 19 28 19 + 24 31 30 21 10 23 24 33 31 20 23 18 24 10 31 16 23 + 23 23 23 10 15 31 26 25 12 23 14 24 20 15 31 25 27 + 23 23 31 26 30 16 25 10 26 31 20 28 18 23 16 20 25 + 33 20 21 20 31 23 18 10 31 10 31 23 25 24 11 23 28 + 15 10 16 25 24 27 31 23 23 15 31 28 23 10 29 25 30 + 19 31 31 31 29 15 28 19 31 19 27 30 26 23 31 31 16 + 29 20 21 10 24 23 28 23 31 29 28 23 20 31 16 20 28 + 10 31 31 31 15 28 31 28 31 15 24 31 31 25 27 15 16 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 0 21 11 15 28 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 0 11 24 12 11 27 24 12 + 21 25 20 15 31 10 19 12 11 11 15 0 31 0 25 28 6 + 11 11 23 24 11 11 24 16 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 0 24 11 11 11 23 15 11 24 18 + 14 10 23 20 23 20 23 25 11 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 0 15 24 10 10 24 + 24 24 24 31 31 25 26 26 0 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 15 23 10 19 25 14 27 12 31 + 23 15 19 25 31 24 23 19 0 25 24 26 23 31 10 27 24 + 24 24 24 31 31 0 18 21 29 24 28 23 25 28 10 21 19 + 24 24 10 18 11 27 20 31 18 19 25 14 26 24 27 25 21 + 19 25 25 25 10 24 26 31 15 31 19 24 20 23 30 24 14 + 30 31 27 21 23 15 0 24 24 27 10 12 24 31 12 21 15 + 28 10 10 0 15 27 15 28 10 27 15 11 19 24 0 15 27 + 12 25 25 31 23 24 12 24 10 15 14 24 25 10 27 25 12 + 31 19 15 10 30 14 10 14 10 28 23 19 10 20 16 31 27 + + 17 11 11 25 21 25 21 12 24 14 23 20 14 14 12 23 15 + 25 16 16 24 15 24 25 15 19 25 25 24 25 14 10 11 25 + 25 25 21 25 25 23 25 25 25 24 25 0 23 25 12 23 23 + 15 11 16 21 21 25 23 23 25 25 21 24 23 25 0 15 24 + 25 25 15 10 25 25 24 20 25 21 25 21 25 16 25 25 25 + 25 25 25 25 25 11 25 24 11 25 25 25 12 21 25 10 18 + 23 25 12 16 12 16 12 11 25 25 25 25 25 25 25 25 16 + 25 25 14 25 25 25 25 11 14 23 23 19 18 25 18 21 11 + 16 12 11 10 14 15 19 25 16 23 25 24 23 16 25 25 11 + 10 10 17 21 23 11 12 12 24 18 20 12 12 12 22 14 21 + 11 18 12 25 23 21 12 21 24 19 24 24 10 23 19 23 21 + 12 24 24 10 21 11 15 25 24 11 10 12 12 21 25 12 12 + 23 11 0 21 21 24 18 15 18 11 15 12 11 16 25 15 20 + 0 19 24 18 24 15 16 21 18 24 15 23 12 6 15 11 15 + 25 11 10 11 24 17 15 23 24 23 24 10 19 12 20 15 23 + 20 21 12 15 14 21 24 10 10 14 25 23 10 21 23 19 24 + 19 24 25 24 23 14 23 19 25 19 21 24 19 10 24 25 12 + 23 11 19 21 14 11 23 11 25 23 23 10 11 24 12 15 23 + 21 24 24 24 20 23 24 23 25 15 14 24 25 16 20 23 12 + + 21 21 23 15 28 15 11 23 24 16 11 12 16 16 24 10 25 + 14 14 14 12 15 11 15 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 23 15 15 15 12 15 23 0 15 24 23 9 + 15 24 14 11 28 14 19 10 15 15 11 12 28 15 24 0 12 + 15 15 16 23 15 15 24 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 10 14 12 15 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 22 25 28 + 21 27 24 14 12 28 24 28 15 19 12 19 23 10 25 6 28 + 18 15 19 23 28 21 20 19 12 24 23 24 20 28 14 24 21 + 23 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 19 + 23 21 12 12 11 24 14 28 14 19 24 10 24 23 24 24 15 + 19 24 23 24 12 21 24 28 15 28 19 23 19 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 9 23 28 10 19 15 + 25 12 14 12 15 25 15 25 14 24 11 11 19 23 12 15 24 + 10 24 23 28 16 21 9 21 14 15 10 23 24 12 24 24 0 + 28 19 15 12 27 10 12 10 14 25 16 19 14 14 12 28 24 + + 17 15 14 28 15 28 24 14 24 20 24 23 20 20 10 24 11 + 27 23 23 27 21 25 27 11 19 28 28 26 28 20 12 11 28 + 28 28 21 28 28 23 28 28 28 27 28 12 24 28 0 23 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 15 15 0 + 28 28 20 14 28 28 24 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 28 27 15 28 28 28 16 24 28 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 10 24 24 19 23 27 23 15 15 + 15 10 11 12 20 15 19 27 23 25 27 27 25 16 27 27 15 + 14 14 17 15 16 11 10 10 27 12 15 12 10 10 22 10 15 + 15 12 10 27 24 15 12 15 25 19 26 27 12 24 19 24 19 + 18 26 25 12 15 15 16 28 27 11 14 10 16 15 27 5 15 + 23 15 12 15 15 27 23 21 12 15 11 18 11 15 27 21 23 + 12 19 26 23 25 15 23 15 23 26 15 24 10 12 15 11 21 + 28 11 12 11 26 17 15 16 26 16 27 12 23 16 14 15 24 + 15 15 0 21 20 24 27 14 14 10 27 24 14 15 25 21 25 + 19 27 27 27 25 10 24 19 27 19 24 25 23 14 27 27 0 + 25 11 19 15 20 15 24 15 27 25 24 14 11 26 0 15 24 + 15 26 27 26 15 24 26 24 27 15 20 26 27 23 23 16 10 + + 14 14 12 27 16 27 23 12 17 18 24 23 18 18 6 24 12 + 27 21 21 26 20 25 27 12 14 27 27 25 27 18 11 10 27 + 27 27 14 27 27 16 27 27 27 26 27 12 24 27 10 16 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 10 12 26 + 0 27 18 12 27 27 17 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 12 23 27 23 16 14 + 12 6 10 11 18 10 12 27 21 24 27 26 24 14 27 27 14 + 12 12 14 16 18 10 3 3 26 14 15 6 3 6 15 11 16 + 14 14 1 27 24 16 6 16 25 16 25 26 11 24 12 24 16 + 16 25 25 11 16 14 15 27 26 10 12 6 15 16 27 10 14 + 16 14 12 16 16 26 23 20 14 14 12 16 10 12 27 20 23 + 12 14 25 23 25 10 21 16 23 25 10 24 3 12 10 10 20 + 27 10 11 10 25 14 8 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 12 26 27 26 24 11 24 12 27 12 23 25 23 12 26 27 10 + 24 10 12 16 18 14 24 14 27 24 24 12 10 25 10 10 24 + 16 25 26 25 15 24 25 24 27 12 18 25 27 21 23 18 10 + + 21 21 23 15 28 15 11 23 21 16 0 12 16 16 24 11 25 + 14 14 14 12 15 11 14 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 21 15 15 15 12 15 23 11 15 24 21 2 + 15 24 14 11 28 14 10 1 15 15 11 12 28 14 24 25 12 + 15 0 16 23 15 15 21 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 11 14 12 10 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 21 25 28 + 21 27 24 14 10 28 24 28 11 18 12 12 23 11 25 4 28 + 18 12 11 23 28 21 20 15 12 24 23 24 20 28 14 24 21 + 21 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 12 + 23 21 12 12 11 24 14 28 12 12 24 10 24 23 24 24 15 + 15 24 23 24 12 21 24 28 12 28 12 23 14 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 2 23 28 10 15 11 + 25 12 14 12 10 25 3 25 14 24 11 11 12 23 12 14 24 + 10 24 23 28 16 21 2 21 14 10 10 23 24 12 24 24 11 + 28 12 12 12 27 10 12 10 14 25 16 12 14 14 12 28 24 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 0 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 17 10 11 25 23 25 20 12 24 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 19 25 25 24 25 12 11 12 25 + 25 25 21 25 25 23 25 25 25 24 25 10 23 25 14 23 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 15 16 24 + 25 25 15 0 25 25 24 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 10 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 19 16 24 16 23 10 + 18 12 12 11 12 15 19 24 15 23 24 24 23 16 24 24 10 + 5 9 17 23 23 12 12 12 24 20 21 12 12 12 22 15 23 + 10 20 12 24 21 23 12 23 23 19 24 24 11 21 19 23 23 + 12 24 23 11 23 10 15 25 24 12 10 12 11 23 24 14 12 + 23 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 19 + 10 19 24 16 23 15 15 23 16 24 15 21 12 10 15 12 15 + 25 12 11 12 24 17 15 23 24 23 24 10 19 11 21 15 21 + 21 23 14 14 12 20 24 9 6 15 24 23 5 23 23 19 23 + 19 24 24 24 23 15 23 19 24 19 20 23 19 8 24 24 14 + 23 12 19 23 14 10 23 10 24 23 21 9 12 24 14 15 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 21 21 23 15 28 15 11 23 21 16 2 12 16 16 24 10 25 + 14 14 14 12 15 11 14 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 21 15 15 15 12 15 23 9 15 24 21 0 + 15 24 14 11 28 14 10 1 15 15 11 12 28 14 24 25 12 + 15 15 16 23 0 15 21 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 10 14 12 10 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 21 25 28 + 21 27 24 14 10 28 24 28 11 18 12 12 23 10 25 2 28 + 18 12 11 23 28 21 20 15 12 24 23 24 20 28 14 24 21 + 21 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 12 + 23 21 12 12 11 24 14 28 12 12 24 10 24 23 24 24 15 + 15 24 23 24 12 21 24 28 12 28 12 23 14 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 0 23 28 10 15 11 + 25 12 14 12 10 25 5 25 14 24 11 11 12 23 12 14 24 + 10 24 23 28 16 21 0 21 14 10 10 23 24 12 24 24 9 + 28 12 12 12 27 10 12 10 14 25 16 12 14 14 12 28 24 + + 21 21 23 15 28 15 11 23 21 16 1 12 16 16 24 10 25 + 14 14 14 12 15 11 14 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 21 15 15 15 12 15 23 10 15 24 21 1 + 15 24 14 11 28 14 10 0 15 15 11 12 28 14 24 25 12 + 15 15 16 23 15 0 21 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 10 14 12 10 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 21 25 28 + 21 27 24 14 10 28 24 28 11 18 12 12 23 10 25 3 28 + 18 12 11 23 28 21 20 15 12 24 23 24 20 28 14 24 21 + 21 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 12 + 23 21 12 12 11 24 14 28 12 12 24 10 24 23 24 24 15 + 15 24 23 24 12 21 24 28 12 28 12 23 14 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 1 23 28 10 15 11 + 25 12 14 12 10 25 4 25 14 24 11 11 12 23 12 14 24 + 10 24 23 28 16 21 1 21 14 10 10 23 24 12 24 24 10 + 28 12 12 12 27 10 12 10 14 25 16 12 14 14 12 28 24 + + 17 10 11 25 23 25 20 12 24 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 19 25 25 24 25 12 11 12 25 + 25 25 21 25 25 23 25 25 25 24 25 10 23 25 14 23 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 15 16 24 + 25 25 15 10 25 25 0 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 10 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 19 16 24 16 23 10 + 18 12 12 11 12 15 19 24 15 23 24 24 23 16 24 24 10 + 5 9 17 23 23 12 12 12 24 20 21 12 12 12 22 15 23 + 10 20 12 24 21 23 12 23 23 19 24 24 11 21 19 23 23 + 12 24 23 11 23 10 15 25 24 12 10 12 11 23 24 14 12 + 23 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 19 + 10 19 24 16 23 15 15 23 16 24 15 21 12 10 15 12 15 + 25 12 11 12 24 17 15 23 24 23 24 10 19 11 21 15 21 + 21 23 14 14 12 20 24 9 6 15 24 23 5 23 23 19 23 + 19 24 24 24 23 15 23 19 24 19 20 23 19 8 24 24 14 + 23 12 19 23 14 10 23 10 24 23 21 9 12 24 14 15 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 0 21 11 15 28 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 0 11 24 12 11 27 24 12 + 21 25 20 15 31 10 19 12 11 11 15 0 31 15 25 28 6 + 11 11 23 24 11 11 24 0 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 0 24 11 11 11 23 15 11 24 18 + 14 10 23 20 23 20 23 25 11 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 0 15 24 10 10 24 + 24 24 24 31 31 25 26 26 0 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 15 23 10 19 25 14 27 12 31 + 23 15 19 25 31 24 23 19 0 25 24 26 23 31 10 27 24 + 24 24 24 31 31 0 18 21 29 24 28 23 25 28 10 21 19 + 24 24 10 18 11 27 20 31 18 19 25 14 26 24 27 25 21 + 19 25 25 25 10 24 26 31 15 31 19 24 20 23 30 24 14 + 30 31 27 21 23 15 0 24 24 27 10 12 24 31 12 21 15 + 28 10 10 0 15 27 15 28 10 27 15 11 19 24 0 15 27 + 12 25 25 31 23 24 12 24 10 15 14 24 25 10 27 25 12 + 31 19 15 10 30 14 10 14 10 28 23 19 10 20 16 31 27 + + 14 14 12 27 16 27 23 12 15 18 24 23 18 18 9 24 12 + 27 21 21 26 20 25 27 12 14 27 27 25 27 18 11 10 27 + 27 27 14 27 27 14 27 27 27 26 27 12 24 27 10 14 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 10 12 26 + 27 27 18 12 27 27 15 23 0 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 11 23 27 23 16 14 + 12 9 10 11 18 10 10 27 21 24 27 26 24 14 27 27 14 + 12 12 14 16 18 10 1 1 26 14 15 3 1 9 14 11 16 + 14 14 3 27 24 16 3 16 25 16 25 26 11 24 11 24 16 + 16 25 25 11 16 14 15 27 26 10 12 9 15 16 27 10 14 + 14 14 12 16 16 26 23 20 14 14 12 16 10 12 27 20 23 + 12 14 25 23 25 10 21 16 23 25 10 24 1 12 10 10 20 + 27 10 11 10 25 14 5 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 12 26 27 26 24 11 24 12 27 10 23 25 23 12 26 27 10 + 24 10 11 16 18 14 24 14 27 24 24 12 10 25 10 10 24 + 16 25 26 25 15 24 25 24 27 12 18 25 27 21 23 18 10 + + 15 14 15 23 25 23 12 15 22 11 14 11 11 11 21 12 23 + 21 5 10 20 10 16 21 23 18 23 23 18 23 11 18 20 23 + 23 23 19 23 23 21 23 23 23 20 23 16 14 23 23 21 14 + 10 20 6 12 25 21 18 14 23 23 12 20 25 21 20 23 20 + 23 23 13 15 23 23 22 11 23 0 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 6 12 4 12 20 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 12 15 21 20 15 14 21 21 14 + 15 15 15 25 25 20 21 21 20 24 24 21 21 21 20 23 25 + 14 24 21 21 12 25 21 25 16 18 18 20 18 12 23 14 25 + 12 18 18 18 25 14 13 23 20 20 15 21 12 25 21 23 14 + 21 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 18 + 16 18 18 10 16 23 10 25 12 18 20 12 21 16 23 20 13 + 23 20 18 20 18 15 21 25 18 25 20 16 18 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 18 16 + 23 20 21 20 15 23 14 23 21 23 12 16 18 15 20 21 23 + 15 20 18 25 12 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 1 11 25 23 + + 14 14 12 27 16 27 23 12 16 18 24 23 18 18 8 24 12 + 27 21 21 26 20 25 27 12 14 27 27 25 27 18 11 10 27 + 27 27 14 27 27 15 27 27 27 26 27 12 24 27 10 15 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 10 12 26 + 27 27 18 12 27 27 16 23 27 23 0 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 11 23 27 23 16 14 + 12 8 10 11 18 10 11 27 21 24 27 26 24 14 27 27 14 + 12 12 14 16 18 10 2 2 26 14 15 4 2 8 14 11 16 + 14 14 2 27 24 16 4 16 25 16 25 26 11 24 11 24 16 + 16 25 25 11 16 14 15 27 26 10 12 8 15 16 27 10 14 + 15 14 12 16 16 26 23 20 14 14 12 16 10 12 27 20 23 + 12 14 25 23 25 10 21 16 23 25 10 24 2 12 10 10 20 + 27 10 11 10 25 14 7 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 12 26 27 26 24 11 24 12 27 11 23 25 23 12 26 27 10 + 24 10 11 16 18 14 24 14 27 24 24 12 10 25 10 10 24 + 16 25 26 25 15 24 25 24 27 12 18 25 27 21 23 18 10 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 0 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 14 14 15 23 25 23 12 15 16 11 14 11 11 11 21 12 23 + 21 1 3 20 10 16 21 23 14 23 23 18 23 11 18 20 23 + 23 23 14 23 23 15 23 23 23 20 23 16 14 23 23 15 14 + 10 20 0 12 25 21 15 14 23 23 12 20 25 21 20 23 20 + 23 23 11 15 23 23 16 11 23 12 23 25 0 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 0 12 2 12 20 23 23 23 23 23 23 23 23 3 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 6 15 21 20 15 14 21 21 14 + 15 15 14 25 25 20 21 21 20 24 24 21 21 21 14 23 25 + 14 24 21 21 12 25 21 25 16 12 18 20 18 12 23 14 25 + 12 18 16 18 25 14 12 23 20 20 15 21 12 25 21 23 14 + 15 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 11 + 16 14 18 10 16 23 3 25 10 18 20 12 21 16 23 20 10 + 23 20 18 20 18 14 21 25 18 25 20 16 11 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 11 16 + 23 20 21 20 15 23 14 23 21 23 12 16 11 15 20 21 23 + 15 20 18 25 11 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 8 11 25 23 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 0 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 18 18 20 18 27 18 9 20 24 14 11 10 14 14 23 10 24 + 16 12 12 15 12 12 16 24 19 18 18 14 18 14 23 23 18 + 18 18 21 18 18 23 18 18 18 15 18 21 11 18 24 23 11 + 12 23 12 6 27 16 19 11 18 18 5 15 27 16 23 24 15 + 18 18 15 20 18 18 24 10 18 11 18 27 18 25 0 18 18 + 18 18 18 18 18 18 18 15 18 18 18 18 16 9 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 18 18 18 12 + 18 18 24 18 18 18 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 14 12 16 15 15 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 22 24 27 + 18 25 23 16 12 27 23 27 15 19 14 19 23 10 24 11 27 + 15 15 19 23 27 18 16 19 15 23 20 23 16 27 16 24 18 + 23 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 19 + 21 19 14 11 12 24 12 27 14 19 23 10 23 21 24 23 15 + 19 23 23 23 14 18 23 27 15 27 19 21 19 16 26 18 10 + 26 27 24 12 14 10 15 20 20 24 16 11 20 27 12 19 15 + 24 15 16 15 15 24 15 24 16 24 9 12 19 20 15 16 24 + 12 23 23 27 14 18 11 18 16 15 10 20 23 14 24 23 11 + 27 19 15 14 26 10 14 10 16 24 14 19 16 12 10 27 24 + + 11 11 12 24 24 24 15 12 14 10 18 14 10 10 16 16 21 + 23 12 12 23 11 21 23 21 11 24 24 23 24 10 14 15 24 + 24 24 11 24 24 12 24 24 24 23 24 12 18 24 18 12 18 + 11 15 12 15 24 23 20 18 24 24 15 23 24 23 15 21 23 + 24 24 10 12 24 24 14 14 24 15 24 24 24 23 24 0 24 + 24 24 24 24 24 11 24 23 11 24 24 24 10 15 24 12 12 + 16 23 10 12 10 12 10 15 24 24 24 24 24 24 24 24 12 + 24 24 20 24 24 24 24 11 20 16 16 20 12 23 12 24 11 + 23 16 15 14 10 18 18 23 12 20 23 23 20 11 23 23 11 + 12 12 11 24 24 15 16 16 23 23 23 16 16 16 11 20 24 + 11 23 16 23 16 24 16 24 21 9 23 23 14 16 20 18 24 + 0 23 21 14 24 11 10 24 23 15 12 16 10 24 23 18 11 + 12 11 12 24 24 23 12 11 23 11 21 10 15 23 23 11 14 + 12 11 23 12 21 18 12 24 12 23 15 16 16 12 18 15 11 + 24 15 14 15 23 11 16 24 23 24 23 12 12 10 23 11 16 + 23 24 18 11 10 15 23 12 12 20 23 18 12 24 20 11 21 + 21 23 23 23 20 20 18 21 23 18 15 21 12 12 23 23 18 + 20 15 14 24 10 11 18 11 23 20 16 12 15 23 18 15 18 + 24 23 23 23 23 16 23 16 23 21 10 23 23 12 14 24 18 + + 12 12 12 27 18 27 23 12 18 16 24 23 16 16 10 23 12 + 26 20 20 25 18 24 26 12 13 27 27 25 27 16 10 0 27 + 27 27 15 27 27 17 27 27 27 25 27 11 24 27 11 17 24 + 18 0 20 23 18 26 24 24 27 27 23 25 20 26 9 12 25 + 27 27 16 12 27 27 18 23 27 23 27 18 27 14 27 27 0 + 27 27 27 27 27 12 27 25 12 27 27 27 14 23 27 12 21 + 23 26 14 20 14 20 15 0 27 27 27 27 27 27 27 27 20 + 27 27 12 27 27 27 27 12 12 23 23 13 21 26 21 18 12 + 14 10 6 10 16 11 13 26 20 24 26 25 24 12 26 26 12 + 12 12 12 18 20 6 10 10 25 15 16 10 10 10 16 12 18 + 12 15 10 26 23 18 10 18 24 15 25 25 10 23 13 24 18 + 15 25 24 10 18 12 14 27 25 6 12 10 14 18 26 11 12 + 17 12 11 18 18 25 21 18 15 12 12 15 6 14 26 18 23 + 11 13 25 21 24 11 20 18 21 25 9 23 10 11 11 0 18 + 27 6 10 0 25 12 10 20 25 20 25 11 20 14 16 12 23 + 16 18 11 18 16 23 25 12 12 12 26 24 12 18 24 18 24 + 13 25 26 25 24 12 24 13 26 13 23 24 21 12 25 26 11 + 24 6 13 18 16 12 24 12 26 24 23 12 6 25 11 9 24 + 18 25 25 25 16 23 25 23 26 12 16 25 26 20 23 20 11 + + 17 14 15 23 25 23 12 15 24 11 14 11 11 11 21 12 23 + 21 6 11 20 10 16 21 23 19 23 23 18 23 11 18 20 23 + 23 23 21 23 23 23 23 23 23 20 23 16 14 23 23 23 14 + 10 20 8 12 25 21 19 14 23 23 12 20 25 21 20 23 20 + 23 23 15 15 23 23 24 11 23 12 23 25 23 24 23 23 23 + 0 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 8 12 5 12 20 23 23 23 23 23 23 23 23 11 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 14 15 21 20 15 16 21 21 14 + 15 15 17 25 25 20 21 21 20 24 24 21 21 21 22 23 25 + 14 24 21 21 12 25 21 25 16 19 18 20 18 12 23 14 25 + 12 18 19 18 25 14 15 23 20 20 15 21 12 25 21 23 14 + 23 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 19 + 16 19 18 10 16 23 11 25 14 19 20 12 21 16 23 20 15 + 23 20 18 20 18 17 21 25 18 25 20 16 19 12 24 15 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 19 16 + 23 20 21 20 15 23 15 23 21 23 12 16 19 15 20 21 23 + 15 20 19 25 14 14 14 14 21 15 12 15 20 18 23 20 14 + 25 19 20 18 24 12 18 12 21 23 11 19 21 0 11 25 23 + + 14 14 15 23 25 23 12 15 14 11 14 11 11 11 21 12 23 + 21 4 0 20 10 16 21 23 14 23 23 18 23 11 18 20 23 + 23 23 14 23 23 14 23 23 23 20 23 16 14 23 23 14 14 + 10 20 3 12 25 21 15 14 23 23 12 20 25 21 20 23 20 + 23 23 11 15 23 23 14 11 23 12 23 25 23 24 23 23 23 + 23 0 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 3 12 6 12 20 23 23 23 23 23 23 23 23 0 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 2 15 21 20 15 14 21 21 14 + 15 15 14 25 25 20 21 21 20 24 24 21 21 21 14 23 25 + 14 24 21 21 12 25 21 25 16 12 18 20 18 12 23 14 25 + 12 18 16 18 25 14 12 23 20 20 15 21 12 25 21 23 14 + 14 14 16 25 25 20 10 10 24 14 23 12 20 24 21 11 11 + 16 14 18 10 16 23 0 25 10 18 20 12 21 16 23 20 10 + 23 20 18 20 18 14 21 25 18 25 20 16 8 12 24 14 12 + 24 25 23 11 11 12 20 15 15 23 21 14 15 25 15 10 16 + 23 20 21 20 15 23 14 23 21 23 12 16 10 15 20 21 23 + 15 20 18 25 11 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 11 11 25 23 + + 14 14 12 27 16 27 23 12 15 18 24 23 18 18 9 24 12 + 27 21 21 26 20 25 27 12 14 27 27 25 27 18 11 10 27 + 27 27 14 27 27 14 27 27 27 26 27 12 24 27 10 14 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 10 12 26 + 27 27 18 12 27 27 15 23 27 23 27 16 27 12 27 27 27 + 27 27 0 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 11 23 27 23 16 14 + 12 9 10 11 18 10 10 27 21 24 27 26 24 14 27 27 14 + 12 12 14 16 18 10 1 1 26 14 15 3 1 9 14 11 16 + 14 14 3 27 24 16 3 16 25 16 25 26 11 24 11 24 16 + 16 25 25 11 16 14 15 27 26 10 12 9 15 16 27 10 14 + 14 14 12 16 16 26 23 20 14 14 12 16 10 12 27 20 23 + 12 14 25 23 25 10 21 16 23 25 10 24 1 12 10 10 20 + 27 10 11 10 25 14 5 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 12 26 27 26 24 11 24 12 27 10 23 25 23 12 26 27 10 + 24 10 11 16 18 14 24 14 27 24 24 12 10 25 10 10 24 + 16 25 26 25 15 24 25 24 27 12 18 25 27 21 23 18 10 + + 18 18 20 18 27 18 2 20 18 14 11 10 14 14 23 10 24 + 16 12 12 15 12 12 16 24 18 18 18 14 18 14 23 23 18 + 18 18 18 18 18 18 18 18 18 15 18 21 11 18 24 18 11 + 12 23 12 0 27 16 12 11 18 18 1 15 27 16 23 24 15 + 18 18 14 20 18 18 18 10 18 4 18 27 18 25 18 18 18 + 18 18 18 0 18 18 18 15 18 18 18 18 16 2 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 18 18 18 12 + 18 18 24 18 18 18 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 12 12 16 15 12 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 18 24 27 + 18 25 23 16 10 27 23 27 12 15 14 15 23 10 24 11 27 + 15 14 12 23 27 18 16 18 15 23 20 23 16 27 16 24 18 + 18 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 12 + 21 18 14 11 12 24 12 27 11 14 23 10 23 21 24 23 12 + 18 23 23 23 14 18 23 27 14 27 15 21 12 16 26 18 10 + 26 27 24 12 14 3 15 20 20 24 16 11 20 27 12 12 12 + 24 15 16 15 12 24 11 24 16 24 2 12 12 20 15 16 24 + 12 23 23 27 14 18 11 18 16 12 10 20 23 14 24 23 11 + 27 14 15 14 26 10 14 10 16 24 14 14 16 12 10 27 24 + + 12 12 14 23 24 23 12 14 18 10 15 12 10 10 20 14 23 + 23 10 10 21 4 18 23 23 14 23 23 20 23 10 16 18 23 + 23 23 15 23 23 17 23 23 23 21 23 15 15 23 21 17 15 + 0 18 10 12 24 23 16 15 23 23 12 21 25 23 18 23 21 + 23 23 10 14 23 23 18 12 23 12 23 24 23 23 23 23 23 + 23 23 23 23 0 12 23 21 12 23 23 23 12 12 23 14 11 + 14 23 12 10 12 10 11 18 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 12 23 14 14 23 11 23 11 24 12 + 23 20 18 16 10 21 21 23 10 16 23 21 16 12 23 23 12 + 14 14 12 24 25 18 20 20 21 24 24 20 20 20 16 23 24 + 12 24 20 23 14 24 20 24 18 14 20 21 16 14 23 15 24 + 11 20 18 16 24 12 12 23 21 18 14 20 12 24 23 21 12 + 17 12 15 24 24 21 11 1 24 12 23 11 18 23 23 5 14 + 15 14 20 11 18 21 10 24 11 20 18 14 20 15 21 18 9 + 23 18 16 18 20 12 20 25 20 25 21 15 14 12 24 12 14 + 24 24 21 5 10 12 21 14 14 23 23 15 14 24 16 14 18 + 23 21 23 21 16 23 15 23 23 21 12 18 14 14 21 23 21 + 16 18 16 24 10 12 15 12 23 16 14 14 18 20 21 18 15 + 24 20 21 20 24 14 20 14 23 23 10 20 23 10 12 25 21 + + 15 14 15 23 25 23 12 15 22 11 14 11 11 11 21 12 23 + 21 5 10 20 10 16 21 23 18 23 23 18 23 11 18 20 23 + 23 23 19 23 23 21 23 23 23 20 23 16 14 23 23 21 14 + 10 20 6 12 25 21 18 14 23 23 12 20 25 21 20 23 20 + 23 23 13 15 23 23 22 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 0 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 6 12 4 12 20 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 12 15 21 20 15 14 21 21 14 + 15 15 15 25 25 20 21 21 20 24 24 21 21 21 20 23 25 + 14 24 21 21 12 25 21 25 16 18 18 20 18 12 23 14 25 + 12 18 18 18 25 14 13 23 20 20 15 21 12 25 21 23 14 + 21 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 18 + 16 18 18 10 16 23 10 25 12 18 20 12 21 16 23 20 13 + 23 20 18 20 18 15 21 25 18 25 20 16 18 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 18 16 + 23 20 21 20 15 23 14 23 21 23 12 16 18 15 20 21 23 + 15 20 18 25 12 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 1 11 25 23 + + 15 15 14 28 15 28 24 14 17 20 24 23 20 20 10 24 11 + 27 23 23 27 21 25 27 11 15 28 28 26 28 20 12 11 28 + 28 28 15 28 28 16 28 28 28 27 28 12 24 28 6 16 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 11 11 27 + 28 28 20 14 28 28 17 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 0 27 15 28 28 28 16 24 28 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 10 24 24 12 23 27 23 15 15 + 12 10 11 12 20 8 12 27 23 25 27 27 25 15 27 27 15 + 14 14 15 15 16 11 10 10 27 12 14 10 10 10 15 10 15 + 15 12 10 27 24 15 10 15 25 18 26 27 12 24 12 24 15 + 18 26 25 12 15 15 16 28 27 11 14 10 16 15 27 1 15 + 16 15 12 15 15 27 23 21 12 15 11 18 11 12 27 21 23 + 12 15 26 23 25 8 23 15 23 26 11 24 10 12 8 11 21 + 28 11 12 11 26 15 10 16 26 16 27 12 23 16 14 15 24 + 14 15 6 21 20 24 27 14 14 10 27 24 14 15 25 21 25 + 12 27 27 27 25 10 24 12 27 12 24 25 23 14 27 27 6 + 25 11 12 15 20 15 24 15 27 25 24 14 11 26 6 11 24 + 15 26 27 26 14 24 26 24 27 11 20 26 27 23 23 16 3 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 0 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 20 20 21 16 27 16 10 21 24 15 11 11 15 15 24 0 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 21 16 16 23 16 16 16 14 16 23 10 16 24 23 10 + 14 23 12 10 27 15 19 10 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 24 11 16 11 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 0 16 16 16 18 10 16 21 12 + 6 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 5 9 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 14 11 15 14 15 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 22 24 27 + 20 26 24 15 12 27 24 27 15 19 12 19 23 0 24 10 27 + 16 15 19 23 27 20 18 19 14 23 21 24 18 27 15 24 20 + 23 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 19 + 23 20 12 12 12 24 12 27 14 19 23 6 24 23 24 23 15 + 19 23 23 23 12 20 24 28 15 28 19 23 19 18 27 20 10 + 27 27 24 14 15 10 14 21 21 24 15 10 21 27 11 19 15 + 25 14 15 14 15 24 15 25 15 24 10 12 19 21 14 15 24 + 11 23 23 27 15 20 10 20 15 15 9 21 23 12 24 23 10 + 27 19 15 12 27 8 12 6 15 25 15 19 15 12 11 28 24 + + 18 18 20 18 27 18 3 20 18 14 11 10 14 14 23 10 24 + 16 12 12 15 12 12 16 24 18 18 18 14 18 14 23 23 18 + 18 18 18 18 18 18 18 18 18 15 18 21 11 18 24 18 11 + 12 23 12 1 27 16 14 11 18 18 0 15 27 16 23 24 15 + 18 18 14 20 18 18 18 10 18 6 18 27 18 25 18 18 18 + 18 18 18 18 18 18 18 15 18 0 18 18 16 3 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 18 18 18 12 + 18 18 24 18 18 18 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 12 12 16 15 12 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 18 24 27 + 18 25 23 16 10 27 23 27 12 15 14 15 23 10 24 11 27 + 15 14 14 23 27 18 16 18 15 23 20 23 16 27 16 24 18 + 18 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 14 + 21 18 14 11 12 24 12 27 11 14 23 10 23 21 24 23 12 + 18 23 23 23 14 18 23 27 14 27 15 21 14 16 26 18 10 + 26 27 24 12 14 4 15 20 20 24 16 11 20 27 12 14 12 + 24 15 16 15 12 24 11 24 16 24 3 12 14 20 15 16 24 + 12 23 23 27 14 18 11 18 16 12 10 20 23 14 24 23 11 + 27 14 15 14 26 10 14 10 16 24 14 14 16 12 10 27 24 + + 15 15 14 28 15 28 24 14 17 20 24 23 20 20 10 24 11 + 27 23 23 27 21 25 27 11 15 28 28 26 28 20 12 11 28 + 28 28 15 28 28 16 28 28 28 27 28 12 24 28 6 16 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 11 11 27 + 28 28 20 14 28 28 17 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 28 27 15 28 0 28 16 24 28 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 10 24 24 12 23 27 23 15 15 + 12 10 11 12 20 8 12 27 23 25 27 27 25 15 27 27 15 + 14 14 15 15 16 11 10 10 27 12 14 10 10 10 15 10 15 + 15 12 10 27 24 15 10 15 25 18 26 27 12 24 12 24 15 + 18 26 25 12 15 15 16 28 27 11 14 10 16 15 27 1 15 + 16 15 12 15 15 27 23 21 12 15 11 18 11 12 27 21 23 + 12 15 26 23 25 8 23 15 23 26 11 24 10 12 8 11 21 + 28 11 12 11 26 15 10 16 26 16 27 12 23 16 14 15 24 + 14 15 6 21 20 24 27 14 14 10 27 24 14 15 25 21 25 + 12 27 27 27 25 10 24 12 27 12 24 25 23 14 27 27 6 + 25 11 12 15 20 15 24 15 27 25 24 14 11 26 6 11 24 + 15 26 27 26 14 24 26 24 27 11 20 26 27 23 23 16 3 + + 15 15 14 28 15 28 24 14 17 20 24 23 20 20 10 24 11 + 27 23 23 27 21 25 27 11 15 28 28 26 28 20 12 11 28 + 28 28 15 28 28 16 28 28 28 27 28 12 24 28 6 16 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 11 11 27 + 28 28 20 14 28 28 17 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 28 27 15 28 28 0 16 24 28 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 10 24 24 12 23 27 23 15 15 + 12 10 11 12 20 8 12 27 23 25 27 27 25 15 27 27 15 + 14 14 15 15 16 11 10 10 27 12 14 10 10 10 15 10 15 + 15 12 10 27 24 15 10 15 25 18 26 27 12 24 12 24 15 + 18 26 25 12 15 15 16 28 27 11 14 10 16 15 27 1 15 + 16 15 12 15 15 27 23 21 12 15 11 18 11 12 27 21 23 + 12 15 26 23 25 8 23 15 23 26 11 24 10 12 8 11 21 + 28 11 12 11 26 15 10 16 26 16 27 12 23 16 14 15 24 + 14 15 6 21 20 24 27 14 14 10 27 24 14 15 25 21 25 + 12 27 27 27 25 10 24 12 27 12 24 25 23 14 27 27 6 + 25 11 12 15 20 15 24 15 27 25 24 14 11 26 6 11 24 + 15 26 27 26 14 24 26 24 27 11 20 26 27 23 23 16 3 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 0 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 18 18 20 18 27 18 7 20 22 14 11 10 14 14 23 10 24 + 16 12 12 15 12 12 16 24 18 18 18 14 18 14 23 23 18 + 18 18 19 18 18 21 18 18 18 15 18 21 11 18 24 21 11 + 12 23 12 5 27 16 18 11 18 18 4 15 27 16 23 24 15 + 18 18 14 20 18 18 22 10 18 10 18 27 18 25 18 18 18 + 18 18 18 18 18 18 18 15 18 18 18 18 16 0 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 18 18 18 12 + 18 18 24 18 18 18 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 12 12 16 15 13 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 20 24 27 + 18 25 23 16 11 27 23 27 13 18 14 18 23 10 24 11 27 + 15 14 18 23 27 18 16 18 15 23 20 23 16 27 16 24 18 + 21 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 18 + 21 18 14 11 12 24 12 27 12 18 23 10 23 21 24 23 13 + 18 23 23 23 14 18 23 27 14 27 18 21 18 16 26 18 10 + 26 27 24 12 14 9 15 20 20 24 16 11 20 27 12 18 13 + 24 15 16 15 13 24 13 24 16 24 7 12 18 20 15 16 24 + 12 23 23 27 14 18 11 18 16 13 10 20 23 14 24 23 11 + 27 18 15 14 26 10 14 10 16 24 14 18 16 12 10 27 24 + + 15 15 14 28 15 28 24 14 16 20 24 23 20 20 10 24 11 + 27 23 23 27 21 25 27 11 15 28 28 26 28 20 12 11 28 + 28 28 15 28 28 15 28 28 28 27 28 12 24 28 8 15 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 11 11 27 + 28 28 20 14 28 28 16 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 28 27 15 28 28 28 16 24 0 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 10 24 24 11 23 27 23 15 15 + 12 10 11 12 20 7 11 27 23 25 27 27 25 15 27 27 15 + 14 14 15 15 16 11 10 10 27 12 14 10 10 10 15 10 15 + 15 12 10 27 24 15 10 15 25 18 26 27 12 24 11 24 15 + 18 26 25 12 15 15 16 28 27 11 14 10 16 15 27 2 15 + 15 15 12 15 15 27 23 21 12 15 11 18 11 12 27 21 23 + 12 15 26 23 25 7 23 15 23 26 11 24 10 12 7 11 21 + 28 11 12 11 26 15 10 16 26 16 27 12 23 16 14 15 24 + 14 15 8 21 20 24 27 14 14 10 27 24 14 15 25 21 25 + 11 27 27 27 25 10 24 11 27 11 24 25 23 14 27 27 8 + 25 11 12 15 20 15 24 15 27 25 24 14 11 26 8 11 24 + 15 26 27 26 14 24 26 24 27 11 20 26 27 23 23 16 2 + + 15 10 10 25 23 25 20 11 22 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 18 25 25 24 25 12 11 12 25 + 25 25 19 25 25 21 25 25 25 24 25 10 23 25 14 21 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 13 16 24 + 25 25 13 9 25 25 22 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 0 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 18 16 24 16 23 10 + 18 12 12 11 12 14 18 24 15 23 24 24 23 14 24 24 10 + 4 7 15 23 23 12 12 12 24 20 21 12 12 12 20 15 23 + 10 20 12 24 21 23 12 23 23 18 24 24 11 21 18 23 23 + 12 24 23 11 23 10 13 25 24 12 9 12 11 23 24 14 11 + 21 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 18 24 16 23 14 15 23 16 24 13 21 12 10 14 12 14 + 25 12 11 12 24 15 13 23 24 23 24 10 18 11 21 13 21 + 21 23 14 14 12 20 24 7 5 15 24 23 4 23 23 18 23 + 18 24 24 24 23 15 23 18 24 18 20 23 18 6 24 24 14 + 23 12 18 23 12 10 23 10 24 23 21 7 12 24 14 13 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 15 15 16 21 25 21 11 16 21 12 12 10 12 12 23 12 24 + 20 10 10 18 11 15 20 24 16 21 21 16 21 12 20 21 21 + 21 21 18 21 21 20 21 21 21 18 21 18 12 21 23 20 12 + 11 21 10 11 25 20 16 12 21 21 11 18 26 20 21 24 18 + 21 21 12 16 21 21 21 10 21 11 21 25 21 24 21 21 21 + 21 21 21 21 21 15 21 18 15 21 21 21 14 11 21 16 0 + 12 20 14 10 14 10 12 21 21 21 21 21 21 21 21 21 10 + 21 21 23 21 21 21 21 15 23 12 12 23 3 20 5 25 15 + 24 23 21 20 12 23 23 20 11 14 20 18 14 15 20 20 15 + 16 16 15 25 26 21 23 23 18 24 25 23 23 23 19 23 25 + 15 24 23 20 12 25 23 25 15 16 16 18 20 12 23 12 25 + 12 16 16 20 25 15 14 21 18 21 16 23 14 25 20 23 15 + 20 15 18 25 25 18 5 11 24 15 24 12 21 24 20 11 16 + 18 16 16 2 15 23 10 25 11 16 21 12 23 18 23 21 12 + 21 21 20 21 16 15 23 26 16 26 18 18 16 14 25 15 12 + 25 25 23 11 12 11 18 16 16 23 20 12 16 25 14 16 15 + 24 18 20 18 14 23 12 24 20 23 11 15 16 16 18 20 23 + 14 21 20 25 12 15 12 15 20 14 12 16 21 16 23 21 12 + 25 16 18 16 25 12 16 12 20 24 12 16 20 10 10 26 23 + + 17 15 16 21 25 21 11 16 24 12 12 10 12 12 23 12 24 + 20 10 11 18 11 15 20 24 19 21 21 16 21 12 20 21 21 + 21 21 21 21 21 23 21 21 21 18 21 18 12 21 23 23 12 + 11 21 10 11 25 20 19 12 21 21 11 18 26 20 21 24 18 + 21 21 15 16 21 21 24 10 21 11 21 25 21 24 21 21 21 + 21 21 21 21 21 15 21 18 15 21 21 21 14 11 21 16 6 + 0 20 14 10 14 10 12 21 21 21 21 21 21 21 21 21 11 + 21 21 23 21 21 21 21 15 23 12 12 23 6 20 8 25 15 + 24 23 21 20 12 23 23 20 14 14 20 18 15 16 20 20 15 + 16 16 17 25 26 21 23 23 18 24 25 23 23 23 22 23 25 + 15 24 23 20 12 25 23 25 15 19 16 19 20 12 23 12 25 + 12 16 19 20 25 15 15 21 18 21 16 23 14 25 20 23 15 + 23 15 18 25 25 18 8 11 24 15 24 12 21 24 20 11 19 + 18 19 16 5 15 23 11 25 14 19 21 12 23 18 23 21 15 + 21 21 20 21 16 17 23 26 16 26 19 18 19 14 25 15 12 + 25 25 23 11 12 11 18 16 16 23 20 12 16 25 14 19 15 + 24 18 20 18 15 23 15 24 20 23 11 15 19 16 18 20 23 + 14 21 20 25 14 15 12 15 20 15 12 16 21 16 23 21 12 + 25 19 18 16 25 12 16 12 20 24 12 19 20 10 10 26 23 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 0 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 0 21 11 15 28 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 0 11 24 12 11 27 24 12 + 21 25 20 15 31 10 19 12 11 11 15 0 31 15 25 28 6 + 11 11 23 24 11 11 24 16 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 0 24 11 11 11 23 15 11 24 18 + 14 10 0 20 23 20 23 25 11 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 0 15 24 10 10 24 + 24 24 24 31 31 25 26 26 0 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 15 23 10 19 25 14 27 12 31 + 23 15 19 25 31 24 23 19 0 25 24 26 23 31 10 27 24 + 24 24 24 31 31 0 18 21 29 24 28 23 25 28 10 21 19 + 24 24 10 18 11 27 20 31 18 19 25 14 26 24 27 25 21 + 19 25 25 25 10 24 26 31 15 31 19 24 20 23 30 24 14 + 30 31 27 21 23 15 0 24 24 27 10 12 24 31 12 21 15 + 28 10 10 0 15 27 15 28 10 27 15 11 19 24 0 15 27 + 12 25 25 31 23 24 12 24 10 15 14 24 25 10 27 25 12 + 31 19 15 10 30 14 10 14 10 28 23 19 10 20 16 31 27 + + 17 10 11 24 23 24 16 12 24 11 20 15 11 11 15 18 20 + 24 12 12 23 12 23 24 20 19 24 24 23 24 11 12 14 24 + 24 24 21 24 24 23 24 24 24 23 24 12 20 24 16 23 20 + 12 14 12 16 23 24 21 20 24 24 16 23 24 24 15 20 23 + 24 24 15 11 24 24 24 15 24 16 24 23 24 21 24 24 24 + 24 24 24 24 24 10 24 23 10 24 24 24 0 16 24 11 14 + 18 24 10 0 10 12 10 14 24 24 24 24 24 24 24 24 12 + 24 24 18 24 24 24 24 10 18 18 18 19 14 24 14 23 10 + 21 15 14 12 11 16 19 24 14 21 24 23 21 16 24 24 10 + 11 11 17 23 24 14 15 15 23 23 23 15 15 15 22 18 23 + 10 23 15 24 18 23 15 23 23 19 23 23 12 18 19 20 23 + 10 23 23 12 23 10 15 24 23 14 11 15 0 23 24 16 12 + 23 10 12 23 23 23 14 12 23 10 20 10 14 21 24 12 19 + 12 19 23 14 23 16 12 23 14 23 15 18 15 12 16 14 15 + 24 14 12 14 23 17 15 24 23 24 23 12 19 6 23 15 18 + 23 23 16 12 11 16 23 11 11 18 24 20 11 23 21 19 23 + 20 23 24 23 21 18 20 20 24 19 16 23 19 11 23 24 16 + 21 14 19 23 14 10 20 10 24 21 18 11 14 23 16 15 20 + 23 23 23 23 23 18 23 18 24 20 11 23 24 12 15 24 16 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 0 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 15 14 15 23 25 23 12 15 22 11 14 11 11 11 21 12 23 + 21 5 10 20 10 16 21 23 18 23 23 18 23 11 18 20 23 + 23 23 19 23 23 21 23 23 23 20 23 16 14 23 23 21 14 + 10 20 6 12 25 21 18 14 23 23 12 20 25 21 20 23 20 + 23 23 13 15 23 23 22 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 6 12 0 12 20 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 12 15 21 20 15 14 21 21 14 + 15 15 15 25 25 20 21 21 20 24 24 21 21 21 20 23 25 + 14 24 21 21 12 25 21 25 16 18 18 20 18 12 23 14 25 + 12 18 18 18 25 14 13 23 20 20 15 21 12 25 21 23 14 + 21 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 18 + 16 18 18 10 16 23 10 25 12 18 20 12 21 16 23 20 13 + 23 20 18 20 18 15 21 25 18 25 20 16 18 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 18 16 + 23 20 21 20 15 23 14 23 21 23 12 16 18 15 20 21 23 + 15 20 18 25 12 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 1 11 25 23 + + 10 10 11 24 23 24 16 11 14 11 20 15 11 11 15 18 20 + 24 12 12 23 12 23 24 20 10 24 24 23 24 11 12 14 24 + 24 24 10 24 24 12 24 24 24 23 24 12 20 24 16 12 20 + 12 14 12 16 23 24 21 20 24 24 16 23 24 24 14 20 23 + 24 24 11 11 24 24 14 15 24 16 24 23 24 21 24 24 24 + 24 24 24 24 24 10 24 23 10 24 24 24 10 16 24 11 14 + 18 24 0 12 0 12 0 14 24 24 24 24 24 24 24 24 12 + 24 24 18 24 24 24 24 10 18 18 18 18 14 24 14 23 10 + 21 15 14 12 11 16 16 24 12 21 24 23 21 10 24 24 10 + 11 11 10 23 24 14 15 15 23 23 23 15 15 15 11 18 23 + 10 23 15 24 18 23 15 23 23 10 23 23 12 18 18 20 23 + 10 23 23 12 23 10 4 24 23 14 11 15 10 23 24 16 10 + 12 10 12 23 23 23 14 12 23 10 20 10 14 21 24 12 15 + 12 10 23 14 23 16 12 23 14 23 14 18 15 12 16 14 12 + 24 14 12 14 23 10 15 24 23 24 23 12 12 4 23 10 18 + 23 23 16 12 11 16 23 11 11 18 24 20 11 23 21 12 23 + 20 23 24 23 21 18 20 20 24 16 16 23 14 11 23 24 16 + 21 14 12 23 11 10 20 10 24 21 18 11 14 23 16 14 20 + 23 23 23 23 23 18 23 18 24 20 11 23 24 12 15 24 16 + + 17 11 12 24 24 24 15 12 24 10 18 14 10 10 16 16 21 + 23 12 12 23 11 21 23 21 19 24 24 23 24 10 14 15 24 + 24 24 21 24 24 23 24 24 24 23 24 12 18 24 18 23 18 + 11 15 12 15 24 23 20 18 24 24 15 23 24 23 15 21 23 + 24 24 15 12 24 24 24 14 24 15 24 24 24 23 24 24 24 + 24 24 24 24 24 11 24 23 11 24 24 24 10 15 24 12 12 + 16 23 10 12 10 12 0 0 24 24 24 24 24 24 24 24 12 + 24 24 20 24 24 24 24 11 20 16 16 20 12 23 12 24 11 + 23 16 15 14 10 18 19 23 14 20 23 23 20 16 23 23 11 + 12 12 17 24 24 15 16 16 23 23 23 16 16 16 22 20 24 + 11 23 16 23 16 24 16 24 21 19 23 23 14 16 20 18 24 + 10 23 21 14 24 11 15 24 23 15 12 16 10 24 23 18 12 + 23 11 12 24 24 23 12 11 23 11 21 0 15 23 23 11 19 + 12 19 23 12 21 18 12 24 14 23 15 16 16 12 18 15 15 + 24 15 14 15 23 17 16 24 23 24 23 12 19 10 23 15 16 + 23 24 18 11 10 15 23 12 12 20 23 18 12 24 20 19 21 + 21 23 23 23 20 20 18 21 23 19 15 21 19 12 23 23 18 + 20 15 19 24 14 11 18 11 23 20 16 12 15 23 18 15 18 + 24 23 23 23 23 16 23 16 23 21 10 23 23 12 14 24 18 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 6 21 11 10 28 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 6 11 24 12 11 27 24 12 + 21 25 20 15 31 10 13 12 11 11 15 6 31 10 25 28 0 + 11 11 23 24 11 11 24 16 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 6 24 11 11 11 23 15 11 24 18 + 14 10 23 20 23 20 23 25 0 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 6 12 24 10 10 24 + 24 24 24 31 31 25 26 26 6 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 11 23 10 13 25 14 27 12 31 + 23 10 13 25 31 24 23 13 6 25 24 26 23 31 10 27 24 + 24 24 24 31 31 6 18 21 29 24 28 23 25 28 10 21 16 + 24 24 10 18 11 27 20 31 18 13 25 14 26 24 27 25 21 + 13 25 25 25 10 24 26 31 10 31 13 24 20 23 30 24 14 + 30 31 27 21 23 15 6 24 24 27 10 12 24 31 12 21 11 + 28 4 10 6 12 27 12 28 10 27 15 11 18 24 6 10 27 + 12 25 25 31 23 24 12 24 10 12 14 24 25 10 27 25 12 + 31 13 9 10 30 14 10 14 10 28 23 13 10 20 16 31 27 + + 23 23 23 18 28 18 12 23 23 18 10 19 18 18 24 19 26 + 19 15 15 19 16 10 12 26 23 18 18 19 18 18 24 24 18 + 18 18 23 18 18 23 18 18 18 19 18 23 19 18 25 23 10 + 16 24 15 12 28 19 0 10 18 18 14 19 29 12 24 26 13 + 18 18 18 23 18 18 23 12 18 12 18 28 18 27 18 18 18 + 18 18 18 18 18 23 18 19 23 18 18 18 21 12 18 23 14 + 12 19 21 15 21 15 20 24 18 0 18 18 18 18 18 18 15 + 18 18 25 18 18 18 18 23 25 14 11 25 14 19 14 28 23 + 27 24 24 24 18 25 25 19 15 19 19 19 4 23 19 13 23 + 23 23 23 28 29 24 24 24 19 27 28 24 24 24 23 25 28 + 23 27 24 19 11 28 24 28 10 20 11 12 24 19 25 12 28 + 20 11 10 24 28 23 21 14 19 24 23 24 21 28 19 25 23 + 23 23 23 28 28 19 14 16 27 23 26 20 24 27 19 19 12 + 23 23 19 14 19 25 15 28 14 11 24 13 24 23 25 24 16 + 14 24 24 24 19 23 24 29 11 29 12 23 15 21 28 23 11 + 28 28 25 19 18 12 19 23 23 25 19 10 23 28 9 16 10 + 26 12 13 19 4 25 10 26 19 25 12 19 14 23 19 12 25 + 13 24 24 28 18 23 10 23 19 4 11 23 24 13 25 24 19 + 28 11 12 19 28 11 19 13 19 26 19 11 19 19 19 29 25 + + 12 12 12 23 24 23 14 12 12 9 16 15 8 8 18 15 23 + 23 11 11 23 10 20 23 23 12 23 23 21 23 4 15 16 23 + 23 23 12 23 23 12 23 23 23 23 23 15 16 23 20 12 16 + 10 16 11 14 24 23 18 16 23 23 14 23 24 23 16 23 23 + 23 23 0 12 23 23 12 12 23 14 23 24 23 23 23 23 23 + 23 23 23 23 23 12 23 23 12 23 23 23 15 14 23 12 12 + 15 23 11 11 11 11 15 16 23 23 0 23 23 23 23 23 11 + 23 23 21 23 23 23 23 12 21 15 15 21 12 23 12 24 12 + 23 18 16 15 4 20 20 23 11 18 23 23 18 12 23 23 12 + 12 12 12 24 24 16 18 18 23 23 24 18 18 18 12 21 24 + 15 23 18 23 15 24 18 24 20 10 21 23 15 15 21 16 24 + 10 21 20 15 24 12 11 23 23 16 12 18 15 24 23 20 12 + 12 15 15 24 24 23 12 10 23 15 23 15 16 23 23 15 12 + 15 12 21 12 20 20 11 24 12 21 16 15 18 14 20 16 10 + 23 16 15 16 21 12 18 24 21 24 23 14 11 11 24 12 15 + 24 24 20 15 9 14 23 12 12 21 23 16 12 24 18 10 20 + 23 23 23 23 18 21 16 23 23 20 14 20 12 12 23 23 20 + 18 16 15 24 0 12 16 12 23 18 15 12 16 21 20 16 16 + 24 21 23 21 24 15 21 15 23 23 15 21 23 15 15 24 20 + + 12 12 12 27 18 27 23 12 18 16 24 23 16 16 10 23 12 + 26 20 20 25 18 24 26 12 13 27 27 25 27 16 10 0 27 + 27 27 15 27 27 17 27 27 27 25 27 11 24 27 11 17 24 + 18 0 20 23 18 26 24 24 27 27 23 25 20 26 9 12 25 + 27 27 16 12 27 27 18 23 27 23 27 18 27 14 27 27 27 + 27 27 27 27 27 12 27 25 12 27 27 27 14 23 27 12 21 + 23 26 14 20 14 20 15 0 27 27 27 0 27 27 27 27 20 + 27 27 12 27 27 27 27 12 12 23 23 13 21 26 21 18 12 + 14 10 6 10 16 11 13 26 20 24 26 25 24 12 26 26 12 + 12 12 12 18 20 6 10 10 25 15 16 10 10 10 16 12 18 + 12 15 10 26 23 18 10 18 24 15 25 25 10 23 13 24 18 + 15 25 24 10 18 12 14 27 25 6 12 10 14 18 26 11 12 + 17 12 11 18 18 25 21 18 15 12 12 15 6 14 26 18 23 + 11 13 25 21 24 11 20 18 21 25 9 23 10 11 11 0 18 + 27 6 10 0 25 12 10 20 25 20 25 11 20 14 16 12 23 + 16 18 11 18 16 23 25 12 12 12 26 24 12 18 24 18 24 + 13 25 26 25 24 12 24 13 26 13 23 24 21 12 25 26 11 + 24 6 13 18 16 12 24 12 26 24 23 12 6 25 11 9 24 + 18 25 25 25 16 23 25 23 26 12 16 25 26 20 23 20 11 + + 12 12 12 27 18 27 23 12 12 16 24 23 16 16 15 23 15 + 26 20 20 25 18 24 26 12 12 27 27 25 27 16 15 9 27 + 27 27 12 27 27 12 27 27 27 25 27 15 24 27 15 12 24 + 18 9 20 23 18 26 24 24 27 27 23 25 20 26 0 12 25 + 27 27 16 12 27 27 12 23 27 23 27 18 27 14 27 27 27 + 27 27 27 27 27 12 27 25 12 27 27 27 15 23 27 12 21 + 23 26 14 20 14 20 15 9 27 27 27 27 0 27 27 27 20 + 27 27 12 27 27 27 27 12 15 23 23 12 21 26 21 18 12 + 14 15 15 15 16 11 11 26 20 24 26 25 24 12 26 26 12 + 12 12 12 18 20 15 10 10 25 15 16 10 10 15 12 15 18 + 15 15 10 26 23 18 10 18 24 15 25 25 10 23 12 24 18 + 15 25 24 15 18 12 14 27 25 15 12 15 15 18 26 11 12 + 12 15 15 18 18 25 21 18 15 15 15 15 15 14 26 18 23 + 15 12 25 21 24 11 20 18 21 25 0 23 10 11 11 9 18 + 27 15 15 9 25 12 10 20 25 20 25 11 20 14 16 12 23 + 16 18 15 18 16 23 25 12 12 15 26 24 12 18 24 18 24 + 12 25 26 25 24 15 24 12 26 11 23 24 21 12 25 26 15 + 24 15 10 18 16 12 24 12 26 24 23 12 15 25 15 0 24 + 18 25 25 25 16 23 25 23 26 12 16 25 26 20 23 20 11 + + 18 18 20 18 27 18 2 20 18 14 11 11 14 14 23 11 24 + 16 12 12 15 12 12 16 24 18 18 18 14 18 14 23 23 18 + 18 18 18 18 18 18 18 18 18 15 18 21 11 18 24 18 11 + 12 23 12 4 27 16 12 11 18 18 6 15 27 16 23 24 15 + 18 18 14 20 18 18 18 10 18 0 18 27 18 25 18 18 18 + 18 18 18 18 18 18 18 15 18 18 18 18 16 2 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 0 18 18 12 + 18 18 24 18 18 18 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 12 12 16 15 12 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 18 24 27 + 18 25 23 16 10 27 23 27 12 15 14 15 23 11 24 11 27 + 15 14 12 23 27 18 16 18 15 23 20 23 16 27 16 24 18 + 18 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 10 + 21 18 14 11 12 24 12 27 11 14 23 10 23 21 24 23 12 + 18 23 23 23 14 18 23 27 14 27 15 21 12 16 26 18 10 + 26 27 24 12 14 1 15 20 20 24 16 11 20 27 12 12 12 + 24 15 16 15 12 24 11 24 16 24 2 12 11 20 15 16 24 + 12 23 23 27 14 18 11 18 16 12 10 20 23 14 24 23 11 + 27 14 15 14 26 10 14 10 16 24 14 14 16 12 11 27 24 + + 21 21 23 15 28 15 11 23 21 16 1 12 16 16 24 10 25 + 14 14 14 12 15 11 14 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 21 15 15 15 12 15 23 10 15 24 21 1 + 15 24 14 11 28 14 10 0 15 15 11 12 28 14 24 25 12 + 15 15 16 23 15 15 21 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 0 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 10 14 12 10 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 21 25 28 + 21 27 24 14 10 28 24 28 11 18 12 12 23 10 25 3 28 + 18 12 11 23 28 21 20 15 12 24 23 24 20 28 14 24 21 + 21 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 12 + 23 21 12 12 11 24 14 28 12 12 24 10 24 23 24 24 15 + 15 24 23 24 12 21 24 28 12 28 12 23 14 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 1 23 28 10 15 11 + 25 12 14 12 10 25 4 25 14 24 11 11 12 23 12 14 24 + 10 24 23 28 16 21 1 21 14 10 10 23 24 12 24 24 10 + 28 12 12 12 27 10 12 10 14 25 16 12 14 14 12 28 24 + + 12 12 12 23 24 23 14 12 18 0 16 12 1 1 18 15 23 + 23 11 11 23 10 20 23 23 14 23 23 21 23 4 15 16 23 + 23 23 15 23 23 17 23 23 23 23 23 14 16 23 20 17 16 + 10 16 11 14 24 23 18 16 23 23 14 23 24 23 16 23 23 + 23 23 9 12 23 23 18 12 23 14 23 24 23 23 23 23 23 + 23 23 23 23 23 12 23 23 12 23 23 23 11 14 23 12 12 + 15 23 11 11 11 11 10 16 23 23 23 23 23 23 23 0 11 + 23 23 21 23 23 23 23 12 21 15 15 21 12 23 12 24 12 + 23 18 16 15 4 20 20 23 11 18 23 23 18 12 23 23 12 + 12 12 12 24 24 16 18 18 23 23 24 18 18 18 16 21 24 + 12 23 18 23 15 24 18 24 20 14 21 23 15 15 21 16 24 + 10 21 20 15 24 12 11 23 23 16 12 18 11 24 23 20 12 + 17 12 14 24 24 23 12 10 23 12 23 10 16 23 23 10 14 + 14 14 21 12 20 20 11 24 12 21 16 15 18 14 20 16 10 + 23 16 15 16 21 12 18 24 21 24 23 14 14 11 24 12 15 + 24 24 20 10 0 14 23 12 12 21 23 16 12 24 18 14 20 + 23 23 23 23 18 21 16 23 23 20 14 20 14 12 23 23 20 + 18 16 15 24 8 12 16 12 23 18 15 12 16 21 20 16 16 + 24 21 23 21 24 15 21 15 23 23 5 21 23 11 12 24 20 + + 17 14 15 23 25 23 12 15 24 11 14 11 11 11 21 12 23 + 21 6 11 20 10 16 21 23 19 23 23 18 23 11 18 20 23 + 23 23 21 23 23 23 23 23 23 20 23 16 14 23 23 23 14 + 10 20 8 12 25 21 19 14 23 23 12 20 25 21 20 23 20 + 23 23 15 15 23 23 24 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 8 12 5 12 20 23 23 23 23 23 23 23 23 0 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 14 15 21 20 15 16 21 21 14 + 15 15 17 25 25 20 21 21 20 24 24 21 21 21 22 23 25 + 14 24 21 21 12 25 21 25 16 19 18 20 18 12 23 14 25 + 12 18 19 18 25 14 15 23 20 20 15 21 12 25 21 23 14 + 23 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 19 + 16 19 18 10 16 23 11 25 14 19 20 12 21 16 23 20 15 + 23 20 18 20 18 17 21 25 18 25 20 16 19 12 24 15 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 19 16 + 23 20 21 20 15 23 15 23 21 23 12 16 19 15 20 21 23 + 15 20 19 25 14 14 14 14 21 15 12 15 20 18 23 20 14 + 25 19 20 18 24 12 18 12 21 23 11 19 21 0 11 25 23 + + 10 10 11 24 23 24 16 11 14 11 20 15 11 11 15 18 20 + 24 12 12 23 12 23 24 20 10 24 24 23 24 11 12 14 24 + 24 24 10 24 24 12 24 24 24 23 24 12 20 24 16 12 20 + 12 14 12 16 23 24 21 20 24 24 16 23 24 24 14 20 23 + 24 24 11 11 24 24 14 15 24 16 24 23 24 21 24 24 24 + 24 24 24 24 24 10 24 23 10 24 24 24 10 16 24 11 14 + 18 24 0 12 0 12 10 14 24 24 24 24 24 24 24 24 12 + 0 24 18 24 24 24 24 10 18 18 18 18 14 24 14 23 10 + 21 15 14 12 11 16 16 24 12 21 24 23 21 10 24 24 10 + 11 11 10 23 24 14 15 15 23 23 23 15 15 15 11 18 23 + 10 23 15 24 18 23 15 23 23 10 23 23 12 18 18 20 23 + 10 23 23 12 23 10 4 24 23 14 11 15 10 23 24 16 10 + 12 10 12 23 23 23 14 12 23 10 20 10 14 21 24 12 15 + 12 10 23 14 23 16 12 23 14 23 14 18 15 12 16 14 12 + 24 14 12 14 23 10 15 24 23 24 23 12 12 4 23 10 18 + 23 23 16 12 11 16 23 11 11 18 24 20 11 23 21 12 23 + 20 23 24 23 21 18 20 20 24 16 16 23 14 11 23 24 16 + 21 14 12 23 11 10 20 10 24 21 18 11 14 23 16 14 20 + 23 23 23 23 23 18 23 18 24 20 11 23 24 12 15 24 16 + + 16 16 15 28 14 28 24 15 16 21 25 24 21 21 11 24 10 + 28 23 23 27 23 26 28 10 16 28 28 27 28 21 12 12 28 + 28 28 16 28 28 16 28 28 28 27 28 14 25 28 10 16 25 + 23 12 23 24 14 28 25 25 28 28 24 27 15 28 12 10 27 + 28 28 21 15 28 28 16 24 28 24 28 14 28 11 28 28 28 + 28 28 28 28 28 16 28 27 16 28 28 28 18 24 28 15 23 + 24 28 18 23 18 23 20 12 28 28 28 28 28 28 28 28 23 + 28 0 4 28 28 28 28 16 10 24 24 9 23 28 23 14 16 + 11 11 12 12 21 10 10 28 23 25 28 27 25 16 28 28 16 + 15 15 16 14 15 12 11 11 27 12 12 11 11 11 16 10 14 + 16 12 11 28 24 14 11 14 26 20 27 27 12 24 9 25 14 + 20 27 26 12 14 16 18 28 27 12 15 11 18 14 28 10 16 + 16 16 14 14 14 27 23 23 12 16 10 20 12 11 28 23 24 + 14 16 27 23 26 10 23 14 23 27 12 24 11 14 10 12 23 + 28 12 12 12 27 16 11 15 27 15 27 14 23 18 12 16 24 + 12 14 10 23 21 24 27 15 15 10 28 25 15 14 25 23 26 + 10 27 28 27 25 10 25 10 28 10 24 26 23 15 27 28 10 + 25 12 12 14 21 16 25 16 28 25 24 15 12 27 10 12 25 + 14 27 27 27 12 24 27 24 28 10 21 27 28 23 24 15 10 + + 23 23 23 33 15 33 27 23 24 24 28 27 24 24 18 28 14 + 31 25 25 31 25 30 31 14 23 33 33 31 33 24 21 20 33 + 33 33 23 33 33 23 33 33 33 31 33 23 28 33 16 23 28 + 25 20 25 27 10 31 29 28 33 33 27 31 6 31 20 15 31 + 33 33 24 23 33 33 24 27 33 27 33 10 33 12 33 33 33 + 33 33 33 33 33 23 33 31 23 33 33 33 24 27 33 23 26 + 28 31 24 25 24 25 24 20 33 33 33 33 33 33 33 33 25 + 33 33 0 33 33 33 33 23 15 28 28 19 26 31 26 10 23 + 15 18 20 21 24 16 19 31 25 29 31 31 29 23 31 31 23 + 23 23 23 10 6 20 18 18 31 12 15 18 18 18 23 15 10 + 23 12 18 31 28 10 18 10 30 24 31 31 21 28 19 28 19 + 24 31 30 21 10 23 24 33 31 20 23 18 24 10 31 16 23 + 23 23 23 10 15 31 26 25 12 23 14 24 20 15 31 25 27 + 23 23 31 26 30 16 25 10 26 31 20 28 18 23 16 20 25 + 33 20 21 20 31 23 18 10 31 10 31 23 25 24 11 23 28 + 15 10 16 25 24 27 31 23 23 15 31 28 23 10 29 25 30 + 19 31 31 31 29 15 28 19 31 19 27 30 26 23 31 31 16 + 29 20 21 10 24 23 28 23 31 29 28 23 20 31 16 20 28 + 10 31 31 31 15 28 31 28 31 15 24 31 31 25 27 15 16 + + 18 18 16 29 12 29 24 16 18 23 25 24 23 23 12 25 6 + 28 23 23 28 23 27 28 4 18 29 29 27 29 23 14 12 29 + 29 29 18 29 29 18 29 29 29 28 29 15 25 29 11 18 25 + 23 12 23 24 12 28 26 25 29 29 24 28 14 28 12 9 28 + 29 29 23 16 29 29 18 24 29 24 29 12 29 10 29 29 29 + 29 29 29 29 29 18 29 28 18 29 29 29 20 24 29 16 24 + 25 28 20 23 20 23 21 12 29 29 29 29 29 29 29 29 23 + 29 29 10 0 29 29 29 18 10 25 25 13 24 28 24 12 18 + 10 12 12 14 23 11 13 28 23 26 28 28 26 18 28 28 18 + 16 16 18 12 14 12 12 12 28 11 12 12 12 12 18 10 12 + 18 11 12 28 25 12 12 12 27 21 27 28 14 25 13 25 13 + 21 27 27 14 12 18 20 29 28 12 16 12 20 12 28 11 18 + 18 18 15 12 12 28 24 23 11 18 6 21 12 10 28 23 24 + 15 18 27 24 27 11 23 12 24 27 12 25 12 15 11 12 23 + 29 12 14 12 27 18 12 14 27 14 28 15 23 20 12 18 25 + 12 12 11 23 23 24 28 16 16 10 28 25 16 12 26 23 27 + 13 28 28 28 26 10 25 13 28 13 24 27 24 16 28 28 11 + 26 12 14 12 23 18 25 18 28 26 25 16 12 27 11 12 25 + 12 27 28 27 12 25 27 25 28 9 23 27 28 23 24 14 11 + + 18 18 16 29 12 29 24 16 18 23 25 24 23 23 12 25 10 + 28 23 23 28 23 27 28 0 18 29 29 27 29 23 14 12 29 + 29 29 18 29 29 18 29 29 29 28 29 15 25 29 11 18 25 + 23 12 23 24 12 28 26 25 29 29 24 28 14 28 12 4 28 + 29 29 23 16 29 29 18 24 29 24 29 12 29 10 29 29 29 + 29 29 29 29 29 18 29 28 18 29 29 29 20 24 29 16 24 + 25 28 20 23 20 23 21 12 29 29 29 29 29 29 29 29 23 + 29 29 10 29 0 29 29 18 10 25 25 10 24 28 24 12 18 + 10 12 12 14 23 11 11 28 23 26 28 28 26 18 28 28 18 + 16 16 18 12 14 12 12 12 28 11 12 12 12 12 18 10 12 + 18 11 12 28 25 12 12 12 27 21 27 28 14 25 10 25 12 + 21 27 27 14 12 18 20 29 28 12 16 12 20 12 28 11 18 + 18 18 15 12 12 28 24 23 11 18 10 21 12 10 28 23 24 + 15 18 27 24 27 11 23 12 24 27 12 25 12 15 11 12 23 + 29 12 14 12 27 18 12 14 27 14 28 15 23 20 12 18 25 + 12 12 11 23 23 24 28 16 16 10 28 25 16 12 26 23 27 + 9 28 28 28 26 10 25 9 28 11 24 27 24 16 28 28 11 + 26 12 14 12 23 18 25 18 28 26 25 16 12 27 11 12 25 + 12 27 28 27 12 25 27 25 28 4 23 27 28 23 24 14 11 + + 18 18 20 18 27 18 0 20 18 14 11 10 14 14 23 10 24 + 16 12 12 15 12 12 16 24 18 18 18 14 18 14 23 23 18 + 18 18 18 18 18 18 18 18 18 15 18 21 11 18 24 18 11 + 12 23 12 2 27 16 12 11 18 18 3 15 27 16 23 24 15 + 18 18 14 20 18 18 18 10 18 2 18 27 18 25 18 18 18 + 18 18 18 18 18 18 18 15 18 18 18 18 16 0 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 18 18 18 12 + 18 18 24 18 18 0 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 12 12 16 15 12 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 18 24 27 + 18 25 23 16 10 27 23 27 12 15 14 15 23 10 24 11 27 + 15 14 12 23 27 18 16 18 15 23 20 23 16 27 16 24 18 + 18 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 10 + 21 18 14 11 12 24 12 27 11 14 23 10 23 21 24 23 12 + 18 23 23 23 14 18 23 27 14 27 15 21 12 16 26 18 10 + 26 27 24 12 14 1 15 20 20 24 16 11 20 27 12 12 12 + 24 15 16 15 12 24 11 24 16 24 0 12 11 20 15 16 24 + 12 23 23 27 14 18 11 18 16 12 10 20 23 14 24 23 11 + 27 14 15 14 26 10 14 10 16 24 14 14 16 12 10 27 24 + + 18 18 16 29 12 29 24 16 18 23 25 24 23 23 19 25 19 + 28 23 23 28 23 27 28 9 18 29 29 27 29 23 19 13 29 + 29 29 18 29 29 18 29 29 29 28 29 19 25 29 19 18 25 + 23 13 23 24 19 28 26 25 29 29 24 28 14 28 12 4 28 + 29 29 23 16 29 29 18 24 29 24 29 19 29 10 29 29 29 + 29 29 29 29 29 18 29 28 18 29 29 29 20 24 29 16 24 + 25 28 20 23 20 23 21 13 29 29 29 29 29 29 29 29 23 + 29 29 13 29 29 29 0 18 19 25 25 10 24 28 24 19 18 + 10 19 19 19 23 11 11 28 23 26 28 28 26 18 28 28 18 + 16 16 18 19 14 19 12 12 28 19 12 12 12 19 18 19 19 + 19 14 14 28 25 19 12 19 27 21 27 28 14 25 10 25 12 + 21 27 27 19 19 18 20 29 28 19 16 19 20 19 28 14 18 + 18 19 19 19 12 28 24 23 19 19 19 21 19 10 28 23 24 + 19 18 27 24 27 11 23 19 24 27 12 25 12 15 11 13 23 + 29 19 19 13 27 18 12 14 27 14 28 15 23 20 13 18 25 + 12 13 19 23 23 24 28 16 16 19 28 25 16 19 26 23 27 + 0 28 28 28 26 19 25 0 28 11 24 27 24 16 28 28 19 + 26 19 14 19 23 18 25 18 28 26 25 16 19 27 19 12 25 + 19 27 28 27 12 25 27 25 28 4 23 27 28 23 24 14 11 + + 15 4 10 24 23 24 18 11 22 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 18 24 24 23 24 12 12 12 24 + 24 24 19 24 24 21 24 24 24 24 24 11 21 24 15 21 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 13 18 24 + 24 24 13 10 24 24 22 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 5 24 24 9 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 0 16 20 20 18 15 24 15 23 7 + 20 14 12 12 12 15 18 24 14 23 24 24 23 14 24 24 4 + 10 10 15 23 23 12 14 14 24 21 23 14 14 14 20 16 23 + 1 21 14 24 20 23 14 23 23 18 23 24 12 20 18 21 23 + 11 23 23 12 23 9 13 24 24 12 10 14 10 23 24 15 11 + 21 1 11 23 23 24 15 12 21 1 18 11 12 20 24 12 18 + 11 18 23 15 23 15 14 23 15 23 13 20 14 11 15 12 13 + 24 12 12 12 23 15 14 23 23 23 24 11 18 10 23 13 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 18 23 + 18 24 24 24 23 16 21 18 24 18 18 23 18 10 24 24 15 + 23 12 18 23 12 7 21 5 24 23 20 10 12 23 15 13 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 0 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 20 20 21 16 27 16 10 21 21 15 10 11 15 15 24 3 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 20 16 16 20 16 16 16 14 16 23 10 16 24 20 10 + 14 23 12 10 27 15 16 10 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 21 11 16 10 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 20 16 16 16 18 10 16 21 12 + 3 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 0 6 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 12 11 15 14 12 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 20 24 27 + 20 26 24 15 9 27 24 27 12 16 12 16 23 3 24 10 27 + 16 12 16 23 27 20 18 16 14 23 21 24 18 27 15 24 20 + 20 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 16 + 23 20 12 12 12 24 12 27 12 16 23 3 24 23 24 23 14 + 16 23 23 23 12 20 24 28 12 28 16 23 16 18 27 20 7 + 27 27 24 14 15 10 14 21 21 24 15 10 21 27 11 16 12 + 25 14 15 14 12 24 12 25 15 24 10 12 16 21 14 15 24 + 11 23 23 27 15 20 10 20 15 12 6 21 23 12 24 23 10 + 27 16 14 12 27 5 12 3 15 25 15 16 15 12 11 28 24 + + 15 14 15 23 25 23 12 15 22 11 14 11 11 11 21 12 23 + 21 5 10 20 10 16 21 23 18 23 23 18 23 11 18 20 23 + 23 23 19 23 23 21 23 23 23 20 23 16 14 23 23 21 14 + 10 20 6 12 25 21 18 14 23 23 12 20 25 21 20 23 20 + 23 23 13 15 23 23 22 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 6 12 4 12 20 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 14 23 12 0 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 12 15 21 20 15 14 21 21 14 + 15 15 15 25 25 20 21 21 20 24 24 21 21 21 20 23 25 + 14 24 21 21 12 25 21 25 16 18 18 20 18 12 23 14 25 + 12 18 18 18 25 14 13 23 20 20 15 21 12 25 21 23 14 + 21 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 18 + 16 18 18 10 16 23 10 25 12 18 20 12 21 16 23 20 13 + 23 20 18 20 18 15 21 25 18 25 20 16 18 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 18 16 + 23 20 21 20 15 23 14 23 21 23 12 16 18 15 20 21 23 + 15 20 18 25 12 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 1 11 25 23 + + 17 16 15 28 15 28 24 15 24 21 25 24 21 21 11 24 10 + 28 23 23 27 23 26 28 10 19 28 28 27 28 21 12 12 28 + 28 28 21 28 28 23 28 28 28 27 28 14 25 28 10 23 25 + 23 12 23 24 14 28 25 25 28 28 24 27 15 28 15 15 27 + 28 28 21 15 28 28 24 24 28 24 28 14 28 11 28 28 28 + 28 28 28 28 28 16 28 27 16 28 28 28 18 24 28 15 23 + 24 28 18 23 18 23 20 12 28 28 28 28 28 28 28 28 23 + 28 28 6 28 28 28 28 16 0 24 24 0 23 28 23 14 16 + 15 11 12 12 21 15 19 28 23 25 28 27 25 16 28 28 16 + 15 15 17 14 15 12 11 11 27 12 15 12 11 11 22 0 14 + 16 12 11 28 24 14 12 14 26 20 27 27 12 24 19 25 19 + 20 27 26 12 14 16 18 28 27 12 15 11 18 14 28 10 16 + 23 16 14 14 15 27 23 23 12 16 10 20 12 15 28 23 24 + 14 19 27 23 26 15 23 14 23 27 15 24 11 14 15 12 23 + 28 12 12 12 27 17 15 15 27 15 27 14 23 18 12 16 24 + 15 14 10 23 21 24 27 15 15 0 28 25 15 14 25 23 26 + 19 27 28 27 25 0 25 19 28 19 24 26 23 15 27 28 10 + 25 12 19 14 21 16 25 16 28 25 24 15 12 27 10 15 25 + 14 27 27 27 15 24 27 24 28 15 21 27 28 23 24 15 10 + + 15 14 15 23 25 23 12 15 22 11 14 11 11 11 21 12 23 + 21 5 10 20 10 16 21 23 18 23 23 18 23 11 18 20 23 + 23 23 19 23 23 21 23 23 23 20 23 16 14 23 23 21 14 + 10 20 6 12 25 21 18 14 23 23 12 20 25 21 20 23 20 + 23 23 13 15 23 23 22 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 6 12 4 12 20 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 14 23 12 12 23 0 21 10 25 14 + 24 21 20 18 11 23 23 21 12 15 21 20 15 14 21 21 14 + 15 15 15 25 25 20 21 21 20 24 24 21 21 21 20 23 25 + 14 24 21 21 12 25 21 25 16 18 18 20 18 12 23 14 25 + 12 18 18 18 25 14 13 23 20 20 15 21 12 25 21 23 14 + 21 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 18 + 16 18 18 10 16 23 10 25 12 18 20 12 21 16 23 20 13 + 23 20 18 20 18 15 21 25 18 25 20 16 18 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 18 16 + 23 20 21 20 15 23 14 23 21 23 12 16 18 15 20 21 23 + 15 20 18 25 12 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 1 11 25 23 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 0 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 0 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 0 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 21 21 23 15 28 15 11 23 24 16 11 12 16 16 24 10 25 + 14 14 14 12 15 11 15 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 23 15 15 15 12 15 23 0 15 24 23 9 + 15 24 14 11 28 14 19 10 15 15 11 12 28 15 24 25 12 + 15 15 16 23 15 15 24 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 0 + 26 24 24 23 16 24 24 14 14 10 14 12 15 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 22 25 28 + 21 27 24 14 12 28 24 28 15 19 12 19 23 10 25 6 28 + 18 15 19 23 28 21 20 19 12 24 23 24 20 28 14 24 21 + 23 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 19 + 23 21 12 12 11 24 14 28 14 19 24 10 24 23 24 24 15 + 19 24 23 24 12 21 24 28 15 28 19 23 19 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 9 23 28 10 19 15 + 25 12 14 12 15 25 15 25 14 24 11 11 19 23 12 15 24 + 10 24 23 28 16 21 9 21 14 15 10 23 24 12 24 24 0 + 28 19 15 12 27 10 12 10 14 25 16 19 14 14 12 28 24 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 0 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 0 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 0 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 20 20 18 30 12 30 25 18 20 23 26 24 23 23 15 25 15 + 29 24 24 28 23 27 29 10 20 30 30 28 30 23 15 14 30 + 30 30 20 30 30 20 30 30 30 28 30 16 26 30 15 20 26 + 23 14 24 25 15 29 27 26 30 30 25 28 12 29 14 10 28 + 30 30 23 18 30 30 20 24 30 25 30 15 30 4 30 30 30 + 30 30 30 30 30 20 30 28 20 30 30 30 21 25 30 18 24 + 25 29 21 24 21 24 23 14 30 30 30 30 30 30 30 30 24 + 30 30 11 30 30 30 30 20 15 25 25 11 24 29 24 15 20 + 0 15 15 0 23 12 12 29 24 27 29 28 27 20 29 29 20 + 18 18 20 15 12 15 12 12 28 15 11 12 12 15 20 15 15 + 20 10 12 29 25 15 12 15 27 23 28 28 15 25 11 26 12 + 23 28 27 15 15 20 21 30 28 15 18 15 21 15 29 12 20 + 20 20 16 15 12 28 24 23 15 20 15 23 15 0 29 23 24 + 16 20 28 24 27 12 24 15 24 28 14 25 12 16 12 14 23 + 30 15 15 14 28 20 12 12 28 12 28 16 24 21 11 20 25 + 11 12 15 23 23 25 28 18 18 15 29 26 18 15 27 23 27 + 10 28 29 28 27 15 26 10 29 12 25 27 24 18 28 29 15 + 27 15 15 15 23 20 26 20 29 27 25 18 15 28 15 14 26 + 15 28 28 28 11 25 28 25 29 10 23 28 29 24 24 12 12 + + 17 12 11 26 20 26 23 12 24 15 23 21 15 15 11 23 14 + 25 18 18 25 16 24 25 14 19 26 26 24 26 15 0 10 26 + 26 26 21 26 26 23 26 26 26 25 26 10 23 26 12 23 23 + 16 10 18 23 20 25 24 23 26 26 23 25 21 25 15 15 25 + 26 26 15 11 26 26 24 21 26 23 26 20 26 15 26 26 26 + 26 26 26 26 26 12 26 25 12 26 26 26 12 23 26 11 20 + 23 25 12 18 12 18 14 10 26 26 26 26 26 26 26 26 18 + 26 26 12 26 26 26 26 12 12 23 23 19 20 25 20 20 12 + 15 11 10 0 0 15 19 25 18 24 25 25 24 16 25 25 12 + 11 11 17 20 21 10 11 11 25 16 18 12 11 11 22 12 20 + 12 16 11 25 23 20 12 20 24 19 24 25 10 23 19 23 20 + 14 24 24 0 20 12 15 26 25 10 11 11 12 20 25 12 12 + 23 12 10 20 20 25 20 16 16 12 14 14 10 15 25 16 21 + 10 19 24 20 24 15 18 20 20 24 15 23 11 10 15 10 16 + 26 10 0 10 24 17 15 21 24 21 25 10 19 12 18 15 23 + 18 20 12 16 15 23 25 11 11 12 25 23 11 20 24 19 24 + 19 25 25 25 24 12 23 19 25 19 23 24 20 11 25 25 12 + 24 10 19 20 15 12 23 12 25 24 23 11 10 24 12 15 23 + 20 24 25 24 18 23 24 23 25 15 15 24 25 18 21 21 12 + + 17 14 12 27 16 27 23 12 24 18 24 23 18 18 0 24 12 + 27 21 21 26 20 25 27 12 19 27 27 25 27 18 11 10 27 + 27 27 21 27 27 23 27 27 27 26 27 12 24 27 10 23 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 15 15 26 + 27 27 18 12 27 27 24 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 19 23 27 23 16 14 + 15 0 10 11 18 0 19 27 21 24 27 26 24 16 27 27 14 + 12 12 17 16 18 10 10 10 26 14 15 12 10 0 22 11 16 + 14 14 5 27 24 16 12 16 25 19 25 26 11 24 19 24 19 + 16 25 25 11 16 14 15 27 26 10 12 0 15 16 27 10 14 + 23 14 12 16 16 26 23 20 14 14 12 16 10 15 27 20 23 + 12 19 25 23 25 15 21 16 23 25 15 24 10 12 15 10 20 + 27 10 11 10 25 17 15 18 25 18 26 12 21 15 15 15 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 19 26 27 26 24 11 24 19 27 19 23 25 23 12 26 27 10 + 24 10 19 16 18 14 24 14 27 24 24 12 10 25 10 15 24 + 16 25 26 25 15 24 25 24 27 15 18 25 27 21 23 18 10 + + 17 12 12 27 18 27 23 12 24 16 24 23 16 16 10 23 12 + 26 20 20 25 18 24 26 12 19 27 27 25 27 16 10 6 27 + 27 27 21 27 27 23 27 27 27 25 27 11 24 27 11 23 24 + 18 6 20 23 18 26 24 24 27 27 23 25 20 26 15 15 25 + 27 27 16 12 27 27 24 23 27 23 27 18 27 14 27 27 27 + 27 27 27 27 27 12 27 25 12 27 27 27 14 23 27 12 21 + 23 26 14 20 14 20 15 6 27 27 27 27 27 27 27 27 20 + 27 27 12 27 27 27 27 12 12 23 23 19 21 26 21 18 12 + 15 10 0 10 16 15 0 26 20 24 26 25 24 16 26 26 12 + 12 12 17 18 20 0 10 10 25 15 16 12 10 10 22 12 18 + 12 15 10 26 23 18 12 18 24 19 25 25 10 23 19 24 19 + 15 25 24 10 18 12 15 27 25 0 12 10 14 18 26 11 12 + 23 12 11 18 18 25 21 18 15 12 12 15 0 15 26 18 23 + 11 19 25 21 24 15 20 18 21 25 15 23 10 11 15 6 18 + 27 0 10 6 25 17 15 20 25 20 25 11 20 14 16 15 23 + 16 18 11 18 16 23 25 12 12 12 26 24 12 18 24 19 24 + 19 25 26 25 24 12 24 19 26 19 23 24 21 12 25 26 11 + 24 0 19 18 16 12 24 12 26 24 23 12 0 25 11 15 24 + 18 25 25 25 16 23 25 23 26 15 16 25 26 20 23 20 11 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 0 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 0 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 0 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 0 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 15 15 14 28 15 28 24 14 15 20 24 23 20 20 15 24 15 + 27 23 23 27 21 25 27 11 15 28 28 26 28 20 15 11 28 + 28 28 15 28 28 15 28 28 28 27 28 15 24 28 15 15 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 11 11 27 + 28 28 20 14 28 28 15 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 28 27 15 28 28 28 16 24 28 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 15 24 24 10 23 27 23 15 15 + 12 15 15 15 20 0 4 27 23 25 27 0 25 15 27 27 15 + 14 14 15 15 16 15 10 10 27 15 14 10 10 15 15 15 15 + 15 12 10 27 24 15 10 15 25 18 26 27 12 24 10 24 15 + 18 26 25 15 15 15 16 28 27 15 14 15 16 15 27 9 15 + 15 15 15 15 15 27 23 21 15 15 15 18 15 12 27 21 23 + 15 15 26 23 25 0 23 15 23 26 11 24 10 12 0 11 21 + 28 15 15 11 26 15 10 16 26 16 27 12 23 16 14 15 24 + 14 15 15 21 20 24 27 14 14 15 27 24 14 15 25 21 25 + 11 27 27 27 25 15 24 11 27 4 24 25 23 14 27 27 15 + 25 15 12 15 20 15 24 15 27 25 24 14 15 26 15 11 24 + 15 26 27 26 14 24 26 24 27 11 20 26 27 23 23 16 4 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 0 21 11 15 28 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 0 11 24 12 11 27 24 12 + 21 25 20 15 31 10 19 12 11 11 15 0 31 15 25 28 6 + 11 11 23 24 11 11 24 16 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 0 24 11 11 11 23 15 11 24 18 + 14 10 23 20 23 20 23 25 11 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 0 0 24 10 10 24 + 24 24 24 31 31 25 26 26 0 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 15 23 10 19 25 14 27 12 31 + 23 15 19 25 31 24 23 19 0 25 24 26 23 31 10 27 24 + 24 24 24 31 31 0 18 21 29 24 28 23 25 28 10 21 19 + 24 24 10 18 11 27 20 31 18 19 25 14 26 24 27 25 21 + 19 25 25 25 10 24 26 31 15 31 19 24 20 23 30 24 14 + 30 31 27 21 23 15 0 24 24 27 10 12 24 31 12 21 15 + 28 10 10 0 15 27 15 28 10 27 15 11 19 24 0 15 27 + 12 25 25 31 23 24 12 24 10 15 14 24 25 10 27 25 12 + 31 19 15 10 30 14 10 14 10 28 23 19 10 20 16 31 27 + + 17 5 11 24 23 24 18 12 24 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 19 24 24 23 24 12 12 12 24 + 24 24 21 24 24 23 24 24 24 24 24 11 21 24 15 23 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 15 18 24 + 24 24 15 10 24 24 24 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 6 24 24 10 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 5 16 20 20 19 15 24 15 23 9 + 20 14 12 12 12 15 19 24 14 23 24 24 23 0 24 24 5 + 10 10 17 23 23 12 14 14 24 21 23 14 14 14 22 16 23 + 0 21 14 24 20 23 14 23 23 19 23 24 12 20 19 21 23 + 11 23 23 12 23 10 15 24 24 12 10 14 10 23 24 15 12 + 23 0 11 23 23 24 15 12 21 0 18 11 12 20 24 12 19 + 11 19 23 15 23 15 14 23 15 23 15 20 14 11 15 12 15 + 24 12 12 12 23 17 15 23 23 23 24 11 19 10 23 15 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 19 23 + 19 24 24 24 23 16 21 19 24 19 18 23 19 10 24 24 15 + 23 12 19 23 14 9 21 6 24 23 20 10 12 23 15 15 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 15 15 16 21 25 21 11 16 16 12 12 10 12 12 23 12 24 + 20 10 10 18 11 15 20 24 15 21 21 16 21 12 20 21 21 + 21 21 15 21 21 15 21 21 21 18 21 18 12 21 23 15 12 + 11 21 10 11 25 20 14 12 21 21 11 18 26 20 21 24 18 + 21 21 12 16 21 21 16 10 21 11 21 25 21 24 21 21 21 + 21 21 21 21 21 15 21 18 15 21 21 21 14 11 21 16 1 + 12 20 14 10 14 10 12 21 21 21 21 21 21 21 21 21 10 + 21 21 23 21 21 21 21 15 23 12 12 23 1 20 0 25 15 + 24 23 21 20 12 23 23 20 10 14 20 18 14 15 0 20 15 + 16 16 15 25 26 21 23 23 18 24 25 23 23 23 15 23 25 + 15 24 23 20 12 25 23 25 15 12 16 18 20 12 23 12 25 + 12 16 15 20 25 15 14 21 18 21 16 23 14 25 20 23 15 + 15 15 18 25 25 18 0 11 24 15 24 12 21 24 20 11 11 + 18 15 16 2 15 23 10 25 6 16 21 12 23 18 23 21 11 + 21 21 20 21 16 15 23 26 16 26 18 18 11 14 25 15 12 + 25 25 23 11 12 11 18 16 16 23 20 12 16 25 14 11 15 + 24 18 20 18 14 23 12 24 20 23 11 15 11 16 18 20 23 + 14 21 20 25 12 15 12 15 20 14 12 16 21 16 23 21 12 + 25 16 18 16 25 12 16 12 20 24 12 16 20 10 10 26 23 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 0 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 14 2 10 24 23 24 18 10 21 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 16 24 24 23 24 12 12 12 24 + 24 24 18 24 24 20 24 24 24 24 24 11 21 24 15 20 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 12 18 24 + 24 24 12 10 24 24 21 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 3 24 24 7 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 2 16 20 20 16 15 24 15 23 6 + 20 14 12 12 12 15 16 24 14 23 24 24 23 13 24 24 0 + 10 10 14 23 23 12 14 14 24 21 23 14 14 14 19 16 23 + 3 21 14 24 20 23 14 23 23 16 23 24 12 20 16 21 23 + 11 23 23 12 23 7 12 24 24 12 10 14 10 23 24 15 9 + 20 3 11 23 23 24 15 12 21 3 18 11 12 20 24 12 16 + 11 16 23 15 23 15 14 23 15 23 12 20 14 11 15 12 12 + 24 12 12 12 23 14 14 23 23 23 24 11 16 10 23 12 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 16 23 + 18 24 24 24 23 16 21 18 24 16 18 23 16 10 24 24 15 + 23 12 16 23 12 6 21 3 24 23 20 10 12 23 15 12 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 14 10 8 25 23 25 20 9 21 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 16 25 25 24 25 12 11 12 25 + 25 25 18 25 25 20 25 25 25 24 25 10 23 25 14 20 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 12 16 24 + 25 25 12 7 25 25 21 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 7 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 16 16 24 16 23 10 + 18 12 12 11 12 14 16 24 15 23 24 24 23 13 24 24 10 + 0 6 14 23 23 12 12 12 24 20 21 12 12 12 19 15 23 + 10 20 12 24 21 23 12 23 23 16 24 24 11 21 16 23 23 + 12 24 23 11 23 10 12 25 24 12 7 12 11 23 24 14 10 + 20 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 16 24 16 23 14 15 23 16 24 12 21 12 10 14 12 14 + 25 12 11 12 24 14 12 23 24 23 24 10 16 11 21 12 21 + 21 23 14 14 12 20 24 6 3 15 24 23 2 23 23 16 23 + 16 24 24 24 23 15 23 16 24 16 20 23 16 5 24 24 14 + 23 12 16 23 12 10 23 10 24 23 21 6 12 24 14 12 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 14 10 8 25 23 25 20 9 21 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 16 25 25 24 25 12 11 12 25 + 25 25 18 25 25 20 25 25 25 24 25 10 23 25 14 20 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 12 16 24 + 25 25 12 7 25 25 21 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 7 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 16 16 24 16 23 10 + 18 12 12 11 12 14 16 24 15 23 24 24 23 13 24 24 10 + 2 0 14 23 23 12 12 12 24 20 21 12 12 12 19 15 23 + 10 20 12 24 21 23 12 23 23 16 24 24 11 21 16 23 23 + 12 24 23 11 23 10 12 25 24 12 7 12 11 23 24 14 10 + 20 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 16 24 16 23 14 15 23 16 24 12 21 12 10 14 12 14 + 25 12 11 12 24 14 12 23 24 23 24 10 16 11 21 12 21 + 21 23 14 14 12 20 24 6 3 15 24 23 2 23 23 16 23 + 16 24 24 24 23 15 23 16 24 16 20 23 16 5 24 24 14 + 23 12 16 23 12 10 23 10 24 23 21 6 12 24 14 12 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 17 5 11 24 23 24 18 12 24 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 19 24 24 23 24 12 12 12 24 + 24 24 21 24 24 23 24 24 24 24 24 11 21 24 15 23 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 15 18 24 + 24 24 15 10 24 24 24 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 6 24 24 10 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 5 16 20 20 19 15 24 15 23 9 + 20 14 12 12 12 15 19 24 14 23 24 24 23 16 24 24 5 + 10 10 0 23 23 12 14 14 24 21 23 14 14 14 22 16 23 + 0 21 14 24 20 23 14 23 23 19 23 24 12 20 19 21 23 + 11 23 23 12 23 10 15 24 24 12 10 14 10 23 24 15 12 + 23 0 11 23 23 24 15 12 21 0 18 11 12 20 24 12 19 + 11 19 23 15 23 15 14 23 15 23 15 20 14 11 15 12 15 + 24 12 12 12 23 17 15 23 23 23 24 11 19 10 23 15 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 19 23 + 19 24 24 24 23 16 21 19 24 19 18 23 19 10 24 24 15 + 23 12 19 23 14 9 21 6 24 23 20 10 12 23 15 15 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 23 23 23 31 0 31 27 23 23 24 28 26 24 24 16 27 15 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 15 31 28 28 31 31 27 31 10 31 18 12 31 + 31 31 24 23 31 31 23 26 31 27 31 15 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 15 27 27 14 25 31 25 15 23 + 12 16 18 20 24 15 15 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 15 10 16 16 16 23 15 15 + 23 11 16 31 27 15 16 15 29 24 30 31 20 27 14 28 4 + 24 30 29 20 15 23 23 31 31 18 23 16 23 15 31 15 23 + 23 23 21 15 0 31 25 24 15 23 15 24 18 12 31 24 26 + 21 23 30 25 29 15 25 15 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 10 9 15 24 24 27 31 23 23 15 31 28 23 15 28 24 29 + 12 31 31 31 28 15 28 12 31 15 27 29 25 23 31 31 15 + 28 18 20 15 24 23 28 23 31 28 27 23 18 30 15 18 28 + 15 30 31 30 10 27 30 27 31 12 24 30 31 25 26 10 15 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 0 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 0 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 15 14 12 27 16 27 23 12 22 18 24 23 18 18 1 24 12 + 27 21 21 26 20 25 27 12 18 27 27 25 27 18 11 10 27 + 27 27 19 27 27 21 27 27 27 26 27 12 24 27 10 21 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 13 13 26 + 27 27 18 12 27 27 22 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 18 23 27 23 16 14 + 13 1 10 11 18 13 18 27 21 24 27 26 24 14 27 27 14 + 12 12 15 16 18 10 0 9 26 14 15 11 9 1 20 11 16 + 14 14 4 27 24 16 11 16 25 18 25 26 11 24 18 24 18 + 16 25 25 11 16 14 15 27 26 10 12 1 15 16 27 10 14 + 21 14 12 16 16 26 23 20 14 14 12 16 10 13 27 20 23 + 12 18 25 23 25 13 21 16 23 25 13 24 8 12 13 10 20 + 27 10 11 10 25 15 13 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 18 26 27 26 24 11 24 18 27 18 23 25 23 12 26 27 10 + 24 10 18 16 18 14 24 14 27 24 24 12 10 25 10 13 24 + 16 25 26 25 15 24 25 24 27 13 18 25 27 21 23 18 10 + + 14 14 12 27 16 27 23 12 21 18 24 23 18 18 3 24 12 + 27 21 21 26 20 25 27 12 16 27 27 25 27 18 11 10 27 + 27 27 18 27 27 20 27 27 27 26 27 12 24 27 10 20 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 12 12 26 + 27 27 18 12 27 27 21 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 16 23 27 23 16 14 + 12 3 10 11 18 12 16 27 21 24 27 26 24 14 27 27 14 + 12 12 14 16 18 10 7 0 26 14 15 9 7 3 19 11 16 + 14 14 2 27 24 16 9 16 25 16 25 26 11 24 16 24 16 + 16 25 25 11 16 14 15 27 26 10 12 3 15 16 27 10 14 + 20 14 12 16 16 26 23 20 14 14 12 16 10 12 27 20 23 + 12 16 25 23 25 12 21 16 23 25 12 24 7 12 12 10 20 + 27 10 11 10 25 14 12 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 16 26 27 26 24 11 24 16 27 16 23 25 23 12 26 27 10 + 24 10 16 16 18 14 24 14 27 24 24 12 10 25 10 12 24 + 16 25 26 25 15 24 25 24 27 12 18 25 27 21 23 18 10 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 0 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 23 23 21 31 10 31 26 21 23 24 27 25 24 24 15 27 15 + 31 24 24 30 24 28 31 12 23 31 31 29 31 24 18 16 31 + 31 31 23 31 31 23 31 31 31 30 31 20 27 31 15 23 27 + 24 16 24 26 15 31 28 27 31 31 26 30 11 31 16 12 30 + 31 31 24 21 31 31 23 25 31 26 31 15 31 11 31 31 31 + 31 31 31 31 31 23 31 30 23 31 31 31 23 26 31 21 25 + 27 31 23 24 23 24 23 16 31 31 31 31 31 31 31 31 24 + 31 31 12 31 31 31 31 23 15 27 27 12 25 31 25 15 23 + 11 15 16 18 24 14 14 31 24 28 31 30 28 23 31 31 23 + 21 21 23 15 11 16 15 15 30 0 0 15 15 15 23 15 15 + 23 10 15 31 27 15 15 15 28 23 29 30 18 27 12 27 10 + 23 29 28 18 15 23 23 31 30 16 21 15 23 15 31 14 23 + 23 23 20 15 10 30 25 24 15 23 15 23 16 11 31 24 25 + 20 23 29 25 28 14 24 15 25 29 16 27 15 20 14 16 24 + 31 16 18 16 29 23 15 11 29 11 30 20 24 23 9 23 27 + 0 10 15 24 24 26 30 21 21 15 31 27 21 15 28 24 28 + 12 30 31 30 28 15 27 12 31 14 26 28 25 21 30 31 15 + 28 16 18 15 24 23 27 23 31 28 27 21 16 29 15 16 27 + 15 29 30 29 0 27 29 27 31 12 24 29 31 24 25 11 14 + + 21 21 20 31 15 31 25 20 24 23 27 25 23 23 14 26 11 + 30 24 24 29 24 28 30 11 21 31 31 28 31 23 16 15 31 + 31 31 21 31 31 23 31 31 31 29 31 18 27 31 12 23 27 + 24 15 24 25 11 30 27 27 31 31 25 29 12 30 15 15 29 + 31 31 23 20 31 31 24 25 31 25 31 11 31 10 31 31 31 + 31 31 31 31 31 21 31 29 21 31 31 31 23 25 31 20 24 + 26 30 23 24 23 24 23 15 31 31 31 31 31 31 31 31 24 + 31 31 12 31 31 31 31 21 12 26 26 19 24 30 24 11 21 + 15 14 15 16 23 15 19 30 24 27 30 29 27 21 30 30 21 + 20 20 21 11 12 15 14 14 29 0 0 14 14 14 22 12 11 + 21 5 14 30 26 11 14 11 28 23 28 29 16 26 19 27 19 + 23 28 28 16 11 21 23 31 29 15 20 14 23 11 30 12 21 + 23 21 18 11 15 29 24 24 0 21 11 23 15 15 30 24 25 + 18 21 28 24 28 15 24 11 24 28 15 26 14 18 15 15 24 + 31 15 16 15 28 21 15 12 28 12 29 18 24 23 10 21 26 + 15 11 12 24 23 25 29 20 20 12 30 27 20 11 27 24 28 + 19 29 30 29 27 12 27 19 30 19 25 28 24 20 29 30 12 + 27 15 19 11 23 21 27 21 30 27 26 20 15 28 12 15 27 + 11 28 29 28 15 26 28 26 30 15 23 28 30 24 25 15 12 + + 14 14 12 27 16 27 23 12 21 18 24 23 18 18 3 24 12 + 27 21 21 26 20 25 27 12 16 27 27 25 27 18 11 10 27 + 27 27 18 27 27 20 27 27 27 26 27 12 24 27 10 20 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 12 12 26 + 27 27 18 12 27 27 21 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 16 23 27 23 16 14 + 12 3 10 11 18 12 16 27 21 24 27 26 24 14 27 27 14 + 12 12 14 16 18 10 7 7 26 14 15 0 7 3 19 11 16 + 14 14 2 27 24 16 9 16 25 16 25 26 11 24 16 24 16 + 16 25 25 11 16 14 15 27 26 10 12 3 15 16 27 10 14 + 20 14 12 16 16 26 23 20 14 14 12 16 10 12 27 20 23 + 12 16 25 23 25 12 21 16 23 25 12 24 7 12 12 10 20 + 27 10 11 10 25 14 12 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 16 26 27 26 24 11 24 16 27 16 23 25 23 12 26 27 10 + 24 10 16 16 18 14 24 14 27 24 24 12 10 25 10 12 24 + 16 25 26 25 15 24 25 24 27 12 18 25 27 21 23 18 10 + + 15 14 12 27 16 27 23 12 22 18 24 23 18 18 1 24 12 + 27 21 21 26 20 25 27 12 18 27 27 25 27 18 11 10 27 + 27 27 19 27 27 21 27 27 27 26 27 12 24 27 10 21 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 13 13 26 + 27 27 18 12 27 27 22 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 18 23 27 23 16 14 + 13 1 10 11 18 13 18 27 21 24 27 26 24 14 27 27 14 + 12 12 15 16 18 10 9 9 26 14 15 11 0 1 20 11 16 + 14 14 4 27 24 16 11 16 25 18 25 26 11 24 18 24 18 + 16 25 25 11 16 14 15 27 26 10 12 1 15 16 27 10 14 + 21 14 12 16 16 26 23 20 14 14 12 16 10 13 27 20 23 + 12 18 25 23 25 13 21 16 23 25 13 24 8 12 13 10 20 + 27 10 11 10 25 15 13 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 18 26 27 26 24 11 24 18 27 18 23 25 23 12 26 27 10 + 24 10 18 16 18 14 24 14 27 24 24 12 10 25 10 13 24 + 16 25 26 25 15 24 25 24 27 13 18 25 27 21 23 18 10 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 0 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 17 10 11 25 23 25 20 12 24 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 19 25 25 24 25 12 11 12 25 + 25 25 21 25 25 23 25 25 25 24 25 10 23 25 14 23 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 15 16 24 + 25 25 15 10 25 25 24 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 10 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 19 16 24 16 23 10 + 18 12 12 11 12 15 19 24 15 23 24 24 23 16 24 24 10 + 5 9 17 23 23 12 12 12 24 20 21 12 12 12 0 15 23 + 10 20 12 24 21 23 12 23 23 19 24 24 11 21 19 23 23 + 12 24 23 11 23 10 15 25 24 12 10 12 11 23 24 14 12 + 23 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 19 + 10 19 24 16 23 15 15 23 16 24 15 21 12 10 15 12 15 + 25 12 11 12 24 17 15 23 24 23 24 10 19 11 21 15 21 + 21 23 14 14 12 20 24 9 6 15 24 23 5 23 23 19 23 + 19 24 24 24 23 15 23 19 24 19 20 23 19 8 24 24 14 + 23 12 19 23 14 10 23 10 24 23 21 9 12 24 14 15 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 0 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 0 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 0 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 21 21 20 31 13 31 25 20 22 23 27 25 23 23 14 26 11 + 30 24 24 29 24 28 30 11 21 31 31 28 31 23 16 15 31 + 31 31 21 31 31 21 31 31 31 29 31 18 27 31 12 21 27 + 24 15 24 25 11 30 27 27 31 31 25 29 12 30 15 13 29 + 31 31 23 20 31 31 22 25 31 25 31 11 31 10 31 31 31 + 31 31 31 31 31 21 31 29 21 31 31 31 23 25 31 20 24 + 26 30 23 24 23 24 23 15 31 31 31 31 31 31 31 31 24 + 31 31 12 31 31 31 31 21 12 26 26 18 24 30 24 11 21 + 13 14 15 16 23 13 18 30 24 27 30 29 27 21 30 30 21 + 20 20 21 11 12 15 14 14 29 1 13 14 14 14 21 12 11 + 21 0 14 30 26 11 14 11 28 23 28 29 16 26 18 27 18 + 23 28 28 16 11 21 23 31 29 15 20 14 23 11 30 12 21 + 21 21 18 11 13 29 24 24 1 21 11 23 15 13 30 24 25 + 18 21 28 24 28 13 24 11 24 28 15 26 14 18 13 15 24 + 31 15 16 15 28 21 14 12 28 12 29 18 24 23 10 21 26 + 13 11 12 24 23 25 29 20 20 12 30 27 20 11 27 24 28 + 18 29 30 29 27 12 27 18 30 18 25 28 24 20 29 30 12 + 27 15 18 11 23 21 27 21 30 27 26 20 15 28 12 15 27 + 11 28 29 28 13 26 28 26 30 13 23 28 30 24 25 13 12 + + 14 14 12 27 16 27 23 12 21 18 24 23 18 18 3 24 12 + 27 21 21 26 20 25 27 12 16 27 27 25 27 18 11 10 27 + 27 27 18 27 27 20 27 27 27 26 27 12 24 27 10 20 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 12 12 26 + 27 27 18 12 27 27 21 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 16 23 27 23 16 14 + 12 3 10 11 18 12 16 27 21 24 27 26 24 14 27 27 14 + 12 12 14 16 18 10 7 7 26 14 15 9 7 3 19 11 16 + 14 14 0 27 24 16 9 16 25 16 25 26 11 24 16 24 16 + 16 25 25 11 16 14 15 27 26 10 12 3 15 16 27 10 14 + 20 14 12 16 16 26 23 20 14 14 12 16 10 12 27 20 23 + 12 16 25 23 25 12 21 16 23 25 12 24 7 12 12 10 20 + 27 10 11 10 25 14 12 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 16 26 27 26 24 11 24 16 27 16 23 25 23 12 26 27 10 + 24 10 16 16 18 14 24 14 27 24 24 12 10 25 10 12 24 + 16 25 26 25 15 24 25 24 27 12 18 25 27 21 23 18 10 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 0 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 15 12 11 26 20 26 23 11 22 15 23 21 15 15 11 23 14 + 25 18 18 25 16 24 25 14 18 26 26 24 26 15 1 10 26 + 26 26 19 26 26 21 26 26 26 25 26 10 23 26 12 21 23 + 16 10 18 23 20 25 24 23 26 26 23 25 21 25 13 14 25 + 26 26 15 11 26 26 22 21 26 23 26 20 26 15 26 26 26 + 26 26 26 26 26 12 26 25 12 26 26 26 12 23 26 11 20 + 23 25 12 18 12 18 14 10 26 26 26 26 26 26 26 26 18 + 26 26 12 26 26 26 26 12 12 23 23 18 20 25 20 20 12 + 15 11 10 1 15 13 18 25 18 24 25 25 24 14 25 25 12 + 11 11 15 20 21 10 11 11 25 16 18 11 11 11 20 12 20 + 12 16 11 25 0 20 11 20 24 18 24 25 8 23 18 23 20 + 14 24 24 1 20 12 13 26 25 10 11 11 12 20 25 12 12 + 21 12 10 20 20 25 20 16 16 12 14 14 10 15 25 16 21 + 10 18 24 20 24 13 18 20 20 24 13 23 11 10 13 10 16 + 26 10 1 10 24 15 13 21 24 21 25 10 18 12 18 13 23 + 18 20 12 16 15 23 25 11 11 12 25 23 11 20 24 18 24 + 18 25 25 25 24 12 23 18 25 18 23 24 20 11 25 25 12 + 24 10 18 20 15 12 23 12 25 24 23 11 10 24 12 13 23 + 20 24 25 24 18 23 24 23 25 14 15 24 25 18 21 21 12 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 0 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 15 14 12 27 16 27 23 12 22 18 24 23 18 18 1 24 12 + 27 21 21 26 20 25 27 12 18 27 27 25 27 18 11 10 27 + 27 27 19 27 27 21 27 27 27 26 27 12 24 27 10 21 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 13 13 26 + 27 27 18 12 27 27 22 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 18 23 27 23 16 14 + 13 1 10 11 18 13 18 27 21 24 27 26 24 14 27 27 14 + 12 12 15 16 18 10 9 9 26 14 15 11 9 1 20 11 16 + 14 14 4 27 24 16 0 16 25 18 25 26 11 24 18 24 18 + 16 25 25 11 16 14 15 27 26 10 12 1 15 16 27 10 14 + 21 14 12 16 16 26 23 20 14 14 12 16 10 13 27 20 23 + 12 18 25 23 25 13 21 16 23 25 13 24 8 12 13 10 20 + 27 10 11 10 25 15 13 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 18 26 27 26 24 11 24 18 27 18 23 25 23 12 26 27 10 + 24 10 18 16 18 14 24 14 27 24 24 12 10 25 10 13 24 + 16 25 26 25 15 24 25 24 27 13 18 25 27 21 23 18 10 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 0 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 23 23 23 14 28 14 12 23 24 18 11 12 18 18 24 11 26 + 12 15 15 12 16 10 15 26 23 14 14 11 14 18 24 24 14 + 14 14 23 14 14 23 14 14 14 12 14 23 10 14 25 23 10 + 16 24 15 12 28 12 19 10 14 14 12 12 29 15 24 26 12 + 14 14 18 23 14 14 24 12 14 12 14 28 14 27 14 14 14 + 14 14 14 14 14 23 14 12 23 14 14 14 21 12 14 23 14 + 11 12 21 15 21 15 20 24 14 14 14 14 14 14 14 14 15 + 14 14 25 14 14 14 14 23 25 11 11 25 14 12 14 28 23 + 27 24 24 24 18 25 25 12 15 0 12 12 15 23 12 12 23 + 23 23 23 28 29 24 24 24 12 27 28 24 24 24 23 25 28 + 23 27 24 12 12 28 24 28 0 20 11 19 24 11 25 10 28 + 20 15 19 24 28 23 21 19 12 24 23 24 21 28 12 25 23 + 23 23 23 28 28 12 14 16 27 23 26 20 24 27 12 16 19 + 23 23 11 14 10 25 15 28 14 19 24 11 24 23 25 24 16 + 19 24 24 24 11 23 24 29 15 29 19 23 19 21 28 23 11 + 28 28 25 16 18 12 12 23 23 25 12 10 23 28 10 19 15 + 26 12 12 12 15 25 15 26 12 25 12 10 19 23 12 15 25 + 6 24 24 28 18 23 10 23 12 15 11 23 24 11 25 24 10 + 28 19 15 11 28 11 11 11 12 26 18 19 12 15 12 29 25 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 0 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 17 12 12 27 18 27 23 12 24 16 24 23 16 16 10 23 12 + 26 20 20 25 18 24 26 12 19 27 27 25 27 16 10 6 27 + 27 27 21 27 27 23 27 27 27 25 27 11 24 27 11 23 24 + 18 6 20 23 18 26 24 24 27 27 23 25 20 26 15 15 25 + 27 27 16 12 27 27 24 23 27 23 27 18 27 14 27 27 27 + 27 27 27 27 27 12 27 25 12 27 27 27 14 23 27 12 21 + 23 26 14 20 14 20 15 6 27 27 27 27 27 27 27 27 20 + 27 27 12 27 27 27 27 12 12 23 23 19 21 26 21 18 12 + 15 10 0 10 16 15 19 26 20 24 26 25 24 16 26 26 12 + 12 12 17 18 20 0 10 10 25 15 16 12 10 10 22 12 18 + 12 15 10 26 23 18 12 18 24 19 0 25 10 23 19 24 19 + 15 25 24 10 18 12 15 27 25 0 12 10 14 18 26 11 12 + 23 12 11 18 18 25 21 18 15 12 12 15 0 15 26 18 23 + 11 19 25 21 24 15 20 18 21 25 15 23 10 11 15 6 18 + 27 0 10 6 25 17 15 20 25 20 25 11 20 14 16 15 23 + 16 18 11 18 16 23 25 12 12 12 26 24 12 18 24 19 24 + 19 25 26 25 24 12 24 19 26 19 23 24 21 12 25 26 11 + 24 0 19 18 16 12 24 12 26 24 23 12 0 25 11 15 24 + 18 25 25 25 16 23 25 23 26 15 16 25 26 20 23 20 11 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 0 21 11 15 28 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 0 11 24 12 11 27 24 12 + 21 25 20 15 31 10 19 12 11 11 15 0 31 15 25 28 6 + 11 11 23 24 11 11 24 16 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 0 24 11 11 11 23 15 11 24 18 + 14 10 23 20 23 20 23 25 11 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 0 15 24 10 10 24 + 24 24 24 31 31 25 26 26 0 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 15 23 10 0 25 14 27 12 31 + 23 15 19 25 31 24 23 19 0 25 24 26 23 31 10 27 24 + 24 24 24 31 31 0 18 21 29 24 28 23 25 28 10 21 19 + 24 24 10 18 11 27 20 31 18 19 25 14 26 24 27 25 21 + 19 25 25 25 10 24 26 31 15 31 19 24 20 23 30 24 14 + 30 31 27 21 23 15 0 24 24 27 10 12 24 31 12 21 15 + 28 10 10 0 15 27 15 28 10 27 15 11 19 24 0 15 27 + 12 25 25 31 23 24 12 24 10 15 14 24 25 10 27 25 12 + 31 19 15 10 30 14 10 14 10 28 23 19 10 20 16 31 27 + + 17 14 12 27 16 27 23 12 24 18 24 23 18 18 0 24 12 + 27 21 21 26 20 25 27 12 19 27 27 25 27 18 11 10 27 + 27 27 21 27 27 23 27 27 27 26 27 12 24 27 10 23 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 15 15 26 + 27 27 18 12 27 27 24 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 19 23 27 23 16 14 + 15 0 10 11 18 15 19 27 21 24 27 26 24 16 27 27 14 + 12 12 17 16 18 10 10 10 26 14 15 12 10 0 22 11 16 + 14 14 5 27 24 16 12 16 25 19 25 26 0 24 19 24 19 + 16 25 25 11 16 14 15 27 26 10 12 0 15 16 27 10 14 + 23 14 12 16 16 26 23 20 14 14 12 16 10 15 27 20 23 + 12 19 25 23 25 15 21 16 23 25 15 24 10 12 15 10 20 + 27 10 11 10 25 17 15 18 25 18 26 12 21 15 15 15 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 19 26 27 26 24 11 24 19 27 19 23 25 23 12 26 27 10 + 24 10 19 16 18 14 24 14 27 24 24 12 10 25 10 15 24 + 16 25 26 25 15 24 25 24 27 15 18 25 27 21 23 18 10 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 0 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 17 16 15 28 15 28 24 15 24 21 25 24 21 21 11 24 10 + 28 23 23 27 23 26 28 10 19 28 28 27 28 21 12 12 28 + 28 28 21 28 28 23 28 28 28 27 28 14 25 28 10 23 25 + 23 12 23 24 14 28 25 25 28 28 24 27 15 28 15 15 27 + 28 28 21 15 28 28 24 24 28 24 28 14 28 11 28 28 28 + 28 28 28 28 28 16 28 27 16 28 28 28 18 24 28 15 23 + 24 28 18 23 18 23 20 12 28 28 28 28 28 28 28 28 23 + 28 28 6 28 28 28 28 16 0 24 24 19 23 28 23 14 16 + 15 11 12 12 21 15 19 28 23 25 28 27 25 16 28 28 16 + 15 15 17 14 15 12 11 11 27 12 15 12 11 11 22 0 14 + 16 12 11 28 24 14 12 14 26 20 27 27 12 24 0 25 19 + 20 27 26 12 14 16 18 28 27 12 15 11 18 14 28 10 16 + 23 16 14 14 15 27 23 23 12 16 10 20 12 15 28 23 24 + 14 19 27 23 26 15 23 14 23 27 15 24 11 14 15 12 23 + 28 12 12 12 27 17 15 15 27 15 27 14 23 18 12 16 24 + 15 14 10 23 21 24 27 15 15 0 28 25 15 14 25 23 26 + 19 27 28 27 25 0 25 19 28 19 24 26 23 15 27 28 10 + 25 12 19 14 21 16 25 16 28 25 24 15 12 27 10 15 25 + 14 27 27 27 15 24 27 24 28 15 21 27 28 23 24 15 10 + + 20 20 21 16 27 16 10 21 24 15 11 11 15 15 24 0 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 21 16 16 23 16 16 16 14 16 23 10 16 24 23 10 + 14 23 12 10 27 15 19 10 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 24 11 16 11 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 20 16 16 16 18 10 16 21 12 + 6 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 5 9 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 14 11 15 14 15 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 22 24 27 + 20 26 24 15 12 27 24 27 15 19 12 19 23 0 24 0 27 + 16 15 19 23 27 20 18 19 14 23 21 24 18 27 15 24 20 + 23 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 19 + 23 20 12 12 12 24 12 27 14 19 23 6 24 23 24 23 15 + 19 23 23 23 12 20 24 28 15 28 19 23 19 18 27 20 10 + 27 27 24 14 15 10 14 21 21 24 15 10 21 27 11 19 15 + 25 14 15 14 15 24 15 25 15 24 10 12 19 21 14 15 24 + 11 23 23 27 15 20 10 20 15 15 9 21 23 12 24 23 10 + 27 19 15 12 27 8 12 6 15 25 15 19 15 12 11 28 24 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 0 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 17 5 11 24 23 24 18 12 24 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 19 24 24 23 24 12 12 12 24 + 24 24 21 24 24 23 24 24 24 24 24 11 21 24 15 23 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 15 18 24 + 24 24 15 10 24 24 24 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 6 24 24 10 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 5 16 20 20 19 15 24 15 23 9 + 20 14 12 12 12 15 19 24 14 23 24 24 23 16 24 24 5 + 10 10 17 23 23 12 14 14 24 21 23 14 14 14 22 16 23 + 0 21 14 24 20 23 14 23 23 19 23 24 12 20 19 21 23 + 0 23 23 12 23 10 15 24 24 12 10 14 10 23 24 15 12 + 23 0 11 23 23 24 15 12 21 0 18 11 12 20 24 12 19 + 11 19 23 15 23 15 14 23 15 23 15 20 14 11 15 12 15 + 24 12 12 12 23 17 15 23 23 23 24 11 19 10 23 15 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 19 23 + 19 24 24 24 23 16 21 19 24 19 18 23 19 10 24 24 15 + 23 12 19 23 14 9 21 6 24 23 20 10 12 23 15 15 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 0 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 0 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 0 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 0 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 15 4 10 24 23 24 18 11 22 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 18 24 24 23 24 12 12 12 24 + 24 24 19 24 24 21 24 24 24 24 24 11 21 24 15 21 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 13 18 24 + 24 24 13 10 24 24 22 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 5 24 24 9 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 4 16 20 20 18 15 24 15 23 7 + 20 14 12 12 12 15 18 24 14 23 24 24 23 14 24 24 4 + 10 10 15 23 23 12 14 14 24 21 23 14 14 14 20 16 23 + 1 21 14 24 20 23 14 23 23 18 23 24 12 20 18 21 23 + 11 23 23 12 23 0 13 24 24 12 10 14 10 23 24 15 11 + 21 1 11 23 23 24 15 12 21 1 18 11 12 20 24 12 18 + 11 18 23 15 23 15 14 23 15 23 13 20 14 11 15 12 13 + 24 12 12 12 23 15 14 23 23 23 24 11 18 10 23 13 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 18 23 + 18 24 24 24 23 16 21 18 24 18 18 23 18 10 24 24 15 + 23 12 18 23 12 7 21 5 24 23 20 10 12 23 15 13 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 23 23 23 33 15 33 27 23 24 24 28 27 24 24 18 28 14 + 31 25 25 31 25 30 31 14 23 33 33 31 33 24 21 20 33 + 33 33 23 33 33 23 33 33 33 31 33 23 28 33 16 23 28 + 25 20 25 27 10 31 29 28 33 33 27 31 6 31 20 15 31 + 33 33 24 23 33 33 24 27 33 27 33 10 33 12 33 33 33 + 33 33 33 33 33 23 33 31 23 33 33 33 24 27 33 23 26 + 28 31 24 25 24 25 24 20 33 33 33 33 33 33 33 33 25 + 33 33 15 33 33 33 33 23 15 28 28 19 26 31 26 10 23 + 15 18 20 21 24 16 19 31 25 29 31 31 29 23 31 31 23 + 23 23 23 10 6 20 18 18 31 12 15 18 18 18 23 15 10 + 23 12 18 31 28 10 18 10 30 24 31 31 21 28 19 28 19 + 24 31 30 21 10 23 0 33 31 20 23 18 24 10 31 16 23 + 23 23 23 10 15 31 26 25 12 23 14 24 20 15 31 25 27 + 23 23 31 26 30 16 25 10 26 31 20 28 18 23 16 20 25 + 33 20 21 20 31 23 18 10 31 10 31 23 25 24 11 23 28 + 15 10 16 25 24 27 31 23 23 15 31 28 23 10 29 25 30 + 19 31 31 31 29 15 28 19 31 19 27 30 26 23 31 31 16 + 29 20 21 10 24 23 28 23 31 29 28 23 20 31 16 20 28 + 10 31 31 31 15 28 31 28 31 15 24 31 31 25 27 15 16 + + 23 23 23 33 15 33 27 23 24 24 28 27 24 24 18 28 14 + 31 25 25 31 25 30 31 14 23 33 33 31 33 24 21 20 33 + 33 33 23 33 33 23 33 33 33 31 33 23 28 33 16 23 28 + 25 20 25 27 10 31 29 28 33 33 27 31 6 31 20 15 31 + 33 33 24 23 33 33 24 27 33 27 33 10 33 12 33 33 33 + 33 33 33 33 33 23 33 31 23 33 33 33 24 27 33 23 26 + 28 31 24 25 24 25 24 20 33 33 33 33 33 33 33 33 25 + 33 33 15 33 33 33 33 23 15 28 28 19 26 31 26 10 23 + 15 18 20 21 24 16 19 31 25 29 31 31 29 23 31 31 23 + 23 23 23 10 6 20 18 18 31 12 15 18 18 18 23 15 10 + 23 12 18 31 28 10 18 10 30 24 31 31 21 28 19 28 19 + 24 31 30 21 10 23 24 0 31 20 23 18 24 10 31 16 23 + 23 23 23 10 15 31 26 25 12 23 14 24 20 15 31 25 27 + 23 23 31 26 30 16 25 10 26 31 20 28 18 23 16 20 25 + 33 20 21 20 31 23 18 10 31 10 31 23 25 24 11 23 28 + 15 10 16 25 24 27 31 23 23 15 31 28 23 10 29 25 30 + 19 31 31 31 29 15 28 19 31 19 27 30 26 23 31 31 16 + 29 20 21 10 24 23 28 23 31 29 28 23 20 31 16 20 28 + 10 31 31 31 15 28 31 28 31 15 24 31 31 25 27 15 16 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 0 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 0 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 14 10 8 25 23 25 20 9 21 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 16 25 25 24 25 12 11 12 25 + 25 25 18 25 25 20 25 25 25 24 25 10 23 25 14 20 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 12 16 24 + 25 25 12 7 25 25 21 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 7 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 16 16 24 16 23 10 + 18 12 12 11 12 14 16 24 15 23 24 24 23 13 24 24 10 + 2 6 14 23 23 12 12 12 24 20 21 12 12 12 19 15 23 + 10 20 12 24 21 23 12 23 23 16 24 24 11 21 16 23 23 + 12 24 23 11 23 10 12 25 24 12 0 12 11 23 24 14 10 + 20 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 16 24 16 23 14 15 23 16 24 12 21 12 10 14 12 14 + 25 12 11 12 24 14 12 23 24 23 24 10 16 11 21 12 21 + 21 23 14 14 12 20 24 6 3 15 24 23 2 23 23 16 23 + 16 24 24 24 23 15 23 16 24 16 20 23 16 5 24 24 14 + 23 12 16 23 12 10 23 10 24 23 21 6 12 24 14 12 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 0 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 0 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 0 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 0 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 15 14 12 27 16 27 23 12 22 18 24 23 18 18 1 24 12 + 27 21 21 26 20 25 27 12 18 27 27 25 27 18 11 10 27 + 27 27 19 27 27 21 27 27 27 26 27 12 24 27 10 21 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 13 13 26 + 27 27 18 12 27 27 22 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 18 23 27 23 16 14 + 13 1 10 11 18 13 18 27 21 24 27 26 24 14 27 27 14 + 12 12 15 16 18 10 9 9 26 14 15 11 9 1 20 11 16 + 14 14 4 27 24 16 11 16 25 18 25 26 11 24 18 24 18 + 16 25 25 11 16 14 15 27 26 10 12 1 15 16 27 0 14 + 21 14 12 16 16 26 23 20 14 14 12 16 10 13 27 20 23 + 12 18 25 23 25 13 21 16 23 25 13 24 8 12 13 10 20 + 27 10 11 10 25 15 13 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 18 26 27 26 24 11 24 18 27 18 23 25 23 12 26 27 10 + 24 10 18 16 18 14 24 14 27 24 24 12 10 25 10 13 24 + 16 25 26 25 15 24 25 24 27 13 18 25 27 21 23 18 10 + + 14 14 15 23 25 23 12 15 21 11 14 11 11 11 21 12 23 + 21 3 8 20 10 16 21 23 16 23 23 18 23 11 18 20 23 + 23 23 18 23 23 20 23 23 23 20 23 16 14 23 23 20 14 + 10 20 5 12 25 21 16 14 23 23 12 20 25 21 20 23 20 + 23 23 12 15 23 23 21 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 5 12 2 12 20 23 23 23 23 23 23 23 23 8 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 11 15 21 20 15 14 21 21 14 + 15 15 14 25 25 20 21 21 20 24 24 21 21 21 19 23 25 + 14 24 21 21 12 25 21 25 16 16 18 20 18 12 23 14 25 + 12 18 16 18 25 14 12 23 20 20 15 21 12 25 21 23 0 + 20 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 16 + 16 16 18 10 16 23 8 25 11 18 20 12 21 16 23 20 12 + 23 20 18 20 18 14 21 25 18 25 20 16 16 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 16 16 + 23 20 21 20 15 23 14 23 21 23 12 16 16 15 20 21 23 + 15 20 18 25 11 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 3 11 25 23 + + 18 18 20 18 27 18 7 20 22 14 11 10 14 14 23 10 24 + 16 12 12 15 12 12 16 24 18 18 18 14 18 14 23 23 18 + 18 18 19 18 18 21 18 18 18 15 18 21 11 18 24 21 11 + 12 23 12 5 27 16 18 11 18 18 4 15 27 16 23 24 15 + 18 18 14 20 18 18 22 10 18 10 18 27 18 25 18 18 18 + 18 18 18 18 18 18 18 15 18 18 18 18 16 7 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 18 18 18 12 + 18 18 24 18 18 18 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 12 12 16 15 13 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 20 24 27 + 18 25 23 16 11 27 23 27 13 18 14 18 23 10 24 11 27 + 15 14 18 23 27 18 16 18 15 23 20 23 16 27 16 24 18 + 0 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 18 + 21 18 14 11 12 24 12 27 12 18 23 10 23 21 24 23 13 + 18 23 23 23 14 18 23 27 14 27 18 21 18 16 26 18 10 + 26 27 24 12 14 9 15 20 20 24 16 11 20 27 12 18 13 + 24 15 16 15 13 24 13 24 16 24 7 12 18 20 15 16 24 + 12 23 23 27 14 18 11 18 16 13 10 20 23 14 24 23 11 + 27 18 15 14 26 10 14 10 16 24 14 18 16 12 10 27 24 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 0 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 0 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 15 15 14 28 15 28 24 14 15 20 24 23 20 20 15 24 15 + 27 23 23 27 21 25 27 11 15 28 28 26 28 20 15 11 28 + 28 28 15 28 28 15 28 28 28 27 28 15 24 28 15 15 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 11 11 27 + 28 28 20 14 28 28 15 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 28 27 15 28 28 28 16 24 28 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 15 24 24 10 23 27 23 15 15 + 12 15 15 15 20 0 4 27 23 25 27 27 25 15 27 27 15 + 14 14 15 15 16 15 10 10 27 15 14 10 10 15 15 15 15 + 15 12 10 27 24 15 10 15 25 18 26 27 12 24 10 24 15 + 18 26 25 15 15 15 16 28 27 15 14 15 16 15 27 9 15 + 15 15 15 0 15 27 23 21 15 15 15 18 15 12 27 21 23 + 15 15 26 23 25 0 23 15 23 26 11 24 10 12 0 11 21 + 28 15 15 11 26 15 10 16 26 16 27 12 23 16 14 15 24 + 14 15 15 21 20 24 27 14 14 15 27 24 14 15 25 21 25 + 11 27 27 27 25 15 24 11 27 4 24 25 23 14 27 27 15 + 25 15 12 15 20 15 24 15 27 25 24 14 15 26 15 11 24 + 15 26 27 26 14 24 26 24 27 11 20 26 27 23 23 16 4 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 0 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 12 12 14 23 24 23 12 14 12 10 15 15 10 10 20 15 23 + 23 10 10 21 4 18 23 23 12 23 23 20 23 10 16 18 23 + 23 23 12 23 23 12 23 23 23 21 23 15 15 23 21 12 15 + 9 18 10 12 24 23 16 15 23 23 12 21 25 23 18 23 21 + 23 23 10 14 23 23 12 12 23 12 23 24 23 23 23 23 23 + 23 23 23 23 23 12 23 21 12 23 23 23 15 12 23 14 11 + 14 23 12 10 12 10 15 18 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 12 23 14 14 23 11 23 11 24 12 + 23 20 18 16 10 21 21 23 10 16 23 21 16 12 23 23 12 + 14 14 12 24 25 18 20 20 21 24 24 20 20 20 12 23 24 + 15 24 20 23 14 24 20 24 18 11 20 21 16 15 23 15 24 + 11 20 18 16 24 12 12 23 21 18 14 20 15 24 23 21 12 + 12 15 15 24 24 0 11 8 24 15 23 15 18 23 23 15 12 + 15 12 20 11 18 21 10 24 11 20 18 14 20 15 21 18 0 + 23 18 16 18 20 12 20 25 20 25 21 15 10 12 24 12 14 + 24 24 21 15 10 12 21 14 14 23 23 15 14 24 16 4 18 + 23 21 23 21 16 23 15 23 23 21 12 18 11 14 21 23 21 + 16 18 16 24 10 12 15 12 23 16 14 14 18 20 21 18 15 + 24 20 21 20 24 14 20 14 23 23 15 20 23 15 15 25 21 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 0 21 11 15 28 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 0 11 24 12 11 27 24 12 + 21 25 20 15 31 10 19 12 11 11 15 0 31 15 25 28 6 + 11 11 23 24 11 11 24 16 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 0 24 11 11 11 23 15 11 24 18 + 14 10 23 20 23 20 23 25 11 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 0 15 24 10 10 24 + 24 24 24 31 31 25 26 26 0 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 15 23 10 19 25 14 27 12 31 + 23 15 19 25 31 24 23 19 0 25 24 26 23 31 10 27 24 + 24 24 24 31 31 0 0 21 29 24 28 23 25 28 10 21 19 + 24 24 10 18 11 27 20 31 18 19 25 14 26 24 27 25 21 + 19 25 25 25 10 24 26 31 15 31 19 24 20 23 30 24 14 + 30 31 27 21 23 15 0 24 24 27 10 12 24 31 12 21 15 + 28 10 10 0 15 27 15 28 10 27 15 11 19 24 0 15 27 + 12 25 25 31 23 24 12 24 10 15 14 24 25 10 27 25 12 + 31 19 15 10 30 14 10 14 10 28 23 19 10 20 16 31 27 + + 14 14 15 23 25 23 12 15 21 11 14 11 11 11 21 12 23 + 21 3 8 20 10 16 21 23 16 23 23 18 23 11 18 20 23 + 23 23 18 23 23 20 23 23 23 20 23 16 14 23 23 20 14 + 10 20 5 12 25 21 16 14 23 23 12 20 25 21 20 23 20 + 23 23 12 15 23 23 21 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 5 12 2 12 20 23 23 23 23 23 23 23 23 8 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 11 15 21 20 15 14 21 21 14 + 15 15 14 25 25 20 21 21 20 24 24 21 21 21 19 23 25 + 14 24 21 21 12 25 21 25 16 16 18 20 18 12 23 14 25 + 12 18 16 18 25 14 12 23 20 20 15 21 12 25 21 23 14 + 20 14 16 25 25 20 10 0 24 14 23 12 20 24 21 10 16 + 16 16 18 10 16 23 8 25 11 18 20 12 21 16 23 20 12 + 23 20 18 20 18 14 21 25 18 25 20 16 16 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 16 16 + 23 20 21 20 15 23 14 23 21 23 12 16 16 15 20 21 23 + 15 20 18 25 11 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 3 11 25 23 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 0 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 0 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 0 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 0 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 12 12 12 27 18 27 23 12 18 16 24 23 16 16 10 23 12 + 26 20 20 25 18 24 26 12 13 27 27 25 27 16 10 0 27 + 27 27 15 27 27 17 27 27 27 25 27 11 24 27 11 17 24 + 18 0 20 23 18 26 24 24 27 27 23 25 20 26 9 12 25 + 27 27 16 12 27 27 18 23 27 23 27 18 27 14 27 27 27 + 27 27 27 27 27 12 27 25 12 27 27 27 14 23 27 12 21 + 23 26 14 20 14 20 15 0 27 27 27 27 27 27 27 27 20 + 27 27 12 27 27 27 27 12 12 23 23 13 21 26 21 18 12 + 14 10 6 10 16 11 13 26 20 24 26 25 24 12 26 26 12 + 12 12 12 18 20 6 10 10 25 15 16 10 10 10 16 12 18 + 12 15 10 26 23 18 10 18 24 15 25 25 10 23 13 24 18 + 15 25 24 10 18 12 14 27 25 6 12 10 14 18 26 11 12 + 17 12 11 18 18 25 21 18 15 12 12 15 0 14 26 18 23 + 11 13 25 21 24 11 20 18 21 25 9 23 10 11 11 0 18 + 27 6 10 0 25 12 10 20 25 20 25 11 20 14 16 12 23 + 16 18 11 18 16 23 25 12 12 12 26 24 12 18 24 18 24 + 13 25 26 25 24 12 24 13 26 13 23 24 21 12 25 26 11 + 24 6 13 18 16 12 24 12 26 24 23 12 6 25 11 9 24 + 18 25 25 25 16 23 25 23 26 12 16 25 26 20 23 20 11 + + 17 12 12 27 18 27 23 12 24 16 24 23 16 16 10 23 12 + 26 20 20 25 18 24 26 12 19 27 27 25 27 16 10 6 27 + 27 27 21 27 27 23 27 27 27 25 27 11 24 27 11 23 24 + 18 6 20 23 18 26 24 24 27 27 23 25 20 26 15 15 25 + 27 27 16 12 27 27 24 23 27 23 27 18 27 14 27 27 27 + 27 27 27 27 27 12 27 25 12 27 27 27 14 23 27 12 21 + 23 26 14 20 14 20 15 6 27 27 27 27 27 27 27 27 20 + 27 27 12 27 27 27 27 12 12 23 23 19 21 26 21 18 12 + 15 10 0 10 16 15 19 26 20 24 26 25 24 16 26 26 12 + 12 12 17 18 20 0 10 10 25 15 16 12 10 10 22 12 18 + 12 15 10 26 23 18 12 18 24 19 25 25 10 23 19 24 19 + 15 25 24 10 18 12 15 27 25 0 12 10 14 18 26 11 12 + 23 12 11 18 18 25 21 18 15 12 12 15 0 0 26 18 23 + 11 19 25 21 24 15 20 18 21 25 15 23 10 11 15 6 18 + 27 0 10 6 25 17 15 20 25 20 25 11 20 14 16 15 23 + 16 18 11 18 16 23 25 12 12 12 26 24 12 18 24 19 24 + 19 25 26 25 24 12 24 19 26 19 23 24 21 12 25 26 11 + 24 0 19 18 16 12 24 12 26 24 23 12 0 25 11 15 24 + 18 25 25 25 16 23 25 23 26 15 16 25 26 20 23 20 11 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 0 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 0 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 0 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 0 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 15 10 10 25 23 25 20 11 22 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 18 25 25 24 25 12 11 12 25 + 25 25 19 25 25 21 25 25 25 24 25 10 23 25 14 21 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 13 16 24 + 25 25 13 9 25 25 22 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 9 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 18 16 24 16 23 10 + 18 12 12 11 12 14 18 24 15 23 24 24 23 14 24 24 10 + 4 7 15 23 23 12 12 12 24 20 21 12 12 12 20 15 23 + 10 20 12 24 21 23 12 23 23 18 24 24 11 21 18 23 23 + 12 24 23 11 23 10 13 25 24 12 9 12 11 23 24 14 11 + 21 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 0 24 16 23 14 15 23 16 24 13 21 12 10 14 12 14 + 25 12 11 12 24 15 13 23 24 23 24 10 18 11 21 13 21 + 21 23 14 14 12 20 24 7 5 15 24 23 4 23 23 18 23 + 18 24 24 24 23 15 23 18 24 18 20 23 18 6 24 24 14 + 23 12 18 23 12 10 23 10 24 23 21 7 12 24 14 13 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 0 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 17 15 16 21 25 21 11 16 24 12 12 10 12 12 23 12 24 + 20 10 11 18 11 15 20 24 19 21 21 16 21 12 20 21 21 + 21 21 21 21 21 23 21 21 21 18 21 18 12 21 23 23 12 + 11 21 10 11 25 20 19 12 21 21 11 18 26 20 21 24 18 + 21 21 15 16 21 21 24 10 21 11 21 25 21 24 21 21 21 + 21 21 21 21 21 15 21 18 15 21 21 21 14 11 21 16 6 + 12 20 14 10 14 10 12 21 21 21 21 21 21 21 21 21 11 + 21 21 23 21 21 21 21 15 23 12 12 23 6 20 8 25 15 + 24 23 21 20 12 23 23 20 14 14 20 18 15 16 20 20 15 + 16 16 17 25 26 21 23 23 18 24 25 23 23 23 22 23 25 + 15 24 23 20 12 25 23 25 15 19 16 19 20 12 23 12 25 + 12 16 19 20 25 15 15 21 18 21 16 23 14 25 20 23 15 + 23 15 18 25 25 18 8 11 24 15 24 12 21 24 20 11 19 + 18 19 16 0 15 23 11 25 14 19 21 12 23 18 23 21 15 + 21 21 20 21 16 17 23 26 16 26 19 18 19 14 25 15 12 + 25 25 23 11 12 11 18 16 16 23 20 12 16 25 14 19 15 + 24 18 20 18 15 23 15 24 20 23 11 15 19 16 18 20 23 + 14 21 20 25 14 15 12 15 20 15 12 16 21 16 23 21 12 + 25 19 18 16 25 12 16 12 20 24 12 19 20 10 10 26 23 + + 11 10 11 24 23 24 16 11 18 11 20 15 11 11 15 18 20 + 24 12 12 23 12 23 24 20 13 24 24 23 24 11 12 14 24 + 24 24 15 24 24 17 24 24 24 23 24 12 20 24 16 17 20 + 12 14 12 16 23 24 21 20 24 24 16 23 24 24 14 20 23 + 24 24 11 11 24 24 18 15 24 16 24 23 24 21 24 24 24 + 24 24 24 24 24 10 24 23 10 24 24 24 6 16 24 11 14 + 18 24 4 12 4 12 10 14 24 24 24 24 24 24 24 24 12 + 24 24 18 24 24 24 24 10 18 18 18 18 14 24 14 23 10 + 21 15 14 12 11 16 16 24 12 21 24 23 21 10 24 24 10 + 11 11 11 23 24 14 15 15 23 23 23 15 15 15 16 18 23 + 10 23 15 24 18 23 15 23 23 13 23 23 12 18 18 20 23 + 10 23 23 12 23 10 9 24 23 14 11 15 6 23 24 16 10 + 17 10 12 23 23 23 14 12 23 10 20 10 14 21 24 12 15 + 12 13 23 14 0 16 12 23 14 23 14 18 15 12 16 14 12 + 24 14 12 14 23 11 15 24 23 24 23 12 13 0 23 10 18 + 23 23 16 12 11 16 23 11 11 18 24 20 11 23 21 13 23 + 20 23 24 23 21 18 20 20 24 16 16 23 14 11 23 24 16 + 21 14 13 23 11 10 20 10 24 21 18 11 14 23 16 14 20 + 23 23 23 23 23 18 23 18 24 20 11 23 24 12 15 24 16 + + 23 23 23 12 29 12 12 23 24 20 11 14 20 20 25 12 27 + 12 16 16 11 18 10 15 27 23 12 12 10 12 20 24 24 12 + 12 12 23 12 12 23 12 12 12 11 12 24 11 12 25 23 11 + 18 24 16 12 29 12 19 11 12 12 12 11 30 15 24 27 11 + 12 12 20 23 12 12 24 14 12 12 12 29 12 27 12 12 12 + 12 12 12 12 12 23 12 11 23 12 12 12 23 12 12 23 15 + 12 12 23 16 23 16 21 24 12 12 12 12 12 12 12 12 16 + 12 12 26 12 12 12 12 23 26 12 12 26 15 12 15 29 23 + 27 25 24 24 20 25 25 12 16 10 12 11 15 23 12 12 23 + 23 23 23 29 30 24 25 25 11 28 28 25 25 25 23 26 29 + 23 28 25 12 12 29 25 29 15 21 10 19 24 12 26 11 29 + 21 15 19 24 29 23 23 19 11 24 23 25 23 29 12 25 23 + 23 23 24 29 29 11 15 18 28 23 27 21 24 27 12 18 19 + 24 23 10 15 0 0 16 29 15 19 24 12 25 24 25 24 18 + 19 24 24 24 10 23 25 30 15 30 19 24 19 23 28 23 12 + 28 29 25 18 20 12 11 23 23 26 12 11 23 29 10 19 15 + 27 11 12 11 15 26 15 27 12 25 12 0 19 23 11 15 25 + 10 24 24 29 20 23 11 23 12 15 12 23 24 10 25 24 11 + 29 19 15 10 28 12 10 12 12 27 20 19 12 16 14 30 25 + + 17 15 16 21 25 21 11 16 24 12 12 10 12 12 23 12 24 + 20 10 11 18 11 15 20 24 19 21 21 16 21 12 20 21 21 + 21 21 21 21 21 23 21 21 21 18 21 18 12 21 23 23 12 + 11 21 10 11 25 20 19 12 21 21 11 18 26 20 21 24 18 + 21 21 15 16 21 21 24 10 21 11 21 25 21 24 21 21 21 + 21 21 21 21 21 15 21 18 15 21 21 21 14 11 21 16 6 + 12 20 14 10 14 10 12 21 21 21 21 21 21 21 21 21 11 + 21 21 23 21 21 21 21 15 23 12 12 23 6 20 8 25 15 + 24 23 21 20 12 23 23 20 14 14 20 18 15 16 20 20 15 + 16 16 17 25 26 21 23 23 18 24 25 23 23 23 22 23 25 + 15 24 23 20 12 25 23 25 15 19 16 19 20 12 23 12 25 + 12 16 19 20 25 15 15 21 18 21 16 23 14 25 20 23 15 + 23 15 18 25 25 18 8 11 24 15 24 12 21 24 20 11 19 + 18 19 16 5 15 23 0 25 14 19 21 12 23 18 23 21 15 + 21 21 20 21 16 17 23 26 16 26 19 18 19 14 25 15 12 + 25 25 23 11 12 11 18 16 16 23 20 12 16 25 14 19 15 + 24 18 20 18 15 23 15 24 20 23 11 15 19 16 18 20 23 + 14 21 20 25 14 15 12 15 20 15 12 16 21 16 23 21 12 + 25 19 18 16 25 12 16 12 20 24 12 19 20 10 10 26 23 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 0 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 0 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 20 20 21 16 27 16 10 21 24 15 11 11 15 15 24 0 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 21 16 16 23 16 16 16 14 16 23 10 16 24 23 10 + 14 23 12 10 27 15 19 10 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 24 11 16 11 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 20 16 16 16 18 10 16 21 12 + 6 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 5 9 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 14 11 15 14 15 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 22 24 27 + 20 26 24 15 12 27 24 27 15 19 12 19 23 0 24 10 27 + 16 15 19 23 27 20 18 19 14 23 21 24 18 27 15 24 20 + 23 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 19 + 23 20 12 12 12 24 12 27 14 0 23 6 24 23 24 23 15 + 19 23 23 23 12 20 24 28 15 28 19 23 19 18 27 20 10 + 27 27 24 14 15 10 14 21 21 24 15 10 21 27 11 19 15 + 25 14 15 14 15 24 15 25 15 24 10 12 19 21 14 15 24 + 11 23 23 27 15 20 10 20 15 15 9 21 23 12 24 23 10 + 27 19 15 12 27 8 12 6 15 25 15 19 15 12 11 28 24 + + 17 12 11 26 20 26 23 12 24 15 23 21 15 15 11 23 14 + 25 18 18 25 16 24 25 14 19 26 26 24 26 15 0 10 26 + 26 26 21 26 26 23 26 26 26 25 26 10 23 26 12 23 23 + 16 10 18 23 20 25 24 23 26 26 23 25 21 25 15 15 25 + 26 26 15 11 26 26 24 21 26 23 26 20 26 15 26 26 26 + 26 26 26 26 26 12 26 25 12 26 26 26 12 23 26 11 20 + 23 25 12 18 12 18 14 10 26 26 26 26 26 26 26 26 18 + 26 26 12 26 26 26 26 12 12 23 23 19 20 25 20 20 12 + 15 11 10 0 15 15 19 25 18 24 25 25 24 16 25 25 12 + 11 11 17 20 21 10 11 11 25 16 18 12 11 11 22 12 20 + 12 16 11 25 23 20 12 20 24 19 24 25 10 23 19 23 20 + 14 24 24 0 20 12 15 26 25 10 11 11 12 20 25 12 12 + 23 12 10 20 20 25 20 16 16 12 14 14 10 15 25 16 21 + 10 19 24 20 24 15 18 20 20 24 0 23 11 10 15 10 16 + 26 10 0 10 24 17 15 21 24 21 25 10 19 12 18 15 23 + 18 20 12 16 15 23 25 11 11 12 25 23 11 20 24 19 24 + 19 25 25 25 24 12 23 19 25 19 23 24 20 11 25 25 12 + 24 10 19 20 15 12 23 12 25 24 23 11 10 24 12 15 23 + 20 24 25 24 18 23 24 23 25 15 15 24 25 18 21 21 12 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 0 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 0 21 11 15 28 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 0 11 24 12 11 27 24 12 + 21 25 20 15 31 10 19 12 11 11 15 0 31 15 25 28 6 + 11 11 23 24 11 11 24 16 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 0 24 11 11 11 23 15 11 24 18 + 14 10 23 20 23 20 23 25 11 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 0 15 24 10 10 24 + 24 24 24 31 31 25 26 26 0 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 15 23 10 19 25 14 27 12 31 + 23 15 19 25 31 24 23 19 0 25 24 26 23 31 10 27 24 + 24 24 24 31 31 0 18 21 29 24 28 23 25 28 10 21 19 + 24 24 10 18 11 27 20 31 18 19 25 14 0 24 27 25 21 + 19 25 25 25 10 24 26 31 15 31 19 24 20 23 30 24 14 + 30 31 27 21 23 15 0 24 24 27 10 12 24 31 12 21 15 + 28 10 10 0 15 27 15 28 10 27 15 11 19 24 0 15 27 + 12 25 25 31 23 24 12 24 10 15 14 24 25 10 27 25 12 + 31 19 15 10 30 14 10 14 10 28 23 19 10 20 16 31 27 + + 17 12 12 27 18 27 23 12 24 16 24 23 16 16 10 23 12 + 26 20 20 25 18 24 26 12 19 27 27 25 27 16 10 6 27 + 27 27 21 27 27 23 27 27 27 25 27 11 24 27 11 23 24 + 18 6 20 23 18 26 24 24 27 27 23 25 20 26 15 15 25 + 27 27 16 12 27 27 24 23 27 23 27 18 27 14 27 27 27 + 27 27 27 27 27 12 27 25 12 27 27 27 14 23 27 12 21 + 23 26 14 20 14 20 15 6 27 27 27 27 27 27 27 27 20 + 27 27 12 27 27 27 27 12 12 23 23 19 21 26 21 18 12 + 15 10 0 10 16 15 19 26 20 24 26 25 24 16 26 26 12 + 12 12 17 18 20 0 10 10 25 15 16 12 10 10 22 12 18 + 12 15 10 26 23 18 12 18 24 19 25 25 10 23 19 24 19 + 15 25 24 10 18 12 15 27 25 0 12 10 14 18 26 11 12 + 23 12 11 18 18 25 21 18 15 12 12 15 0 15 26 18 23 + 11 19 25 21 24 15 20 18 21 25 15 23 10 0 15 6 18 + 27 0 10 6 25 17 15 20 25 20 25 11 20 14 16 15 23 + 16 18 11 18 16 23 25 12 12 12 26 24 12 18 24 19 24 + 19 25 26 25 24 12 24 19 26 19 23 24 21 12 25 26 11 + 24 0 19 18 16 12 24 12 26 24 23 12 0 25 11 15 24 + 18 25 25 25 16 23 25 23 26 15 16 25 26 20 23 20 11 + + 17 14 12 27 16 27 23 12 24 18 24 23 18 18 0 24 12 + 27 21 21 26 20 25 27 12 19 27 27 25 27 18 11 10 27 + 27 27 21 27 27 23 27 27 27 26 27 12 24 27 10 23 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 15 15 26 + 27 27 18 12 27 27 24 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 19 23 27 23 16 14 + 15 0 10 11 18 15 19 27 21 24 27 26 24 16 27 27 14 + 12 12 17 16 18 10 10 10 26 14 15 12 10 0 22 11 16 + 14 14 5 27 24 16 12 16 25 19 25 26 11 24 19 24 19 + 16 25 25 11 16 14 15 27 26 10 12 0 15 16 27 10 14 + 23 14 12 16 16 26 23 20 14 14 12 16 10 15 27 20 23 + 12 19 25 23 25 15 21 16 23 25 15 24 10 12 0 10 20 + 27 10 11 10 25 17 15 18 25 18 26 12 21 15 15 15 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 19 26 27 26 24 11 24 19 27 19 23 25 23 12 26 27 10 + 24 10 19 16 18 14 24 14 27 24 24 12 10 25 10 15 24 + 16 25 26 25 15 24 25 24 27 15 18 25 27 21 23 18 10 + + 17 10 11 24 23 24 16 12 24 11 20 15 11 11 15 18 20 + 24 12 12 23 12 23 24 20 19 24 24 23 24 11 12 14 24 + 24 24 21 24 24 23 24 24 24 23 24 12 20 24 16 23 20 + 12 14 12 16 23 24 21 20 24 24 16 23 24 24 15 20 23 + 24 24 15 11 24 24 24 15 24 16 24 23 24 21 24 24 24 + 24 24 24 24 24 10 24 23 10 24 24 24 0 16 24 11 14 + 18 24 10 12 10 12 10 14 24 24 24 24 24 24 24 24 12 + 24 24 18 24 24 24 24 10 18 18 18 19 14 24 14 23 10 + 21 15 14 12 11 16 19 24 14 21 24 23 21 16 24 24 10 + 11 11 17 23 24 14 15 15 23 23 23 15 15 15 22 18 23 + 10 23 15 24 18 23 15 23 23 19 23 23 12 18 19 20 23 + 10 23 23 12 23 10 15 24 23 14 11 15 0 23 24 16 12 + 23 10 12 23 23 23 14 12 23 10 20 10 14 21 24 12 19 + 12 19 23 14 23 16 12 23 14 23 15 18 15 12 16 0 15 + 24 14 12 14 23 17 15 24 23 24 23 12 19 6 23 15 18 + 23 23 16 12 11 16 23 11 11 18 24 20 11 23 21 19 23 + 20 23 24 23 21 18 20 20 24 19 16 23 19 11 23 24 16 + 21 14 19 23 14 10 20 10 24 21 18 11 14 23 16 15 20 + 23 23 23 23 23 18 23 18 24 20 11 23 24 12 15 24 16 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 0 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 0 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 0 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 12 14 11 26 20 26 23 11 12 15 23 21 15 15 19 23 19 + 25 18 18 25 16 24 25 14 12 26 26 24 26 15 19 13 26 + 26 26 12 26 26 12 26 26 26 25 26 19 23 26 19 12 23 + 16 13 18 23 20 25 24 23 26 26 23 25 21 25 10 14 25 + 26 26 15 11 26 26 12 21 26 23 26 20 26 15 26 26 26 + 26 26 26 26 26 12 26 25 12 26 26 26 19 23 26 11 20 + 23 25 12 18 12 18 19 13 26 26 26 26 26 26 26 26 18 + 26 26 13 26 26 26 26 14 19 23 23 12 20 25 20 20 12 + 15 19 19 19 15 12 12 25 18 24 25 25 24 12 25 25 14 + 14 11 12 20 21 19 11 11 25 19 18 11 11 19 12 19 20 + 19 16 14 25 23 20 11 20 24 14 24 25 9 23 12 23 20 + 14 24 24 19 20 12 12 26 25 19 11 19 19 20 25 14 12 + 12 19 19 20 20 25 20 16 19 19 19 19 19 15 25 19 21 + 19 12 24 20 24 12 18 20 20 24 10 23 11 13 12 13 16 + 26 19 0 13 24 12 11 21 24 21 25 10 18 13 18 12 23 + 18 20 19 19 15 23 25 11 12 19 25 23 14 20 24 16 24 + 14 25 25 25 24 19 23 14 25 12 23 24 20 11 25 25 19 + 24 19 0 20 15 12 23 12 25 24 23 11 19 24 19 10 23 + 20 24 25 24 18 23 24 23 25 14 19 24 25 19 21 21 12 + + 17 12 11 26 20 26 23 12 24 15 23 21 15 15 11 23 14 + 25 18 18 25 16 24 25 14 19 26 26 24 26 15 0 10 26 + 26 26 21 26 26 23 26 26 26 25 26 10 23 26 12 23 23 + 16 10 18 23 20 25 24 23 26 26 23 25 21 25 15 15 25 + 26 26 15 11 26 26 24 21 26 23 26 20 26 15 26 26 26 + 26 26 26 26 26 12 26 25 12 26 26 26 12 23 26 11 20 + 23 25 12 18 12 18 14 10 26 26 26 26 26 26 26 26 18 + 26 26 12 26 26 26 26 12 12 23 23 19 20 25 20 20 12 + 15 11 10 0 15 15 19 25 18 24 25 25 24 16 25 25 12 + 11 11 17 20 21 10 11 11 25 16 18 12 11 11 22 12 20 + 12 16 11 25 23 20 12 20 24 19 24 25 10 23 19 23 20 + 14 24 24 0 20 12 15 26 25 10 11 11 12 20 25 12 12 + 23 12 10 20 20 25 20 16 16 12 14 14 10 15 25 16 21 + 10 19 24 20 24 15 18 20 20 24 15 23 11 10 15 10 16 + 26 10 0 0 24 17 15 21 24 21 25 10 19 12 18 15 23 + 18 20 12 16 15 23 25 11 11 12 25 23 11 20 24 19 24 + 19 25 25 25 24 12 23 19 25 19 23 24 20 11 25 25 12 + 24 10 19 20 15 12 23 12 25 24 23 11 10 24 12 15 23 + 20 24 25 24 18 23 24 23 25 15 15 24 25 18 21 21 12 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 0 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 21 21 23 15 28 15 11 23 24 16 11 12 16 16 24 10 25 + 14 14 14 12 15 11 15 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 23 15 15 15 12 15 23 0 15 24 23 9 + 15 24 14 11 28 14 19 10 15 15 11 12 28 15 24 25 12 + 15 15 16 23 15 15 24 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 10 14 12 15 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 22 25 28 + 21 27 24 14 12 28 24 28 15 19 12 19 23 10 25 6 28 + 18 15 19 23 28 21 20 19 12 24 23 24 20 28 14 24 21 + 23 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 19 + 23 21 12 12 11 24 14 28 14 19 24 10 24 23 24 24 15 + 19 24 23 24 12 0 24 28 15 28 19 23 19 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 9 23 28 10 19 15 + 25 12 14 12 15 25 15 25 14 24 11 11 19 23 12 15 24 + 10 24 23 28 16 21 9 21 14 15 10 23 24 12 24 24 0 + 28 19 15 12 27 10 12 10 14 25 16 19 14 14 12 28 24 + + 17 5 11 24 23 24 18 12 24 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 19 24 24 23 24 12 12 12 24 + 24 24 21 24 24 23 24 24 24 24 24 11 21 24 15 23 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 15 18 24 + 24 24 15 10 24 24 24 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 6 24 24 10 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 5 16 20 20 19 15 24 15 23 9 + 20 14 12 12 12 15 19 24 14 23 24 24 23 16 24 24 5 + 10 10 17 23 23 12 14 14 24 21 23 14 14 14 22 16 23 + 0 21 14 24 20 23 14 23 23 19 23 24 12 20 19 21 23 + 11 23 23 12 23 10 15 24 24 12 10 14 10 23 24 15 12 + 23 0 11 23 23 24 15 12 21 0 18 11 12 20 24 12 19 + 11 19 23 15 23 15 14 23 15 23 15 20 14 11 15 12 15 + 24 12 12 12 23 17 0 23 23 23 24 11 19 10 23 15 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 19 23 + 19 24 24 24 23 16 21 19 24 19 18 23 19 10 24 24 15 + 23 12 19 23 14 9 21 6 24 23 20 10 12 23 15 15 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 17 11 11 25 21 25 21 12 24 14 23 20 14 14 12 23 15 + 25 16 16 24 15 24 25 15 19 25 25 24 25 14 10 11 25 + 25 25 21 25 25 23 25 25 25 24 25 0 23 25 12 23 23 + 15 11 16 21 21 25 23 23 25 25 21 24 23 25 15 15 24 + 25 25 15 10 25 25 24 20 25 21 25 21 25 16 25 25 25 + 25 25 25 25 25 11 25 24 11 25 25 25 12 21 25 10 18 + 23 25 12 16 12 16 12 11 25 25 25 25 25 25 25 25 16 + 25 25 14 25 25 25 25 11 14 23 23 19 18 25 18 21 11 + 16 12 11 10 14 15 19 25 16 23 25 24 23 16 25 25 11 + 10 10 17 21 23 11 12 12 24 18 20 12 12 12 22 14 21 + 11 18 12 25 23 21 12 21 24 19 24 24 10 23 19 23 21 + 12 24 24 10 21 11 15 25 24 11 10 12 12 21 25 12 12 + 23 11 0 21 21 24 18 15 18 11 15 12 11 16 25 15 20 + 0 19 24 18 24 15 16 21 18 24 15 23 12 6 15 11 15 + 25 11 10 11 24 17 15 0 24 23 24 10 19 12 20 15 23 + 20 21 12 15 14 21 24 10 10 14 25 23 10 21 23 19 24 + 19 24 25 24 23 14 23 19 25 19 21 24 19 10 24 25 12 + 23 11 19 21 14 11 23 11 25 23 23 10 11 24 12 15 23 + 21 24 24 24 20 23 24 23 25 15 14 24 25 16 20 23 12 + + 21 21 20 31 15 31 25 20 24 23 27 25 23 23 14 26 11 + 30 24 24 29 24 28 30 11 21 31 31 28 31 23 16 15 31 + 31 31 21 31 31 23 31 31 31 29 31 18 27 31 12 23 27 + 24 15 24 25 11 30 27 27 31 31 25 29 12 30 15 15 29 + 31 31 23 20 31 31 24 25 31 25 31 11 31 10 31 31 31 + 31 31 31 31 31 21 31 29 21 31 31 31 23 25 31 20 24 + 26 30 23 24 23 24 23 15 31 31 31 31 31 31 31 31 24 + 31 31 12 31 31 31 31 21 12 26 26 19 24 30 24 11 21 + 15 14 15 16 23 15 19 30 24 27 30 29 27 21 30 30 21 + 20 20 21 11 12 15 14 14 29 0 15 14 14 14 22 12 11 + 21 5 14 30 26 11 14 11 28 23 28 29 16 26 19 27 19 + 23 28 28 16 11 21 23 31 29 15 20 14 23 11 30 12 21 + 23 21 18 11 15 29 24 24 0 21 11 23 15 15 30 24 25 + 18 21 28 24 28 15 24 11 24 28 15 26 14 18 15 15 24 + 31 15 16 15 28 21 15 12 0 12 29 18 24 23 10 21 26 + 15 11 12 24 23 25 29 20 20 12 30 27 20 11 27 24 28 + 19 29 30 29 27 12 27 19 30 19 25 28 24 20 29 30 12 + 27 15 19 11 23 21 27 21 30 27 26 20 15 28 12 15 27 + 11 28 29 28 15 26 28 26 30 15 23 28 30 24 25 15 12 + + 17 5 11 24 23 24 18 12 24 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 19 24 24 23 24 12 12 12 24 + 24 24 21 24 24 23 24 24 24 24 24 11 21 24 15 23 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 15 18 24 + 24 24 15 10 24 24 24 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 6 24 24 10 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 5 16 20 20 19 15 24 15 23 9 + 20 14 12 12 12 15 19 24 14 23 24 24 23 16 24 24 5 + 10 10 17 23 23 12 14 14 24 21 23 14 14 14 22 16 23 + 0 21 14 24 20 23 14 23 23 19 23 24 12 20 19 21 23 + 11 23 23 12 23 10 15 24 24 12 10 14 10 23 24 15 12 + 23 0 11 23 23 24 15 12 21 0 18 11 12 20 24 12 19 + 11 19 23 15 23 15 14 23 15 23 15 20 14 11 15 12 15 + 24 12 12 12 23 17 15 23 23 0 24 11 19 10 23 15 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 19 23 + 19 24 24 24 23 16 21 19 24 19 18 23 19 10 24 24 15 + 23 12 19 23 14 9 21 6 24 23 20 10 12 23 15 15 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 18 18 16 29 15 29 24 16 24 23 25 24 23 23 12 25 0 + 28 23 23 28 23 27 28 10 19 29 29 27 29 23 14 12 29 + 29 29 21 29 29 23 29 29 29 28 29 15 25 29 11 23 25 + 23 12 23 24 12 28 26 25 29 29 24 28 14 28 15 15 28 + 29 29 23 16 29 29 24 24 29 24 29 12 29 10 29 29 29 + 29 29 29 29 29 18 29 28 18 29 29 29 20 24 29 16 24 + 25 28 20 23 20 23 21 12 29 29 29 29 29 29 29 29 23 + 29 29 10 29 29 29 29 18 10 25 25 19 24 28 24 12 18 + 15 12 12 14 23 15 19 28 23 26 28 28 26 18 28 28 18 + 16 16 18 12 14 12 12 12 28 11 15 12 12 12 22 10 12 + 18 11 12 28 25 12 12 12 27 21 27 28 14 25 19 25 19 + 21 27 27 14 12 18 20 29 28 12 16 12 20 12 28 11 18 + 23 18 15 12 15 28 24 23 11 18 0 21 12 15 28 23 24 + 15 19 27 24 27 15 23 12 24 27 15 25 12 15 15 12 23 + 29 12 14 12 27 18 15 14 27 14 0 15 23 20 12 18 25 + 15 12 11 23 23 24 28 16 16 10 28 25 16 12 26 23 27 + 19 28 28 28 26 10 25 19 28 19 24 27 24 16 28 28 11 + 26 12 19 12 23 18 25 18 28 26 25 16 12 27 11 15 25 + 12 27 28 27 15 25 27 25 28 15 23 27 28 23 24 15 11 + + 17 11 12 24 24 24 15 12 24 10 18 14 10 10 16 16 21 + 23 12 12 23 11 21 23 21 19 24 24 23 24 10 14 15 24 + 24 24 21 24 24 23 24 24 24 23 24 12 18 24 18 23 18 + 11 15 12 15 24 23 20 18 24 24 15 23 24 23 15 21 23 + 24 24 15 12 24 24 24 14 24 15 24 24 24 23 24 24 24 + 24 24 24 24 24 11 24 23 11 24 24 24 10 15 24 12 12 + 16 23 10 12 10 12 0 15 24 24 24 24 24 24 24 24 12 + 24 24 20 24 24 24 24 11 20 16 16 20 12 23 12 24 11 + 23 16 15 14 10 18 19 23 14 20 23 23 20 16 23 23 11 + 12 12 17 24 24 15 16 16 23 23 23 16 16 16 22 20 24 + 11 23 16 23 16 24 16 24 21 19 23 23 14 16 20 18 24 + 10 23 21 14 24 11 15 24 23 15 12 16 10 24 23 18 12 + 23 11 12 24 24 23 12 11 23 11 21 0 15 23 23 11 19 + 12 19 23 12 21 18 12 24 14 23 15 16 16 12 18 15 15 + 24 15 14 15 23 17 16 24 23 24 23 0 19 10 23 15 16 + 23 24 18 11 10 15 23 12 12 20 23 18 12 24 20 19 21 + 21 23 23 23 20 20 18 21 23 19 15 21 19 12 23 23 18 + 20 15 19 24 14 11 18 11 23 20 16 12 15 23 18 15 18 + 24 23 23 23 23 16 23 16 23 21 10 23 23 12 14 24 18 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 0 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 17 12 14 23 24 23 12 14 24 10 15 12 10 10 20 14 23 + 23 10 11 21 10 18 23 23 19 23 23 20 23 10 16 18 23 + 23 23 21 23 23 23 23 23 23 21 23 15 15 23 21 23 15 + 5 18 10 12 24 23 19 15 23 23 12 21 25 23 18 23 21 + 23 23 15 14 23 23 24 12 23 12 23 24 23 23 23 23 23 + 23 23 23 23 23 12 23 21 12 23 23 23 12 12 23 14 11 + 14 23 12 10 12 10 11 18 23 23 23 23 23 23 23 23 11 + 23 23 23 23 23 23 23 12 23 14 14 23 11 23 11 24 12 + 23 20 18 16 10 21 21 23 14 16 23 21 16 16 23 23 12 + 14 14 17 24 25 18 20 20 21 24 24 20 20 20 22 23 24 + 12 24 20 23 14 24 20 24 18 19 20 21 16 14 23 15 24 + 11 20 19 16 24 12 15 23 21 18 14 20 12 24 23 21 12 + 23 12 15 24 24 21 11 6 24 12 23 11 18 23 23 0 19 + 15 19 20 11 18 21 11 24 14 20 18 14 20 15 21 18 15 + 23 18 16 18 20 17 20 25 20 25 21 15 19 0 24 15 14 + 24 24 21 0 10 12 21 14 14 23 23 15 14 24 16 19 18 + 23 21 23 21 16 23 15 23 23 21 12 18 19 14 21 23 21 + 16 18 19 24 14 12 15 12 23 16 14 14 18 20 21 18 15 + 24 20 21 20 24 14 20 14 23 23 10 20 23 10 12 25 21 + + 17 11 11 25 21 25 21 12 24 14 23 20 14 14 12 23 15 + 25 16 16 24 15 24 25 15 19 25 25 24 25 14 10 11 25 + 25 25 21 25 25 23 25 25 25 24 25 0 23 25 12 23 23 + 15 11 16 21 21 25 23 23 25 25 21 24 23 25 15 15 24 + 25 25 15 10 25 25 24 20 25 21 25 21 25 16 25 25 25 + 25 25 25 25 25 11 25 24 11 25 25 25 12 21 25 10 18 + 23 25 12 16 12 16 12 11 25 25 25 25 25 25 25 25 16 + 25 25 14 25 25 25 25 11 14 23 23 19 18 25 18 21 11 + 16 12 11 10 14 15 19 25 16 23 25 24 23 16 25 25 11 + 10 10 17 21 23 11 12 12 24 18 20 12 12 12 22 14 21 + 11 18 12 25 23 21 12 21 24 19 24 24 10 23 19 23 21 + 12 24 24 10 21 11 15 25 24 11 10 12 12 21 25 12 12 + 23 11 0 21 21 24 18 15 18 11 15 12 11 16 25 15 20 + 0 19 24 18 24 15 16 21 18 24 15 23 12 6 15 11 15 + 25 11 10 11 24 17 15 23 24 23 24 10 19 12 0 15 23 + 20 21 12 15 14 21 24 10 10 14 25 23 10 21 23 19 24 + 19 24 25 24 23 14 23 19 25 19 21 24 19 10 24 25 12 + 23 11 19 21 14 11 23 11 25 23 23 10 11 24 12 15 23 + 21 24 24 24 20 23 24 23 25 15 14 24 25 16 20 23 12 + + 23 23 24 12 30 12 14 24 24 21 12 15 21 21 25 12 27 + 11 18 18 10 20 10 15 27 23 12 12 0 12 21 24 25 12 + 12 12 23 12 12 23 12 12 12 10 12 24 12 12 26 23 12 + 20 25 18 14 30 11 19 12 12 12 14 10 31 15 25 27 10 + 12 12 21 24 12 12 24 15 12 14 12 30 12 28 12 12 12 + 12 12 12 12 12 23 12 10 23 12 12 12 23 14 12 24 16 + 12 11 23 18 23 18 23 25 12 12 12 12 12 12 12 12 18 + 12 12 27 12 12 12 12 23 27 12 12 27 16 11 16 30 23 + 28 25 25 24 21 26 26 11 18 11 11 10 15 23 11 11 23 + 24 24 23 30 31 25 25 25 10 28 29 25 25 25 23 27 30 + 23 28 25 11 12 30 25 30 15 23 10 19 24 12 27 12 30 + 23 15 19 24 30 23 23 19 10 25 24 25 23 30 11 26 23 + 23 23 24 30 30 10 16 20 28 23 27 23 25 28 11 20 19 + 24 23 0 16 10 26 18 30 16 19 25 12 25 24 26 25 20 + 19 25 24 25 0 23 25 31 15 31 19 24 19 23 29 0 12 + 29 30 26 20 21 14 10 24 24 27 11 12 24 30 11 20 15 + 27 10 11 10 15 27 15 27 11 26 14 10 19 24 10 15 26 + 11 25 24 30 21 23 12 23 11 15 12 24 25 6 26 25 12 + 30 19 15 0 29 12 0 12 11 27 21 19 11 18 15 31 26 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 0 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 17 12 12 27 18 27 23 12 24 16 24 23 16 16 10 23 12 + 26 20 20 25 18 24 26 12 19 27 27 25 27 16 10 6 27 + 27 27 21 27 27 23 27 27 27 25 27 11 24 27 11 23 24 + 18 6 20 23 18 26 24 24 27 27 23 25 20 26 15 15 25 + 27 27 16 12 27 27 24 23 27 23 27 18 27 14 27 27 27 + 27 27 27 27 27 12 27 25 12 27 27 27 14 23 27 12 21 + 23 26 14 20 14 20 15 6 27 27 27 27 27 27 27 27 20 + 27 27 12 27 27 27 27 12 12 23 23 19 21 26 21 18 12 + 15 10 0 10 16 15 19 26 20 24 26 25 24 16 26 26 12 + 12 12 17 18 20 0 10 10 25 15 16 12 10 10 22 12 18 + 12 15 10 26 23 18 12 18 24 19 25 25 10 23 19 24 19 + 15 25 24 10 18 12 15 27 25 0 12 10 14 18 26 11 12 + 23 12 11 18 18 25 21 18 15 12 12 15 0 15 26 18 23 + 11 19 25 21 24 15 20 18 21 25 15 23 10 11 15 6 18 + 27 0 10 6 25 17 15 20 25 20 25 11 20 14 16 15 23 + 0 18 11 18 16 23 25 12 12 12 26 24 12 18 24 19 24 + 19 25 26 25 24 12 24 19 26 19 23 24 21 12 25 26 11 + 24 0 19 18 16 12 24 12 26 24 23 12 0 25 11 15 24 + 18 25 25 25 16 23 25 23 26 15 16 25 26 20 23 20 11 + + 23 23 24 12 30 12 14 24 24 21 12 15 21 21 25 12 27 + 11 18 18 10 20 10 15 27 23 12 12 0 12 21 24 25 12 + 12 12 23 12 12 23 12 12 12 10 12 24 12 12 26 23 12 + 20 25 18 14 30 11 19 12 12 12 14 10 31 15 25 27 10 + 12 12 21 24 12 12 24 15 12 14 12 30 12 28 12 12 12 + 12 12 12 12 12 23 12 10 23 12 12 12 23 14 12 24 16 + 12 11 23 18 23 18 23 25 12 12 12 12 12 12 12 12 18 + 12 12 27 12 12 12 12 23 27 12 12 27 16 11 16 30 23 + 28 25 25 24 21 26 26 11 18 11 11 10 15 23 11 11 23 + 24 24 23 30 31 25 25 25 10 28 29 25 25 25 23 27 30 + 23 28 25 11 12 30 25 30 15 23 10 19 24 12 27 12 30 + 23 15 19 24 30 23 23 19 10 25 24 25 23 30 11 26 23 + 23 23 24 30 30 10 16 20 28 23 27 23 25 28 11 20 19 + 24 23 0 16 10 26 18 30 16 19 25 12 25 24 26 25 20 + 19 25 24 25 0 23 25 31 15 31 19 24 19 23 29 23 12 + 29 0 26 20 21 14 10 24 24 27 11 12 24 30 11 20 15 + 27 10 11 10 15 27 15 27 11 26 14 10 19 24 10 15 26 + 11 25 24 30 21 23 12 23 11 15 12 24 25 6 26 25 12 + 30 19 15 0 29 12 0 12 11 27 21 19 11 18 15 31 26 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 0 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 0 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 15 14 15 23 25 23 12 15 22 11 14 11 11 11 21 12 23 + 21 5 10 20 10 16 21 23 18 23 23 18 23 11 18 20 23 + 23 23 19 23 23 21 23 23 23 20 23 16 14 23 23 21 14 + 10 20 6 12 25 21 18 14 23 23 12 20 25 21 20 23 20 + 23 23 13 15 23 23 22 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 6 12 4 12 20 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 12 15 21 20 15 14 21 21 14 + 15 15 15 25 25 20 21 21 20 24 24 21 21 21 20 23 25 + 14 24 21 21 12 25 21 25 16 18 18 20 18 12 23 14 25 + 12 18 18 18 25 14 13 23 20 20 15 21 12 25 21 23 14 + 21 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 18 + 16 18 18 10 16 23 10 25 12 18 20 12 21 16 23 20 13 + 23 20 18 20 18 15 21 25 18 25 20 16 18 12 24 14 12 + 24 25 23 10 0 12 20 15 15 23 21 14 15 25 15 18 16 + 23 20 21 20 15 23 14 23 21 23 12 16 18 15 20 21 23 + 15 20 18 25 12 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 1 11 25 23 + + 15 14 15 23 25 23 12 15 22 11 14 11 11 11 21 12 23 + 21 5 10 20 10 16 21 23 18 23 23 18 23 11 18 20 23 + 23 23 19 23 23 21 23 23 23 20 23 16 14 23 23 21 14 + 10 20 6 12 25 21 18 14 23 23 12 20 25 21 20 23 20 + 23 23 13 15 23 23 22 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 6 12 4 12 20 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 12 15 21 20 15 14 21 21 14 + 15 15 15 25 25 20 21 21 20 24 24 21 21 21 20 23 25 + 14 24 21 21 12 25 21 25 16 18 18 20 18 12 23 14 25 + 12 18 18 18 25 14 13 23 20 20 15 21 12 25 21 23 14 + 21 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 18 + 16 18 18 10 16 23 10 25 12 18 20 12 21 16 23 20 13 + 23 20 18 20 18 15 21 25 18 25 20 16 18 12 24 14 12 + 24 25 23 10 11 0 20 15 15 23 21 14 15 25 15 18 16 + 23 20 21 20 15 23 14 23 21 23 12 16 18 15 20 21 23 + 15 20 18 25 12 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 1 11 25 23 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 0 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 15 10 10 25 23 25 20 11 22 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 18 25 25 24 25 12 11 12 25 + 25 25 19 25 25 21 25 25 25 24 25 10 23 25 14 21 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 13 16 24 + 25 25 13 9 25 25 22 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 9 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 18 16 24 16 23 10 + 18 12 12 11 12 14 18 24 15 23 24 24 23 14 24 24 10 + 4 7 15 23 23 12 12 12 24 20 21 12 12 12 20 15 23 + 10 20 12 24 21 23 12 23 23 18 24 24 11 21 18 23 23 + 12 24 23 11 23 10 13 25 24 12 9 12 11 23 24 14 11 + 21 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 18 24 16 23 14 15 23 16 24 13 21 12 10 14 12 14 + 25 12 11 12 24 15 13 23 24 23 24 10 18 11 21 13 21 + 21 23 14 14 12 20 24 0 5 15 24 23 4 23 23 18 23 + 18 24 24 24 23 15 23 18 24 18 20 23 18 6 24 24 14 + 23 12 18 23 12 10 23 10 24 23 21 7 12 24 14 13 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 14 10 8 25 23 25 20 9 21 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 16 25 25 24 25 12 11 12 25 + 25 25 18 25 25 20 25 25 25 24 25 10 23 25 14 20 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 12 16 24 + 25 25 12 7 25 25 21 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 7 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 16 16 24 16 23 10 + 18 12 12 11 12 14 16 24 15 23 24 24 23 13 24 24 10 + 2 6 14 23 23 12 12 12 24 20 21 12 12 12 19 15 23 + 10 20 12 24 21 23 12 23 23 16 24 24 11 21 16 23 23 + 12 24 23 11 23 10 12 25 24 12 7 12 11 23 24 14 10 + 20 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 16 24 16 23 14 15 23 16 24 12 21 12 10 14 12 14 + 25 12 11 12 24 14 12 23 24 23 24 10 16 11 21 12 21 + 21 23 14 14 12 20 24 6 0 15 24 23 2 23 23 16 23 + 16 24 24 24 23 15 23 16 24 16 20 23 16 5 24 24 14 + 23 12 16 23 12 10 23 10 24 23 21 6 12 24 14 12 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 0 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 0 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 20 20 21 16 27 16 10 21 24 15 11 11 15 15 24 0 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 21 16 16 23 16 16 16 14 16 23 10 16 24 23 10 + 14 23 12 10 27 15 19 10 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 24 11 16 11 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 20 16 16 16 18 10 16 21 12 + 6 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 5 9 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 14 11 15 14 15 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 22 24 27 + 20 26 24 15 12 27 24 27 15 19 12 19 23 0 24 10 27 + 16 15 19 23 27 20 18 19 14 23 21 24 18 27 15 24 20 + 23 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 19 + 23 20 12 12 12 24 12 27 14 19 23 6 24 23 24 23 15 + 19 23 23 23 12 20 24 28 15 28 19 23 19 18 27 20 10 + 27 27 24 14 15 10 14 21 21 24 15 0 21 27 11 19 15 + 25 14 15 14 15 24 15 25 15 24 10 12 19 21 14 15 24 + 11 23 23 27 15 20 10 20 15 15 9 21 23 12 24 23 10 + 27 19 15 12 27 8 12 6 15 25 15 19 15 12 11 28 24 + + 15 10 10 25 23 25 20 11 22 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 18 25 25 24 25 12 11 12 25 + 25 25 19 25 25 21 25 25 25 24 25 10 23 25 14 21 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 13 16 24 + 25 25 13 9 25 25 22 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 9 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 18 16 24 16 23 10 + 18 12 12 11 12 14 18 24 15 23 24 24 23 14 24 24 10 + 4 7 15 23 23 12 12 12 24 20 21 12 12 12 20 15 23 + 10 20 12 24 21 23 12 23 23 18 24 24 11 21 18 23 23 + 12 24 23 11 23 10 13 25 24 12 9 12 11 23 24 14 11 + 21 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 18 24 16 23 14 15 23 16 24 13 21 12 10 14 12 14 + 25 12 11 12 24 15 13 23 24 23 24 10 18 11 21 13 21 + 21 23 14 14 12 20 24 7 5 15 24 23 0 23 23 18 23 + 18 24 24 24 23 15 23 18 24 18 20 23 18 6 24 24 14 + 23 12 18 23 12 10 23 10 24 23 21 7 12 24 14 13 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 0 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 17 15 14 28 15 28 24 14 24 20 24 23 20 20 10 24 11 + 27 23 23 27 21 25 27 11 19 28 28 26 28 20 12 11 28 + 28 28 21 28 28 23 28 28 28 27 28 12 24 28 0 23 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 15 15 27 + 28 28 20 14 28 28 24 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 28 27 15 28 28 28 16 24 28 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 10 24 24 19 23 27 23 15 15 + 15 10 11 12 20 15 19 27 23 25 27 27 25 16 27 27 15 + 14 14 17 15 16 11 10 10 27 12 15 12 10 10 22 10 15 + 15 12 10 27 24 15 12 15 25 19 26 27 12 24 19 24 19 + 18 26 25 12 15 15 16 28 27 11 14 10 16 15 27 5 15 + 23 15 12 15 15 27 23 21 12 15 11 18 11 15 27 21 23 + 12 19 26 23 25 15 23 15 23 26 15 24 10 12 15 11 21 + 28 11 12 11 26 17 15 16 26 16 27 12 23 16 14 15 24 + 15 15 0 21 20 24 27 14 14 10 27 24 14 15 0 21 25 + 19 27 27 27 25 10 24 19 27 19 24 25 23 14 27 27 0 + 25 11 19 15 20 15 24 15 27 25 24 14 11 26 0 15 24 + 15 26 27 26 15 24 26 24 27 15 20 26 27 23 23 16 10 + + 17 12 14 23 24 23 12 14 24 10 15 12 10 10 20 14 23 + 23 10 11 21 10 18 23 23 19 23 23 20 23 10 16 18 23 + 23 23 21 23 23 23 23 23 23 21 23 15 15 23 21 23 15 + 5 18 10 12 24 23 19 15 23 23 12 21 25 23 18 23 21 + 23 23 15 14 23 23 24 12 23 12 23 24 23 23 23 23 23 + 23 23 23 23 23 12 23 21 12 23 23 23 12 12 23 14 11 + 14 23 12 10 12 10 11 18 23 23 23 23 23 23 23 23 11 + 23 23 23 23 23 23 23 12 23 14 14 23 11 23 11 24 12 + 23 20 18 16 10 21 21 23 14 16 23 21 16 16 23 23 12 + 14 14 17 24 25 18 20 20 21 24 24 20 20 20 22 23 24 + 12 24 20 23 14 24 20 24 18 19 20 21 16 14 23 15 24 + 11 20 19 16 24 12 15 23 21 18 14 20 12 24 23 21 12 + 23 12 15 24 24 21 11 6 24 12 23 11 18 23 23 0 19 + 15 19 20 11 18 21 11 24 14 20 18 14 20 15 21 18 15 + 23 18 16 18 20 17 20 25 20 25 21 15 19 12 24 15 14 + 24 24 21 0 10 12 21 14 14 23 23 15 14 24 16 0 18 + 23 21 23 21 16 23 15 23 23 21 12 18 19 14 21 23 21 + 16 18 19 24 14 12 15 12 23 16 14 14 18 20 21 18 15 + 24 20 21 20 24 14 20 14 23 23 10 20 23 10 12 25 21 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 0 21 11 15 28 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 0 11 24 12 11 27 24 12 + 21 25 20 15 31 10 19 12 11 11 15 0 31 15 25 28 6 + 11 11 23 24 11 11 24 16 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 0 24 11 11 11 23 15 11 24 18 + 14 10 23 20 23 20 23 25 11 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 0 15 24 10 10 24 + 24 24 24 31 31 25 26 26 0 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 15 23 10 19 25 14 27 12 31 + 23 15 19 25 31 24 23 19 0 25 24 26 23 31 10 27 24 + 24 24 24 31 31 0 18 21 29 24 28 23 25 28 10 21 19 + 24 24 10 18 11 27 20 31 18 19 25 14 26 24 27 25 21 + 19 25 25 25 10 24 26 31 15 31 19 24 20 23 30 24 14 + 30 31 27 21 23 15 0 24 24 27 10 12 24 31 12 21 0 + 28 10 10 0 15 27 15 28 10 27 15 11 19 24 0 15 27 + 12 25 25 31 23 24 12 24 10 15 14 24 25 10 27 25 12 + 31 19 15 10 30 14 10 14 10 28 23 19 10 20 16 31 27 + + 17 16 15 28 15 28 24 15 24 21 25 24 21 21 11 24 10 + 28 23 23 27 23 26 28 10 19 28 28 27 28 21 12 12 28 + 28 28 21 28 28 23 28 28 28 27 28 14 25 28 10 23 25 + 23 12 23 24 14 28 25 25 28 28 24 27 15 28 15 15 27 + 28 28 21 15 28 28 24 24 28 24 28 14 28 11 28 28 28 + 28 28 28 28 28 16 28 27 16 28 28 28 18 24 28 15 23 + 24 28 18 23 18 23 20 12 28 28 28 28 28 28 28 28 23 + 28 28 6 28 28 28 28 16 0 24 24 19 23 28 23 14 16 + 15 11 12 12 21 15 19 28 23 25 28 27 25 16 28 28 16 + 15 15 17 14 15 12 11 11 27 12 15 12 11 11 22 0 14 + 16 12 11 28 24 14 12 14 26 20 27 27 12 24 19 25 19 + 20 27 26 12 14 16 18 28 27 12 15 11 18 14 28 10 16 + 23 16 14 14 15 27 23 23 12 16 10 20 12 15 28 23 24 + 14 19 27 23 26 15 23 14 23 27 15 24 11 14 15 12 23 + 28 12 12 12 27 17 15 15 27 15 27 14 23 18 12 16 24 + 15 14 10 23 21 24 27 15 15 0 28 25 15 14 25 23 26 + 0 27 28 27 25 0 25 19 28 19 24 26 23 15 27 28 10 + 25 12 19 14 21 16 25 16 28 25 24 15 12 27 10 15 25 + 14 27 27 27 15 24 27 24 28 15 21 27 28 23 24 15 10 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 0 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 0 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 6 21 21 10 23 12 9 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 6 13 14 10 10 16 10 31 9 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 6 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 6 20 31 24 + 29 27 26 25 23 27 27 6 21 12 6 10 12 24 6 0 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 6 15 31 27 31 12 23 11 13 25 15 28 14 31 + 23 11 13 25 31 24 24 13 10 26 24 27 24 31 6 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 6 23 18 + 25 24 11 20 12 27 21 31 20 13 26 15 27 25 27 26 23 + 13 26 25 26 11 24 27 31 11 31 13 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 6 14 24 31 12 23 12 + 28 10 0 0 12 28 14 28 6 27 16 12 20 24 10 9 27 + 12 26 25 31 23 24 14 24 6 12 15 24 26 11 27 26 14 + 31 13 10 11 31 15 11 15 6 28 23 13 6 21 18 31 27 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 0 21 11 15 28 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 0 11 24 12 11 27 24 12 + 21 25 20 15 31 10 19 12 11 11 15 0 31 15 25 28 6 + 11 11 23 24 11 11 24 16 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 0 24 11 11 11 23 15 11 24 18 + 14 10 23 20 23 20 23 25 11 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 0 15 24 10 10 24 + 24 24 24 31 31 25 26 26 0 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 15 23 10 19 25 14 27 12 31 + 23 15 19 25 31 24 23 19 0 25 24 26 23 31 10 27 24 + 24 24 24 31 31 0 18 21 29 24 28 23 25 28 10 21 19 + 24 24 10 18 11 27 20 31 18 19 25 14 26 24 27 25 21 + 19 25 25 25 10 24 26 31 15 31 19 24 20 23 30 24 14 + 30 31 27 21 23 15 0 24 24 27 10 12 24 31 12 21 15 + 28 10 10 0 0 27 15 28 10 27 15 11 19 24 0 15 27 + 12 25 25 31 23 24 12 24 10 15 14 24 25 10 27 25 12 + 31 19 15 10 30 14 10 14 10 28 23 19 10 20 16 31 27 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 0 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 20 20 21 16 27 16 10 21 24 15 11 11 15 15 24 0 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 21 16 16 23 16 16 16 14 16 23 10 16 24 23 10 + 14 23 12 10 27 15 19 10 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 24 11 16 11 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 20 16 16 16 18 10 16 21 12 + 6 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 5 9 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 14 11 15 14 15 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 22 24 27 + 20 26 24 15 12 27 24 27 15 19 12 19 23 0 24 10 27 + 16 15 19 23 27 20 18 19 14 23 21 24 18 27 15 24 20 + 23 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 19 + 23 20 12 12 12 24 12 27 14 19 23 6 24 23 24 23 15 + 19 23 23 23 12 20 24 28 15 28 19 23 19 18 27 20 10 + 27 27 24 14 15 10 14 21 21 24 15 10 21 27 11 19 15 + 25 14 15 14 15 24 0 25 15 24 10 12 19 21 14 15 24 + 11 23 23 27 15 20 10 20 15 15 9 21 23 12 24 23 10 + 27 19 15 12 27 8 12 6 15 25 15 19 15 12 11 28 24 + + 17 16 15 28 15 28 24 15 24 21 25 24 21 21 11 24 10 + 28 23 23 27 23 26 28 10 19 28 28 27 28 21 12 12 28 + 28 28 21 28 28 23 28 28 28 27 28 14 25 28 10 23 25 + 23 12 23 24 14 28 25 25 28 28 24 27 15 28 15 15 27 + 28 28 21 15 28 28 24 24 28 24 28 14 28 11 28 28 28 + 28 28 28 28 28 16 28 27 16 28 28 28 18 24 28 15 23 + 24 28 18 23 18 23 20 12 28 28 28 28 28 28 28 28 23 + 28 28 6 28 28 28 28 16 0 24 24 19 23 28 23 14 16 + 15 11 12 12 21 15 19 28 23 25 28 27 25 16 28 28 16 + 15 15 17 14 15 12 11 11 27 12 15 12 11 11 22 0 14 + 16 12 11 28 24 14 12 14 26 20 27 27 12 24 19 25 19 + 20 27 26 12 14 16 18 28 27 12 15 11 18 14 28 10 16 + 23 16 14 14 15 27 23 23 12 16 10 20 12 15 28 23 24 + 14 19 27 23 26 15 23 14 23 27 15 24 11 14 15 12 23 + 28 12 12 12 27 17 15 15 27 15 27 14 23 18 12 16 24 + 15 14 10 23 21 24 27 15 15 0 28 25 15 14 25 23 26 + 19 27 28 27 25 0 25 0 28 19 24 26 23 15 27 28 10 + 25 12 19 14 21 16 25 16 28 25 24 15 12 27 10 15 25 + 14 27 27 27 15 24 27 24 28 15 21 27 28 23 24 15 10 + + 14 14 15 23 25 23 12 15 14 14 14 19 12 12 21 19 23 + 21 12 8 20 10 16 21 23 14 23 23 19 23 11 19 20 23 + 23 23 14 23 23 14 23 23 23 20 23 19 19 23 23 14 14 + 14 20 11 12 25 21 15 14 23 23 14 20 25 21 20 23 20 + 23 23 11 15 23 23 14 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 19 12 23 15 12 + 12 21 12 11 12 14 19 20 23 23 23 23 23 23 23 23 8 + 23 23 23 23 23 23 23 14 23 14 12 23 12 21 11 25 14 + 24 21 20 19 11 23 23 21 5 19 21 20 15 14 21 21 14 + 15 15 14 25 25 20 21 21 20 24 24 21 21 21 14 23 25 + 19 24 21 21 12 25 21 25 16 12 18 20 18 19 23 14 25 + 12 18 16 19 25 14 12 23 20 20 15 21 19 25 21 23 14 + 14 19 19 25 25 20 11 12 24 19 23 19 20 24 21 19 11 + 19 14 19 14 19 23 8 25 10 18 20 13 21 16 23 20 10 + 23 20 19 20 19 14 21 25 18 25 20 16 0 13 24 14 12 + 24 25 23 19 14 12 20 15 15 23 21 14 15 25 15 10 16 + 23 20 21 20 15 23 14 23 0 23 12 19 10 15 20 21 23 + 15 20 18 25 11 14 14 14 21 15 12 15 20 18 23 20 19 + 25 18 20 19 24 12 19 13 21 23 19 18 21 19 19 25 23 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 0 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 15 14 15 23 25 23 12 15 22 11 14 11 11 11 21 12 23 + 21 5 10 20 10 16 21 23 18 23 23 18 23 11 18 20 23 + 23 23 19 23 23 21 23 23 23 20 23 16 14 23 23 21 14 + 10 20 6 12 25 21 18 14 23 23 12 20 25 21 20 23 20 + 23 23 13 15 23 23 22 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 6 12 4 12 20 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 12 15 21 20 15 14 21 21 14 + 15 15 15 25 25 20 21 21 20 24 24 21 21 21 20 23 25 + 14 24 21 21 12 25 21 25 16 18 18 20 18 12 23 14 25 + 12 18 18 18 25 14 13 23 20 20 15 21 12 25 21 23 14 + 21 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 18 + 16 18 18 10 16 23 10 25 12 18 20 12 21 16 23 20 13 + 23 20 18 20 18 15 21 25 18 25 20 16 18 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 18 16 + 23 20 21 20 15 23 14 23 21 23 0 16 18 15 20 21 23 + 15 20 18 25 12 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 1 11 25 23 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 0 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 23 23 23 12 29 12 12 23 24 20 11 14 20 20 25 12 27 + 12 16 16 11 18 10 15 27 23 12 12 10 12 20 24 24 12 + 12 12 23 12 12 23 12 12 12 11 12 24 11 12 25 23 11 + 18 24 16 12 29 12 19 11 12 12 12 11 30 15 24 27 11 + 12 12 20 23 12 12 24 14 12 12 12 29 12 27 12 12 12 + 12 12 12 12 12 23 12 11 23 12 12 12 23 12 12 23 15 + 12 12 23 16 23 16 21 24 12 12 12 12 12 12 12 12 16 + 12 12 26 12 12 12 12 23 26 12 12 26 15 12 15 29 23 + 27 25 24 24 20 25 25 12 16 10 12 11 15 23 12 12 23 + 23 23 23 29 30 24 25 25 11 28 28 25 25 25 23 26 29 + 23 28 25 12 12 29 25 29 15 21 10 19 24 12 26 11 29 + 21 15 19 24 29 23 23 19 11 24 23 25 23 29 12 25 23 + 23 23 24 29 29 11 15 18 28 23 27 21 24 27 12 18 19 + 24 23 10 15 0 25 16 29 15 19 24 12 25 24 25 24 18 + 19 24 24 24 10 23 25 30 15 30 19 24 19 23 28 23 12 + 28 29 25 18 20 12 11 23 23 26 12 11 23 29 10 19 15 + 27 11 12 11 15 26 15 27 12 25 12 0 0 23 11 15 25 + 10 24 24 29 20 23 11 23 12 15 12 23 24 10 25 24 11 + 29 19 15 10 28 12 10 12 12 27 20 19 12 16 14 30 25 + + 14 10 8 25 23 25 20 9 21 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 16 25 25 24 25 12 11 12 25 + 25 25 18 25 25 20 25 25 25 24 25 10 23 25 14 20 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 12 16 24 + 25 25 12 7 25 25 21 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 7 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 16 16 24 16 23 10 + 18 12 12 11 12 14 16 24 15 23 24 24 23 13 24 24 10 + 2 6 14 23 23 12 12 12 24 20 21 12 12 12 19 15 23 + 10 20 12 24 21 23 12 23 23 16 24 24 11 21 16 23 23 + 12 24 23 11 23 10 12 25 24 12 7 12 11 23 24 14 10 + 20 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 16 24 16 23 14 15 23 16 24 12 21 12 10 14 12 14 + 25 12 11 12 24 14 12 23 24 23 24 10 16 11 21 12 21 + 21 23 14 14 12 20 24 6 3 15 24 23 2 23 23 16 23 + 16 24 24 24 23 15 23 16 24 16 20 23 16 0 24 24 14 + 23 12 16 23 12 10 23 10 24 23 21 6 12 24 14 12 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 23 23 23 14 28 14 12 23 23 18 10 15 18 18 24 15 26 + 15 15 15 15 16 10 12 26 23 14 14 15 14 18 24 24 14 + 14 14 23 14 14 23 14 14 14 15 14 23 15 14 25 23 10 + 16 24 15 12 28 15 4 10 14 14 12 15 29 12 24 26 12 + 14 14 18 23 14 14 23 12 14 12 14 28 14 27 14 14 14 + 14 14 14 14 14 23 14 15 23 14 14 14 21 12 14 23 14 + 11 15 21 15 21 15 20 24 14 14 14 14 14 14 14 14 15 + 14 14 25 14 14 14 14 23 25 11 11 25 14 15 14 28 23 + 27 24 24 24 18 25 25 15 15 15 15 15 0 23 15 12 23 + 23 23 23 28 29 24 24 24 15 27 28 24 24 24 23 25 28 + 23 27 24 15 11 28 24 28 10 20 11 12 24 15 25 10 28 + 20 11 10 24 28 23 21 14 15 24 23 24 21 28 15 25 23 + 23 23 23 28 28 15 14 16 27 23 26 20 24 27 15 16 12 + 23 23 15 14 15 25 15 28 14 11 24 11 24 23 25 24 16 + 14 24 24 24 15 23 24 29 11 29 12 23 15 21 28 23 11 + 28 28 25 16 18 12 15 23 23 25 15 10 23 28 4 16 10 + 26 12 12 15 0 25 10 26 15 25 12 15 14 23 0 12 25 + 9 24 24 28 18 23 10 23 15 0 11 23 24 11 25 24 15 + 28 11 12 15 28 11 15 11 15 26 18 11 15 15 15 29 25 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 0 21 11 15 28 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 0 11 24 12 11 27 24 12 + 21 25 20 15 31 10 19 12 11 11 15 0 31 15 25 28 6 + 11 11 23 24 11 11 24 16 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 0 24 11 11 11 23 15 11 24 18 + 14 10 23 20 23 20 23 25 11 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 0 15 24 10 10 24 + 24 24 24 31 31 25 26 26 0 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 15 23 10 19 25 14 27 12 31 + 23 15 19 25 31 24 23 19 0 25 24 26 23 31 10 27 24 + 24 24 24 31 31 0 18 21 29 24 28 23 25 28 10 21 19 + 24 24 10 18 11 27 20 31 18 19 25 14 26 24 27 25 21 + 19 25 25 25 10 24 26 31 15 31 19 24 20 23 30 24 14 + 30 31 27 21 23 15 0 24 24 27 10 12 24 31 12 21 15 + 28 10 10 0 15 27 15 28 10 27 15 11 19 24 0 0 27 + 12 25 25 31 23 24 12 24 10 15 14 24 25 10 27 25 12 + 31 19 15 10 30 14 10 14 10 28 23 19 10 20 16 31 27 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 0 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 17 15 14 28 15 28 24 14 24 20 24 23 20 20 10 24 11 + 27 23 23 27 21 25 27 11 19 28 28 26 28 20 12 11 28 + 28 28 21 28 28 23 28 28 28 27 28 12 24 28 0 23 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 15 15 27 + 28 28 20 14 28 28 24 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 28 27 15 28 28 28 16 24 28 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 10 24 24 19 23 27 23 15 15 + 15 10 11 12 20 15 19 27 23 25 27 27 25 16 27 27 15 + 14 14 17 15 16 11 10 10 27 12 15 12 10 10 22 10 15 + 15 12 10 27 24 15 12 15 25 19 26 27 12 24 19 24 19 + 18 26 25 12 15 15 16 28 27 11 14 10 16 15 27 5 15 + 23 15 12 15 15 27 23 21 12 15 11 18 11 15 27 21 23 + 12 19 26 23 25 15 23 15 23 26 15 24 10 12 15 11 21 + 28 11 12 11 26 17 15 16 26 16 27 12 23 16 14 15 24 + 15 15 0 21 20 24 27 14 14 10 27 24 14 15 25 21 25 + 19 27 27 27 25 10 24 19 27 19 24 25 23 14 27 27 0 + 0 11 19 15 20 15 24 15 27 25 24 14 11 26 0 15 24 + 15 26 27 26 15 24 26 24 27 15 20 26 27 23 23 16 10 + + 15 15 14 28 15 28 24 14 15 20 24 23 20 20 15 24 15 + 27 23 23 27 21 25 27 11 15 28 28 26 28 20 15 11 28 + 28 28 15 28 28 15 28 28 28 27 28 15 24 28 15 15 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 11 11 27 + 28 28 20 14 28 28 15 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 28 27 15 28 28 28 16 24 28 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 15 24 24 10 23 27 23 15 15 + 12 15 15 15 20 0 4 27 23 25 27 27 25 15 27 27 15 + 14 14 15 15 16 15 10 10 27 15 14 10 10 15 15 15 15 + 15 12 10 27 24 15 10 15 25 18 26 27 12 24 10 24 15 + 18 26 25 15 15 15 16 28 27 15 14 15 16 15 27 9 15 + 15 15 15 15 15 27 23 21 15 15 15 18 15 12 27 21 23 + 15 15 26 23 25 0 23 15 23 26 11 24 10 12 0 11 21 + 28 15 15 11 26 15 10 16 26 16 27 12 23 16 14 15 24 + 14 15 15 21 20 24 27 14 14 15 27 24 14 15 25 21 25 + 11 27 27 27 25 15 24 11 27 4 24 25 23 14 27 27 15 + 25 0 12 15 20 15 24 15 27 25 24 14 15 26 15 11 24 + 15 26 27 26 14 24 26 24 27 11 20 26 27 23 23 16 4 + + 17 12 12 27 18 27 23 12 24 16 24 23 16 16 10 23 12 + 26 20 20 25 18 24 26 12 19 27 27 25 27 16 10 6 27 + 27 27 21 27 27 23 27 27 27 25 27 11 24 27 11 23 24 + 18 6 20 23 18 26 24 24 27 27 23 25 20 26 15 15 25 + 27 27 16 12 27 27 24 23 27 23 27 18 27 14 27 27 27 + 27 27 27 27 27 12 27 25 12 27 27 27 14 23 27 12 21 + 23 26 14 20 14 20 15 6 27 27 27 27 27 27 27 27 20 + 27 27 12 27 27 27 27 12 12 23 23 19 21 26 21 18 12 + 15 10 0 10 16 15 19 26 20 24 26 25 24 16 26 26 12 + 12 12 17 18 20 0 10 10 25 15 16 12 10 10 22 12 18 + 12 15 10 26 23 18 12 18 24 19 25 25 10 23 19 24 19 + 15 25 24 10 18 12 15 27 25 0 12 10 14 18 26 11 12 + 23 12 11 18 18 25 21 18 15 12 12 15 0 15 26 18 23 + 11 19 25 21 24 15 20 18 21 25 15 23 10 11 15 6 18 + 27 0 10 6 25 17 15 20 25 20 25 11 20 14 16 15 23 + 16 18 11 18 16 23 25 12 12 12 26 24 12 18 24 19 24 + 19 25 26 25 24 12 24 19 26 19 23 24 21 12 25 26 11 + 24 0 0 18 16 12 24 12 26 24 23 12 0 25 11 15 24 + 18 25 25 25 16 23 25 23 26 15 16 25 26 20 23 20 11 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 0 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 0 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 20 20 21 16 27 16 10 21 21 15 10 11 15 15 24 3 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 20 16 16 20 16 16 16 14 16 23 10 16 24 20 10 + 14 23 12 10 27 15 16 10 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 21 11 16 10 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 20 16 16 16 18 10 16 21 12 + 3 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 2 6 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 12 11 15 14 12 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 20 24 27 + 20 26 24 15 9 27 24 27 12 16 12 16 23 3 24 10 27 + 16 12 16 23 27 20 18 16 14 23 21 24 18 27 15 24 20 + 20 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 16 + 23 20 12 12 12 24 12 27 12 16 23 3 24 23 24 23 14 + 16 23 23 23 12 20 24 28 12 28 16 23 16 18 27 20 7 + 27 27 24 14 15 10 14 21 21 24 15 10 21 27 11 16 12 + 25 14 15 14 12 24 12 25 15 24 10 12 16 21 14 15 24 + 11 23 23 27 15 0 10 20 15 12 6 21 23 12 24 23 10 + 27 16 14 12 27 5 12 3 15 25 15 16 15 12 11 28 24 + + 20 20 21 16 27 16 10 21 22 15 10 11 15 15 24 1 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 20 16 16 21 16 16 16 14 16 23 10 16 24 21 10 + 14 23 12 10 27 15 18 10 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 22 11 16 10 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 20 16 16 16 18 10 16 21 12 + 5 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 4 7 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 12 11 15 14 13 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 20 24 27 + 20 26 24 15 11 27 24 27 13 18 12 18 23 1 24 10 27 + 16 13 18 23 27 20 18 18 14 23 21 24 18 27 15 24 20 + 21 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 18 + 23 20 12 12 12 24 12 27 12 18 23 4 24 23 24 23 14 + 18 23 23 23 12 20 24 28 13 28 18 23 18 18 27 20 8 + 27 27 24 14 15 10 14 21 21 24 15 10 21 27 11 18 13 + 25 14 15 14 13 24 13 25 15 24 10 12 18 21 14 15 24 + 11 23 23 27 15 20 0 20 15 13 7 21 23 12 24 23 10 + 27 18 14 12 27 6 12 4 15 25 15 18 15 12 11 28 24 + + 20 20 21 16 27 16 10 21 21 15 10 11 15 15 24 3 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 20 16 16 20 16 16 16 14 16 23 10 16 24 20 10 + 14 23 12 10 27 15 16 10 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 21 11 16 10 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 20 16 16 16 18 10 16 21 12 + 3 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 2 6 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 12 11 15 14 12 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 20 24 27 + 20 26 24 15 9 27 24 27 12 16 12 16 23 3 24 10 27 + 16 12 16 23 27 20 18 16 14 23 21 24 18 27 15 24 20 + 20 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 16 + 23 20 12 12 12 24 12 27 12 16 23 3 24 23 24 23 14 + 16 23 23 23 12 20 24 28 12 28 16 23 16 18 27 20 7 + 27 27 24 14 15 10 14 21 21 24 15 10 21 27 11 16 12 + 25 14 15 14 12 24 12 25 15 24 10 12 16 21 14 15 24 + 11 23 23 27 15 20 10 0 15 12 6 21 23 12 24 23 10 + 27 16 14 12 27 5 12 3 15 25 15 16 15 12 11 28 24 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 0 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 0 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 20 20 21 16 27 16 10 21 21 15 10 11 15 15 24 3 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 20 16 16 20 16 16 16 14 16 23 10 16 24 20 10 + 14 23 12 10 27 15 16 10 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 21 11 16 10 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 20 16 16 16 18 10 16 21 12 + 3 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 2 6 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 12 11 15 14 12 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 20 24 27 + 20 26 24 15 9 27 24 27 12 16 12 16 23 3 24 10 27 + 16 12 16 23 27 20 18 16 14 23 21 24 18 27 15 24 20 + 20 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 16 + 23 20 12 12 12 24 12 27 12 16 23 3 24 23 24 23 14 + 16 23 23 23 12 20 24 28 12 28 16 23 16 18 27 20 7 + 27 27 24 14 15 10 14 21 21 24 15 10 21 27 11 16 12 + 25 14 15 14 12 24 12 25 15 24 10 12 16 21 14 15 24 + 11 23 23 27 15 20 10 20 15 12 0 21 23 12 24 23 10 + 27 16 14 12 27 5 12 3 15 25 15 16 15 12 11 28 24 + + 18 18 20 18 27 18 9 20 24 14 11 10 14 14 23 10 24 + 16 12 12 15 12 12 16 24 19 18 18 14 18 14 23 23 18 + 18 18 21 18 18 23 18 18 18 15 18 21 11 18 24 23 11 + 12 23 12 6 27 16 19 11 18 18 5 15 27 16 23 24 15 + 18 18 15 20 18 18 24 10 18 11 18 27 18 25 18 18 18 + 18 18 18 18 18 18 18 15 18 18 18 18 16 9 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 18 18 18 12 + 18 18 24 18 18 18 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 14 12 16 15 15 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 22 24 27 + 18 25 23 16 12 27 23 27 15 19 14 19 23 10 24 11 27 + 15 15 19 23 27 18 16 19 15 23 20 23 16 27 16 24 18 + 23 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 19 + 21 19 14 11 12 24 12 27 14 19 23 10 23 21 24 23 15 + 19 23 23 23 14 18 23 27 15 27 19 21 19 16 26 18 10 + 26 27 24 12 14 10 15 20 20 24 16 11 20 27 12 19 15 + 24 15 16 15 15 24 15 24 16 24 9 12 19 20 15 16 24 + 12 23 23 27 14 18 11 18 16 15 10 0 23 14 24 23 11 + 27 19 15 14 26 10 14 10 16 24 14 19 16 12 10 27 24 + + 20 20 18 30 12 30 25 18 20 23 26 24 23 23 15 25 15 + 29 24 24 28 23 27 29 10 20 30 30 28 30 23 15 14 30 + 30 30 20 30 30 20 30 30 30 28 30 16 26 30 15 20 26 + 23 14 24 25 15 29 27 26 30 30 25 28 12 29 14 10 28 + 30 30 23 18 30 30 20 24 30 25 30 15 30 4 30 30 30 + 30 30 30 30 30 20 30 28 20 30 30 30 21 25 30 18 24 + 25 29 21 24 21 24 23 14 30 30 30 30 30 30 30 30 24 + 30 30 11 30 30 30 30 20 15 25 25 11 24 29 24 15 20 + 0 15 15 15 23 12 12 29 24 27 29 28 27 20 29 29 20 + 18 18 20 15 12 15 12 12 28 15 11 12 12 15 20 15 15 + 20 10 12 29 25 15 12 15 27 23 28 28 15 25 11 26 12 + 23 28 27 15 15 20 21 30 28 15 18 15 21 15 29 12 20 + 20 20 16 15 12 28 24 23 15 20 15 23 15 0 29 23 24 + 16 20 28 24 27 12 24 15 24 28 14 25 12 16 12 14 23 + 30 15 15 14 28 20 12 12 28 12 28 16 24 21 11 20 25 + 11 12 15 23 23 25 28 18 18 15 29 26 18 15 27 23 27 + 10 28 29 28 27 15 26 10 29 12 25 27 24 18 28 29 15 + 27 15 15 15 23 20 26 20 29 27 25 18 0 28 15 14 26 + 15 28 28 28 11 25 28 25 29 10 23 28 29 24 24 12 12 + + 17 12 12 27 18 27 23 12 24 16 24 23 16 16 10 23 12 + 26 20 20 25 18 24 26 12 19 27 27 25 27 16 10 6 27 + 27 27 21 27 27 23 27 27 27 25 27 11 24 27 11 23 24 + 18 6 20 23 18 26 24 24 27 27 23 25 20 26 15 15 25 + 27 27 16 12 27 27 24 23 27 23 27 18 27 14 27 27 27 + 27 27 27 27 27 12 27 25 12 27 27 27 14 23 27 12 21 + 23 26 14 20 14 20 15 6 27 27 27 27 27 27 27 27 20 + 27 27 12 27 27 27 27 12 12 23 23 19 21 26 21 18 12 + 15 10 0 10 16 15 19 26 20 24 26 25 24 16 26 26 12 + 12 12 17 18 20 0 10 10 25 15 16 12 10 10 22 12 18 + 12 15 10 26 23 18 12 18 24 19 25 25 10 23 19 24 19 + 15 25 24 10 18 12 15 27 25 0 12 10 14 18 26 11 12 + 23 12 11 18 18 25 21 18 15 12 12 15 0 15 26 18 23 + 11 19 25 21 24 15 20 18 21 25 15 23 10 11 15 6 18 + 27 0 10 6 25 17 15 20 25 20 25 11 20 14 16 15 23 + 16 18 11 18 16 23 25 12 12 12 26 24 12 18 24 19 24 + 19 25 26 25 24 12 24 19 26 19 23 24 21 12 25 26 11 + 24 0 19 18 16 12 24 12 26 24 23 12 0 0 11 15 24 + 18 25 25 25 16 23 25 23 26 15 16 25 26 20 23 20 11 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 0 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 17 15 14 28 15 28 24 14 24 20 24 23 20 20 10 24 11 + 27 23 23 27 21 25 27 11 19 28 28 26 28 20 12 11 28 + 28 28 21 28 28 23 28 28 28 27 28 12 24 28 0 23 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 15 15 27 + 28 28 20 14 28 28 24 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 28 27 15 28 28 28 16 24 28 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 10 24 24 19 23 27 23 15 15 + 15 10 11 12 20 15 19 27 23 25 27 27 25 16 27 27 15 + 14 14 17 15 16 11 10 10 27 12 15 12 10 10 22 10 15 + 15 12 10 27 24 15 12 15 25 19 26 27 12 24 19 24 19 + 18 26 25 12 15 15 16 28 27 11 14 10 16 15 27 5 15 + 23 15 12 15 15 27 23 21 12 15 11 18 11 15 27 21 23 + 12 19 26 23 25 15 23 15 23 26 15 24 10 12 15 11 21 + 28 11 12 11 26 17 15 16 26 16 27 12 23 16 14 15 24 + 15 15 0 21 20 24 27 14 14 10 27 24 14 15 25 21 25 + 19 27 27 27 25 10 24 19 27 19 24 25 23 14 27 27 0 + 25 11 19 15 20 15 24 15 27 25 24 14 11 26 0 0 24 + 15 26 27 26 15 24 26 24 27 15 20 26 27 23 23 16 10 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 0 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 0 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 21 21 23 15 28 15 11 23 24 16 11 12 16 16 24 10 25 + 14 14 14 12 15 11 15 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 23 15 15 15 12 15 23 0 15 24 23 9 + 15 24 14 11 28 14 19 10 15 15 11 12 28 15 24 25 12 + 15 15 16 23 15 15 24 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 10 14 12 15 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 22 25 28 + 21 27 24 14 12 28 24 28 15 19 12 19 23 10 25 6 28 + 18 15 19 23 28 21 20 19 12 24 23 24 20 28 14 24 21 + 23 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 19 + 23 21 12 12 11 24 14 28 14 19 24 10 24 23 24 24 15 + 19 24 23 24 12 21 24 28 15 28 19 23 19 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 9 23 28 10 19 15 + 25 12 14 12 15 25 15 25 14 24 11 11 19 23 12 15 24 + 10 24 23 28 16 21 9 21 14 15 10 23 24 12 24 24 0 + 28 0 15 12 27 10 12 10 14 25 16 19 14 14 12 28 24 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 0 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 0 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 23 23 24 12 30 12 14 24 24 21 12 15 21 21 25 12 27 + 11 18 18 10 20 10 15 27 23 12 12 0 12 21 24 25 12 + 12 12 23 12 12 23 12 12 12 10 12 24 12 12 26 23 12 + 20 25 18 14 30 11 19 12 12 12 14 10 31 15 25 27 10 + 12 12 21 24 12 12 24 15 12 14 12 30 12 28 12 12 12 + 12 12 12 12 12 23 12 10 23 12 12 12 23 14 12 24 16 + 12 11 23 18 23 18 23 25 12 12 12 12 12 12 12 12 18 + 12 12 27 12 12 12 12 23 27 12 12 27 16 11 16 30 23 + 28 25 25 24 21 26 26 11 18 11 11 10 15 23 11 11 23 + 24 24 23 30 31 25 25 25 10 28 29 25 25 25 23 27 30 + 23 28 25 11 12 30 25 30 15 23 10 19 24 12 27 12 30 + 23 15 19 24 30 23 23 19 10 25 24 25 23 30 11 26 23 + 23 23 24 30 30 10 16 20 28 23 27 23 25 28 11 20 19 + 24 23 0 16 10 26 18 30 16 19 25 12 25 24 26 25 20 + 19 25 24 25 0 23 25 31 15 31 19 24 19 23 29 23 12 + 29 30 26 20 21 14 10 24 24 27 11 12 24 30 11 20 15 + 27 10 11 10 15 27 15 27 11 26 14 10 19 24 10 15 26 + 11 25 24 30 21 23 12 23 11 15 12 24 25 6 26 25 12 + 30 19 15 0 0 12 0 12 11 27 21 19 11 18 15 31 26 + + 21 21 23 15 28 15 11 23 24 16 11 12 16 16 24 10 25 + 14 14 14 12 15 11 15 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 23 15 15 15 12 15 23 0 15 24 23 9 + 15 24 14 11 28 14 19 10 15 15 11 12 28 15 24 25 12 + 15 15 16 23 15 15 24 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 10 14 12 15 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 22 25 28 + 21 27 24 14 12 28 24 28 15 19 12 19 23 10 25 6 28 + 18 15 19 23 28 21 20 19 12 24 23 24 20 28 14 24 21 + 23 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 19 + 23 21 12 12 11 24 14 28 14 19 24 10 24 23 24 24 15 + 19 24 23 24 12 21 24 28 15 28 19 23 19 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 9 23 28 10 19 15 + 25 12 14 12 15 25 15 25 14 24 11 11 19 23 12 15 24 + 10 24 23 28 16 21 9 21 14 15 10 23 24 12 24 24 0 + 28 19 15 12 27 0 12 10 14 25 16 19 14 14 12 28 24 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 0 16 10 29 23 18 10 23 20 33 28 + + 23 23 24 12 30 12 14 24 24 21 12 15 21 21 25 12 27 + 11 18 18 10 20 10 15 27 23 12 12 0 12 21 24 25 12 + 12 12 23 12 12 23 12 12 12 10 12 24 12 12 26 23 12 + 20 25 18 14 30 11 19 12 12 12 14 10 31 15 25 27 10 + 12 12 21 24 12 12 24 15 12 14 12 30 12 28 12 12 12 + 12 12 12 12 12 23 12 10 23 12 12 12 23 14 12 24 16 + 12 11 23 18 23 18 23 25 12 12 12 12 12 12 12 12 18 + 12 12 27 12 12 12 12 23 27 12 12 27 16 11 16 30 23 + 28 25 25 24 21 26 26 11 18 11 11 10 15 23 11 11 23 + 24 24 23 30 31 25 25 25 10 28 29 25 25 25 23 27 30 + 23 28 25 11 12 30 25 30 15 23 10 19 24 12 27 12 30 + 23 15 19 24 30 23 23 19 10 25 24 25 23 30 11 26 23 + 23 23 24 30 30 10 16 20 28 23 27 23 25 28 11 20 19 + 24 23 0 16 10 26 18 30 16 19 25 12 25 24 26 25 20 + 19 25 24 25 0 23 25 31 15 31 19 24 19 23 29 23 12 + 29 30 26 20 21 14 10 24 24 27 11 12 24 30 11 20 15 + 27 10 11 10 15 27 15 27 11 26 14 10 19 24 10 15 26 + 11 25 24 30 21 23 12 23 11 15 12 24 25 6 26 25 12 + 30 19 15 0 29 12 0 0 11 27 21 19 11 18 15 31 26 + + 24 24 24 14 31 14 15 24 24 23 12 16 23 23 26 15 28 + 15 20 20 15 21 11 10 28 24 14 14 15 14 23 25 25 14 + 14 14 24 14 14 24 14 14 14 15 14 24 15 14 27 24 12 + 21 25 20 15 31 15 12 12 14 14 15 15 31 10 25 28 9 + 14 14 23 24 14 14 24 16 14 15 14 31 14 28 14 14 14 + 14 14 14 14 14 24 14 15 24 14 14 14 23 15 14 24 18 + 14 15 23 20 23 20 23 25 14 14 14 14 14 14 14 14 20 + 14 14 27 14 14 14 14 24 27 14 14 27 18 15 18 31 24 + 28 26 25 25 23 27 27 15 20 15 15 15 12 24 15 10 24 + 24 24 24 31 31 25 26 26 15 29 30 26 26 26 24 27 31 + 24 29 26 15 14 31 26 31 11 23 10 4 25 15 27 12 31 + 23 10 11 25 31 24 23 11 15 25 24 26 23 31 15 27 24 + 24 24 24 31 31 15 18 21 29 24 28 23 25 28 15 21 16 + 24 24 15 18 15 27 20 31 18 10 25 14 26 24 27 25 21 + 11 25 25 25 15 24 26 31 10 31 4 24 20 23 30 24 14 + 30 31 27 21 23 15 15 24 24 27 15 12 24 31 12 21 11 + 28 4 10 15 12 27 12 28 15 27 15 15 18 24 15 10 27 + 12 25 25 31 23 24 12 24 15 12 14 24 25 10 27 25 15 + 31 10 0 15 30 14 15 14 0 28 23 10 15 20 16 31 27 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 0 23 19 0 21 18 31 27 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 0 18 10 23 20 33 28 + + 17 12 12 23 24 23 14 12 24 5 16 12 6 6 18 15 23 + 23 11 11 23 10 20 23 23 19 23 23 21 23 10 15 16 23 + 23 23 21 23 23 23 23 23 23 23 23 14 16 23 20 23 16 + 10 16 11 14 24 23 19 16 23 23 14 23 24 23 16 23 23 + 23 23 15 12 23 23 24 12 23 14 23 24 23 23 23 23 23 + 23 23 23 23 23 12 23 23 12 23 23 23 11 14 23 12 12 + 15 23 11 11 11 11 10 16 23 23 23 23 23 23 23 23 11 + 23 23 21 23 23 23 23 12 21 15 15 21 12 23 12 24 12 + 23 18 16 15 10 20 20 23 14 18 23 23 18 16 23 23 12 + 12 12 17 24 24 16 18 18 23 23 24 18 18 18 22 21 24 + 12 23 18 23 15 24 18 24 20 19 21 23 15 15 21 16 24 + 10 21 20 15 24 12 15 23 23 16 12 18 11 24 23 20 12 + 23 12 14 24 24 23 12 10 23 12 23 10 16 23 23 10 19 + 14 19 21 12 20 20 11 24 14 21 16 15 18 14 20 16 15 + 23 16 15 16 21 17 18 24 21 24 23 14 19 11 24 15 15 + 24 24 20 10 5 14 23 12 12 21 23 16 12 24 18 19 20 + 23 23 23 23 18 21 16 23 23 20 14 20 19 12 23 23 20 + 18 16 19 24 14 12 16 12 23 18 15 12 16 21 20 16 16 + 24 21 23 21 24 15 21 15 23 23 0 0 23 11 12 24 20 + + 23 23 23 14 28 14 12 23 23 18 10 15 18 18 24 15 26 + 15 15 15 15 16 10 12 26 23 14 14 15 14 18 24 24 14 + 14 14 23 14 14 23 14 14 14 15 14 23 15 14 25 23 10 + 16 24 15 12 28 15 4 10 14 14 12 15 29 12 24 26 12 + 14 14 18 23 14 14 23 12 14 12 14 28 14 27 14 14 14 + 14 14 14 14 14 23 14 15 23 14 14 14 21 12 14 23 14 + 11 15 21 15 21 15 20 24 14 14 14 14 14 14 14 14 15 + 14 14 25 14 14 14 14 23 25 11 11 25 14 15 14 28 23 + 27 24 24 24 18 25 25 15 15 15 15 15 0 23 15 12 23 + 23 23 23 28 29 24 24 24 15 27 28 24 24 24 23 25 28 + 23 27 24 15 11 28 24 28 10 20 11 12 24 15 25 10 28 + 20 11 10 24 28 23 21 14 15 24 23 24 21 28 15 25 23 + 23 23 23 28 28 15 14 16 27 23 26 20 24 27 15 16 12 + 23 23 15 14 15 25 15 28 14 11 24 11 24 23 25 24 16 + 14 24 24 24 15 23 24 29 11 29 12 23 15 21 28 23 11 + 28 28 25 16 18 12 15 23 23 25 15 10 23 28 4 16 10 + 26 12 12 15 0 25 10 26 15 25 12 15 14 23 15 12 25 + 9 24 24 28 18 23 10 23 15 0 11 23 24 11 25 24 15 + 28 11 12 15 28 11 15 11 15 26 18 11 0 15 15 29 25 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 0 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 0 33 28 + + 17 14 15 23 25 23 12 15 24 11 14 11 11 11 21 12 23 + 21 6 11 20 10 16 21 23 19 23 23 18 23 11 18 20 23 + 23 23 21 23 23 23 23 23 23 20 23 16 14 23 23 23 14 + 10 20 8 12 25 21 19 14 23 23 12 20 25 21 20 23 20 + 23 23 15 15 23 23 24 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 8 12 5 12 20 23 23 23 23 23 23 23 23 11 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 14 15 21 20 15 16 21 21 14 + 15 15 17 25 25 20 21 21 20 24 24 21 21 21 22 23 25 + 14 24 21 21 12 25 21 25 16 19 18 20 18 12 23 14 25 + 12 18 19 18 25 14 15 23 20 20 15 21 12 25 21 23 14 + 23 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 19 + 16 19 18 10 16 23 11 25 14 19 20 12 21 16 23 20 15 + 23 20 18 20 18 17 21 25 18 25 20 16 19 12 24 15 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 19 16 + 23 20 21 20 15 23 15 23 21 23 12 16 19 15 20 21 23 + 15 20 19 25 14 14 14 14 21 15 12 15 20 18 23 20 14 + 25 19 20 18 24 12 18 12 21 23 11 19 21 0 11 0 23 + + 17 16 18 20 26 20 10 18 24 12 12 0 12 12 23 11 24 + 18 11 11 16 12 14 18 24 19 20 20 15 20 12 21 23 20 + 20 20 21 20 20 23 20 20 20 16 20 20 12 20 23 23 12 + 12 23 11 10 26 18 19 12 20 20 10 16 27 18 23 24 16 + 20 20 15 18 20 20 24 8 20 11 20 26 20 24 20 20 20 + 20 20 20 20 20 16 20 16 16 20 20 20 15 10 20 18 10 + 11 18 15 11 15 11 14 23 20 20 20 20 20 20 20 20 11 + 20 20 24 20 20 20 20 16 24 11 11 24 10 18 10 26 16 + 24 23 23 21 12 23 23 18 14 12 18 16 15 16 18 18 16 + 18 18 17 26 27 23 23 23 16 25 25 23 23 23 22 24 26 + 16 25 23 18 12 26 23 26 15 19 15 19 21 11 24 12 26 + 14 15 19 21 26 16 15 20 16 23 18 23 15 26 18 23 16 + 23 16 20 26 26 16 10 12 25 16 24 14 23 24 18 12 19 + 20 19 15 10 14 23 11 26 14 19 23 11 23 20 23 23 15 + 20 23 21 23 15 17 23 27 15 27 19 20 19 15 25 16 11 + 25 26 23 12 12 10 16 18 18 24 18 12 18 26 12 19 15 + 24 16 18 16 15 24 15 24 18 23 10 14 19 18 16 18 23 + 12 23 21 26 14 16 12 16 18 15 11 18 23 15 23 23 12 + 26 19 16 15 25 11 15 11 18 24 12 19 18 11 0 27 0 +EOF diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ATSP-instances/ry48p.atsp b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ATSP-instances/ry48p.atsp new file mode 100644 index 0000000000000000000000000000000000000000..b02a98c289107d68e881a985a4cf2c8a1c6ff4e2 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ATSP-instances/ry48p.atsp @@ -0,0 +1,200 @@ +NAME: ry48p +TYPE: ATSP +COMMENT: Asymmetric TSP (Fischetti) +DIMENSION: 48 +EDGE_WEIGHT_TYPE: EXPLICIT +EDGE_WEIGHT_FORMAT: FULL_MATRIX +EDGE_WEIGHT_SECTION + 9999999 1593 569 2056 1327 1009 947 301 234 1800 625 700 754 790 529 + 395 1385 856 1179 821 1085 385 730 1808 915 2076 1120 1002 1297 1026 + 592 1448 694 743 2254 880 1137 330 1121 449 786 1594 1264 755 2354 + 593 849 1216 + 1619 9999999 1191 656 595 2304 2128 1797 1674 834 1348 1620 1183 1050 1629 + 1339 2444 2039 2350 1646 1334 1322 1167 1079 1182 624 2307 2171 478 2272 + 1923 1192 1837 982 1060 2132 2312 1884 1047 1513 1051 550 2287 2125 1123 + 1765 1388 718 + 528 1297 9999999 1682 809 1309 1170 624 506 1445 526 488 561 402 610 + 429 1510 1072 1419 882 801 250 401 1351 485 1579 1436 1194 898 1194 + 816 1054 728 471 1828 1000 1276 837 898 465 459 1183 1314 989 1876 + 708 620 968 + 2097 723 1781 9999999 996 2674 2595 2360 2236 501 1846 2061 1616 1580 2108 + 1884 2678 2590 2635 2068 1584 1847 1638 930 1328 187 2635 2582 948 2669 + 2421 1197 2183 1506 620 2438 2782 2337 1328 1959 1513 680 2603 2497 648 + 2142 1827 1058 + 1310 680 780 1023 9999999 1690 1754 1424 1279 787 900 1153 759 612 1201 + 1098 1918 1682 1858 1148 876 975 761 759 639 820 1759 1651 417 1694 + 1459 718 1292 566 1005 1632 1870 1540 493 1131 954 496 1760 1629 1144 + 1306 886 295 + 1156 2218 1336 2687 1745 9999999 358 1020 964 2253 998 774 1089 1369 692 + 1349 364 339 249 801 1187 1286 1135 2157 1442 2473 276 303 1881 258 + 681 1588 708 1488 2624 391 254 704 1508 879 1636 2165 300 429 2588 + 668 1014 1735 + 827 2103 1085 2504 1692 258 9999999 972 759 2236 834 724 970 1102 604 + 1227 535 54 493 551 1165 1066 974 1908 1239 2379 508 124 1677 311 + 386 1483 590 1382 2444 204 391 614 1437 820 1410 2049 471 245 2595 + 386 858 1615 + 190 1684 698 2274 1395 1116 792 9999999 387 2016 797 691 984 1055 677 + 445 1348 868 1148 936 1246 404 816 1965 1191 2206 1272 1050 1323 1057 + 505 1607 839 890 2379 972 1098 327 1471 545 973 1756 1200 786 2415 + 616 920 1552 + 217 1673 526 2144 1366 1009 796 413 9999999 1941 696 570 899 793 452 + 515 1094 619 1003 758 937 524 615 1760 1020 2103 1133 749 1323 900 + 465 1379 477 762 2222 632 1020 317 1178 247 908 1609 1140 473 2205 + 392 824 1237 + 1892 856 1591 636 780 2323 2205 2133 2014 9999999 1544 1649 1258 1170 1709 + 1716 2377 2141 2443 1629 1320 1686 1395 378 1015 383 2367 2191 833 2283 + 2062 800 1897 1257 448 2138 2287 2109 803 1810 1520 415 2270 2119 478 + 1932 1486 706 + 660 1316 535 1817 893 1084 780 764 592 1407 9999999 323 304 464 344 + 787 1129 839 1180 507 450 669 189 1400 416 1760 992 905 963 975 + 745 890 503 643 1901 829 1118 775 749 403 986 1343 1039 813 1921 + 564 418 853 + 673 1626 580 1892 1168 829 719 745 438 1582 366 9999999 537 648 217 + 787 1031 541 896 370 568 609 434 1536 589 1928 807 792 1282 790 + 677 930 214 705 1993 690 926 561 936 442 987 1422 772 547 1895 + 410 343 1015 + 786 1289 570 1603 682 1203 1059 956 885 1353 297 547 9999999 328 632 + 937 1377 1023 1316 495 332 849 227 1130 254 1474 1322 1106 933 1097 + 955 530 617 535 1634 949 1254 884 521 702 891 1051 1127 1096 1568 + 844 326 758 + 776 1066 499 1584 536 1245 1106 1016 913 1157 331 690 236 9999999 746 + 720 1414 1137 1420 747 457 711 234 1016 211 1370 1479 1144 617 1341 + 1115 761 697 443 1549 1172 1452 939 461 555 768 949 1319 1135 1589 + 791 555 566 + 434 1750 629 2111 1152 812 635 592 499 1693 299 220 686 769 9999999 + 837 1005 609 839 473 664 664 440 1510 773 2009 952 567 1243 788 + 531 1137 228 918 2134 466 902 500 1012 333 916 1638 889 435 2012 + 373 519 1160 + 430 1369 449 1956 1178 1364 1169 534 490 1736 747 829 850 721 832 + 9999999 1524 1019 1405 1055 1018 221 649 1586 854 1849 1420 1180 1082 1460 + 920 1405 886 659 2137 1144 1366 685 1164 621 512 1489 1507 1040 2047 + 848 988 1247 + 1295 2527 1426 2755 1976 340 497 1247 1189 2385 1187 918 1228 1425 1065 + 1531 9999999 659 233 866 1323 1565 1347 2089 1544 2637 126 545 2079 346 + 772 1567 751 1683 2693 613 274 1026 1535 1207 1826 2313 171 795 2715 + 822 1033 1946 + 851 2101 1064 2399 1615 452 196 834 668 2196 775 586 1078 1175 512 + 1028 645 9999999 513 509 1136 909 1009 1929 1194 2379 419 165 1787 323 + 377 1412 467 1184 2407 118 370 608 1422 609 1362 2042 507 269 2516 + 311 838 1685 + 1210 2372 1385 2679 1919 125 516 1170 1001 2442 1102 873 1280 1418 955 + 1398 269 524 9999999 759 1146 1399 1311 2170 1428 2617 79 287 2039 310 + 680 1564 664 1553 2738 407 99 894 1569 1003 1787 2101 329 655 2629 + 808 934 1871 + 723 1779 819 2056 1170 726 592 967 815 1664 406 377 543 649 370 + 1104 750 631 866 9999999 499 841 652 1371 782 1895 694 658 1243 682 + 724 937 213 1047 2019 544 735 791 814 500 1189 1511 799 550 1948 + 438 262 1047 + 1005 1475 840 1600 715 1188 1122 1256 970 1208 508 618 304 615 716 + 999 1175 1107 1206 542 9999999 984 461 1106 460 1480 1125 1128 1115 1054 + 1132 571 755 708 1546 1033 1198 987 545 798 1228 1161 1075 1037 1506 + 876 346 791 + 404 1421 317 1918 1059 1275 1025 420 534 1663 616 660 745 742 683 + 328 1491 904 1452 882 921 9999999 559 1624 718 1903 1280 1053 978 1282 + 710 1140 809 557 2124 984 1278 702 1022 491 558 1414 1335 949 2111 + 695 791 1189 + 546 1189 345 1638 718 1246 1034 781 682 1314 251 504 225 264 593 + 685 1412 863 1312 570 521 614 9999999 1221 414 1559 1246 970 860 1134 + 868 724 662 436 1807 986 1162 706 620 469 665 1181 1090 930 1741 + 586 412 770 + 1695 962 1414 866 621 1982 1923 1990 1749 352 1256 1480 1015 1106 1502 + 1646 2199 1954 2105 1419 1063 1542 1227 9999999 875 798 2153 1991 950 1929 + 1892 683 1620 1115 725 1886 2083 1857 766 1520 1554 459 2052 2040 646 + 1834 1330 537 + 952 1029 537 1441 451 1411 1250 1051 833 1110 524 581 184 228 691 + 923 1568 1237 1419 765 423 873 429 1023 9999999 1310 1350 1283 719 1235 + 1158 538 901 518 1452 1060 1373 1166 461 645 851 966 1332 1218 1365 + 945 553 568 + 2061 722 1713 298 813 2633 2414 2254 2162 487 1606 1867 1419 1350 1900 + 1728 2730 2455 2548 1965 1542 1732 1654 755 1299 9999999 2571 2564 831 2422 + 2357 1210 2057 1254 464 2359 2669 2163 1071 1856 1577 497 2540 2371 714 + 2232 1643 952 + 1173 2364 1322 2759 1912 246 530 1243 1011 2335 1125 907 1166 1454 860 + 1547 298 463 75 661 1197 1362 1227 2108 1302 2550 9999999 381 2018 248 + 661 1602 780 1547 2606 420 191 880 1573 1000 1781 2079 174 619 2648 + 753 963 1735 + 872 2158 1106 2574 1739 273 278 943 833 2234 799 677 1120 1245 559 + 1161 484 163 337 574 1169 1163 970 2001 1196 2375 300 9999999 1849 265 + 508 1383 470 1421 2587 298 224 586 1380 880 1471 2064 358 421 2425 + 553 898 1601 + 1284 503 875 979 375 1874 1736 1429 1243 911 1052 1170 836 658 1334 + 1037 1998 1731 2002 1427 1041 1120 857 969 674 971 1966 1800 9999999 1785 + 1630 936 1323 562 1243 1670 2000 1464 791 1188 747 482 2009 1704 1232 + 1380 1060 565 + 1099 2354 1305 2528 1734 138 418 1078 934 2189 1030 752 1046 1218 717 + 1360 411 417 261 556 1122 1145 1085 1986 1225 2534 255 247 1956 9999999 + 596 1445 581 1540 2501 244 146 896 1491 946 1677 2102 263 483 2439 + 674 965 1749 + 672 1921 948 2388 1537 594 394 495 425 2053 849 589 973 1137 388 + 847 886 350 613 693 1076 778 791 1943 1066 2367 690 390 1561 612 + 9999999 1467 530 1124 2558 369 690 287 1441 455 1363 1989 709 283 2489 + 373 800 1504 + 1387 1277 1020 1219 545 1467 1455 1553 1281 883 765 950 675 770 1139 + 1245 1543 1437 1541 853 570 1325 824 534 657 1287 1625 1490 863 1468 + 1542 9999999 1015 891 1183 1448 1554 1406 266 1142 1162 765 1435 1465 1175 + 1278 700 632 + 747 1668 719 2159 1183 633 500 722 525 1896 400 251 636 742 322 + 812 931 385 692 236 727 855 678 1643 847 1988 774 490 1324 685 + 411 1093 9999999 1028 2141 469 655 532 1049 427 1228 1649 725 424 2064 + 190 462 1251 + 702 1023 383 1383 644 1420 1272 914 824 1280 575 723 604 352 820 + 695 1665 1366 1642 867 806 648 542 1173 567 1316 1504 1408 601 1556 + 1093 826 937 9999999 1521 1187 1466 964 764 617 399 1000 1492 1147 1647 + 980 701 554 + 2318 1080 1876 516 1131 2587 2633 2328 2298 516 1836 2047 1595 1561 2094 + 2137 2690 2509 2644 1942 1545 1967 1716 700 1385 594 2612 2552 1137 2467 + 2474 1260 2162 1513 9999999 2468 2699 2387 1201 2007 1886 661 2545 2527 285 + 2358 1796 954 + 789 2177 966 2481 1629 411 179 930 754 2061 841 687 957 1116 621 + 1236 636 263 374 506 985 1055 927 1804 1104 2429 390 232 1693 296 + 499 1359 448 1361 2370 9999999 353 488 1394 800 1428 1896 532 217 2479 + 423 825 1536 + 1154 2403 1241 2712 1817 176 340 1199 1014 2320 1146 874 1232 1392 791 + 1398 350 419 151 739 1116 1282 1204 2209 1436 2570 289 240 1959 237 + 591 1666 726 1490 2732 312 9999999 855 1610 1063 1665 2126 207 600 2664 + 754 1054 1852 + 514 1895 655 2265 1531 739 492 329 290 2007 671 615 962 939 389 + 708 1052 549 850 682 1173 592 708 1878 1139 2305 1015 636 1528 843 + 313 1391 469 1078 2343 529 887 9999999 1286 361 1114 1923 979 340 2437 + 474 928 1576 + 1232 1141 943 1222 534 1485 1372 1439 1153 879 678 862 390 611 949 + 1157 1610 1385 1532 829 382 1057 770 734 483 1183 1580 1504 754 1350 + 1357 255 1001 641 1214 1312 1653 1420 9999999 1030 1168 709 1451 1329 1247 + 1090 653 364 + 262 1623 397 1915 1050 898 682 573 237 1775 342 439 636 698 196 + 638 1092 683 1125 578 695 364 487 1644 667 1815 1011 842 1238 1022 + 543 1179 456 771 2058 795 910 449 1058 9999999 812 1411 1112 610 2066 + 417 574 1033 + 798 1070 476 1489 790 1729 1582 940 954 1562 957 922 957 695 1068 + 567 1847 1458 1743 1210 1096 627 846 1502 838 1554 1835 1462 709 1766 + 1195 1150 1063 496 1727 1452 1803 1194 997 833 9999999 1159 1857 1385 1819 + 1098 1074 907 + 1536 598 1201 631 449 2195 2058 1776 1767 494 1261 1519 1138 900 1547 + 1459 2231 1924 2156 1470 993 1388 1175 407 955 569 2225 2090 501 2123 + 2002 841 1592 988 699 1868 2137 1899 658 1530 1127 9999999 2060 1916 745 + 1667 1272 510 + 1176 2389 1379 2717 1694 332 408 1260 1022 2321 1004 879 1079 1384 814 + 1588 250 496 217 685 1100 1308 1175 1985 1293 2589 236 498 1912 170 + 709 1428 781 1574 2471 530 212 851 1544 1096 1675 2133 9999999 708 2454 + 706 907 1672 + 619 2085 990 2459 1541 520 280 793 507 2204 821 644 1092 1176 420 + 948 636 231 605 629 1046 945 831 1990 1162 2387 600 416 1766 494 + 197 1483 420 1173 2410 250 615 445 1441 539 1294 1902 590 9999999 2434 + 423 757 1531 + 2281 1127 1889 727 1131 2498 2445 2443 2350 594 1874 2030 1591 1659 2192 + 2056 2593 2501 2532 1979 1553 2056 1761 577 1529 595 2553 2613 1292 2555 + 2474 1123 2106 1632 324 2448 2712 2465 1183 2151 1793 795 2542 2526 9999999 + 2196 1783 1001 + 584 1919 727 2331 1424 610 491 761 514 1839 455 427 733 833 282 + 933 769 376 712 433 886 636 694 1782 964 2210 748 583 1400 675 + 375 1234 152 1078 2279 377 665 332 1160 485 1090 1641 631 415 2342 + 9999999 645 1281 + 856 1456 670 1757 900 860 842 1110 831 1365 324 480 335 625 525 + 981 1008 896 1082 250 274 802 470 1140 486 1609 1062 832 1051 937 + 914 615 426 857 1856 786 1087 955 560 646 1048 1351 1035 809 1752 + 679 9999999 811 + 1209 724 957 1012 248 1750 1558 1373 1393 683 957 1018 588 633 1190 + 1169 1840 1656 1912 1112 811 1188 873 590 428 984 1759 1682 509 1743 + 1590 480 1202 703 1134 1594 1913 1515 346 1227 968 537 1714 1616 1145 + 1371 902 9999999 +EOF diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/DNAFA-instances/pbm.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/DNAFA-instances/pbm.txt new file mode 100644 index 0000000000000000000000000000000000000000..38c5037087b666772205bd1b5b3df10869fdf485 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/DNAFA-instances/pbm.txt @@ -0,0 +1,2 @@ +30 +/Mallba/ProblemInstances/DNAFA-instances/x60189_4.dat diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/DNAFA-instances/score.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/DNAFA-instances/score.txt new file mode 100644 index 0000000000000000000000000000000000000000..ff26d92ffee9db43bb3000c7413d23c456eb2822 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/DNAFA-instances/score.txt @@ -0,0 +1,39 @@ + 0 1 0 304 1 1 1 0 7 -163 247 1 2 1 1 0 0 2 0 1 1 1 2 1 1 107 0 1 3 1 1 0 1 286 1 3 0 1 1 + 1 0 1 1 -3 3 -1 331 -302 2 5 0 1 0 0 -1 -2 -2 2 281 0 -413 1 0 168 -2 2 0 -3 39 412 2 155 1 4 247 274 0 53 + 0 1 0 -2 225 0 2 1 0 -1 1 178 1 2 -2 -1 -2 -149 -3 -1 -2 2 1 366 -2 4 2 -2 -7 -2 -3 -363 -2 -2 -327 -1 -1 -353 -3 + 304 1 -2 0 -1 -27 -1 0 -1 -160 327 -3 43 -1 1 4 1 2 1 -1 1 -4 2 1 1 200 -1 1 1 1 1 2 1 283 -1 3 3 1 1 + 1 -3 225 -1 0 -2 -3 -3 -2 -1 0 1 0 -1 1 -1 -1 -279 -2 -2 2 0 -106 104 -2 1 2 -2 2 -1 -1 -252 0 -1 -65 0 -1 -250 -1 + 1 3 0 -27 -2 0 1 0 -2 -1 -14 -1 -346 1 -1 6 -88 -1 -241 -2 -1 1 0 1 -2 -276 1 -2 2 -2 -2 1 1 -1 -3 -1 0 3 3 + 1 -1 2 -1 -3 1 0 0 1 -1 -3 -1 2 -6 -414 0 -1 -2 -1 1 -301 2 99 1 1 1 271 6 1 -1 -1 -2 1 -1 1 -3 -2 -1 -1 + 0 331 1 0 -3 0 0 0 -302 0 1 0 1 0 0 1 2 2 3 185 0 -317 1 0 72 -4 2 0 0 2 316 2 155 0 0 247 178 0 3 + 7 -302 0 -1 -2 -2 1 -302 0 -26 2 -1 2 -4 -1 0 -1 -2 -1 -156 -1 288 -2 1 -43 1 1 -2 3 -1 -287 1 -306 -1 1 -377 -149 -1 -1 + -163 2 -1 -160 -1 -1 -1 0 -26 0 -103 2 1 -1 2 1 0 -1 0 -2 1 -1 -1 1 1 0 0 1 1 2 2 1 76 -289 -2 5 -2 2 2 + 247 5 1 327 0 -14 -3 1 2 -103 0 1 30 1 1 1 1 0 -2 1 2 0 1 0 -4 187 2 0 0 0 0 0 0 226 1 0 1 2 5 + 1 0 178 -3 1 -1 -1 0 -1 2 1 0 1 0 -2 -1 1 1 1 2 0 1 2 271 0 1 -1 -4 -309 161 1 -54 0 1 -316 -1 2 -44 23 + 2 1 1 43 0 -346 2 1 2 1 30 1 0 1 1 1 150 0 303 1 1 0 1 0 0 292 1 0 0 0 0 0 0 -2 1 0 1 1 0 + 1 0 2 -1 -1 1 -6 0 -4 -1 1 0 1 0 6 260 -251 2 -123 0 6 2 -1 0 0 1 -2 -300 0 2 -1 -2 0 -1 0 -3 -2 0 -1 + 1 0 -2 1 1 -1 -414 0 -1 2 1 -2 1 6 0 -1 1 1 3 2 301 -2 -79 0 0 1 -251 -6 0 1 1 2 0 1 2 3 2 0 1 + 0 -1 -1 4 -1 6 0 1 0 1 1 -1 1 260 -1 0 -306 2 -178 1 -2 -1 -1 0 0 -4 -2 -100 0 2 3 -2 0 0 1 1 1 -3 3 + 0 -2 -2 1 -1 -88 -1 2 -1 0 1 1 150 -251 1 -306 0 2 339 -1 1 -1 -1 1 1 18 -2 91 1 2 3 -2 1 1 -1 1 1 1 3 + 2 -2 -149 2 -279 -1 -2 2 -2 -1 0 1 0 2 1 2 2 0 -1 -1 1 -1 252 -28 1 2 115 3 1 1 1 176 1 2 -1 1 -1 174 1 + 0 2 -3 1 -2 -241 -1 3 -1 0 -2 1 303 -123 3 -178 339 -1 0 -1 1 -1 -1 1 1 171 0 1 1 2 2 1 1 1 -2 2 1 2 2 + 1 281 -1 -1 -2 -2 1 185 -156 -2 1 2 1 0 2 1 -1 -1 -1 0 0 -312 -1 0 324 1 1 -2 2 214 313 1 9 -1 -3 101 310 3 228 + 1 0 -2 1 2 -1 -301 0 -1 1 2 0 1 6 301 -2 1 1 1 0 0 -2 1 0 0 1 -138 -6 0 1 1 3 0 1 0 3 2 0 1 + 1 -413 2 -4 0 1 2 -317 288 -1 0 1 0 2 -2 -1 -1 -1 -1 -312 -2 0 1 -2 -199 1 1 -2 0 -70 -443 -2 -141 -2 3 -233 -305 1 -84 + 2 1 1 2 -106 0 99 1 -2 -1 1 2 1 -1 -79 -1 -1 252 -1 -1 1 1 0 -2 0 2 228 0 -2 0 0 3 -2 2 -1 2 -1 1 0 + 1 0 366 1 104 1 1 0 1 1 0 271 0 0 0 0 1 -28 1 0 0 -2 -2 0 0 1 -3 0 -100 1 1 -242 0 3 -420 0 2 -232 1 + 1 168 -2 1 -2 -2 1 72 -43 1 -4 0 0 0 0 0 1 1 1 324 0 -199 0 0 0 1 -3 -2 2 195 200 2 0 1 -3 0 204 3 209 + 107 -2 4 200 1 -276 1 -4 1 0 187 1 292 1 1 -4 18 2 171 1 1 1 2 1 1 0 0 1 -3 -2 -2 0 1 86 2 3 0 -2 -2 + 0 2 2 -1 2 1 271 2 1 0 2 -1 1 -2 -251 -2 -2 115 0 1 -138 1 228 -3 -3 0 0 1 1 -1 -1 -1 -3 -1 1 -2 -1 -1 -1 + 1 0 -2 1 -2 -2 6 0 -2 1 0 -4 0 -300 -6 -100 91 3 1 -2 -6 -2 0 0 -2 1 1 0 2 1 1 2 0 1 0 3 2 0 1 + 3 -3 -7 1 2 2 1 0 3 1 0 -309 0 0 0 0 1 1 1 2 0 0 -2 -100 2 -3 1 2 0 -141 1 1 0 -3 145 0 0 -3 -3 + 1 39 -2 1 -1 -2 -1 2 -1 2 0 161 0 2 1 2 2 1 2 214 1 -70 0 1 195 -2 -1 1 -141 0 71 -1 1 1 -1 1 75 1 291 + 1 412 -3 1 -1 -2 -1 316 -287 2 0 1 0 -1 1 3 3 1 2 313 1 -443 0 1 200 -2 -1 1 1 71 0 -1 140 1 -2 232 306 2 85 + 0 2 -363 2 -252 1 -2 2 1 1 0 -54 0 -2 2 -2 -2 176 1 1 3 -2 3 -242 2 0 -1 2 1 -1 -1 0 2 2 203 -1 1 378 -1 + 1 155 -2 1 0 1 1 155 -306 76 0 0 0 0 0 0 1 1 1 9 0 -141 -2 0 0 1 -3 0 0 1 140 2 0 3 0 285 2 0 1 + 286 1 -2 283 -1 -1 -1 0 -1 -289 226 1 -2 -1 1 0 1 2 1 -1 1 -2 2 3 1 86 -1 1 -3 1 1 2 3 0 -1 3 2 1 1 + 1 4 -327 -1 -65 -3 1 0 1 -2 1 -316 1 0 2 1 -1 -1 -2 -3 0 3 -1 -420 -3 2 1 0 145 -1 -2 203 0 -1 0 1 -2 193 4 + 3 247 -1 3 0 -1 -3 247 -377 5 0 -1 0 -3 3 1 1 1 2 101 3 -233 2 0 0 3 -2 3 0 1 232 -1 285 3 1 0 94 -2 1 + 0 274 -1 3 -1 0 -2 178 -149 -2 1 2 1 -2 2 1 1 -1 1 310 2 -305 -1 2 204 0 -1 2 0 75 306 1 2 2 -2 94 0 -1 89 + 1 0 -353 1 -250 3 -1 0 -1 2 2 -44 1 0 0 -3 1 174 2 3 0 1 1 -232 3 -2 -1 0 -3 1 2 378 0 1 193 -2 -1 0 2 + 1 53 -3 1 -1 3 -1 3 -1 2 5 23 0 -1 1 3 3 1 2 228 1 -84 0 1 209 -2 -1 1 -3 291 85 -1 1 1 4 1 89 2 0 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/DNAFA-instances/x60189_4.dat b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/DNAFA-instances/x60189_4.dat new file mode 100644 index 0000000000000000000000000000000000000000..2420540d8e2ec36ca87aa056d31adcdf8a1d7feb --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/DNAFA-instances/x60189_4.dat @@ -0,0 +1,78 @@ +>frag0000 +caccatctcaggcctggagccagaccataaatacaagatgaacctgtacggcttccacggtggccagcgcgtgggccccatctctgtcattggggtgacgggtgagtggatgatggcagccccagggtgggagccgtgggagggtcaccctcttgctctttggtgatgactggtggggaatgggccaggggtccggtcagcaccacagacctgcttgtggctggggctccccttggccttcctctgaggctgacccctggctcctcctgagcagggaggggccgtcaggagctctgctgtgctggtg +>frag0001 +agcacagctcttcatcctctcctctcctgtggcctttcctatccctcaccctgaccctcctgccctcagcccccacctcacccccacctcccaacacccaggccacctctccctgtccctccagcaccgcctctcttttgagcacagccccactcggcctctgcacccctggcctcccagcactggggtctcttcgccatcttttgttcactgggcttctgtctttgctccgcaacaagctcagcacactcctcccgaggccagagcctggggtgtgttcctggatccagctcctcaccagctgccagcagcctcagagcatctttaccctgaattcccctggataccttcctaccccacctccagtccccgatcctagtttgagccactgtcacctctcaccagggccaccaactgcctactggcc +>frag0002 +agggcacattttctagggctgtcttccaaccctgccccacccacactcactcacctgtgacgcccacggcagacaccgggcccaggcgccgcccctcgtggaggccgtacaggtgcatcttgtacttgcgcccaggctccaggcccctcacagtgaccttgctctcctggcccccaacacgcaccgcctggggccgcccgtccctgtccttgtactgcacggtgaaggagtcaaagcggccctgggggacggtccaggaaaggctcagcgagtcaggggaggatcctgtcactgtcagctcccccaggagaggctcctcggggggccctggggctctgtgcctggttctgtagggctgggggtctcgtccacatcctcttgtggggctgaaaggtaatatagggggatacagagtttaagggtttaagggcaacttgctttgctggtgctgtcaacagaggtcatacatcaaatgcgcccctccaga +>frag0003 +catctcaggcctggagccagaccataaatacaagatgaacctgtacggcttccacggtggccagcgcgtgggccccatctctgtcattggggtgacgggtgagtggatgatggcagccccagggtgggagccgtgggagggtcaccctcttgctctttggtgatgactggtggggaatgggccaggggtccggtcagcaccacagacctgcttgtggctggggctccccttggccttcctctgaggctgacccctggctcctcctgagcagggaggggccgtcaggagctctgctgtgctggtggctgtcccagacccccacagctgaccctggaacttgtcatgtgtgttagctgtcagttgagcaggaccacccagccccaagaatgggcttttc +>frag0004 +gctcagcgagtcaggggaggatcctgtcactgtcagctcccccaggagaggctcctcggggggccctggggctctgtgcctggttctgtagggctgggggtctcgtccacatcctcttgtggggctgaaaggtaatatagggggatacagagtttaagggtttaagggcaacttgctttgctggtgctgtcaacagaggtcatacatcaaatgcgcccctccagagcaggctgagggctggggcagctttgagttcgccgttcagtgactcttggaataagagccggtgaggtatccccgagcccccgactgtactgctggcagagctgcactgttagaaacctccagaaggcaa +>frag0005 +gcccctgacacgcatcacctggggccgcccgtccctgtccttgtactgcacggtgaaggagtcgaagtggccctgggggatggtccaggagaggctcagcgagtcaggggaggatcctgtcactgtcagctcccccaggagcggctcctcagggggctccggggcctcagtgctgagttccgtggggctgggggtctcttcctctgcagctgagaaaaggagatatagagaggatgccaggtgcctgggggatgtgctcaggtcttcaagggaaggagggagaaaccatggccactactgggtatgtgaggtcatttcagaaaagcccattcttggggctgggtgg +>frag0006 +gaattcccaacctcaggtgatccacccgcctcggcctcccaaaatgctaggattacaggcgtgaaccactgctcccagcccagaatttcttttttagcccacgtttttctagtgaaaataatacagcaacattatgtggaaagcttgaaaaacagaaaacaagaatctcatagtcctactttctcccccagctgccggcattaataacaatgtgtgtagtgcacattcccttcctgtattttgcatgcagaggctgttttaaagttgcaatcagtgttcataaagttcttggcacttccttttttgtacacaagtacattgtaatcattcacctcacggctacacaaccagcattcatcatcgtttcaatggttatttgatgcgttgcggtgaaagcactataacaaaattaatcatcttctacgggtcatttg +>frag0007 +agcacagctcttcatcctctcctctcctgtggcctttcctatccctcaccctgaccctcctgccctcagcccccacctcacccccacctcccaacacccaggccacctctccctgtccctccagcaccgcctctcttttgagcacagccccactcggcctctgcacccctggcctcccagcactggggtctcttcgccatcttttgttcactgggcttctgtctttgctccgcaacaagctcagcacactcctcccgaggccagagcctggggtgtgttcctggatccagctcctcaccagctgccagcagcctcagagcatctttaccct +>frag0008 +gctggtgaggagctggatccaggaacacaccccaggctctggcctcgggaggagtgtgctgagcttgttgcggagcaaagacagaagcccagtgaacaaaagatggcgaagagaccccagtgctgggaggccaggggtgcagaggccgagtggggctgtgctcaaaagagaggcggtgctggagggacagggagaggtggcctgggtgttgggaggtgggggtgaggtgggggctgagggcaggagggtcagggtgagggataggaaaggccacaggagaggagaggatgaagagctgtgctggaggggctgtgggcagcatcgtcctgctcttgggcactttgtgttttgtgacacatcctttctatgctgaactgaggagccagggacctcactgtccccacacgtgtctgtccaactccagaggatgaagccgagaccacccaagcagtg +>frag0009 +ccaaagagcaagagggtgaccctcccacggctcccaccctggggctgccatcatccactcacccgtcaccccaatgacagagatggggcccacgcgctggccaccgtggaagccgtacaggttcatcttgtatttatggtctggctccaggcctgagatggtgaccccgtcctcgtgccccggcacccgcaccgccttgggctgcccatccccattcctgtactggaccaggaagtggtcaaactggccctcgggaaccgtccaggacaggctgagggagtcaggggtggcatctgtcatggtcagctcccccaggcgaggcttgatggggggctcaggggtcatggtaggcactgcttgggtggtctcggcttcat +>frag0010 +tggccagcgcgtgggccccatctctgtcattggggtgacgggtgagtggatgatggcagccccagggtgggagccgtgggagggtcaccctcttgctctttggtgatgactggtggggaatgggccaggggtccggtcagcaccacagacctgcttgtggctggggctccccttggccttcctctgaggctgacccctggctcctcctgagcagggaggggccgtcaggagctctgctgtgctggtggctgtcccagacccccacagctgaccctggaacttgtcatgtgtgttagctgtcagttgagcaggaccacccagccccaa +>frag0011 +atgctctttctagcctcctggcctttgcaccagctgtgattatctgacacacttcaccttctctctaaagctgtcaccaagctaaggcatgcctggcctcaggtcctggctgtcccctgggtacccatgggcagggtgacttaggcgtccctgtctggtcctgacctgagccctgggcctccctatcacatgctcacccgcctttgcttcatttgctggattgcagcctgtctctccatgacatgtctttccataatgttgctatattcctttcactgtgagccccatcaagacagaaatatgtataggaaaatggtagagaagggcacattttctagggctgtcttccaaccctgccccacccacactcactcacctgtgacgcccacggcagacaccgggcccaggcgccgcccctcgtggaggccgtacaggtgcatcttgtacttgcgcccaggctccaggcccctcacagtgaccttgctctcctggcccccaac +>frag0012 +tgtcagttgagcaggaccacccagccccaagaatgggcttttctgaaatgacctcacatacccagtagtggccatggtttctccctccttcccttgaagacctgagcacatcccccaggcacctggcatcctctctatatctccttttctcagctgcagaggaagagacccccagccccacggaactcagcactgaggccccggagccccctgaggagccgctcctgggggagctgacagtgacaggatcctcccctgactcgctgagcctctcctggaccatcccccagggccacttcgactccttcaccgtgcagtacaaggacagggacgggcggccccaggtgatgcgtgtcaggggcgaggagagcgaggtcaccgtggggggcctggagcccgggcgcaaatacaagatgcacctgta +>frag0013 +gaattctttgctgaatgaacaaattggcccattggtgagaaaggtctgttcctattcctattccaatagtgggcttccagagtgtgcagtcgacgcgctgcccctcactgccttctgtcttccttcacggcccctagtcaactccacagagaaagcacactaccaggaatcagggacgcagaaaaattctcttcaacagatttcaaaagagggtccaattcctttgtcgtgaagaactttgctactcaaggggcgtgatcatgggccagcagcatccgcatcatttcttgttggaaatgcgagaatctctggccctagcccaaacctgttgaaccccaatctgcctcttagcaagatccccaagcatggaaacgtgcaaaagaagcccggctggtgagaatatttttgttttcatgaagttgcagagaaagcaacatcttctagggccatcttcctcact +>frag0014 +attaattttgttatagtgctttcaccgcaacgcatcaaataaccattgaaacgatgatgaatgctggttgtgtagccgtgaggtgaatgattacaatgtacttgtgtacaaaaaaggaagtgccaagaactttatgaacactgattgcaactttaaaacagcctctgcatgcaaaatacaggaagggaatgtgcactacacacattgttattaatgccggcagctgggggagaaagtaggactatgagattcttgttttctgtttttcaagctttccacataatgttgctgtattattttcactagaaaaacgtgggctaaaaaagaaattctgggctgggagcagtggttcacgcctgtaatcctagcattttgggaggccgaggcgggtggatcacctgaggttgggaattc +>frag0015 +tttcaaaagagggtccaattcctttgtcgtgaagaactttgctactcaaggggcgtgatcatgggccagcagcatccgcatcatttcttgttggaaatgcgagaatctctggccctagcccaaacctgttgaaccccaatctgcctcttagcaagatccccaagcatggaaacgtgcaaaagaagcccggctggtgagaatatttttgttttcatgaagttgcagagaaagcaacatcttctagggccatcttcctcactcacaaacactcacctgtcacacccacggtggacaccgggcccacacgccgcccct +>frag0016 +ctggaccatcccccagggccacttcgactccttcaccgtgcagtacaaggacagggacgggcggccccaggtgatgcgtgtcaggggcgaggagagcgaggtcaccgtggggggcctggagcccgggcgcaaatacaagatgcacctgtacggcctccacgaggggcggcgtgtgggcccggtgtccaccgtgggtgtgacaggtgagtgtttgtgagtgaggaagatggccctagaagatgttgctttctctgcaacttcatgaaaacaaaaatattctcaccagccgggcttcttttgcacgtttccatgcttggggatcttgctaagaggcagattggggttcaacaggtttgggctagggccagagattctcgcatttccaacaagaaatgatgcggatgctgctggcccatgatcacgccccttgagtagcaaagttcttcacgacaaaggaattggaccct +>frag0017 +ctgctgtcatgaataaccccatcgtgagttcttccatgctataactttttcctgctttaataattttcttaggacagatgcccagaactgggattattgggtcaaaggaaatgagaattactttggctcctgacactatgtctcagttgccttctggaggtttctaacagtgcagctctgccagcagtacagtcgggggctcggggatacctcaccggctcttattccaagagtcactgaacggcgaactcaaagctgccccagccctcagcctgctctggaggggcgcatttgatgtatgacctctgttgacagcaccagcaaagcaagttgcccttaaacccttaaactctgtatccccctatattacctttcagccccacaagaggatgtggacgagacccccagccctacagaaccaggca +>frag0018 +cctggcatcctctctatatctccttttctcagctgcagaggaagagacccccagccccacggaactcagcactgaggccccggagccccctgaggagccgctcctgggggagctgacagtgacaggatcctcccctgactcgctgagcctctcctggaccatcccccagggccacttcgactccttcaccgtgcagtacaaggacagggacgggcggccccaggtgatgcgtgtcaggggcgaggagagcgaggtcaccgtggggggcctggagcccgggcgcaaatacaagatgcacctgtacggcctccacgaggggcggcgtgtgggcccggtgtccaccgtgggtgtgacaggtgagtgtttgtgagtgaggaagatggccctagaagatgttgctttctctgcaacttcatgaaaacaaaaatattctcaccagccgggcttcttttgcacgtttccatgcttggggatcttgctaagaggcagatt +>frag0019 +gccccactcggcctctgcacccctggcctcccagcactggggtctcttcgccatcttttgttcactgggcttctgtctttgctccgcaacaagctcagcacactcctcccgaggccagagcctggggtgtgttcctggatccagctcctcaccagctgccagcagcctcagagcatctttaccctgaattcccctggataccttcctaccccacctccagtccccgatcctagtttgagccactgtcacctctcaccagggccaccaactgcctactggcctcgctgcctccaggctccctgccaccccatccccatcttcagcccccacggatgagcttcacacaggcacagctgctggggccatctcagcacagacctaggcaaccacaccctcaaccccgggagaccccaggcctagtgagtggtcccctcctctgctcccacacttcaggat +>frag0020 +aaggaagtgccaagaactttatgaacactgattgcaactttaaaacagcctctgcatgcaaaatacaggaagggaatgtgcactacacacattgttattaatgccggcagctgggggagaaagtaggactatgagattcttgttttctgtttttcaagctttccacataatgttgctgtattattttcactagaaaaacgtgggctaaaaaagaaattctgggctgggagcagtggttcacgcctgtaatcctagcattttgggaggccgaggcgggtggatcacctgaggttgggaattc +>frag0021 +gatggggtggcagggagcctggaggcagcgaggccagtaggcagttggtggccctggtgagaggtgacagtggctcaaactaggatcggggactggaggtggggtaggaaggtatccaggggaattcagggtaaagatgctctgaggctgctggcagctggtgaggagctggatccaggaacacaccccaggctctggcctcgggaggagtgtgctgagcttgttgcggagcaaagacagaagcccagtgaacaaaagatggcgaagagaccccagtgctgggaggccaggggtgcagaggccgagtggggctgtgctcaaaagagaggcggtgctggagggacagggagaggtggcctgggtgttgggaggtgggggtgaggtgggggctgagggcaggagggtcagggtgagggataggaaaggccacaggagaggagagga +>frag0022 +acggctacacaaccagcattcatcatcgtttcaatggttatttgatgcgttgcggtgaaagcactataacaaaattaatcatcttctacgggtcatttgtgttcctgacacatctgctgtcatgaataaccccatcgtgagttcttccatgctataactttttcctgctttaataattttcttaggacagatgcccagaactgggattattgggtcaaaggaaatgagaattactttggctcctgacactatgtctcagttgccttctggaggtttctaacagtgcagctctgccagcagtacagtcgggggctcggggatacctcaccggctcttattccaagagtcactgaacggcgaactca +>frag0023 +gtctctccatgacatgtctttccataatgttgctatattcctttcactgtgagccccatcaagacagaaatatgtataggaaaatggtagagaagggcacattttctagggctgtcttccaaccctgccccacccacactcactcacctgtgacgcccacggcagacaccgggcccaggcgccgcccctcgtggaggccgtacaggtgcatcttgtacttgcgcccaggctccaggcccctcacagtgaccttgctctcctggcccccaacacgcaccgcctggggccgcccgtccctgtccttgtactgcacggtgaaggagtcaaagcggccctgggggacggtccaggaaaggctcagcgagtcaggggaggatcctgtcactgtcagctcccccaggagaggctcctcggggggccctggggctctgtgcctggttctgtagggctgggggtctc +>frag0024 +gccagagcctggggtgtgttcctggatccagctcctcaccagctgccagcagcctcagagcatctttaccctgaattcccctggataccttcctaccccacctccagtccccgatcctagtttgagccactgtcacctctcaccagggccaccaactgcctactggcctcgctgcctccaggctccctgccaccccatccccatcttcagcccccacggatgagcttcacacaggcacagctgctggggccatctcagcacagacctaggcaaccacaccctcaaccccgggagaccccaggcctagtgagtggtcccctcctc +>frag0025 +caccacagacctgcttgtggctggggctccccttggccttcctctgaggctgacccctggctcctcctgagcagggaggggccgtcaggagctctgctgtgctggtggctgtcccagacccccacagctgaccctggaacttgtcatgtgtgttagctgtcagttgagcaggaccacccagccccaagaatgggcttttctgaaatgacctcacatacccagtagtggccatggtttctccctccttcccttgaagacctgagcacatcccccaggcacctggcatcctctctatatctccttttctcagctgcagaggaagagacccccagccccacggaactcagcactgaggccccggagccccctgaggagccgctcctgggggagctgacagtgacaggatcctcccctgactcgctgagcctctcctggaccatcccccaggg +>frag0026 +aatctcatagtcctactttctcccccagctgccggcattaataacaatgtgtgtagtgcacattcccttcctgtattttgcatgcagaggctgttttaaagttgcaatcagtgttcataaagttcttggcacttccttttttgtacacaagtacattgtaatcattcacctcacggctacacaaccagcattcatcatcgtttcaatggttatttgatgcgttgcggtgaaagcactataacaaaattaatcatcttctacgggtcatttgtgttcctgacacatctgctgtcatgaataaccccatcgtgagttcttccatgctataactttttcctgctttaataattttcttaggacagatgcccagaactgggattattgggtcaaaggaaatgag +>frag0027 +gcatttccaacaagaaatgatgcggatgctgctggcccatgatcacgccccttgagtagcaaagttcttcacgacaaaggaattggaccctcttttgaaatctgttgaagagaatttttctgcgtccctgattcctggtagtgtgctttctctgtggagttgactaggggccgtgaaggaagacagaaggcagtgaggggcagcgcgtcgactgcacactctggaagcccactattggaataggaataggaacagacctttctcaccaatgggccaatttgttcattcagcaaagaattc +>frag0028 +gtgcccttctctaccattttcctatacatatttctgtcttgatggggctcacagtgaaaggaatatagcaacattatggaaagacatgtcatggagagacaggctgcaatccagcaaatgaagcaaaggcgggtgagcatgtgatagggaggcccagggctcaggtcaggaccagacagggacgcctaagtcaccctgcccatgggtacccaggggacagccaggacctgaggccaggcatgccttagcttggtgacagctttagagagaaggtgaagtgtgtcagataatcacagctggtgcaaaggc +>frag0029 +ctgtcacctctcaccagggccaccaactgcctactggcctcgctgcctccaggctccctgccaccccatccccatcttcagcccccacggatgagcttcacacaggcacagctgctggggccatctcagcacagacctaggcaaccacaccctcaaccccgggagaccccaggcctagtgagtggtcccctcctctgctcccacacttcaggatgagatactcaccgtaaaggacaccccactcaatcctcagtgcctctcacgtgccatgctctttctagcctcctggcctttgcaccagctgtgattatctgacacacttcaccttctctctaaagctgtcaccaagctaaggcatgcctggcctcaggtcctggctgtcccctgggtacccatgggcagggtgacttaggcgtccctgtctggtcc +>frag0030 +cctctcctctcctgtggcctttcctatccctcaccctgaccctcctgccctcagcccccacctcacccccacctcccaacacccaggccacctctccctgtccctccagcaccgcctctcttttgagcacagccccactcggcctctgcacccctggcctcccagcactggggtctcttcgccatcttttgttcactgggcttctgtctttgctccgcaacaagctcagcacactcctcccgaggccagagcctggggtgtgttcctggatccagctcctcaccagctgccagcagcctcagagcatctttaccctgaattcccctggataccttcctaccccacctccagtccccgatcctagtttgagccactgtcacctctcaccagggccaccaactgcctactggcctcgctgcctccaggctccctgccaccccatcc +>frag0031 +tcaaagctgccccagccctcagcctgctctggaggggcgcatttgatgtatgacctctgttgacagcaccagcaaagcaagttgcccttaaacccttaaactctgtatccccctatattacctttcagccccacaagaggatgtggacgagacccccagccctacagaaccaggcacagagccccagggccccccgaggagcctctcctgggggagctgacagtgacaggatcctcccctgactcgctgagcctttcctggaccgtcccccagggccgctttgactccttcaccgtgcagtacaaggacagggacgggcggccccaggcggtgcgtgttgggggccaggagagcaaggtcactgtgaggggcctggagcctgggcgcaag +>frag0032 +gtcagctcccccaggcgaggcttgatggggggctcaggggtcatggtaggcactgcttgggtggtctcggcttcatcctctggagttggacagacacgtgtggggacagtgaggtccctggctcctcagttcagcatagaaaggatgtgtcacaaaacacaaagtgcccaagagcaggacgatgctgcccacagcccctccagcacagctcttcatcctctcctctcctgtggcctttcctatccctcaccctgaccctcctgccctcagcccccacctcacccccacctcccaacacccaggccacctctccctgtccctccagcaccgcctctcttttgagcacagccccactc +>frag0033 +cacccctgactccctcagcctgtcctggacggttcccgagggccagtttgaccacttcctggtccagtacaggaatggggatgggcagcccaaggcggtgcgggtgccggggcacgaggacggggtcaccatctcaggcctggagccagaccataaatacaagatgaacctgtacggcttccacggtggccagcgcgtgggccccatctctgtcattggggtgacgggtgagtggatgatggcagccccagggtgggagccgtgggagggtcaccctcttgctctttggtgatgactggtggggaatgggccaggggtccggtcagcaccacagacctgcttgtggctggggctccccttggccttcctctgaggctgacccctggctcctcctgagcagggaggggccgtc +>frag0034 +ggccccccgaggagcctctcctgggggagctgacagtgacaggatcctcccctgactcgctgagcctttcctggaccgtcccccagggccgctttgactccttcaccgtgcagtacaaggacagggacgggcggccccaggcggtgcgtgttgggggccaggagagcaaggtcactgtgaggggcctggagcctgggcgcaagtacaagatgcacctgtacggcctccacgaggggcggcgcctgggcccggtgtctgccgtgggcgtcacaggtgagtgagtgtgggtggggcagggttggaagacagccctagaaaatgtgcccttctctaccattttcctatacatatttctgtcttgatggggctcacagtgaaaggaatatagcaacattatggaaagacatgtcatggagagacaggctgcaatccagcaaatgaagcaaaggcgggtgagcatgtgat +>frag0035 +ttcatcctctggagttggacagacacgtgtggggacagtgaggtccctggctcctcagttcagcatagaaaggatgtgtcacaaaacacaaagtgcccaagagcaggacgatgctgcccacagcccctccagcacagctcttcatcctctcctctcctgtggcctttcctatccctcaccctgaccctcctgccctcagcccccacctcacccccacctcccaacacccaggccacctctccctgtccctccagcaccgcctctcttttgagcacagccccactcggcctctgcacccctggcctcccagcactggggtctcttcgccatcttttgttcactgggcttctgtctttgctccgcaacaagctcagcac +>frag0036 +tcggcctctgcacccctggcctcccagcactggggtctcttcgccatcttttgttcactgggcttctgtctttgctccgcaacaagctcagcacactcctcccgaggccagagcctggggtgtgttcctggatccagctcctcaccagctgccagcagcctcagagcatctttaccctgaattcccctggataccttcctaccccacctccagtccccgatcctagtttgagccactgtcacctctcaccagggccaccaactgcctactggcctcgctgcctccaggctccctgccaccccatccccat +>frag0037 +aaagctgccccagccctcagcctgctctggaggggcgcatttgatgtatgacctctgttgacagcaccagcaaagcaagttgcccttaaacccttaaactctgtatccccctatattacctttcagccccacaagaggatgtggacgagacccccagccctacagaaccaggcacagagccccagggccccccgaggagcctctcctgggggagctgacagtgacaggatcctcccctgactcgctgagcctttcctggaccgtcccccagggccgctttgactccttcaccgtgcagtacaaggacagggacgggcggccccaggcggtgcgtgttgggggccaggagagcaaggtcactgtgaggggcctggagcc +>frag0038 +cctagtttgagccactgtcacctctcaccagggccaccaactgcctactggcctcgctgcctccaggctccctgccaccccatccccatcttcagcccccacggatgagcttcacacaggcacagctgctggggccatctcagcacagacctaggcaaccacaccctcaaccccgggagaccccaggcctagtgagtggtcccctcctctgctcccacacttcaggatgagatactcaccgtaaaggacaccccactcaatcctcagtgcctctcacgtgccatgctctttctagcctcctggcc diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/MAXSAT-instances/format.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/MAXSAT-instances/format.txt new file mode 100644 index 0000000000000000000000000000000000000000..dc630e19477ddc67cbc6cb78c485461b4cc04dcc --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/MAXSAT-instances/format.txt @@ -0,0 +1,4 @@ +// number of variables, number of clauses and number of literals per clause. +// clause 1 (finalized in 0), if literal < 0 then the literal is negated. + +// clause N (finalized in 0), if literal < 0 then the literal is negated. diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/MAXSAT-instances/sat1.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/MAXSAT-instances/sat1.txt new file mode 100644 index 0000000000000000000000000000000000000000..f8aa7feb0eb9664001f550dc4c5f37757f16bc47 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/MAXSAT-instances/sat1.txt @@ -0,0 +1,44 @@ +10 43 3 +-4 -1 5 0 +-1 -9 -10 0 +-5 -3 -8 0 +-4 -8 -5 0 +2 6 7 0 +-9 -1 -10 0 +5 -3 -9 0 +1 -3 -5 0 +7 2 -4 0 +-7 3 4 0 +-2 1 -9 0 +-8 1 3 0 +3 6 7 0 +-1 -3 -2 0 +4 7 -2 0 +-8 -7 -3 0 +4 3 2 0 +-5 -4 1 0 +-9 10 -8 0 +-6 2 8 0 +-7 -8 5 0 +-7 -5 3 0 +7 9 -10 0 +1 -6 -3 0 +1 -9 6 0 +10 9 4 0 +-8 3 7 0 +8 7 -3 0 +-8 4 9 0 +8 -5 4 0 +8 10 1 0 +-1 -7 8 0 +6 2 5 0 +6 2 10 0 +2 -6 4 0 +-3 9 -1 0 +9 1 -10 0 +10 -5 -8 0 +-10 6 1 0 +1 7 2 0 +-6 3 2 0 +-1 -9 8 0 +-5 2 -10 0 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/MAXSAT-instances/sat2.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/MAXSAT-instances/sat2.txt new file mode 100644 index 0000000000000000000000000000000000000000..806241f36dba6858b65c4aac3d5fc5afc2ae7950 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/MAXSAT-instances/sat2.txt @@ -0,0 +1,4301 @@ +1000 4300 3 +881 -647 537 0 +-739 396 282 0 +-43 -487 -52 0 +-643 205 796 0 +939 -885 -829 0 +-361 576 421 0 +-193 904 -238 0 +-940 902 26 0 +-177 -783 257 0 +439 942 675 0 +-794 714 -977 0 +310 -524 523 0 +-762 -494 260 0 +-578 305 502 0 +-805 -630 547 0 +729 855 -76 0 +-168 -754 667 0 +965 -418 93 0 +-668 -824 -495 0 +286 976 339 0 +776 -809 -157 0 +395 -120 838 0 +412 895 703 0 +-472 -479 -19 0 +-65 -918 945 0 +-682 -47 -590 0 +-956 996 316 0 +-969 120 222 0 +809 938 995 0 +-882 131 -976 0 +34 61 -359 0 +475 182 -67 0 +105 -391 986 0 +616 -867 -339 0 +-830 236 752 0 +-415 124 903 0 +-473 585 681 0 +203 -11 380 0 +-874 -126 -568 0 +498 -850 -74 0 +435 -113 -261 0 +-690 542 148 0 +-800 -657 752 0 +-624 269 526 0 +794 177 512 0 +-620 -987 819 0 +292 -87 455 0 +-945 758 946 0 +-723 421 908 0 +131 -977 369 0 +-811 -172 875 0 +971 410 -522 0 +287 474 -157 0 +753 458 491 0 +-265 -653 -269 0 +743 890 -606 0 +-207 555 211 0 +-367 799 403 0 +869 559 -407 0 +33 657 488 0 +834 -663 646 0 +-318 -109 804 0 +-235 572 452 0 +-257 -977 984 0 +386 -388 800 0 +-879 -50 131 0 +91 936 -258 0 +215 -310 -748 0 +911 842 670 0 +-514 442 496 0 +8 -111 35 0 +616 -77 325 0 +266 796 918 0 +-22 -261 -317 0 +-654 827 647 0 +48 -267 -905 0 +-921 418 407 0 +685 930 -196 0 +593 379 212 0 +-407 812 805 0 +-983 -942 919 0 +-138 32 678 0 +-306 764 -898 0 +-752 637 573 0 +916 332 -598 0 +890 350 -859 0 +-216 -821 -218 0 +-497 -981 -276 0 +-681 -893 -12 0 +765 -862 -222 0 +-740 6 666 0 +4 145 -59 0 +825 217 14 0 +135 889 -870 0 +-147 -85 -563 0 +298 -876 929 0 +-341 943 997 0 +329 -258 299 0 +-41 911 -906 0 +439 716 450 0 +-300 709 -704 0 +-363 125 260 0 +-442 776 474 0 +-615 -612 593 0 +233 -271 40 0 +661 248 -981 0 +-549 736 228 0 +565 -795 97 0 +706 -314 881 0 +-513 -476 -125 0 +54 721 822 0 +355 -327 -772 0 +-94 588 284 0 +-977 697 485 0 +-144 560 -671 0 +112 -780 324 0 +649 35 -134 0 +84 912 -265 0 +-705 21 858 0 +-224 -991 491 0 +930 -610 -668 0 +-956 -723 -845 0 +-694 798 527 0 +-208 726 594 0 +-151 311 279 0 +-347 -499 994 0 +679 195 -34 0 +-214 829 -895 0 +771 -106 -532 0 +684 855 942 0 +-323 552 -191 0 +-412 -8 -319 0 +327 -117 702 0 +-752 -663 234 0 +427 -92 846 0 +662 -736 -344 0 +164 774 -856 0 +-303 818 -889 0 +-791 -899 477 0 +-786 626 791 0 +-185 -589 -126 0 +964 314 466 0 +175 -299 -442 0 +-384 -545 -365 0 +-584 -719 -906 0 +901 -305 51 0 +-5 671 -804 0 +-895 417 55 0 +579 -693 586 0 +259 863 -872 0 +-176 -933 213 0 +829 437 24 0 +-322 -321 910 0 +-522 -696 641 0 +-682 -538 202 0 +108 450 798 0 +254 505 663 0 +-672 -420 116 0 +-652 -294 759 0 +-196 987 -572 0 +-219 -576 -261 0 +357 -975 -458 0 +164 -44 726 0 +-508 909 286 0 +-201 97 594 0 +-218 -198 776 0 +669 199 -655 0 +-146 822 360 0 +838 -958 372 0 +733 718 412 0 +-445 835 -924 0 +554 -488 155 0 +365 -834 -230 0 +-735 364 348 0 +540 -162 803 0 +-547 113 374 0 +-242 -569 -572 0 +-121 501 -174 0 +213 -815 -942 0 +370 758 492 0 +889 -733 -256 0 +636 -149 273 0 +543 176 -58 0 +92 941 402 0 +-683 -952 924 0 +788 -686 -56 0 +849 -866 155 0 +-121 837 323 0 +-578 866 277 0 +62 -504 857 0 +192 807 -944 0 +647 -350 -468 0 +816 967 -910 0 +-48 -745 285 0 +-894 -521 -397 0 +374 -616 905 0 +-968 -290 -854 0 +-770 747 -777 0 +610 779 -278 0 +-704 -452 964 0 +51 -774 -681 0 +532 -752 -528 0 +-738 433 -319 0 +17 635 -456 0 +-969 709 390 0 +68 317 -980 0 +-502 95 462 0 +-952 -920 -127 0 +280 -820 102 0 +466 635 -896 0 +446 967 -261 0 +-672 -626 396 0 +-609 392 103 0 +826 383 740 0 +-404 218 281 0 +112 -548 941 0 +-463 -408 975 0 +449 245 748 0 +-657 -752 668 0 +395 -915 739 0 +-246 100 -469 0 +975 388 814 0 +-669 -738 -465 0 +-199 203 336 0 +-85 -167 -662 0 +455 -789 475 0 +514 427 -915 0 +806 -825 -635 0 +720 -228 -179 0 +-941 -82 -700 0 +228 -256 -547 0 +374 732 -204 0 +-927 -79 58 0 +-535 -860 -669 0 +391 674 817 0 +-36 -15 -318 0 +-690 -538 -206 0 +-824 418 685 0 +-981 512 -849 0 +-268 -343 952 0 +-914 -720 -827 0 +173 -697 -115 0 +-95 628 -419 0 +-10 521 -459 0 +-539 236 396 0 +-922 -709 740 0 +-248 -746 679 0 +215 511 503 0 +-799 -121 -631 0 +-438 300 -651 0 +-76 287 135 0 +-566 186 706 0 +944 -756 230 0 +-950 264 -581 0 +113 953 821 0 +270 -214 192 0 +-442 145 -143 0 +-951 -931 349 0 +499 903 331 0 +-618 -654 112 0 +-287 -662 -243 0 +440 -691 -429 0 +-374 -370 -707 0 +-559 -883 -214 0 +988 439 471 0 +-239 -13 -732 0 +-997 593 751 0 +287 324 -135 0 +-624 -341 -298 0 +-796 851 -884 0 +198 -191 -81 0 +-71 -647 -421 0 +840 -87 56 0 +-710 465 -8 0 +-465 787 375 0 +573 524 232 0 +-373 -775 28 0 +7 516 -771 0 +-623 -951 770 0 +-152 841 656 0 +741 387 510 0 +49 287 642 0 +-202 -881 -389 0 +-265 -953 -752 0 +-756 -927 -479 0 +-422 227 25 0 +-162 -663 659 0 +-878 935 999 0 +86 982 -458 0 +781 515 510 0 +225 289 890 0 +929 -495 -377 0 +-857 866 -433 0 +436 221 530 0 +-750 8 -24 0 +-413 860 121 0 +609 375 321 0 +850 950 -27 0 +432 -539 -267 0 +-677 242 326 0 +-157 21 -736 0 +-812 -679 726 0 +787 856 -859 0 +-874 50 626 0 +-884 248 127 0 +-716 84 606 0 +825 382 308 0 +-922 -917 250 0 +625 -410 514 0 +144 -975 -311 0 +-570 115 -736 0 +-20 -584 179 0 +373 -515 -166 0 +705 985 226 0 +-707 816 -140 0 +535 -60 441 0 +800 459 -568 0 +50 -180 630 0 +365 715 -819 0 +17 -379 -454 0 +828 178 -957 0 +-383 -741 -258 0 +-740 -336 736 0 +178 -870 417 0 +375 205 216 0 +402 73 -492 0 +-361 63 -409 0 +-996 -741 152 0 +-981 411 808 0 +-875 -71 -26 0 +-448 627 -161 0 +-25 -808 -657 0 +866 -202 -348 0 +-963 -713 671 0 +-464 -642 215 0 +52 -312 -258 0 +96 -466 945 0 +-303 -957 -152 0 +-451 229 530 0 +-695 -547 835 0 +820 -646 294 0 +410 -921 15 0 +-40 520 837 0 +-610 -90 26 0 +-454 576 539 0 +469 -563 -62 0 +477 -897 -272 0 +394 -395 650 0 +551 318 -99 0 +406 -498 361 0 +-219 -348 -116 0 +551 82 -262 0 +-684 487 505 0 +-806 -903 -348 0 +-289 56 587 0 +-780 231 667 0 +-452 -44 68 0 +-586 96 -107 0 +-672 470 242 0 +178 287 46 0 +-648 -366 263 0 +777 126 435 0 +939 -289 -364 0 +830 -176 883 0 +-772 890 803 0 +-68 -429 -616 0 +659 -54 -227 0 +-502 53 999 0 +-430 -909 129 0 +-716 -970 -554 0 +57 -256 242 0 +-152 -255 -478 0 +-347 127 918 0 +127 328 368 0 +731 866 -936 0 +561 331 -525 0 +545 -188 -504 0 +919 765 -243 0 +-724 -864 -492 0 +645 425 -299 0 +949 -38 -968 0 +84 17 202 0 +-884 -28 -736 0 +-1 -410 -464 0 +493 467 -755 0 +642 -759 830 0 +-455 543 -47 0 +-523 885 -72 0 +-761 751 -575 0 +129 9 -836 0 +-621 -59 756 0 +-392 203 -919 0 +200 347 31 0 +-605 -359 525 0 +-869 -339 827 0 +871 -493 79 0 +721 -892 -406 0 +-140 -934 -96 0 +764 -796 -245 0 +365 1000 60 0 +-922 517 -990 0 +893 704 122 0 +819 -586 957 0 +170 184 491 0 +-72 664 381 0 +-1000 295 -918 0 +-868 525 -309 0 +534 -189 210 0 +461 -432 -990 0 +-605 71 -826 0 +527 -317 990 0 +974 -516 -442 0 +-443 -137 -84 0 +-713 -181 -555 0 +626 945 -996 0 +255 685 -306 0 +214 744 -786 0 +-183 -19 -812 0 +-704 472 678 0 +-321 -540 83 0 +277 953 128 0 +-693 -432 -452 0 +-59 -145 41 0 +135 -220 -865 0 +-601 122 -557 0 +-162 -877 238 0 +-373 -649 -579 0 +982 -445 -623 0 +-172 797 687 0 +138 -288 -868 0 +221 668 -570 0 +180 254 -469 0 +39 -766 657 0 +56 -465 773 0 +599 -183 127 0 +-263 81 169 0 +-74 432 -813 0 +-487 -756 -126 0 +-288 -285 -552 0 +-873 52 760 0 +221 631 -550 0 +-812 -310 -242 0 +-328 -141 -278 0 +-792 441 41 0 +51 983 -547 0 +-993 -150 -613 0 +352 564 -483 0 +123 389 -989 0 +-52 830 -364 0 +680 -189 46 0 +-241 634 -130 0 +-720 -401 -297 0 +731 -349 -736 0 +6 -452 8 0 +927 -875 911 0 +309 344 -112 0 +-326 610 -426 0 +843 -699 978 0 +546 118 856 0 +-397 -455 262 0 +653 914 -500 0 +480 848 130 0 +-304 679 672 0 +-765 984 -907 0 +-847 425 -46 0 +199 -727 -716 0 +-350 -281 -804 0 +394 851 -540 0 +-267 -334 -282 0 +339 754 558 0 +-835 -603 155 0 +628 -96 832 0 +-532 899 142 0 +-51 909 -248 0 +-913 20 -577 0 +-688 668 -529 0 +-725 430 198 0 +-887 -454 849 0 +-753 39 177 0 +-584 104 -805 0 +75 296 983 0 +-28 919 -18 0 +68 -848 -550 0 +185 -922 415 0 +-762 873 -367 0 +181 -79 -468 0 +709 -685 410 0 +600 553 -718 0 +-568 -757 309 0 +483 682 -439 0 +-923 847 -668 0 +-513 -668 392 0 +304 -813 880 0 +410 -179 -943 0 +205 -615 -377 0 +354 -131 -917 0 +614 -715 -891 0 +-150 -794 -375 0 +-970 376 325 0 +514 -584 -824 0 +-311 -847 -247 0 +919 -867 433 0 +273 872 -788 0 +958 9 -279 0 +-674 546 -261 0 +-954 678 -774 0 +-739 232 -328 0 +-196 -416 272 0 +338 921 900 0 +-655 -872 -286 0 +-232 -974 399 0 +-772 -199 -428 0 +-553 -778 306 0 +289 -84 151 0 +-483 866 -897 0 +-399 692 844 0 +-35 423 624 0 +-461 -88 -231 0 +-211 -956 -462 0 +-966 -994 40 0 +990 -149 813 0 +-228 853 913 0 +39 -330 -785 0 +-942 -726 -9 0 +-754 -122 -194 0 +539 503 710 0 +-123 461 -815 0 +425 -169 362 0 +3 -954 -383 0 +-538 -374 -8 0 +217 -318 51 0 +299 -499 -919 0 +-452 -121 -674 0 +211 -463 980 0 +-342 563 514 0 +839 691 814 0 +8 646 -632 0 +-487 -231 -401 0 +-479 -206 335 0 +-629 852 354 0 +950 -48 -406 0 +954 -977 415 0 +-315 -858 866 0 +-912 -799 -376 0 +-509 519 964 0 +-550 99 -996 0 +-173 342 483 0 +-677 -525 -828 0 +933 858 23 0 +425 166 -174 0 +-879 -970 -171 0 +618 -303 -364 0 +-76 507 512 0 +762 -604 947 0 +-188 256 -232 0 +730 -854 811 0 +338 -535 606 0 +-24 -772 102 0 +-132 -947 -454 0 +993 -344 476 0 +596 -856 -965 0 +-814 70 -553 0 +229 659 751 0 +38 473 696 0 +928 222 337 0 +-795 -524 -700 0 +-183 281 -516 0 +-169 249 -378 0 +394 -292 941 0 +-200 -806 -739 0 +33 777 358 0 +92 -168 162 0 +-995 -880 -189 0 +181 -495 428 0 +358 45 849 0 +-579 275 -391 0 +116 -466 -982 0 +923 513 -194 0 +-965 -325 -741 0 +-238 -655 643 0 +767 246 257 0 +-199 -826 -318 0 +-728 656 -603 0 +-395 -279 885 0 +259 -342 63 0 +-370 -928 -388 0 +556 544 348 0 +-886 115 788 0 +70 -668 690 0 +-55 -680 -474 0 +814 457 899 0 +-15 239 953 0 +249 184 -6 0 +-608 611 735 0 +-761 468 324 0 +60 -86 -731 0 +363 38 105 0 +-53 -780 953 0 +-140 953 -163 0 +464 -410 438 0 +221 151 438 0 +98 415 698 0 +36 489 -655 0 +998 332 580 0 +-326 -971 105 0 +927 -857 499 0 +-677 -593 -779 0 +-622 -24 457 0 +-22 452 364 0 +-844 -647 194 0 +-101 -348 36 0 +115 -547 970 0 +-202 -261 -878 0 +272 -286 -125 0 +-722 -773 -601 0 +-796 250 273 0 +-834 -265 766 0 +-799 773 -680 0 +-296 841 980 0 +-902 -855 -699 0 +-301 -130 238 0 +799 -916 917 0 +-944 -681 731 0 +606 729 751 0 +649 67 582 0 +-267 -909 -979 0 +816 -889 650 0 +-716 -205 228 0 +530 -161 302 0 +175 823 -319 0 +-344 -944 -701 0 +433 272 -254 0 +94 113 -130 0 +806 -399 -508 0 +-880 897 -456 0 +-288 602 -793 0 +-999 92 362 0 +98 581 698 0 +-994 -428 -524 0 +-565 -967 -848 0 +97 814 -999 0 +842 -904 -899 0 +-61 627 437 0 +340 -977 371 0 +-220 302 336 0 +831 -591 251 0 +107 957 -949 0 +-552 -601 988 0 +-630 348 167 0 +-519 -587 404 0 +783 809 -377 0 +345 -315 -918 0 +-904 346 584 0 +-785 -201 -381 0 +-679 854 -334 0 +-117 367 836 0 +-274 -329 891 0 +-940 429 22 0 +341 -974 768 0 +-972 494 14 0 +-988 -457 -613 0 +997 -391 607 0 +-188 667 -874 0 +-468 814 927 0 +950 -677 -438 0 +-839 -469 691 0 +184 918 401 0 +-236 500 697 0 +-488 -595 -274 0 +390 -536 -162 0 +317 907 -247 0 +928 899 -770 0 +962 872 341 0 +-717 14 1000 0 +-805 -635 535 0 +-950 720 -883 0 +32 -360 390 0 +-176 -541 503 0 +-394 -550 279 0 +-387 -913 228 0 +-125 89 93 0 +329 99 -136 0 +435 -938 39 0 +856 -304 -915 0 +452 -818 129 0 +-18 -532 -493 0 +794 -408 -714 0 +-428 38 983 0 +992 609 -295 0 +-390 -477 574 0 +197 884 -530 0 +-79 -955 -958 0 +142 -455 465 0 +601 953 -622 0 +478 -678 947 0 +-443 -778 2 0 +608 -893 696 0 +421 565 300 0 +-164 140 -726 0 +-299 -320 214 0 +-237 1000 70 0 +136 -886 -613 0 +-145 802 692 0 +822 -641 -939 0 +-631 343 822 0 +554 -679 621 0 +176 432 523 0 +125 181 -41 0 +422 809 845 0 +691 -625 -281 0 +-605 967 -687 0 +809 155 -45 0 +-350 510 -722 0 +747 -816 -758 0 +301 -392 -3 0 +198 -856 -397 0 +-304 965 808 0 +-120 -412 641 0 +95 -903 702 0 +146 -932 776 0 +-231 -163 -696 0 +682 668 -939 0 +-819 460 451 0 +57 -799 -592 0 +-391 453 769 0 +-381 -877 -983 0 +686 595 68 0 +-800 -485 39 0 +396 803 821 0 +-727 -988 -37 0 +-883 66 805 0 +-966 432 -977 0 +-786 468 192 0 +-849 24 -514 0 +-67 690 153 0 +-526 -518 442 0 +27 631 -245 0 +701 211 -58 0 +514 243 904 0 +58 483 956 0 +-815 -870 -158 0 +-296 993 -476 0 +-913 -581 -512 0 +-497 -11 -2 0 +-127 118 767 0 +-655 -302 -514 0 +273 293 395 0 +145 -390 338 0 +-716 117 -563 0 +273 172 256 0 +449 -693 -283 0 +19 -907 -97 0 +-237 -163 -509 0 +99 -813 886 0 +924 3 51 0 +-107 -314 515 0 +-907 184 367 0 +850 539 800 0 +-457 714 420 0 +411 -604 367 0 +643 -791 636 0 +-613 -888 500 0 +526 -605 47 0 +-431 947 930 0 +-660 -860 148 0 +-129 269 753 0 +-488 130 -958 0 +-772 491 422 0 +-910 -339 461 0 +13 -143 504 0 +-414 406 643 0 +-284 182 772 0 +-271 211 -577 0 +946 139 114 0 +-524 -463 108 0 +-424 -688 111 0 +317 780 -384 0 +-3 -50 -678 0 +719 -15 969 0 +-287 -899 -66 0 +-74 187 -865 0 +-346 794 910 0 +869 -166 121 0 +347 -540 224 0 +-26 -281 600 0 +-849 -788 -906 0 +-880 -348 -128 0 +-19 904 -430 0 +715 -377 490 0 +406 230 675 0 +-495 -110 615 0 +474 315 180 0 +-883 672 -444 0 +578 -534 -662 0 +711 -112 -400 0 +-659 642 -144 0 +-693 676 52 0 +-258 716 997 0 +-38 -436 729 0 +-87 -622 -369 0 +516 309 4 0 +-425 657 -965 0 +870 -441 714 0 +-512 822 678 0 +-942 -982 -868 0 +-609 -78 -679 0 +44 -405 -463 0 +-334 -663 -534 0 +413 510 -451 0 +-846 865 475 0 +-559 -765 957 0 +178 222 -276 0 +-437 -645 -369 0 +-936 768 -601 0 +57 -136 554 0 +-374 28 -583 0 +-355 -926 -539 0 +-696 -381 -329 0 +243 720 287 0 +529 811 -790 0 +-961 889 -611 0 +113 542 89 0 +804 -345 532 0 +894 295 508 0 +-606 -894 70 0 +-898 -441 499 0 +-124 -372 -948 0 +223 -909 914 0 +-389 271 782 0 +345 -421 -32 0 +-137 771 -230 0 +587 -689 74 0 +642 351 -523 0 +-255 -297 673 0 +997 656 108 0 +-726 603 442 0 +390 -864 -452 0 +400 -532 -627 0 +215 876 656 0 +945 250 235 0 +651 -754 890 0 +254 -511 516 0 +53 623 -605 0 +500 798 696 0 +170 -84 933 0 +210 -168 150 0 +-765 871 514 0 +532 -793 -440 0 +-320 661 54 0 +422 121 -372 0 +-498 -693 -1 0 +-743 -352 327 0 +-917 -673 -251 0 +-172 -155 -598 0 +-356 -50 627 0 +-512 -498 46 0 +336 181 -852 0 +-585 -393 -178 0 +-849 -222 -478 0 +-677 -471 -645 0 +-729 -432 -517 0 +-147 -571 -730 0 +259 -368 270 0 +-461 524 -696 0 +-316 -700 758 0 +174 -966 -342 0 +-586 -16 114 0 +-208 -123 -490 0 +-864 851 -818 0 +-690 -524 -778 0 +301 -541 855 0 +664 -200 196 0 +-609 -207 452 0 +-991 451 -897 0 +429 168 954 0 +399 343 -962 0 +801 252 -200 0 +-457 -499 -480 0 +726 -1000 83 0 +675 -498 771 0 +282 631 394 0 +666 -595 90 0 +573 -538 121 0 +98 -901 925 0 +781 245 440 0 +-747 680 53 0 +557 -113 -787 0 +666 257 751 0 +-445 -232 251 0 +-582 -754 382 0 +-849 -303 255 0 +-950 -420 -313 0 +181 -5 29 0 +-16 -298 -965 0 +94 -785 -598 0 +618 -326 -549 0 +-337 474 283 0 +-476 -696 -349 0 +658 -423 526 0 +-973 880 943 0 +420 847 794 0 +565 833 -352 0 +254 755 312 0 +27 323 338 0 +709 996 479 0 +-636 851 -680 0 +102 -873 -263 0 +903 982 -37 0 +424 -366 805 0 +-468 755 638 0 +380 48 586 0 +427 212 414 0 +178 354 -673 0 +-156 -558 -192 0 +-670 -106 383 0 +-127 838 857 0 +195 -973 -987 0 +994 -891 112 0 +850 542 -238 0 +-124 -382 772 0 +-177 332 494 0 +-844 -511 818 0 +-843 -108 -721 0 +982 -463 899 0 +298 -810 -232 0 +-147 -17 -774 0 +-383 -592 748 0 +368 -321 882 0 +35 473 -855 0 +-578 927 654 0 +-620 683 694 0 +781 -54 169 0 +742 -256 -115 0 +622 -387 -123 0 +380 364 234 0 +133 659 80 0 +260 632 -265 0 +990 -596 -966 0 +944 694 995 0 +774 -212 -504 0 +-906 168 -75 0 +5 824 886 0 +55 982 34 0 +313 -87 -257 0 +792 575 586 0 +76 439 35 0 +449 542 330 0 +-95 111 971 0 +-433 -726 802 0 +-605 992 596 0 +-655 856 -631 0 +-413 600 -606 0 +165 843 -5 0 +883 -481 -210 0 +-579 -21 -533 0 +-232 -44 125 0 +434 -776 -171 0 +-509 -279 -29 0 +-910 795 -564 0 +-417 915 216 0 +67 983 -871 0 +565 -855 -675 0 +110 -387 461 0 +602 -88 -294 0 +-40 781 -826 0 +-996 612 -440 0 +916 -446 -606 0 +-947 684 -618 0 +48 694 7 0 +-497 866 58 0 +-915 77 710 0 +445 95 594 0 +710 682 -379 0 +581 -551 -419 0 +-873 -536 917 0 +-267 -794 51 0 +-890 -20 521 0 +969 104 529 0 +130 -929 237 0 +-426 216 93 0 +225 301 -589 0 +-825 -461 -918 0 +-426 82 901 0 +-878 185 -992 0 +510 -136 -850 0 +399 288 883 0 +-334 4 -807 0 +610 -512 -685 0 +-550 556 12 0 +-788 -492 8 0 +-473 190 -244 0 +-63 -446 598 0 +-774 -933 -219 0 +928 -311 -600 0 +-466 265 322 0 +817 -869 -57 0 +-887 940 63 0 +-603 862 -109 0 +-711 -845 -143 0 +415 226 192 0 +-275 321 607 0 +-954 312 600 0 +944 -377 -353 0 +320 -404 820 0 +58 -958 -858 0 +225 -289 -278 0 +-185 -797 -914 0 +486 123 895 0 +-863 -769 -812 0 +452 -322 -621 0 +-604 -591 649 0 +473 818 993 0 +265 912 150 0 +540 -107 -3 0 +3 -326 -128 0 +181 814 -41 0 +-646 -606 196 0 +-29 305 -547 0 +-966 -282 -398 0 +905 -994 -465 0 +89 -883 698 0 +724 -706 767 0 +691 -575 81 0 +-835 180 176 0 +-489 -205 585 0 +-718 -198 -28 0 +759 -647 406 0 +-740 -89 187 0 +-231 529 -319 0 +548 -387 406 0 +613 950 538 0 +-719 -331 -520 0 +616 728 871 0 +538 425 865 0 +-504 336 -716 0 +-497 274 133 0 +557 -132 -809 0 +-911 -226 -128 0 +484 -390 609 0 +-191 -396 81 0 +739 444 788 0 +-619 350 107 0 +-298 560 1000 0 +-179 -243 154 0 +476 -979 886 0 +275 -606 -674 0 +-495 220 -340 0 +-38 -653 14 0 +27 -676 832 0 +-121 820 403 0 +815 726 -337 0 +-409 878 -750 0 +-458 -618 129 0 +-619 -294 625 0 +-504 201 526 0 +394 447 974 0 +-774 -371 6 0 +589 -641 -846 0 +-803 257 934 0 +-516 -909 -306 0 +714 521 -782 0 +445 -19 -48 0 +627 -174 -483 0 +-257 -39 -527 0 +-873 762 -609 0 +445 -575 -844 0 +61 580 -816 0 +-86 578 317 0 +-35 -244 -127 0 +312 -836 786 0 +106 600 425 0 +-417 373 724 0 +98 -354 339 0 +482 -465 580 0 +-99 -730 311 0 +300 501 8 0 +-118 -332 -680 0 +-272 351 918 0 +94 798 833 0 +743 693 454 0 +560 656 -842 0 +-18 175 -643 0 +592 -423 830 0 +723 23 -507 0 +155 342 307 0 +-113 -738 454 0 +77 -430 -740 0 +171 283 -262 0 +-907 -866 -853 0 +-370 -881 429 0 +726 522 -817 0 +360 225 -648 0 +-974 47 492 0 +-993 -103 330 0 +-572 592 131 0 +-588 295 193 0 +-240 -954 -787 0 +941 797 417 0 +-263 245 326 0 +-227 -317 -550 0 +114 539 309 0 +204 223 -420 0 +538 400 -602 0 +-630 47 500 0 +-293 -59 189 0 +-599 50 -501 0 +-615 772 928 0 +-1000 343 -494 0 +953 189 -451 0 +-310 349 317 0 +86 427 151 0 +-577 -685 318 0 +-264 732 337 0 +-130 816 -496 0 +-784 -994 -921 0 +-258 128 277 0 +158 -86 -992 0 +-335 -683 -537 0 +720 901 -244 0 +863 -290 163 0 +-501 368 -681 0 +-221 -127 -1 0 +-584 677 -864 0 +981 -370 -623 0 +-114 602 -63 0 +-198 322 -981 0 +907 -533 -124 0 +153 299 -836 0 +-70 -659 -575 0 +-806 694 -823 0 +-333 -628 -151 0 +95 212 46 0 +259 575 -809 0 +228 902 -894 0 +-308 981 448 0 +-153 -341 20 0 +92 616 966 0 +326 -743 -859 0 +328 -843 347 0 +653 -428 -401 0 +212 717 -475 0 +306 -976 -469 0 +462 -974 -653 0 +379 -310 437 0 +712 -698 -483 0 +-989 126 -848 0 +478 -92 -769 0 +515 878 774 0 +-763 494 605 0 +399 314 122 0 +118 759 -195 0 +-61 905 -917 0 +-774 550 -693 0 +-657 -222 263 0 +-923 665 352 0 +655 -267 -936 0 +-297 -442 -448 0 +-347 -866 -174 0 +630 -866 -116 0 +-429 628 -274 0 +-751 -630 -352 0 +-9 666 -468 0 +-544 -140 -594 0 +356 705 506 0 +-645 -248 546 0 +-643 338 -37 0 +148 684 522 0 +475 336 -315 0 +198 302 194 0 +919 -795 921 0 +24 607 145 0 +-316 593 -52 0 +761 -292 -37 0 +456 766 682 0 +-814 -294 348 0 +-940 417 722 0 +712 -131 465 0 +-987 -449 -78 0 +987 -639 824 0 +288 -314 458 0 +686 528 -813 0 +-539 -282 81 0 +32 889 937 0 +579 -161 281 0 +-768 -518 626 0 +-386 -130 866 0 +-721 736 -414 0 +-137 725 -275 0 +140 -157 293 0 +-257 -183 -90 0 +832 -404 -111 0 +-123 -955 -792 0 +-149 999 66 0 +-660 -659 -151 0 +80 243 -258 0 +972 -247 -865 0 +436 961 254 0 +-120 -251 -492 0 +744 618 -748 0 +867 36 -93 0 +-629 -793 345 0 +-443 542 -187 0 +-40 -358 -592 0 +634 806 -122 0 +363 316 -634 0 +-229 338 -451 0 +-452 -798 391 0 +-29 174 -585 0 +15 -609 -136 0 +-751 659 -813 0 +-45 962 -593 0 +-475 439 -271 0 +-949 858 631 0 +931 233 917 0 +-824 74 -274 0 +529 -560 -464 0 +-355 892 -526 0 +193 787 734 0 +-949 583 727 0 +675 -296 -745 0 +652 279 639 0 +314 241 -815 0 +-227 -578 919 0 +653 -278 -718 0 +986 46 -146 0 +974 -651 693 0 +206 781 -523 0 +284 -712 930 0 +-977 458 -497 0 +-80 -825 769 0 +-578 85 -297 0 +202 420 -852 0 +-231 -589 -38 0 +-542 553 -661 0 +-258 -979 36 0 +59 821 159 0 +949 148 -411 0 +-469 383 -200 0 +-466 342 -232 0 +790 211 160 0 +-525 363 -196 0 +695 -77 -2 0 +123 -639 19 0 +-200 636 -671 0 +-898 19 798 0 +-593 -496 -32 0 +267 -125 91 0 +-98 -188 623 0 +602 685 -198 0 +-69 875 -387 0 +825 -289 227 0 +-285 -551 753 0 +875 -178 -57 0 +-682 -686 614 0 +-614 756 -241 0 +-654 -736 235 0 +-743 -845 375 0 +-893 763 246 0 +406 -233 610 0 +468 100 466 0 +-705 293 43 0 +-724 -697 634 0 +-517 -184 -743 0 +327 849 227 0 +694 869 -145 0 +447 222 975 0 +-512 -834 609 0 +258 -423 -681 0 +204 584 925 0 +532 27 -920 0 +-402 -786 938 0 +807 -401 -373 0 +-492 812 526 0 +-988 779 -926 0 +60 -858 -774 0 +340 -277 -547 0 +-747 329 601 0 +610 -826 624 0 +930 -596 -227 0 +395 742 563 0 +-171 970 396 0 +-655 -664 -701 0 +284 103 275 0 +-758 -824 -979 0 +191 868 891 0 +-290 -479 108 0 +410 -576 -176 0 +-473 223 -956 0 +-687 -127 386 0 +145 -189 713 0 +54 49 -507 0 +-700 510 230 0 +993 989 135 0 +843 -454 900 0 +663 478 584 0 +285 -784 288 0 +-199 404 -713 0 +-374 -147 238 0 +-58 21 -893 0 +289 963 -278 0 +-886 642 -185 0 +85 -130 77 0 +-927 210 166 0 +-587 418 145 0 +-652 878 -171 0 +952 207 826 0 +262 -953 -165 0 +-589 -404 174 0 +-878 411 705 0 +549 -187 -469 0 +-332 481 364 0 +155 214 -991 0 +-16 -928 160 0 +849 699 -388 0 +653 831 -22 0 +398 415 768 0 +-805 -288 -201 0 +947 -95 -942 0 +-872 59 553 0 +-386 -223 260 0 +202 82 881 0 +-44 -944 -670 0 +-886 -706 306 0 +-459 -774 -452 0 +-826 -361 -562 0 +-318 -732 512 0 +-716 -791 647 0 +-103 821 153 0 +-858 -938 114 0 +-973 826 870 0 +457 -326 -320 0 +301 808 556 0 +-502 960 146 0 +-456 -88 -144 0 +-915 -856 521 0 +-526 -71 -405 0 +626 24 -395 0 +919 171 191 0 +-122 -60 268 0 +862 -650 -735 0 +117 -511 949 0 +649 797 82 0 +-907 -919 136 0 +644 843 -849 0 +635 213 149 0 +970 204 460 0 +-216 -728 -159 0 +466 -989 693 0 +-106 200 -666 0 +-429 250 -980 0 +967 465 788 0 +-8 -939 803 0 +605 113 -797 0 +-37 -187 -164 0 +-380 -551 -387 0 +-705 758 800 0 +725 -470 267 0 +-909 -123 -996 0 +568 334 -211 0 +-530 608 551 0 +-615 173 444 0 +-592 -617 -158 0 +-793 684 -373 0 +-706 991 177 0 +727 -9 -204 0 +-608 486 174 0 +532 -570 876 0 +970 490 832 0 +232 884 -162 0 +-439 161 -565 0 +-692 235 -767 0 +437 831 -610 0 +-461 -672 878 0 +-371 -303 -258 0 +937 -162 -795 0 +-996 599 -98 0 +813 -466 395 0 +440 -851 469 0 +-64 -432 -555 0 +921 875 752 0 +303 -71 474 0 +-445 666 604 0 +-124 380 -322 0 +770 348 341 0 +-371 194 -14 0 +-668 -689 -275 0 +-800 -539 628 0 +419 -727 -587 0 +925 -376 714 0 +579 371 525 0 +539 216 789 0 +-143 87 -927 0 +-878 -248 -479 0 +459 164 -265 0 +522 783 554 0 +924 281 -484 0 +214 -322 779 0 +806 -425 470 0 +-248 518 349 0 +-210 139 -554 0 +3 -426 577 0 +934 659 548 0 +486 576 -801 0 +390 -402 21 0 +184 -113 927 0 +789 708 35 0 +405 -680 -962 0 +606 -958 -268 0 +-268 647 -56 0 +616 -257 221 0 +880 -310 -627 0 +847 501 -515 0 +-495 -289 178 0 +511 789 135 0 +609 -92 438 0 +-141 -357 -74 0 +-762 -434 305 0 +390 257 574 0 +119 199 -231 0 +935 -303 295 0 +871 -692 596 0 +538 -29 588 0 +-776 -502 553 0 +-711 908 -645 0 +879 224 -108 0 +931 -278 369 0 +849 -926 944 0 +854 395 234 0 +943 -46 -430 0 +-993 -624 -80 0 +-152 -868 252 0 +234 -473 -273 0 +370 984 691 0 +454 -708 -934 0 +720 230 967 0 +-941 -56 782 0 +-793 959 863 0 +286 -380 846 0 +-332 502 -455 0 +-66 865 974 0 +-123 -646 -318 0 +-341 -851 -344 0 +750 -837 915 0 +-341 -18 -318 0 +356 -624 -955 0 +-800 -669 500 0 +-700 204 -60 0 +992 -794 -819 0 +273 -734 -715 0 +579 -101 -436 0 +941 640 -156 0 +-802 182 402 0 +578 -763 -740 0 +-541 875 -13 0 +-27 -706 -7 0 +-43 -704 -442 0 +-853 -642 -420 0 +99 -351 664 0 +-293 22 -296 0 +-412 -847 997 0 +114 -709 413 0 +408 -91 323 0 +-502 868 402 0 +-300 122 689 0 +96 179 -814 0 +-308 -399 -289 0 +376 -656 -122 0 +605 -906 -148 0 +14 -495 909 0 +-646 66 -4 0 +959 833 -12 0 +198 -368 -16 0 +414 850 -363 0 +-982 -842 -365 0 +-524 283 -919 0 +-357 802 -733 0 +-772 391 161 0 +-611 239 494 0 +217 211 135 0 +965 -737 501 0 +499 351 112 0 +746 621 102 0 +-574 689 -533 0 +927 -66 -483 0 +316 715 -389 0 +-117 -336 -861 0 +-482 -365 -492 0 +905 -178 -653 0 +-183 812 -820 0 +-422 -555 -483 0 +550 678 -31 0 +282 778 -14 0 +-964 -549 -730 0 +-589 23 -595 0 +13 -923 691 0 +30 356 912 0 +-884 437 -563 0 +13 -996 931 0 +-243 -452 -74 0 +116 549 -237 0 +-222 285 668 0 +261 -888 -458 0 +216 -937 -525 0 +-14 185 119 0 +-785 272 -276 0 +487 -361 443 0 +987 -28 342 0 +-224 -505 -245 0 +620 655 525 0 +442 -103 128 0 +-248 759 81 0 +-762 22 389 0 +552 -145 262 0 +737 520 -131 0 +95 -295 473 0 +-396 -678 518 0 +-827 -55 -863 0 +-432 132 172 0 +-322 94 -33 0 +-290 665 626 0 +-966 275 -284 0 +-835 -508 174 0 +-940 417 175 0 +369 345 -267 0 +-350 429 201 0 +-489 31 185 0 +857 574 47 0 +204 -573 416 0 +-207 -298 220 0 +780 -991 -452 0 +-287 -775 -523 0 +374 484 -596 0 +449 -289 -755 0 +238 564 -251 0 +134 517 -908 0 +-811 540 66 0 +-237 20 -239 0 +934 222 -769 0 +-927 -23 -716 0 +348 981 260 0 +-595 901 537 0 +623 641 -823 0 +126 -620 782 0 +-566 -383 -658 0 +-717 -345 -164 0 +-22 -808 50 0 +613 42 65 0 +568 -207 -976 0 +-225 52 -836 0 +132 -463 -325 0 +-590 -386 -593 0 +634 -53 722 0 +648 -242 -410 0 +-352 -400 -642 0 +-69 -514 143 0 +181 -760 -465 0 +347 -875 -177 0 +882 -983 14 0 +121 103 -992 0 +-734 380 -322 0 +-986 -920 -926 0 +872 -781 565 0 +-800 903 329 0 +588 234 -960 0 +-411 375 584 0 +503 -210 189 0 +-209 767 610 0 +-992 925 622 0 +394 350 96 0 +-163 851 -778 0 +-852 -221 822 0 +796 -21 148 0 +-423 736 150 0 +696 -795 33 0 +-719 778 195 0 +-19 -625 894 0 +132 -883 -183 0 +-699 9 -923 0 +-956 -249 248 0 +-591 160 -988 0 +564 479 -399 0 +552 463 -840 0 +-422 -349 -200 0 +713 687 36 0 +-541 -817 -915 0 +221 552 -288 0 +-890 -578 143 0 +41 669 -195 0 +-35 107 -411 0 +948 -745 51 0 +581 628 719 0 +814 -304 -456 0 +-271 70 492 0 +115 214 -92 0 +216 -885 -306 0 +-942 804 242 0 +-121 716 577 0 +543 -146 -639 0 +-589 404 -435 0 +-590 120 854 0 +663 900 -211 0 +-337 -47 -359 0 +9 -628 -677 0 +-348 -648 -332 0 +680 475 388 0 +742 254 -732 0 +-521 127 466 0 +778 -310 -969 0 +-367 369 991 0 +95 -87 710 0 +741 -956 585 0 +-405 263 140 0 +580 557 54 0 +-121 -946 617 0 +-971 -99 -509 0 +-151 367 240 0 +-239 -522 464 0 +-545 -534 948 0 +373 -197 559 0 +762 907 -263 0 +684 -261 -537 0 +-134 3 -45 0 +558 -150 -902 0 +-296 356 -865 0 +983 581 -892 0 +714 185 -300 0 +576 -696 -504 0 +150 950 -809 0 +-56 420 -15 0 +-92 59 -925 0 +-670 -483 -284 0 +-762 -702 96 0 +975 759 294 0 +-857 -518 142 0 +937 -486 518 0 +-244 -585 -845 0 +-129 -834 216 0 +-439 385 926 0 +-377 29 -922 0 +-989 -502 -303 0 +892 -472 422 0 +-275 -561 26 0 +-747 887 -791 0 +277 -762 111 0 +-967 -891 286 0 +-470 -164 261 0 +762 527 -558 0 +159 -757 553 0 +944 270 558 0 +-398 -3 151 0 +-9 -715 80 0 +436 -15 -947 0 +872 -60 -213 0 +658 298 -787 0 +2 -784 94 0 +461 398 -696 0 +-550 982 -33 0 +199 -645 -154 0 +732 361 617 0 +-515 -386 -115 0 +-105 73 -165 0 +-145 165 48 0 +751 -977 -39 0 +995 -918 -892 0 +772 651 578 0 +110 311 -640 0 +-388 -139 693 0 +493 96 798 0 +-225 600 -253 0 +-226 -574 -530 0 +-86 156 599 0 +379 -15 299 0 +-953 622 967 0 +690 -454 -764 0 +688 -463 -265 0 +-123 -473 -282 0 +580 451 -242 0 +-642 523 -57 0 +-569 561 898 0 +754 -557 228 0 +121 547 734 0 +-133 -329 -314 0 +357 643 45 0 +-576 247 -677 0 +-819 8 -642 0 +312 496 941 0 +678 -196 46 0 +222 622 -17 0 +318 -303 757 0 +239 -649 219 0 +-944 -516 -448 0 +-336 293 290 0 +368 -868 915 0 +-84 11 -373 0 +40 -699 -964 0 +-202 849 -470 0 +627 -951 71 0 +441 238 354 0 +657 517 32 0 +-694 -306 -77 0 +-236 -977 821 0 +-304 -194 61 0 +236 -921 118 0 +-646 -644 691 0 +625 544 202 0 +785 992 -843 0 +504 -494 -713 0 +44 -556 192 0 +788 168 -891 0 +276 -183 940 0 +899 -163 705 0 +-440 172 -863 0 +-378 775 262 0 +285 670 583 0 +-235 35 414 0 +-106 117 -671 0 +999 -213 -140 0 +362 -775 977 0 +-882 197 -734 0 +-820 -969 -873 0 +335 920 740 0 +-919 350 -312 0 +-271 849 -548 0 +-643 -642 5 0 +-150 52 473 0 +-433 455 692 0 +-365 -631 918 0 +-390 -280 -124 0 +70 -544 -976 0 +-193 -235 -163 0 +-803 58 770 0 +-107 817 -323 0 +-67 954 124 0 +516 291 629 0 +-545 760 361 0 +483 591 -141 0 +650 294 -570 0 +-53 -855 -45 0 +57 -940 449 0 +471 -134 843 0 +-618 -732 -452 0 +-895 674 -939 0 +-970 -550 26 0 +220 493 874 0 +-948 159 602 0 +-777 195 898 0 +346 104 802 0 +-77 90 -923 0 +-441 -648 -480 0 +264 288 939 0 +385 780 267 0 +-195 -861 244 0 +143 713 -836 0 +-542 733 -739 0 +-138 -480 837 0 +527 -480 -38 0 +950 252 48 0 +993 -436 812 0 +563 705 -378 0 +-464 369 838 0 +843 378 571 0 +-391 634 680 0 +-799 -626 113 0 +599 -28 -285 0 +155 -210 981 0 +109 545 206 0 +-56 583 601 0 +969 -436 260 0 +-153 629 969 0 +-419 -514 -99 0 +-802 16 -922 0 +478 -996 778 0 +645 -389 -188 0 +-726 718 635 0 +-467 -116 272 0 +-669 105 -302 0 +763 -372 -778 0 +291 226 885 0 +-790 669 99 0 +889 -995 716 0 +130 777 926 0 +907 -699 268 0 +717 -940 718 0 +271 -425 247 0 +-502 -808 -866 0 +514 -958 709 0 +-984 841 16 0 +556 -188 999 0 +771 954 -758 0 +-182 -990 -919 0 +-44 475 -859 0 +-694 -423 -696 0 +296 -945 -131 0 +48 140 775 0 +365 275 615 0 +604 -950 757 0 +-861 -820 -377 0 +-763 -435 696 0 +-3 130 -493 0 +-567 281 -685 0 +-372 609 -445 0 +597 338 -679 0 +-400 588 68 0 +-909 536 -785 0 +455 -275 -102 0 +-362 -693 -529 0 +-709 -239 -513 0 +894 679 888 0 +-163 -479 -470 0 +459 264 -456 0 +-272 325 773 0 +297 -991 -119 0 +378 502 198 0 +-65 -466 57 0 +-411 -381 95 0 +970 862 699 0 +941 585 -538 0 +-239 41 35 0 +659 -210 826 0 +330 260 804 0 +509 80 -343 0 +-244 243 -134 0 +-338 -620 605 0 +698 -213 -768 0 +298 -923 762 0 +-995 41 -763 0 +309 -285 865 0 +996 104 619 0 +-896 -478 660 0 +-800 -904 -404 0 +546 812 101 0 +487 36 186 0 +-689 -218 -646 0 +482 490 304 0 +-503 -946 -116 0 +-722 52 430 0 +-905 -949 505 0 +776 969 866 0 +292 -613 957 0 +-26 -240 515 0 +429 58 -978 0 +149 86 -175 0 +982 -863 -415 0 +960 -343 717 0 +-836 688 102 0 +-762 609 -496 0 +117 630 -979 0 +-334 916 552 0 +-110 253 828 0 +-165 -873 -905 0 +670 -486 -898 0 +400 -529 -651 0 +-240 -334 -981 0 +-728 -869 -271 0 +957 101 -67 0 +226 -679 363 0 +-228 234 899 0 +-420 -43 965 0 +-535 -974 -97 0 +352 -162 737 0 +-141 -723 -553 0 +-76 -936 567 0 +943 -520 88 0 +683 557 827 0 +-939 49 551 0 +-645 -76 -797 0 +386 -913 -167 0 +694 -615 257 0 +-201 -294 154 0 +-492 -108 66 0 +-653 469 158 0 +717 294 444 0 +-881 -528 754 0 +-750 -23 -880 0 +26 578 -83 0 +933 386 742 0 +-913 910 -846 0 +489 -934 721 0 +-756 -611 -208 0 +155 446 977 0 +162 -899 -406 0 +951 355 290 0 +-810 -301 534 0 +618 846 -264 0 +36 755 -636 0 +-820 -709 736 0 +-442 304 -383 0 +449 66 -764 0 +-323 -635 298 0 +65 -624 254 0 +-43 -257 362 0 +348 -199 940 0 +-5 955 626 0 +-242 -3 651 0 +619 235 -881 0 +-203 -908 466 0 +526 874 -221 0 +-935 799 852 0 +618 -427 243 0 +724 -648 64 0 +576 -164 -662 0 +-772 710 -932 0 +986 578 -872 0 +-409 -920 573 0 +-126 499 335 0 +248 -533 -267 0 +-360 -755 862 0 +-811 1 577 0 +-73 -81 419 0 +-278 -367 600 0 +425 155 -186 0 +726 905 926 0 +798 -478 -415 0 +-134 301 -617 0 +709 12 175 0 +744 326 -578 0 +-114 473 79 0 +833 276 577 0 +26 808 -346 0 +-860 414 -158 0 +329 -731 -61 0 +874 -377 903 0 +223 108 -790 0 +-791 215 898 0 +404 341 -186 0 +996 972 490 0 +-126 -518 256 0 +-513 -754 604 0 +176 267 -31 0 +-196 -819 172 0 +834 -11 986 0 +-82 -849 -931 0 +450 746 -60 0 +159 196 615 0 +530 -75 318 0 +562 -316 112 0 +-206 -404 157 0 +-569 289 -530 0 +-152 -201 2 0 +497 749 -639 0 +314 -368 289 0 +698 -899 935 0 +768 -133 239 0 +991 -934 231 0 +-964 742 141 0 +-969 135 94 0 +232 519 158 0 +-547 939 736 0 +-176 202 -160 0 +-748 -999 -473 0 +219 134 -382 0 +666 989 607 0 +-55 87 -355 0 +-800 673 -722 0 +-38 -973 -751 0 +-373 32 787 0 +423 74 217 0 +-515 529 -444 0 +-426 969 378 0 +649 -218 -389 0 +316 767 -901 0 +417 -753 712 0 +-595 -300 635 0 +403 689 569 0 +-130 536 131 0 +-410 -758 621 0 +654 -826 -928 0 +514 210 217 0 +-417 -570 755 0 +-833 -491 945 0 +439 -381 -1 0 +895 183 18 0 +330 682 -26 0 +201 822 -550 0 +-52 269 -817 0 +877 -274 -264 0 +360 -688 172 0 +-43 152 -209 0 +-632 961 327 0 +361 -923 662 0 +739 952 176 0 +-196 -218 371 0 +752 -160 446 0 +-912 -881 168 0 +383 70 792 0 +110 268 -324 0 +719 988 -837 0 +554 127 290 0 +826 626 300 0 +161 28 471 0 +-934 921 -240 0 +-415 -19 -297 0 +-486 -734 114 0 +-839 890 -299 0 +303 565 833 0 +-679 -632 180 0 +582 -439 66 0 +961 -41 -820 0 +-59 594 -151 0 +-426 -422 -826 0 +-107 8 -235 0 +844 958 -838 0 +-210 -243 193 0 +307 258 418 0 +485 -57 492 0 +-150 110 -460 0 +870 320 219 0 +529 -410 885 0 +762 -967 -506 0 +-288 -458 -211 0 +-583 -974 -330 0 +-825 847 457 0 +-496 -597 -548 0 +931 560 334 0 +-457 -290 291 0 +754 796 555 0 +938 359 -334 0 +668 486 782 0 +-361 -678 840 0 +170 -13 213 0 +-808 156 300 0 +-98 -834 461 0 +-58 417 233 0 +-885 -719 144 0 +-193 -485 -392 0 +826 -876 391 0 +165 972 -472 0 +-317 -920 649 0 +839 -697 893 0 +-529 739 -156 0 +-271 -1 -952 0 +286 -535 452 0 +-555 201 -78 0 +-740 -765 -492 0 +62 778 -924 0 +-46 967 -621 0 +592 984 -29 0 +-310 235 262 0 +473 391 -87 0 +1000 -82 717 0 +344 -62 -844 0 +994 -174 -36 0 +-380 591 -160 0 +469 -781 -968 0 +596 -152 780 0 +-773 -133 493 0 +-240 -354 -26 0 +-701 -869 416 0 +-229 181 -618 0 +735 154 982 0 +-212 -277 -928 0 +-220 217 271 0 +-778 -487 -371 0 +350 -657 505 0 +148 11 746 0 +410 27 999 0 +-476 -998 -405 0 +922 507 606 0 +275 752 -410 0 +-510 842 680 0 +805 -316 -960 0 +672 -765 -771 0 +-200 -470 -162 0 +-232 -334 440 0 +593 -757 -676 0 +-6 -971 779 0 +71 -193 -913 0 +28 -832 230 0 +798 659 843 0 +-196 990 -932 0 +95 -37 600 0 +-137 -175 509 0 +20 778 -620 0 +-341 -644 841 0 +19 -235 -55 0 +-96 -828 905 0 +543 -279 218 0 +-939 341 859 0 +137 558 711 0 +-555 678 453 0 +-84 288 -306 0 +-959 510 592 0 +856 793 -623 0 +767 -821 922 0 +444 -810 -325 0 +-12 175 -942 0 +267 979 358 0 +-977 -660 838 0 +-126 840 -92 0 +-44 241 133 0 +-522 361 325 0 +212 921 -756 0 +399 915 945 0 +581 -631 507 0 +998 641 572 0 +585 -670 849 0 +-959 -846 -32 0 +-13 961 24 0 +-942 -807 -923 0 +-975 139 3 0 +-793 164 -591 0 +-496 -802 -512 0 +969 655 -929 0 +463 576 -823 0 +736 937 485 0 +800 496 -963 0 +799 -263 -445 0 +959 708 534 0 +706 -50 -414 0 +-615 339 -50 0 +973 -85 896 0 +559 510 260 0 +-714 783 689 0 +-581 -110 -257 0 +-429 162 -843 0 +285 -951 718 0 +19 -353 -510 0 +302 532 167 0 +-992 -477 -537 0 +-152 844 -819 0 +134 212 -215 0 +643 9 -709 0 +927 -821 443 0 +-101 -680 782 0 +333 440 100 0 +926 192 -269 0 +124 858 -413 0 +-376 151 938 0 +-605 -700 -461 0 +981 103 -770 0 +-258 -575 323 0 +-405 604 -353 0 +418 -485 709 0 +733 595 -892 0 +-845 289 -619 0 +-181 617 -216 0 +302 706 -102 0 +385 -631 -4 0 +805 492 820 0 +-543 -386 -876 0 +-344 -164 -420 0 +-286 841 -779 0 +426 -502 -9 0 +179 923 850 0 +-437 606 -278 0 +365 527 801 0 +-696 -505 517 0 +114 -324 746 0 +-926 204 919 0 +194 922 217 0 +446 -101 75 0 +-188 -287 -60 0 +-962 -856 -744 0 +587 -578 110 0 +-299 439 -728 0 +681 534 815 0 +-2 525 435 0 +286 154 -72 0 +374 121 -858 0 +-816 731 -479 0 +530 973 125 0 +541 835 -841 0 +-764 125 -742 0 +196 600 60 0 +-599 -312 -811 0 +458 -813 853 0 +430 -394 288 0 +400 81 17 0 +338 303 460 0 +108 652 446 0 +-630 507 566 0 +-981 314 635 0 +-800 -586 156 0 +-365 -246 704 0 +-118 -777 802 0 +352 -190 585 0 +921 -720 992 0 +331 486 891 0 +575 554 -577 0 +330 29 98 0 +-245 961 -111 0 +-510 588 799 0 +474 -321 -565 0 +137 -57 839 0 +843 -508 243 0 +342 -242 -315 0 +48 -370 -193 0 +195 -44 168 0 +-796 619 -913 0 +908 965 408 0 +-935 924 259 0 +-644 -817 -387 0 +840 903 456 0 +-737 656 175 0 +177 -355 651 0 +-446 -660 -34 0 +-726 -333 772 0 +842 900 -545 0 +102 456 -143 0 +126 311 897 0 +14 937 106 0 +833 -951 796 0 +-361 -766 -377 0 +-782 -110 -786 0 +-408 -150 -921 0 +-124 -101 467 0 +749 -433 -126 0 +931 446 -485 0 +4 754 890 0 +277 -509 661 0 +263 -271 550 0 +-36 342 -246 0 +832 29 -235 0 +-877 -603 -265 0 +-543 253 -342 0 +-997 -658 957 0 +572 360 742 0 +-960 350 739 0 +-968 -221 206 0 +-845 -515 746 0 +485 200 -915 0 +-801 835 78 0 +-360 517 -530 0 +-415 40 -545 0 +207 29 619 0 +363 -565 -557 0 +-32 346 24 0 +617 428 -446 0 +594 995 -564 0 +-123 -588 884 0 +-18 -801 -373 0 +-962 814 -526 0 +-289 605 -48 0 +222 -971 578 0 +-867 -551 -856 0 +-6 646 -445 0 +-485 -777 -480 0 +-573 -73 975 0 +-874 -126 -354 0 +-57 -559 501 0 +-188 -304 626 0 +-948 -474 383 0 +-496 -275 213 0 +616 606 -88 0 +228 612 240 0 +268 -482 -502 0 +-461 -403 -41 0 +-170 401 -841 0 +279 -579 435 0 +893 934 -311 0 +931 349 -484 0 +534 -247 308 0 +265 703 -585 0 +198 -570 166 0 +166 483 551 0 +-169 -542 -89 0 +-726 352 754 0 +-991 -951 -768 0 +-571 -133 -810 0 +-588 -976 -62 0 +-388 -840 935 0 +-211 799 -640 0 +-793 -63 -831 0 +682 180 637 0 +675 229 -364 0 +847 -572 -703 0 +800 -760 -56 0 +816 98 -78 0 +696 -679 547 0 +-715 987 -482 0 +-247 242 -972 0 +410 186 -174 0 +-194 61 -325 0 +859 787 836 0 +847 -39 -557 0 +-685 -148 -504 0 +-934 44 54 0 +904 -978 -186 0 +704 24 -276 0 +-59 113 -148 0 +384 491 -896 0 +-708 314 124 0 +220 -277 -229 0 +-74 -607 185 0 +211 -330 954 0 +427 201 562 0 +827 205 -253 0 +495 485 218 0 +-460 999 327 0 +-530 -958 -662 0 +-78 -234 -109 0 +185 -177 236 0 +675 893 -507 0 +-528 -915 510 0 +-972 111 -566 0 +915 -156 528 0 +901 -453 -489 0 +919 -91 -859 0 +-69 255 986 0 +-232 -33 286 0 +859 -99 -11 0 +-291 425 664 0 +-793 588 89 0 +615 -410 -521 0 +-953 -531 817 0 +537 168 -747 0 +808 123 -521 0 +-878 -978 779 0 +465 -986 -861 0 +295 872 -593 0 +190 159 147 0 +-441 -341 986 0 +144 -729 60 0 +559 877 -491 0 +29 -339 434 0 +-85 -297 140 0 +195 -6 115 0 +368 -609 -504 0 +-894 -749 623 0 +102 -366 743 0 +-823 -31 -567 0 +654 84 -148 0 +-130 116 -306 0 +728 -91 -281 0 +-628 -536 81 0 +269 901 920 0 +-695 -65 49 0 +-66 919 -884 0 +-508 88 -847 0 +-607 289 -682 0 +94 657 -131 0 +283 -508 841 0 +70 -479 -492 0 +227 574 -600 0 +690 708 515 0 +-853 -269 575 0 +-615 -717 18 0 +-139 166 -483 0 +720 746 976 0 +-328 320 -370 0 +985 709 637 0 +-499 -494 -589 0 +275 733 -469 0 +-666 877 -96 0 +644 362 653 0 +956 -27 -73 0 +-855 -834 -797 0 +-529 -922 -879 0 +-43 -573 404 0 +840 802 -831 0 +-42 -662 -303 0 +997 -340 -489 0 +-610 323 -901 0 +238 310 44 0 +-507 802 252 0 +839 84 870 0 +-676 -173 -606 0 +720 249 -358 0 +-796 422 139 0 +223 -946 246 0 +513 -700 -506 0 +560 -310 -147 0 +670 520 -652 0 +-146 -910 922 0 +333 -969 -164 0 +936 -814 585 0 +106 -135 979 0 +-48 191 544 0 +-667 -46 916 0 +551 -241 -269 0 +152 -493 231 0 +271 987 523 0 +-584 -751 444 0 +68 -488 661 0 +-490 -774 801 0 +-388 769 -394 0 +-319 -163 -936 0 +213 -978 410 0 +-856 339 -24 0 +590 -526 779 0 +753 -150 376 0 +866 253 -675 0 +-949 -892 -976 0 +260 -174 240 0 +339 351 -198 0 +-944 27 -773 0 +769 557 -149 0 +541 808 -100 0 +-847 601 -406 0 +-248 -786 546 0 +-596 -551 741 0 +537 -593 -253 0 +774 -333 -240 0 +-85 -244 696 0 +-190 -135 -392 0 +-916 141 721 0 +25 223 -354 0 +-966 -976 514 0 +572 -756 697 0 +370 98 -446 0 +585 -812 289 0 +775 -613 -943 0 +-171 -332 600 0 +-127 784 755 0 +-904 498 261 0 +-915 -462 961 0 +-733 -574 880 0 +-1000 -769 804 0 +-723 581 60 0 +-482 911 -884 0 +295 290 -271 0 +1 670 -304 0 +-13 452 772 0 +589 -963 -263 0 +781 132 87 0 +240 902 716 0 +464 636 564 0 +-853 179 297 0 +-359 -811 709 0 +-215 872 -534 0 +921 974 -653 0 +785 -964 -728 0 +108 741 307 0 +-890 21 -654 0 +-177 -236 686 0 +707 716 -998 0 +671 -791 936 0 +172 678 -967 0 +193 -742 800 0 +425 -880 780 0 +114 798 215 0 +964 954 -972 0 +-101 -320 -32 0 +583 812 -424 0 +973 607 -588 0 +-675 949 -544 0 +580 -790 -145 0 +-535 346 -911 0 +-334 388 -809 0 +-634 -25 -39 0 +-209 -148 520 0 +246 767 -669 0 +813 256 -148 0 +712 764 -19 0 +-755 -21 42 0 +-668 518 -187 0 +-711 954 -504 0 +768 753 -260 0 +-811 810 -824 0 +-225 941 -860 0 +751 -969 453 0 +-995 409 592 0 +-85 -582 791 0 +-681 -135 727 0 +-444 715 -286 0 +-303 199 373 0 +628 -966 -433 0 +-140 -186 967 0 +-930 758 850 0 +267 954 73 0 +-467 847 -272 0 +-466 -399 -104 0 +-906 459 -156 0 +465 -685 -412 0 +756 -482 795 0 +-661 -852 -464 0 +5 -615 116 0 +507 -752 607 0 +-184 298 -100 0 +305 104 424 0 +810 -771 -769 0 +-707 328 -936 0 +-506 -707 -899 0 +160 910 -833 0 +492 282 301 0 +633 211 -157 0 +256 231 -575 0 +-652 -794 881 0 +-874 963 880 0 +745 -136 -460 0 +-537 230 88 0 +-576 103 -42 0 +586 280 -862 0 +925 -5 863 0 +814 -567 72 0 +-852 -41 765 0 +410 419 -93 0 +985 654 -377 0 +-355 -171 750 0 +731 673 -576 0 +-240 633 -157 0 +578 959 936 0 +-981 675 -205 0 +690 -393 452 0 +603 -909 251 0 +222 -875 -689 0 +-597 -837 -124 0 +859 -345 -683 0 +123 -938 -452 0 +905 375 -465 0 +-947 -927 672 0 +369 33 -648 0 +-861 -530 -346 0 +740 290 845 0 +-94 559 589 0 +-753 301 -57 0 +-70 -486 -537 0 +-913 -607 -76 0 +703 -826 -202 0 +-192 303 -663 0 +-749 194 274 0 +889 -733 89 0 +-978 551 999 0 +344 -655 251 0 +-288 718 -470 0 +-411 687 36 0 +864 -890 252 0 +497 -431 -15 0 +-620 79 -411 0 +-972 -337 -712 0 +-645 923 -372 0 +-878 -545 747 0 +683 -211 -38 0 +-437 764 -30 0 +413 -40 -740 0 +-526 -392 -574 0 +-330 982 323 0 +649 587 200 0 +232 -586 -256 0 +-324 215 -510 0 +7 249 83 0 +933 767 252 0 +-481 670 -457 0 +-894 322 68 0 +473 -832 552 0 +555 -295 100 0 +-684 946 397 0 +383 417 381 0 +-755 759 634 0 +5 674 -708 0 +154 684 -647 0 +-501 -219 844 0 +-944 154 -949 0 +-353 411 633 0 +561 573 -430 0 +445 -773 -111 0 +445 436 -786 0 +-617 385 -609 0 +50 820 -763 0 +797 -553 -104 0 +719 -557 900 0 +-896 299 -738 0 +-751 232 947 0 +181 -189 -607 0 +768 293 -818 0 +955 -35 -687 0 +28 298 310 0 +688 -761 -269 0 +-937 459 -143 0 +834 807 -11 0 +-601 61 300 0 +-642 -137 -562 0 +-653 -78 536 0 +423 -435 -68 0 +-205 -367 623 0 +-615 -260 266 0 +-280 -685 955 0 +-341 539 504 0 +137 850 538 0 +767 -488 670 0 +-454 -607 457 0 +-75 107 928 0 +-4 324 -894 0 +-817 -272 113 0 +-673 -186 149 0 +-732 -393 -472 0 +865 -102 -551 0 +345 -404 -846 0 +-427 -468 -857 0 +188 466 -698 0 +805 -470 939 0 +-559 -565 42 0 +466 -208 756 0 +795 465 -367 0 +495 -787 -281 0 +-126 921 -222 0 +271 -980 192 0 +823 -767 974 0 +577 827 -822 0 +716 -614 694 0 +472 774 883 0 +-653 -74 -847 0 +376 -448 382 0 +369 689 973 0 +416 880 -869 0 +937 810 -967 0 +677 560 -627 0 +717 994 173 0 +-784 -392 -422 0 +-965 6 -545 0 +-870 1000 296 0 +950 -356 -171 0 +674 380 48 0 +-953 276 377 0 +984 -642 24 0 +-225 968 -25 0 +6 -995 99 0 +-861 686 -907 0 +578 19 74 0 +-307 474 -768 0 +74 109 -774 0 +900 -545 129 0 +754 -403 609 0 +966 -327 -186 0 +314 310 -382 0 +632 622 -227 0 +999 -254 -470 0 +561 481 -768 0 +350 -108 603 0 +-248 742 -527 0 +-368 131 837 0 +-633 479 19 0 +-597 -32 166 0 +-384 349 -253 0 +-211 618 -734 0 +319 591 997 0 +211 60 -687 0 +293 -689 475 0 +-18 -636 -315 0 +-880 -109 -332 0 +256 -172 -82 0 +-591 -788 371 0 +-997 689 960 0 +-624 -428 936 0 +665 181 -385 0 +1 -898 -886 0 +-377 -577 379 0 +-729 235 954 0 +921 173 -635 0 +904 -544 -112 0 +-919 660 875 0 +-548 180 -442 0 +598 -386 -331 0 +176 -843 -339 0 +943 -944 -273 0 +431 -671 -948 0 +-97 841 -688 0 +-10 78 600 0 +714 -595 867 0 +592 -431 -990 0 +-110 672 -765 0 +-70 -33 -508 0 +733 -730 661 0 +-585 -861 763 0 +-363 319 -553 0 +252 -536 209 0 +-656 641 412 0 +453 773 -200 0 +647 541 24 0 +-784 -536 -948 0 +-247 381 -260 0 +800 -626 -405 0 +-204 -1000 639 0 +-241 -799 -536 0 +387 223 2 0 +-930 -129 -441 0 +116 -829 -637 0 +668 -975 977 0 +-636 387 -948 0 +741 188 -410 0 +-106 934 -17 0 +240 675 629 0 +970 68 332 0 +627 -6 -591 0 +374 68 399 0 +-357 853 373 0 +-616 -114 358 0 +701 78 910 0 +-121 679 115 0 +594 -640 81 0 +68 871 981 0 +-34 -765 -800 0 +-503 -582 651 0 +922 -839 -501 0 +-236 757 661 0 +-3 -883 640 0 +174 389 -61 0 +-1 -110 -705 0 +-246 663 -25 0 +485 -968 -47 0 +413 794 80 0 +-339 60 -379 0 +-760 942 -748 0 +782 744 -414 0 +409 747 -691 0 +126 411 -619 0 +-715 -431 -597 0 +-922 -147 -145 0 +-826 252 -996 0 +-651 -296 263 0 +-796 291 882 0 +-790 472 -61 0 +412 -31 -59 0 +523 611 -211 0 +942 -917 -613 0 +-613 -147 -587 0 +-481 -359 -822 0 +769 -26 854 0 +504 -566 -930 0 +728 -211 -559 0 +-331 -84 9 0 +456 872 -158 0 +774 668 272 0 +107 -142 786 0 +85 217 -278 0 +-460 -282 -945 0 +751 -46 -981 0 +-729 522 -433 0 +496 -177 -85 0 +541 -430 -543 0 +987 364 -929 0 +-417 -124 -659 0 +935 13 302 0 +65 -707 117 0 +401 -112 -351 0 +-610 940 366 0 +302 544 -928 0 +898 -417 732 0 +-966 391 124 0 +24 -114 -470 0 +374 -799 741 0 +-160 915 423 0 +-26 -124 132 0 +-239 408 161 0 +-350 88 -389 0 +602 466 261 0 +471 -180 505 0 +881 178 -345 0 +-474 811 77 0 +-366 -62 565 0 +-113 -43 519 0 +-688 380 -435 0 +227 -439 -73 0 +-293 -774 -343 0 +-354 -781 143 0 +-211 510 859 0 +-55 80 -499 0 +-738 -522 -849 0 +-964 -206 761 0 +126 39 -906 0 +863 759 -292 0 +30 -449 995 0 +-768 860 175 0 +-658 -86 -26 0 +762 532 -639 0 +-216 386 554 0 +-443 306 -756 0 +754 747 838 0 +569 -115 340 0 +925 -725 971 0 +-645 665 -603 0 +-421 687 -982 0 +797 508 -485 0 +84 207 -828 0 +409 -943 -432 0 +-920 30 -226 0 +-630 -939 -127 0 +-246 340 -711 0 +-948 366 200 0 +-542 -828 441 0 +-513 -759 78 0 +404 289 -81 0 +-868 -88 803 0 +4 376 -888 0 +273 -31 596 0 +-760 -468 168 0 +-783 98 431 0 +933 159 705 0 +560 334 -437 0 +-60 418 875 0 +-641 267 -419 0 +-456 -280 -201 0 +-229 205 587 0 +695 644 93 0 +-467 14 -714 0 +704 805 883 0 +-113 498 -355 0 +-703 12 -262 0 +-242 -604 -649 0 +702 251 -244 0 +518 640 328 0 +398 -137 476 0 +-374 -504 -709 0 +-898 -186 289 0 +39 752 147 0 +685 53 601 0 +-73 -547 881 0 +-662 808 -52 0 +-232 -493 278 0 +-146 649 -461 0 +-226 776 931 0 +-881 -463 206 0 +728 605 -331 0 +-9 -600 619 0 +815 -592 -730 0 +930 -693 -877 0 +-314 -961 807 0 +-398 316 -733 0 +-897 -81 -539 0 +254 -948 -383 0 +170 -379 -793 0 +183 624 -652 0 +937 686 98 0 +-106 -976 330 0 +-602 1 -127 0 +-22 271 751 0 +87 -466 515 0 +-665 -216 238 0 +970 -802 576 0 +-418 243 968 0 +4 -622 -510 0 +954 -44 -547 0 +-681 -552 579 0 +-495 -525 6 0 +-546 -466 860 0 +883 722 115 0 +-914 558 575 0 +-255 -156 647 0 +-640 -228 -114 0 +747 352 297 0 +354 -627 179 0 +-44 -908 850 0 +-745 838 -243 0 +676 998 893 0 +748 -514 98 0 +-890 -175 -589 0 +111 -873 7 0 +124 803 748 0 +48 -711 139 0 +-641 576 233 0 +-553 163 598 0 +327 -192 -299 0 +-588 -306 796 0 +-341 -926 688 0 +73 -569 -955 0 +320 -958 74 0 +411 2 -210 0 +159 582 -51 0 +-510 163 -378 0 +-935 42 -513 0 +-973 -651 952 0 +-886 -276 884 0 +-343 -295 434 0 +-66 521 -888 0 +90 -599 -176 0 +797 257 68 0 +938 -108 -129 0 +-476 282 231 0 +887 273 -480 0 +-437 674 162 0 +735 911 -334 0 +-543 -316 -422 0 +747 335 39 0 +-599 -236 567 0 +692 499 -589 0 +780 -393 970 0 +879 -318 -633 0 +756 446 541 0 +-84 -770 -606 0 +954 266 934 0 +-316 243 -584 0 +-359 311 817 0 +-807 648 -685 0 +-1 -224 915 0 +-485 -309 346 0 +-961 110 122 0 +371 173 147 0 +-956 -757 -321 0 +749 104 -467 0 +-344 709 765 0 +-521 -278 -297 0 +635 -354 183 0 +678 920 -955 0 +82 -883 -672 0 +643 -38 274 0 +15 -871 -427 0 +-276 607 357 0 +477 -728 394 0 +-910 -84 163 0 +136 908 758 0 +-934 -493 533 0 +70 -290 424 0 +740 -4 960 0 +178 -775 -770 0 +135 598 62 0 +319 38 955 0 +-566 -907 -781 0 +569 99 470 0 +15 -610 977 0 +538 221 119 0 +-227 -477 860 0 +-479 136 -786 0 +305 564 -772 0 +504 -593 63 0 +66 -34 601 0 +423 -576 -305 0 +64 -265 -969 0 +-118 143 369 0 +-486 824 -261 0 +-39 -363 -809 0 +996 -197 -297 0 +-328 -401 -782 0 +-28 -581 806 0 +-397 -474 953 0 +-45 -661 172 0 +870 -213 683 0 +298 -69 492 0 +838 511 -360 0 +-400 514 195 0 +782 884 638 0 +-421 -192 -789 0 +-277 -472 -384 0 +-191 -579 73 0 +-944 -585 -897 0 +1 301 143 0 +404 -815 -342 0 +-136 -857 -183 0 +576 22 -773 0 +-877 548 654 0 +578 -600 93 0 +513 -128 353 0 +688 -325 -652 0 +-631 512 71 0 +74 -15 -638 0 +748 -597 356 0 +-344 366 -575 0 +-153 -835 -117 0 +-274 -332 -997 0 +-835 333 -36 0 +-217 -320 40 0 +-91 240 435 0 +-796 -311 851 0 +506 538 -915 0 +150 -318 -895 0 +-251 -818 631 0 +552 628 63 0 +713 -447 -535 0 +184 -786 386 0 +-458 -422 573 0 +327 191 5 0 +289 291 220 0 +62 222 -208 0 +-463 -970 -52 0 +336 727 612 0 +-753 -464 -596 0 +379 -948 321 0 +593 -880 -698 0 +-366 331 -328 0 +-351 -235 193 0 +871 671 -663 0 +-544 479 147 0 +323 406 -21 0 +172 46 262 0 +-500 -138 715 0 +966 776 491 0 +149 6 338 0 +-477 500 -650 0 +-243 850 580 0 +-768 -76 -232 0 +376 -438 912 0 +310 -674 -3 0 +940 -474 -645 0 +46 -866 142 0 +373 969 -495 0 +-358 801 -758 0 +736 -496 -20 0 +-580 1 479 0 +133 658 -577 0 +899 -580 -558 0 +607 -427 850 0 +991 82 764 0 +14 -514 -434 0 +848 -553 -385 0 +73 791 -509 0 +-277 23 799 0 +821 -961 538 0 +676 -5 706 0 +-864 -257 -941 0 +-124 32 -150 0 +-490 576 -171 0 +-44 -835 -257 0 +-715 -706 341 0 +992 -752 -70 0 +56 -435 -217 0 +348 298 -680 0 +604 325 -30 0 +-529 -881 564 0 +-971 -548 -233 0 +800 -382 -224 0 +343 -173 -587 0 +-189 -368 -319 0 +-901 975 -494 0 +728 627 768 0 +533 224 941 0 +738 240 -871 0 +473 589 -39 0 +-569 -185 706 0 +-817 342 358 0 +145 -956 -549 0 +306 -69 -485 0 +550 842 929 0 +-698 113 -9 0 +-143 -884 -488 0 +-891 -474 -907 0 +-62 -451 793 0 +-836 730 896 0 +382 -755 936 0 +83 366 712 0 +-765 874 -679 0 +840 -541 -382 0 +-784 297 -334 0 +-444 -144 -705 0 +-372 -821 -798 0 +102 -292 577 0 +524 -49 225 0 +-699 -225 420 0 +780 -221 807 0 +832 959 -951 0 +-443 146 -998 0 +-336 312 -425 0 +-724 -2 -490 0 +488 -472 632 0 +606 997 -474 0 +989 -725 163 0 +-30 -484 365 0 +914 -465 908 0 +-896 378 -151 0 +-901 599 23 0 +193 -643 915 0 +738 168 322 0 +-599 -231 -477 0 +599 -163 985 0 +-645 829 713 0 +-751 596 80 0 +147 -171 69 0 +990 737 -961 0 +84 111 951 0 +944 -679 -910 0 +245 371 -771 0 +-337 62 -461 0 +272 -47 -326 0 +418 189 927 0 +867 810 -657 0 +835 856 -649 0 +-628 -360 658 0 +-139 -351 490 0 +177 -373 287 0 +847 -448 98 0 +-108 488 544 0 +-23 578 476 0 +178 -683 611 0 +-656 -309 285 0 +938 -913 632 0 +606 700 -649 0 +27 421 -624 0 +201 -587 822 0 +697 111 -844 0 +-276 -355 -736 0 +953 278 -606 0 +518 609 173 0 +-795 -86 35 0 +212 -146 398 0 +-811 375 -854 0 +-770 807 346 0 +435 983 -403 0 +73 300 94 0 +940 -879 134 0 +78 -307 136 0 +-507 110 -600 0 +655 -264 987 0 +265 150 -29 0 +348 724 -635 0 +238 339 343 0 +-591 91 -949 0 +186 -313 -771 0 +-571 825 -160 0 +-363 -721 -627 0 +-488 726 16 0 +482 -958 976 0 +-407 150 963 0 +835 76 884 0 +456 -354 241 0 +-46 458 561 0 +-772 426 -802 0 +-814 110 -232 0 +8 708 794 0 +-341 -581 66 0 +385 946 77 0 +-294 628 -495 0 +439 131 -593 0 +379 570 -337 0 +-967 -353 137 0 +693 -923 -958 0 +-475 -278 274 0 +856 -308 -527 0 +-204 918 -326 0 +503 328 859 0 +679 -667 -502 0 +-521 415 -495 0 +-968 299 -45 0 +-80 699 349 0 +359 -621 -602 0 +962 136 -982 0 +-868 15 758 0 +-742 -91 -717 0 +-469 733 436 0 +-308 -672 79 0 +-815 605 379 0 +-687 -600 -855 0 +658 -634 517 0 +-419 -624 -216 0 +520 620 -297 0 +502 664 -672 0 +174 -194 -347 0 +642 285 409 0 +-626 856 698 0 +-819 -994 431 0 +624 -349 -308 0 +350 -876 540 0 +126 424 -893 0 +-560 -376 -543 0 +-97 -390 -875 0 +439 -925 -413 0 +-357 -516 832 0 +599 -609 -768 0 +-698 -340 -765 0 +108 421 -964 0 +-856 -7 964 0 +65 -504 -85 0 +694 -57 -224 0 +73 -62 -288 0 +326 946 785 0 +36 853 169 0 +-574 156 538 0 +127 -374 -935 0 +375 -5 -761 0 +817 583 -403 0 +-178 -316 -825 0 +-193 -751 293 0 +526 -522 848 0 +91 -354 -53 0 +363 -168 680 0 +-721 -229 -418 0 +-927 -319 -653 0 +-410 -710 546 0 +391 644 967 0 +-636 -50 225 0 +-445 -635 631 0 +-26 701 340 0 +83 -96 868 0 +-607 -522 865 0 +-620 -519 62 0 +-199 750 -54 0 +959 -533 -492 0 +51 665 -784 0 +209 -654 137 0 +574 -262 622 0 +-41 -567 -415 0 +319 708 -563 0 +-441 -146 -569 0 +-166 354 -661 0 +606 -382 -255 0 +756 -122 109 0 +-354 -577 399 0 +-225 212 -289 0 +761 951 703 0 +-132 828 -690 0 +-389 501 -185 0 +-573 -462 78 0 +272 511 -42 0 +810 358 467 0 +-389 -286 678 0 +-44 -391 -415 0 +987 825 807 0 +73 204 -589 0 +532 937 -434 0 +637 797 410 0 +-227 -840 -889 0 +760 437 839 0 +644 -221 325 0 +-790 -670 -961 0 +-353 -999 445 0 +-625 -135 -52 0 +416 -709 -393 0 +-642 545 -875 0 +-49 -303 297 0 +201 -597 204 0 +420 -150 995 0 +-265 -519 -853 0 +-889 401 737 0 +779 679 186 0 +583 88 -299 0 +561 252 958 0 +884 -23 570 0 +210 -20 266 0 +706 263 -912 0 +-937 648 -521 0 +-601 -176 672 0 +-455 -640 138 0 +-904 -721 -259 0 +-70 -612 872 0 +-678 635 215 0 +-768 526 707 0 +-690 -494 -752 0 +360 625 572 0 +154 -66 512 0 +929 738 -286 0 +963 698 177 0 +449 -713 -212 0 +-292 -539 551 0 +-841 -688 -122 0 +452 817 -256 0 +-426 -312 -263 0 +-463 407 561 0 +-968 373 147 0 +765 -359 303 0 +420 -51 -862 0 +-815 676 237 0 +572 470 -540 0 +-927 -889 -547 0 +-111 -116 649 0 +-981 -546 463 0 +-513 -146 400 0 +708 -102 461 0 +-140 1000 789 0 +-724 615 576 0 +635 -197 -291 0 +263 658 590 0 +182 -966 -289 0 +-865 -74 -447 0 +705 327 -531 0 +954 540 -56 0 +-839 38 -857 0 +-218 -691 736 0 +-660 639 816 0 +-63 -637 519 0 +-49 -819 -336 0 +989 -803 -838 0 +-365 -438 -203 0 +24 -494 -430 0 +791 -550 493 0 +-666 -793 100 0 +-725 -139 -253 0 +-787 -9 -191 0 +-208 -322 -895 0 +997 -371 491 0 +-443 599 -220 0 +-386 -969 -731 0 +261 -648 878 0 +834 -158 730 0 +998 392 276 0 +-939 472 -427 0 +-310 -797 618 0 +881 -785 485 0 +-95 -854 382 0 +541 956 -737 0 +-826 983 -163 0 +-232 -310 306 0 +-149 -355 -706 0 +884 -86 475 0 +-126 782 -631 0 +952 -730 934 0 +-760 -1000 971 0 +-710 125 472 0 +650 948 -457 0 +830 94 -201 0 +429 772 839 0 +-401 953 -25 0 +-402 847 -905 0 +407 -420 235 0 +239 705 519 0 +339 -963 545 0 +-811 -300 -151 0 +163 -913 -107 0 +-46 248 726 0 +982 630 -612 0 +577 381 417 0 +-686 -780 -642 0 +-395 -28 -330 0 +-67 986 -427 0 +717 999 -363 0 +-174 -878 843 0 +376 829 795 0 +779 -322 129 0 +-42 70 752 0 +-33 850 358 0 +690 -527 -923 0 +-761 867 328 0 +-927 117 554 0 +159 -997 -427 0 +316 509 854 0 +373 124 -442 0 +-856 852 -708 0 +638 -720 899 0 +-434 861 -912 0 +824 -402 -795 0 +817 215 704 0 +441 13 439 0 +83 687 -714 0 +-791 -70 69 0 +412 -728 931 0 +-240 122 -961 0 +378 220 450 0 +493 612 228 0 +-189 521 912 0 +-772 536 -436 0 +-380 -578 -859 0 +905 305 -489 0 +430 48 -1000 0 +920 294 -312 0 +-670 -797 47 0 +-423 -86 -169 0 +958 -531 817 0 +-163 -743 -855 0 +-225 956 -769 0 +-852 912 282 0 +952 -276 -978 0 +173 -618 706 0 +769 -823 555 0 +375 -740 577 0 +889 -306 585 0 +-415 258 -163 0 +-121 337 -428 0 +-745 -16 259 0 +192 556 -850 0 +772 617 -606 0 +-598 -260 -180 0 +741 -108 -988 0 +-363 3 967 0 +-590 -941 587 0 +506 -391 817 0 +-102 183 -368 0 +-341 -790 -772 0 +-965 -65 902 0 +245 429 -940 0 +613 365 186 0 +-933 718 -175 0 +615 636 -111 0 +-763 -138 -578 0 +903 -851 -319 0 +196 -702 -289 0 +787 -988 455 0 +688 426 603 0 +206 46 -204 0 +-530 -986 994 0 +979 875 -79 0 +-603 557 -25 0 +62 -358 -811 0 +-231 -96 -457 0 +-72 599 779 0 +300 489 -200 0 +-804 936 433 0 +923 738 -565 0 +919 -879 -563 0 +269 -967 -747 0 +-318 669 -546 0 +-226 173 369 0 +-844 -550 433 0 +809 -514 -354 0 +-911 -932 -844 0 +814 -481 -628 0 +813 497 -61 0 +650 326 -206 0 +478 506 -382 0 +-908 -341 457 0 +-713 -411 140 0 +-384 -276 -805 0 +689 232 -860 0 +727 -337 273 0 +121 534 25 0 +384 -403 -338 0 +-128 299 -615 0 +-363 -714 612 0 +63 -17 767 0 +-522 685 32 0 +-921 -256 -427 0 +393 -748 413 0 +17 -55 -792 0 +-483 559 116 0 +634 -489 453 0 +-458 5 968 0 +-94 246 946 0 +-919 -678 -509 0 +340 -181 513 0 +-668 234 570 0 +-913 521 -393 0 +831 -534 973 0 +928 202 -522 0 +-740 -429 535 0 +-454 118 -895 0 +-91 -402 993 0 +-806 763 994 0 +573 710 -133 0 +258 -455 -9 0 +-481 897 287 0 +692 -650 378 0 +6 103 -151 0 +4 -176 -80 0 +111 -787 -248 0 +-946 782 -954 0 +917 772 165 0 +308 833 224 0 +-439 -156 791 0 +284 -613 912 0 +832 443 -240 0 +945 859 171 0 +284 -326 590 0 +-21 76 193 0 +-659 -315 942 0 +-121 -923 502 0 +-913 328 -578 0 +-149 563 561 0 +-299 -866 -673 0 +-44 528 -576 0 +-385 545 -813 0 +-249 625 694 0 +909 -328 571 0 +-240 237 -86 0 +-624 -164 -449 0 +-687 -494 -319 0 +209 -664 950 0 +997 828 972 0 +-350 -213 -488 0 +-15 -558 85 0 +-717 842 532 0 +-944 -265 -932 0 +-123 -880 211 0 +-530 -857 702 0 +373 548 -883 0 +-773 -930 992 0 +809 -788 -786 0 +996 911 454 0 +129 525 265 0 +-101 -983 -856 0 +550 -806 286 0 +417 -828 -999 0 +551 70 -194 0 +12 -896 191 0 +-935 882 -963 0 +986 -487 -733 0 +319 -1000 -384 0 +140 -920 -703 0 +-347 -10 594 0 +482 -645 906 0 +-982 951 295 0 +926 -499 846 0 +732 -215 -797 0 +923 81 752 0 +-696 791 -978 0 +-130 -636 -666 0 +-298 46 142 0 +-946 -318 -332 0 +520 753 402 0 +242 745 796 0 +-124 878 631 0 +366 312 840 0 +-76 -254 -113 0 +-680 808 565 0 +-721 223 339 0 +939 868 -149 0 +964 31 644 0 +-340 768 -291 0 +246 366 -473 0 +804 182 283 0 +348 56 941 0 +-239 71 104 0 +-365 443 -959 0 +-924 -314 986 0 +-939 -157 -148 0 +48 -344 421 0 +-133 -914 -356 0 +706 -302 200 0 +-261 599 -761 0 +-606 -111 -207 0 +232 661 113 0 +-995 -997 180 0 +179 353 450 0 +39 -343 -540 0 +949 -360 -824 0 +149 -588 -961 0 +-620 -739 -915 0 +376 -801 -152 0 +-301 -278 300 0 +778 -966 -504 0 +947 -915 -325 0 +293 -453 280 0 +-184 -94 507 0 +-920 -360 73 0 +-500 -578 589 0 +-257 -315 835 0 +-396 -501 618 0 +-217 -692 -232 0 +-305 741 522 0 +611 635 -340 0 +336 -199 -739 0 +-61 -218 243 0 +-419 -745 723 0 +-68 846 -67 0 +222 -634 -479 0 +-220 -483 -586 0 +964 -126 368 0 +-927 297 -964 0 +-843 955 708 0 +-100 -895 -734 0 +271 -62 -404 0 +346 111 65 0 +419 -192 781 0 +-952 -404 209 0 +-850 -18 -277 0 +164 -419 671 0 +958 -292 800 0 +636 289 362 0 +-122 -28 837 0 +480 396 954 0 +-888 -508 381 0 +-910 -715 559 0 +-422 104 -331 0 +-736 586 679 0 +-362 733 -34 0 +-330 953 967 0 +127 -215 296 0 +-415 675 -809 0 +-606 753 -599 0 +156 946 70 0 +-355 -73 396 0 +-32 -99 177 0 +100 862 729 0 +-648 -45 125 0 +675 -543 -80 0 +396 669 -338 0 +-370 -607 -89 0 +792 106 -925 0 +352 -396 -430 0 +-129 957 -290 0 +358 -218 54 0 +-917 -995 -668 0 +-221 -140 -347 0 +-334 -722 890 0 +-458 -893 230 0 +-209 987 -175 0 +928 -993 -96 0 +-208 976 -410 0 +576 966 252 0 +-157 460 -914 0 +306 -965 -122 0 +463 -425 -954 0 +105 557 243 0 +270 -914 -517 0 +-352 -579 979 0 +35 -679 -855 0 +-610 51 154 0 +546 -137 -612 0 +396 913 -605 0 +-489 -262 535 0 +51 -959 209 0 +-719 292 764 0 +-759 566 365 0 +-401 331 -118 0 +237 -622 -192 0 +790 447 987 0 +842 -290 857 0 +267 -970 -207 0 +830 -688 215 0 +549 -540 402 0 +-303 -427 446 0 +-987 -655 176 0 +521 -709 806 0 +-602 -805 -178 0 +-743 960 -580 0 +-524 -29 -353 0 +-187 -190 663 0 +-485 -180 5 0 +-380 -1 -871 0 +-186 -405 92 0 +242 -736 832 0 +860 915 -598 0 +64 62 -667 0 +-292 47 -409 0 +362 612 -935 0 +69 -448 882 0 +-291 784 -539 0 +979 -641 407 0 +97 342 769 0 +-366 38 174 0 +-596 -509 777 0 +130 892 261 0 +314 75 -524 0 +256 795 510 0 +380 864 771 0 +-672 -361 -477 0 +776 -219 595 0 +-861 898 234 0 +-371 -187 300 0 +635 -76 156 0 +828 518 490 0 +825 846 -614 0 +453 6 482 0 +-334 -33 -309 0 +-28 546 -757 0 +485 -274 95 0 +-363 -548 877 0 +879 -82 -689 0 +-723 100 674 0 +418 76 -706 0 +908 9 962 0 +-23 510 843 0 +-193 860 171 0 +935 -4 127 0 +350 103 131 0 +464 -459 -515 0 +51 776 734 0 +-448 -342 642 0 +614 -24 694 0 +-51 -721 -994 0 +538 -600 -611 0 +916 88 -287 0 +-488 -939 153 0 +252 677 746 0 +263 71 616 0 +934 -920 -10 0 +605 -252 925 0 +-680 496 -880 0 +648 -640 -4 0 +567 100 -831 0 +196 -712 388 0 +-488 -18 497 0 +886 -267 -637 0 +-504 519 111 0 +-96 277 697 0 +146 -48 453 0 +-305 815 330 0 +-921 -142 715 0 +-110 -43 -948 0 +612 -922 13 0 +799 659 309 0 +-315 369 54 0 +-831 338 352 0 +-515 880 100 0 +-575 -675 -470 0 +-236 -283 -76 0 +-125 -112 -130 0 +431 935 116 0 +-34 953 451 0 +629 -713 640 0 +-96 379 -681 0 +200 402 99 0 +-953 -423 -386 0 +-166 637 -113 0 +563 314 -179 0 +877 264 -993 0 +-337 48 -743 0 +-362 -390 844 0 +-542 -374 -376 0 +305 -468 -939 0 +-801 541 726 0 +-239 802 716 0 +-381 418 -676 0 +593 -656 241 0 +418 -757 125 0 +-823 -485 -303 0 +-459 -747 -345 0 +846 -209 -709 0 +-739 565 655 0 +-945 484 -56 0 +-373 -659 211 0 +-165 -624 -153 0 +395 446 -267 0 +189 -32 137 0 +368 -597 -679 0 +415 270 -503 0 +37 -903 -68 0 +30 753 -203 0 +-760 -520 777 0 +728 196 445 0 +-180 695 823 0 +152 -284 140 0 +-898 409 -862 0 +849 69 -839 0 +225 694 -575 0 +210 45 -18 0 +-691 -297 76 0 +195 -820 -485 0 +-27 -741 -956 0 +-81 -514 -825 0 +831 -72 268 0 +-258 -723 -984 0 +476 351 414 0 +101 76 722 0 +-291 -866 -567 0 +411 268 98 0 +-988 599 -418 0 +991 366 -270 0 +141 478 -744 0 +-787 497 756 0 +535 -388 219 0 +-817 -815 250 0 +-690 544 -749 0 +-937 20 -404 0 +46 693 82 0 +584 -897 -847 0 +939 653 -335 0 +-189 -903 -400 0 +844 519 -652 0 +135 -257 491 0 +52 -312 103 0 +-642 -625 -800 0 +-724 -850 -785 0 +-547 279 -986 0 +-632 -600 -108 0 +62 -735 -204 0 +82 213 -231 0 +364 308 277 0 +-325 -534 504 0 +-755 872 760 0 +910 423 -639 0 +-702 854 -156 0 +213 655 232 0 +753 729 550 0 +-282 -98 232 0 +987 -999 5 0 +784 54 481 0 +947 844 599 0 +-112 1000 295 0 +-663 -235 190 0 +-354 700 -746 0 +233 245 517 0 +596 -415 987 0 +-117 -458 877 0 +228 788 703 0 +285 -9 661 0 +-370 -407 -539 0 +407 -324 92 0 +695 -246 260 0 +-573 -165 -544 0 +35 85 -240 0 +-549 -441 496 0 +-891 631 703 0 +-389 -548 368 0 +-385 -457 807 0 +-650 -691 708 0 +-877 -153 -832 0 +-209 958 292 0 +643 -153 -640 0 +710 45 300 0 +-603 171 -901 0 +401 -984 751 0 +540 372 724 0 +601 995 231 0 +605 -861 211 0 +-61 -89 660 0 +232 411 31 0 +-207 471 632 0 +-886 7 436 0 +248 -137 464 0 +616 -754 29 0 +-684 -645 807 0 +532 -668 -194 0 +477 -541 227 0 +-793 -670 -775 0 +-323 -675 637 0 +325 508 -612 0 +499 -71 -335 0 +482 67 677 0 +-87 905 492 0 +-616 -328 -228 0 +304 964 -228 0 +-308 -359 952 0 +845 -652 794 0 +161 -92 375 0 +670 -872 926 0 +686 6 -576 0 +-732 33 -630 0 +-151 -341 400 0 +937 -890 160 0 +-92 -971 -730 0 +207 -232 107 0 +-810 -597 -213 0 +312 246 -944 0 +503 -504 -473 0 +-448 654 -243 0 +267 367 819 0 +-441 765 270 0 +-582 -189 713 0 +-763 762 419 0 +530 678 -442 0 +-482 599 -495 0 +-469 -535 555 0 +-209 856 -11 0 +-370 569 -165 0 +9 307 654 0 +175 -718 51 0 +530 736 205 0 +-635 972 -848 0 +746 -419 -427 0 +571 -84 181 0 +-248 414 -298 0 +-240 293 664 0 +-196 657 -8 0 +328 -629 623 0 +777 -690 196 0 +155 -330 117 0 +-37 891 -40 0 +-630 222 -926 0 +-389 296 -48 0 +359 666 455 0 +-20 636 300 0 +-122 374 -427 0 +-918 90 -107 0 +217 958 984 0 +973 -656 -134 0 +-753 288 715 0 +206 903 435 0 +874 118 -447 0 +-882 146 -105 0 +-760 -635 -580 0 +-712 -733 140 0 +-50 919 788 0 +87 791 -16 0 +213 506 -42 0 +395 171 -898 0 +687 -829 -91 0 +-325 819 553 0 +-449 169 643 0 +799 -734 -270 0 +324 -305 372 0 +-757 -114 17 0 +71 -969 275 0 +490 544 136 0 +16 -774 745 0 +-578 -736 487 0 +210 -812 428 0 +-255 -412 -159 0 +114 -583 208 0 +778 290 985 0 +171 -466 -797 0 +-35 -254 124 0 +643 979 524 0 +-405 -922 979 0 +177 990 -54 0 +456 -733 371 0 +-369 280 786 0 +527 986 658 0 +173 -291 -613 0 +-176 471 726 0 +234 908 -576 0 +-597 -760 -33 0 +410 340 93 0 +898 457 622 0 +-158 -671 -308 0 +-786 714 -543 0 +-400 846 -507 0 +59 -497 74 0 +912 915 819 0 +464 -798 -938 0 +589 -222 -143 0 +-830 207 731 0 +-285 -472 -748 0 +88 65 125 0 +-948 -11 366 0 +-452 161 420 0 +-395 984 818 0 +619 -508 -358 0 +-644 -49 -923 0 +-273 580 176 0 +-463 540 -724 0 +-666 -337 340 0 +118 161 -282 0 +-506 796 -387 0 +-754 610 190 0 +-434 152 -468 0 +-329 -991 -760 0 +-682 324 -438 0 +-601 -3 -127 0 +-5 -453 254 0 +516 -597 -925 0 +-239 641 -486 0 +-14 795 -113 0 +-251 -145 -810 0 +817 426 854 0 +111 997 -370 0 +-243 -147 965 0 +106 -911 9 0 +-606 -628 623 0 +-6 -259 122 0 +105 -958 658 0 +932 416 24 0 +-158 -56 322 0 +968 -651 -185 0 +-186 -671 346 0 +749 911 717 0 +-816 -912 653 0 +38 221 663 0 +-379 59 313 0 +-164 -414 -295 0 +-34 638 -633 0 +-794 490 457 0 +102 -582 -728 0 +-490 -161 -927 0 +902 677 -322 0 +221 922 746 0 +-869 350 -304 0 +184 145 734 0 +641 192 624 0 +-305 -492 -430 0 +611 786 -841 0 +-13 -949 764 0 +-500 364 -783 0 +277 -155 736 0 +890 -48 603 0 +506 -371 504 0 +456 -452 371 0 +513 -427 -584 0 +198 -820 433 0 +809 -206 -373 0 +710 -731 505 0 +-120 481 656 0 +458 -999 -600 0 +347 610 -56 0 +-361 -753 139 0 +426 -982 641 0 +-820 802 -961 0 +957 701 340 0 +-84 -643 30 0 +963 -464 919 0 +301 -643 472 0 +-354 42 -297 0 +-705 -650 694 0 +-818 714 206 0 +-289 -397 -274 0 +70 711 -516 0 +538 739 -683 0 +-328 159 658 0 +979 12 80 0 +-702 -899 173 0 +-691 746 685 0 +649 720 -628 0 +329 -231 871 0 +884 -361 69 0 +-939 -112 -245 0 +-569 174 -214 0 +-792 833 -579 0 +-521 570 -469 0 +-761 510 808 0 +-32 -901 -894 0 +756 204 293 0 +-202 290 102 0 +-697 -638 -343 0 +874 -533 934 0 +576 -99 965 0 +419 206 -92 0 +111 -777 -827 0 +-936 323 716 0 +-155 -584 291 0 +46 -164 -438 0 +559 759 722 0 +628 -821 -569 0 +-360 -876 555 0 +279 -732 -432 0 +824 -579 348 0 +-363 -283 945 0 +101 423 -56 0 +588 855 -684 0 +757 257 214 0 +-488 29 -775 0 +316 -14 -667 0 +742 -832 954 0 +-591 -694 -859 0 +-147 986 -798 0 +640 -662 437 0 +-828 -462 871 0 +-991 430 153 0 +-719 -303 6 0 +343 73 495 0 +465 592 684 0 +-966 -931 411 0 +-945 355 -104 0 +-288 -771 -328 0 +-715 365 -656 0 +774 277 799 0 +-395 -697 33 0 +782 -426 -732 0 +-673 223 738 0 +-884 -130 -674 0 +408 568 -261 0 +-103 623 207 0 +-823 639 -546 0 +-576 700 -11 0 +-625 -51 440 0 +880 -754 14 0 +708 -743 -327 0 +-4 -371 -11 0 +266 314 -844 0 +897 988 934 0 +189 450 869 0 +420 -541 112 0 +599 288 36 0 +-319 -77 749 0 +-421 -906 -222 0 +-793 259 -141 0 +394 -660 -757 0 +-474 959 -24 0 +-543 950 302 0 +-589 538 299 0 +-297 638 250 0 +735 -584 320 0 +-747 -333 -809 0 +801 -705 942 0 +-341 -622 204 0 +73 832 -237 0 +-705 -53 -995 0 +607 -992 328 0 +401 -513 33 0 +803 483 197 0 +129 -281 387 0 +113 401 -110 0 +39 612 928 0 +348 -539 -9 0 +267 -663 -524 0 +-354 376 326 0 +-180 -451 754 0 +-952 -356 521 0 +-127 -645 36 0 +-312 -965 -697 0 +-975 633 159 0 +-770 -713 983 0 +-612 -105 198 0 +329 533 -860 0 +-91 487 -422 0 +560 -586 -206 0 +-104 -317 402 0 +-582 -94 976 0 +897 575 -211 0 +-640 -813 -992 0 +819 -792 297 0 +-312 -337 -194 0 +349 -692 -933 0 +320 459 -413 0 +911 278 787 0 +704 26 -160 0 +102 -923 -831 0 +776 -930 -623 0 +241 -280 -991 0 +158 722 -270 0 +750 -936 707 0 +916 661 334 0 +-441 770 598 0 +418 -677 888 0 +-944 44 621 0 +820 278 -862 0 +-712 -824 272 0 +209 -375 -400 0 +-715 -788 -82 0 +339 706 239 0 +475 -822 428 0 +-341 -132 215 0 +174 39 604 0 +308 400 -774 0 +719 -862 579 0 +-172 -505 -856 0 +-540 -589 -672 0 +-925 816 684 0 +-52 61 -398 0 +363 -177 735 0 +-763 383 -917 0 +-401 830 -359 0 +-779 114 -643 0 +54 138 902 0 +327 -576 -717 0 +418 635 729 0 +-506 773 -711 0 +-950 213 -814 0 +-103 -7 -225 0 +220 -309 539 0 +-925 59 -757 0 +454 986 591 0 +599 -124 -971 0 +730 -721 -825 0 +128 -84 -157 0 +615 602 57 0 +-132 -658 681 0 +-209 -782 354 0 +805 -540 110 0 +596 -230 -939 0 +-513 -169 -183 0 +-184 848 619 0 +-898 -794 -215 0 +16 613 -370 0 +291 -861 990 0 +409 118 318 0 +863 -839 378 0 +-236 -642 -770 0 +-958 300 451 0 +137 -364 465 0 +-169 -728 -981 0 +-320 77 -645 0 +361 -982 674 0 +315 -29 600 0 +685 -645 563 0 +-5 751 8 0 +-287 -979 -119 0 +-532 692 -113 0 +-192 -772 435 0 +44 -801 998 0 +-254 -960 385 0 +-613 81 -822 0 +725 -470 511 0 +335 713 -770 0 +928 390 57 0 +183 -237 277 0 +367 -855 649 0 +249 302 979 0 +577 349 -841 0 +883 340 978 0 +-153 -931 133 0 +465 897 -186 0 +80 26 885 0 +639 386 -674 0 +37 -663 -421 0 +709 749 14 0 +-173 409 -610 0 +-228 -154 534 0 +242 -585 403 0 +-295 -961 978 0 +-284 -915 -588 0 +-895 478 -595 0 +-166 -905 -538 0 +194 449 -232 0 +-355 331 -188 0 +727 202 246 0 +972 -764 350 0 +417 91 -841 0 +864 315 -239 0 +-610 -189 506 0 +69 -354 -365 0 +441 61 -981 0 +75 193 -883 0 +-918 562 -351 0 +686 304 885 0 +595 -30 -446 0 +-997 -338 -487 0 +355 217 -25 0 +104 -311 420 0 +728 -407 748 0 +784 -972 -554 0 +750 791 421 0 +996 -488 -214 0 +791 -797 -480 0 +-944 -999 401 0 +-505 -46 341 0 +-453 759 -660 0 +598 157 -984 0 +-884 52 766 0 +727 767 -869 0 +-663 575 -382 0 +473 -262 -511 0 +475 -78 325 0 +-948 808 -311 0 +-957 -280 29 0 +-19 -685 150 0 +454 500 718 0 +-646 638 278 0 +-287 -705 392 0 +727 -409 677 0 +936 -134 340 0 +-385 -185 -599 0 +774 305 -223 0 +703 184 628 0 +-20 733 -158 0 +-72 -612 -154 0 +965 512 -627 0 +-820 -887 905 0 +-506 364 -368 0 +-224 -572 -74 0 +-173 -724 -946 0 +-735 -856 422 0 +231 -145 704 0 +-739 126 -503 0 +128 525 -716 0 +-491 -261 -838 0 +-25 -325 -811 0 +-160 185 295 0 +631 -61 -692 0 +633 642 -476 0 +703 -681 264 0 +-964 -595 537 0 +-504 -664 615 0 +504 336 -996 0 +434 551 589 0 +-607 604 313 0 +81 -600 -27 0 +-729 -810 977 0 +-716 603 -838 0 +645 -320 297 0 +-12 124 -152 0 +-436 -342 935 0 +-175 -195 925 0 +-786 -848 -276 0 +947 -761 328 0 +539 967 -986 0 +-809 -912 489 0 +999 549 966 0 +74 880 347 0 +596 -863 -22 0 +-249 -521 -60 0 +-977 654 887 0 +545 -813 204 0 +-317 -152 543 0 +515 965 935 0 +153 6 -86 0 +554 -773 100 0 +97 -875 94 0 +-363 852 -331 0 +778 -28 -503 0 +-344 567 -966 0 +-262 -73 997 0 +36 666 -675 0 +345 591 -426 0 +61 -869 -606 0 +605 -934 229 0 +-279 89 -103 0 +-449 -479 -652 0 +365 -570 -651 0 +229 201 479 0 +-352 238 -324 0 +-948 480 -19 0 +-120 -605 -127 0 +-316 875 923 0 +-243 -684 -543 0 +331 640 -429 0 +907 359 -272 0 +-757 446 -794 0 +-118 -684 -570 0 +413 154 -141 0 +270 -850 75 0 +-189 514 797 0 +-685 193 -4 0 +-849 -588 963 0 +489 19 -117 0 +-192 353 496 0 +148 653 206 0 +-475 -610 848 0 +558 919 489 0 +-62 -726 566 0 +-747 -844 772 0 +-342 15 -371 0 +115 -42 150 0 +-724 -171 915 0 +772 -292 470 0 +79 -848 -941 0 +-797 -592 -159 0 +418 247 763 0 +-696 -784 590 0 +-625 -696 -49 0 +134 791 -559 0 +708 -792 -775 0 +-367 -62 -264 0 +-607 -264 -195 0 +663 -500 -307 0 +924 584 458 0 +785 -117 -100 0 +-229 -687 -883 0 +910 -642 -830 0 +149 775 -175 0 +38 498 -827 0 +-621 -212 415 0 +-793 -42 -221 0 +140 886 -74 0 +-654 635 419 0 +624 585 798 0 +401 -604 -820 0 +-279 23 629 0 +-890 783 -106 0 +-842 -506 108 0 +477 864 830 0 +-109 -470 178 0 +443 -598 -328 0 +493 -687 -562 0 +-757 -85 -296 0 +-462 254 -128 0 +-307 -651 653 0 +-47 -560 436 0 +-161 540 597 0 +-39 510 -708 0 +954 594 536 0 +994 106 -969 0 +446 431 -196 0 +-342 -719 -451 0 +946 -547 -167 0 +-678 -968 -817 0 +643 941 -254 0 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/MTTP-instances/mttp100.dat b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/MTTP-instances/mttp100.dat new file mode 100644 index 0000000000000000000000000000000000000000..9d358cf6aa8c39b595c0c985ad8d402bfcaa92ca --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/MTTP-instances/mttp100.dat @@ -0,0 +1,307 @@ +100 + +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 + +5 +10 +15 +20 +25 +29 +34 +39 +44 +49 +53 +58 +63 +68 +73 +77 +82 +87 +92 +97 +101 +106 +111 +116 +121 +125 +130 +135 +140 +145 +149 +154 +159 +164 +169 +173 +178 +183 +188 +193 +197 +202 +207 +212 +217 +221 +226 +231 +236 +241 +245 +250 +255 +260 +265 +269 +274 +279 +284 +289 +293 +298 +303 +308 +313 +317 +322 +327 +332 +337 +341 +346 +351 +356 +361 +365 +370 +375 +380 +385 +389 +394 +399 +404 +409 +413 +418 +423 +428 +433 +437 +442 +447 +452 +457 +461 +466 +471 +476 +481 + +60.000000 +40.000000 +7.000000 +3.000000 +50.000000 +120.000000 +80.000000 +7.000000 +3.000000 +100.000000 +180.000000 +120.000000 +7.000000 +3.000000 +150.000000 +240.000000 +160.000000 +7.000000 +3.000000 +200.000000 +300.000000 +200.000000 +7.000000 +3.000000 +250.000000 +360.000000 +240.000000 +7.000000 +3.000000 +300.000000 +420.000000 +280.000000 +7.000000 +3.000000 +350.000000 +480.000000 +320.000000 +7.000000 +3.000000 +400.000000 +540.000000 +360.000000 +7.000000 +3.000000 +450.000000 +600.000000 +400.000000 +7.000000 +3.000000 +500.000000 +660.000000 +440.000000 +7.000000 +3.000000 +550.000000 +720.000000 +480.000000 +7.000000 +3.000000 +600.000000 +780.000000 +520.000000 +7.000000 +3.000000 +650.000000 +840.000000 +560.000000 +7.000000 +3.000000 +700.000000 +900.000000 +600.000000 +7.000000 +3.000000 +750.000000 +960.000000 +640.000000 +7.000000 +3.000000 +800.000000 +1020.000000 +680.000000 +7.000000 +3.000000 +850.000000 +1080.000000 +720.000000 +7.000000 +3.000000 +900.000000 +1140.000000 +760.000000 +7.000000 +3.000000 +950.000000 +1200.000000 +800.000000 +7.000000 +3.000000 +1000.000000 + +200 +) diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/MTTP-instances/mttp20.dat b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/MTTP-instances/mttp20.dat new file mode 100644 index 0000000000000000000000000000000000000000..9dde3f3f6c33f8af480223ccbb65e4d85f7a7f32 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/MTTP-instances/mttp20.dat @@ -0,0 +1,84 @@ +20 + +2 +4 +1 +7 +4 +3 +5 +2 +4 +7 +2 +9 +8 +6 +1 +4 +9 +7 +8 +2 + +3 +5 +6 +8 +10 +15 +16 +20 +25 +29 +30 +36 +49 +59 +80 +81 +89 +97 +100 +105 + +15.000000 +20.000000 +16.000000 +19.000000 +10.000000 +25.000000 +17.000000 +18.000000 +21.000000 +17.000000 +31.000000 +2.000000 +26.000000 +42.000000 +50.000000 +19.000000 +17.000000 +21.000000 +22.000000 +13.000000 + + +00001111111111111111 70.000000 + +01001110111011111111 70.000000 + +01101101101011111111 70.000000 + +01101101111011110111 70.000000 + +01101101111111101111 70.000000 + +10001111111011111110 70.000000 + +10100111011111111111 70.000000 + +10100111111011101111 70.000000 + +10100111111111111011 70.000000 +) diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ONEMAX-instances/format.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ONEMAX-instances/format.txt new file mode 100644 index 0000000000000000000000000000000000000000..179a679c6acdd98547519dd0a9817f97d090c1e2 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ONEMAX-instances/format.txt @@ -0,0 +1 @@ +// dimension of the bitstring. diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ONEMAX-instances/onemax10.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ONEMAX-instances/onemax10.txt new file mode 100644 index 0000000000000000000000000000000000000000..f599e28b8ab0d8c9c57a486c89c4a5132dcbd3b2 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/ONEMAX-instances/onemax10.txt @@ -0,0 +1 @@ +10 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/RAS-instances/RAS10.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/RAS-instances/RAS10.txt new file mode 100644 index 0000000000000000000000000000000000000000..46fc036a365b6974c890aa814bedd3051d6f7fc1 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/RAS-instances/RAS10.txt @@ -0,0 +1,2 @@ +10 +-5.12 5.12 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/RAS-instances/RAS20.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/RAS-instances/RAS20.txt new file mode 100644 index 0000000000000000000000000000000000000000..1b596f14a84500a18015f4cb01cd98662fa8d5e1 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/RAS-instances/RAS20.txt @@ -0,0 +1,2 @@ +20 +-5.12 5.12 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/RAS-instances/format.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/RAS-instances/format.txt new file mode 100644 index 0000000000000000000000000000000000000000..5be6f83d9fddd6a5d1d6c0d0db8e3ed83ffecae3 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/RAS-instances/format.txt @@ -0,0 +1,2 @@ +// number of variables +// range of the variables diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/RND-instances/rnd149.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/RND-instances/rnd149.txt new file mode 100644 index 0000000000000000000000000000000000000000..15c44e939beddcc8939956fca407b31ab7e8c3f2 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/RND-instances/rnd149.txt @@ -0,0 +1 @@ +149 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/SPHERE-instances/SPH10.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/SPHERE-instances/SPH10.txt new file mode 100644 index 0000000000000000000000000000000000000000..46fc036a365b6974c890aa814bedd3051d6f7fc1 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/SPHERE-instances/SPH10.txt @@ -0,0 +1,2 @@ +10 +-5.12 5.12 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/SPHERE-instances/SPH20.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/SPHERE-instances/SPH20.txt new file mode 100644 index 0000000000000000000000000000000000000000..1b596f14a84500a18015f4cb01cd98662fa8d5e1 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/SPHERE-instances/SPH20.txt @@ -0,0 +1,2 @@ +20 +-5.12 5.12 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/SPHERE-instances/format.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/SPHERE-instances/format.txt new file mode 100644 index 0000000000000000000000000000000000000000..5be6f83d9fddd6a5d1d6c0d0db8e3ed83ffecae3 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/SPHERE-instances/format.txt @@ -0,0 +1,2 @@ +// number of variables +// range of the variables diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/format.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/format.txt new file mode 100644 index 0000000000000000000000000000000000000000..abccebeceea08458897056d271204612c007bfdd --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/format.txt @@ -0,0 +1,3 @@ +// Number of customers, Vehicle capacity, Maximum time per route, Service time and best known cost +// Depot Coordenates +// Customer coordenates and demand diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpinfo.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpinfo.txt new file mode 100644 index 0000000000000000000000000000000000000000..a63a622379b2f179d21292e5d5c159208ae49efa --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpinfo.txt @@ -0,0 +1,47 @@ +There are currently 24 data files. + +The first set of data files are the 10 test problems from +Chapter 9 of S.Eilon, C.D.T.Watson-Gandy and N.Christofides +"Distribution management: mathematical modelling and +practical analysis" Griffin, London 1971. + +Test problems 1, 2, ..., 10 from Chapter 9 are available +in files vrp1, vrp2, ..., vrp10 respectively. + +The format of these data files is apparent from the tables +of data given in the above reference. + +The second set of data files are the 14 test problems from +Chapter 11 of N.Christofides, A.Mingozzi, P.Toth and C.Sandi +(eds) "Combinatorial optimization", John Wiley, Chichester 1979. + +Test problems 1, 2, ..., 14 from Chapter 11 are available +in files vrpnc1, vrpnc2, ..., vrpnc14 respectively. + +The format of these data files is: +number of customers, vehicle capacity, maximum route time, drop time +depot x-coordinate, depot y-coordinate +for each customer in turn: x-coordinate, y-coordinate, quantity + +Both sets of files are of size 15Kb (approximately). + + + +OTHER SOURCES + +Test data for vehicle routing problems is also available +using the Web from http://www-apache.imag.fr/~paugerat/VRP/INSTANCES + +A variety of vehicle routing problems are also available from the +elib library: +telnet elib.zib.de and login as elib +WWW access available at: +ftp://ftp.zib.de/pub/Packages/mp-testdata/index.html + + + +A full listing of the problem areas covered by OR-library can +be found in the file info + +ftp access available at mscmga.ms.ic.ac.uk +WWW access available at http://mscmga.ms.ic.ac.uk/ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc1.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc1.txt new file mode 100644 index 0000000000000000000000000000000000000000..fb9bd54da242164bf97d2c33ee41ef9d7b42e825 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc1.txt @@ -0,0 +1,52 @@ + 50 160 999999 0 524.61 + 30 40 + 37 52 7 + 49 49 30 + 52 64 16 + 20 26 9 + 40 30 21 + 21 47 15 + 17 63 19 + 31 62 23 + 52 33 11 + 51 21 5 + 42 41 19 + 31 32 29 + 5 25 23 + 12 42 21 + 36 16 10 + 52 41 15 + 27 23 3 + 17 33 41 + 13 13 9 + 57 58 28 + 62 42 8 + 42 57 8 + 16 57 16 + 8 52 10 + 7 38 28 + 27 68 7 + 30 48 15 + 43 67 14 + 58 48 6 + 58 27 19 + 37 69 11 + 38 46 12 + 46 10 23 + 61 33 26 + 62 63 17 + 63 69 6 + 32 22 9 + 45 35 15 + 59 15 14 + 5 6 7 + 10 17 27 + 21 10 13 + 5 64 11 + 30 15 16 + 39 10 10 + 32 39 5 + 25 32 25 + 25 55 17 + 48 28 18 + 56 37 10 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc10.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc10.txt new file mode 100644 index 0000000000000000000000000000000000000000..bd6fc1bc1fb5e50565e8f2ceb004465900fab284 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc10.txt @@ -0,0 +1,201 @@ + 199 200 200 10 865.94 + 35 35 + 41 49 10 + 35 17 7 + 55 45 13 + 55 20 19 + 15 30 26 + 25 30 3 + 20 50 5 + 10 43 9 + 55 60 16 + 30 60 16 + 20 65 12 + 50 35 19 + 30 25 23 + 15 10 20 + 30 5 8 + 10 20 19 + 5 30 2 + 20 40 12 + 15 60 17 + 45 65 9 + 45 20 11 + 45 10 18 + 55 5 29 + 65 35 3 + 65 20 6 + 45 30 17 + 35 40 16 + 41 37 16 + 64 42 9 + 40 60 21 + 31 52 27 + 35 69 23 + 53 52 11 + 65 55 14 + 63 65 8 + 2 60 5 + 20 20 8 + 5 5 16 + 60 12 31 + 40 25 9 + 42 7 5 + 24 12 5 + 23 3 7 + 11 14 18 + 6 38 16 + 2 48 1 + 8 56 27 + 13 52 36 + 6 68 30 + 47 47 13 + 49 58 10 + 27 43 9 + 37 31 14 + 57 29 18 + 63 23 2 + 53 12 6 + 32 12 7 + 36 26 18 + 21 24 28 + 17 34 3 + 12 24 13 + 24 58 19 + 27 69 10 + 15 77 9 + 62 77 20 + 49 73 25 + 67 5 25 + 56 39 36 + 37 47 6 + 37 56 5 + 57 68 15 + 47 16 25 + 44 17 9 + 46 13 8 + 49 11 18 + 49 42 13 + 53 43 14 + 61 52 3 + 57 48 23 + 56 37 6 + 55 54 26 + 15 47 16 + 14 37 11 + 11 31 7 + 16 22 41 + 4 18 35 + 28 18 26 + 26 52 9 + 26 35 15 + 31 67 3 + 15 19 1 + 22 22 2 + 18 24 22 + 26 27 27 + 25 24 20 + 22 27 11 + 25 21 12 + 19 21 10 + 20 26 9 + 18 18 17 + 37 52 7 + 49 49 30 + 52 64 16 + 20 26 9 + 40 30 21 + 21 47 15 + 17 63 19 + 31 62 23 + 52 33 11 + 51 21 5 + 42 41 19 + 31 32 29 + 5 25 23 + 12 42 21 + 36 16 10 + 52 41 15 + 27 23 3 + 17 33 41 + 13 13 9 + 57 58 28 + 62 42 8 + 42 57 8 + 16 57 16 + 8 52 10 + 7 38 28 + 27 68 7 + 30 48 15 + 43 67 14 + 58 48 6 + 58 27 19 + 37 69 11 + 38 46 12 + 46 10 23 + 61 33 26 + 62 63 17 + 63 69 6 + 32 22 9 + 45 35 15 + 59 15 14 + 5 6 7 + 10 17 27 + 21 10 13 + 5 64 11 + 30 15 16 + 39 10 10 + 32 39 5 + 25 32 25 + 25 55 17 + 48 28 18 + 56 37 10 + 22 22 18 + 36 26 26 + 21 45 11 + 45 35 30 + 55 20 21 + 33 34 19 + 50 50 15 + 55 45 16 + 26 59 29 + 40 66 26 + 55 65 37 + 35 51 16 + 62 35 12 + 62 57 31 + 62 24 8 + 21 36 19 + 33 44 20 + 9 56 13 + 62 48 15 + 66 14 22 + 44 13 28 + 26 13 12 + 11 28 6 + 7 43 27 + 17 64 14 + 41 46 18 + 55 34 17 + 35 16 29 + 52 26 13 + 43 26 22 + 31 76 25 + 22 53 28 + 26 29 27 + 50 40 19 + 55 50 10 + 54 10 12 + 60 15 14 + 47 66 24 + 30 60 16 + 30 50 33 + 12 17 15 + 15 14 11 + 16 19 18 + 21 48 17 + 50 30 21 + 51 42 27 + 50 15 19 + 48 21 20 + 12 38 5 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc11.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc11.txt new file mode 100644 index 0000000000000000000000000000000000000000..adea50e594c6d2f24dab30d6a34b55247880a65b --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc11.txt @@ -0,0 +1,122 @@ + 120 200 999999 0 866.37 + 10 45 + 25 1 25 + 25 3 7 + 31 5 13 + 32 5 6 + 31 7 14 + 32 9 5 + 34 9 11 + 46 9 19 + 35 7 5 + 34 6 15 + 35 5 15 + 47 6 17 + 40 5 13 + 39 3 12 + 36 3 18 + 73 6 13 + 73 8 18 + 24 36 12 + 76 6 17 + 76 10 4 + 76 13 7 + 78 3 12 + 78 9 13 + 79 3 8 + 79 5 16 + 79 11 15 + 82 3 6 + 82 7 5 + 90 15 9 + 84 3 11 + 84 5 10 + 84 9 3 + 85 1 7 + 87 5 2 + 85 8 4 + 87 7 4 + 86 41 18 + 86 44 14 + 86 46 12 + 85 55 17 + 89 43 20 + 89 46 14 + 89 52 16 + 92 42 10 + 92 52 9 + 94 42 11 + 94 44 7 + 94 48 13 + 96 42 5 + 99 46 4 + 99 50 21 + 83 80 13 + 83 83 11 + 85 81 12 + 85 85 14 + 85 89 10 + 87 80 8 + 87 86 16 + 90 77 19 + 90 88 5 + 93 82 17 + 93 84 7 + 93 89 16 + 94 86 14 + 95 80 17 + 99 89 13 + 37 83 17 + 50 80 13 + 35 85 14 + 35 87 16 + 44 86 7 + 46 89 13 + 46 83 9 + 46 87 11 + 46 89 35 + 48 83 5 + 50 85 28 + 50 88 7 + 54 86 3 + 54 90 10 + 10 35 7 + 10 40 12 + 18 30 11 + 17 35 10 + 16 38 8 + 14 40 11 + 15 42 21 + 11 42 4 + 18 40 15 + 21 39 16 + 20 40 4 + 18 41 16 + 20 44 7 + 22 44 10 + 16 45 9 + 20 45 11 + 25 45 17 + 30 55 12 + 20 50 11 + 22 51 7 + 18 49 9 + 16 48 11 + 20 55 12 + 18 53 7 + 14 50 8 + 15 51 6 + 16 54 5 + 28 33 12 + 33 38 13 + 30 50 7 + 13 40 7 + 15 36 8 + 18 31 11 + 25 37 13 + 30 46 11 + 25 52 10 + 16 33 7 + 25 35 4 + 5 40 20 + 5 50 13 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc12.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc12.txt new file mode 100644 index 0000000000000000000000000000000000000000..939f5dd0516f7cd0f9ccc4e7f478be5f16796fd1 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc12.txt @@ -0,0 +1,102 @@ + 100 200 999999 0 1541.14 + 40 50 + 45 68 10 + 45 70 30 + 42 66 10 + 42 68 10 + 42 65 10 + 40 69 20 + 40 66 20 + 38 68 20 + 38 70 10 + 35 66 10 + 35 69 10 + 25 85 20 + 22 75 30 + 22 85 10 + 20 80 40 + 20 85 40 + 18 75 20 + 15 75 20 + 15 80 10 + 30 50 10 + 30 52 20 + 28 52 20 + 28 55 10 + 25 50 10 + 25 52 40 + 25 55 10 + 23 52 10 + 23 55 20 + 20 50 10 + 20 55 10 + 10 35 20 + 10 40 30 + 8 40 40 + 8 45 20 + 5 35 10 + 5 45 10 + 2 40 20 + 0 40 30 + 0 45 20 + 35 30 10 + 35 32 10 + 33 32 20 + 33 35 10 + 32 30 10 + 30 30 10 + 30 32 30 + 30 35 10 + 28 30 10 + 28 35 10 + 26 32 10 + 25 30 10 + 25 35 10 + 44 5 20 + 42 10 40 + 42 15 10 + 40 5 30 + 40 15 40 + 38 5 30 + 38 15 10 + 35 5 20 + 50 30 10 + 50 35 20 + 50 40 50 + 48 30 10 + 48 40 10 + 47 35 10 + 47 40 10 + 45 30 10 + 45 35 10 + 95 30 30 + 95 35 20 + 53 30 10 + 92 30 10 + 53 35 50 + 45 65 20 + 90 35 10 + 88 30 10 + 88 35 20 + 87 30 10 + 85 25 10 + 85 35 30 + 75 55 20 + 72 55 10 + 70 58 20 + 68 60 30 + 66 55 10 + 65 55 20 + 65 60 30 + 63 58 10 + 60 55 10 + 60 60 10 + 67 85 20 + 65 85 40 + 65 82 10 + 62 80 30 + 60 80 10 + 60 85 30 + 58 75 20 + 55 80 10 + 55 85 20 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc13.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc13.txt new file mode 100644 index 0000000000000000000000000000000000000000..975ff61d3de5f392401e22590f3b3cb0c632992f --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc13.txt @@ -0,0 +1,122 @@ + 120 200 720 50 1162.55 + 10 45 + 25 1 25 + 25 3 7 + 31 5 13 + 32 5 6 + 31 7 14 + 32 9 5 + 34 9 11 + 46 9 19 + 35 7 5 + 34 6 15 + 35 5 15 + 47 6 17 + 40 5 13 + 39 3 12 + 36 3 18 + 73 6 13 + 73 8 18 + 24 36 12 + 76 6 17 + 76 10 4 + 76 13 7 + 78 3 12 + 78 9 13 + 79 3 8 + 79 5 16 + 79 11 15 + 82 3 6 + 82 7 5 + 90 15 9 + 84 3 11 + 84 5 10 + 84 9 3 + 85 1 7 + 87 5 2 + 85 8 4 + 87 7 4 + 86 41 18 + 86 44 14 + 86 46 12 + 85 55 17 + 89 43 20 + 89 46 14 + 89 52 16 + 92 42 10 + 92 52 9 + 94 42 11 + 94 44 7 + 94 48 13 + 96 42 5 + 99 46 4 + 99 50 21 + 83 80 13 + 83 83 11 + 85 81 12 + 85 85 14 + 85 89 10 + 87 80 8 + 87 86 16 + 90 77 19 + 90 88 5 + 93 82 17 + 93 84 7 + 93 89 16 + 94 86 14 + 95 80 17 + 99 89 13 + 37 83 17 + 50 80 13 + 35 85 14 + 35 87 16 + 44 86 7 + 46 89 13 + 46 83 9 + 46 87 11 + 46 89 35 + 48 83 5 + 50 85 28 + 50 88 7 + 54 86 3 + 54 90 10 + 10 35 7 + 10 40 12 + 18 30 11 + 17 35 10 + 16 38 8 + 14 40 11 + 15 42 21 + 11 42 4 + 18 40 15 + 21 39 16 + 20 40 4 + 18 41 16 + 20 44 7 + 22 44 10 + 16 45 9 + 20 45 11 + 25 45 17 + 30 55 12 + 20 50 11 + 22 51 7 + 18 49 9 + 16 48 11 + 20 55 12 + 18 53 7 + 14 50 8 + 15 51 6 + 16 54 5 + 28 33 12 + 33 38 13 + 30 50 7 + 13 40 7 + 15 36 8 + 18 31 11 + 25 37 13 + 30 46 11 + 25 52 10 + 16 33 7 + 25 35 4 + 5 40 20 + 5 50 13 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc14.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc14.txt new file mode 100644 index 0000000000000000000000000000000000000000..02946d9e3b9e76b09e6a5fd36cbe27ba3e7d9045 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc14.txt @@ -0,0 +1,102 @@ + 100 200 1040 90 1395.85 + 40 50 + 45 68 10 + 45 70 30 + 42 66 10 + 42 68 10 + 42 65 10 + 40 69 20 + 40 66 20 + 38 68 20 + 38 70 10 + 35 66 10 + 35 69 10 + 25 85 20 + 22 75 30 + 22 85 10 + 20 80 40 + 20 85 40 + 18 75 20 + 15 75 20 + 15 80 10 + 30 50 10 + 30 52 20 + 28 52 20 + 28 55 10 + 25 50 10 + 25 52 40 + 25 55 10 + 23 52 10 + 23 55 20 + 20 50 10 + 20 55 10 + 10 35 20 + 10 40 30 + 8 40 40 + 8 45 20 + 5 35 10 + 5 45 10 + 2 40 20 + 0 40 30 + 0 45 20 + 35 30 10 + 35 32 10 + 33 32 20 + 33 35 10 + 32 30 10 + 30 30 10 + 30 32 30 + 30 35 10 + 28 30 10 + 28 35 10 + 26 32 10 + 25 30 10 + 25 35 10 + 44 5 20 + 42 10 40 + 42 15 10 + 40 5 30 + 40 15 40 + 38 5 30 + 38 15 10 + 35 5 20 + 50 30 10 + 50 35 20 + 50 40 50 + 48 30 10 + 48 40 10 + 47 35 10 + 47 40 10 + 45 30 10 + 45 35 10 + 95 30 30 + 95 35 20 + 53 30 10 + 92 30 10 + 53 35 50 + 45 65 20 + 90 35 10 + 88 30 10 + 88 35 20 + 87 30 10 + 85 25 10 + 85 35 30 + 75 55 20 + 72 55 10 + 70 58 20 + 68 60 30 + 66 55 10 + 65 55 20 + 65 60 30 + 63 58 10 + 60 55 10 + 60 60 10 + 67 85 20 + 65 85 40 + 65 82 10 + 62 80 30 + 60 80 10 + 60 85 30 + 58 75 20 + 55 80 10 + 55 85 20 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc2.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc2.txt new file mode 100644 index 0000000000000000000000000000000000000000..214012a909ccd3117a058d0bd58aeab4dceb7011 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc2.txt @@ -0,0 +1,77 @@ + 75 140 999999 0 835.26 + 40 40 + 22 22 18 + 36 26 26 + 21 45 11 + 45 35 30 + 55 20 21 + 33 34 19 + 50 50 15 + 55 45 16 + 26 59 29 + 40 66 26 + 55 65 37 + 35 51 16 + 62 35 12 + 62 57 31 + 62 24 8 + 21 36 19 + 33 44 20 + 9 56 13 + 62 48 15 + 66 14 22 + 44 13 28 + 26 13 12 + 11 28 6 + 7 43 27 + 17 64 14 + 41 46 18 + 55 34 17 + 35 16 29 + 52 26 13 + 43 26 22 + 31 76 25 + 22 53 28 + 26 29 27 + 50 40 19 + 55 50 10 + 54 10 12 + 60 15 14 + 47 66 24 + 30 60 16 + 30 50 33 + 12 17 15 + 15 14 11 + 16 19 18 + 21 48 17 + 50 30 21 + 51 42 27 + 50 15 19 + 48 21 20 + 12 38 5 + 15 56 22 + 29 39 12 + 54 38 19 + 55 57 22 + 67 41 16 + 10 70 7 + 6 25 26 + 65 27 14 + 40 60 21 + 70 64 24 + 64 4 13 + 36 6 15 + 30 20 18 + 20 30 11 + 15 5 28 + 50 70 9 + 57 72 37 + 45 42 30 + 38 33 10 + 50 4 8 + 66 8 11 + 59 5 3 + 35 60 1 + 27 24 6 + 40 20 10 + 40 37 20 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc3.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc3.txt new file mode 100644 index 0000000000000000000000000000000000000000..8bfcc47fe499af55bd1213cc23848420d71e7309 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc3.txt @@ -0,0 +1,102 @@ + 100 200 999999 0 826.14 + 35 35 + 41 49 10 + 35 17 7 + 55 45 13 + 55 20 19 + 15 30 26 + 25 30 3 + 20 50 5 + 10 43 9 + 55 60 16 + 30 60 16 + 20 65 12 + 50 35 19 + 30 25 23 + 15 10 20 + 30 5 8 + 10 20 19 + 5 30 2 + 20 40 12 + 15 60 17 + 45 65 9 + 45 20 11 + 45 10 18 + 55 5 29 + 65 35 3 + 65 20 6 + 45 30 17 + 35 40 16 + 41 37 16 + 64 42 9 + 40 60 21 + 31 52 27 + 35 69 23 + 53 52 11 + 65 55 14 + 63 65 8 + 2 60 5 + 20 20 8 + 5 5 16 + 60 12 31 + 40 25 9 + 42 7 5 + 24 12 5 + 23 3 7 + 11 14 18 + 6 38 16 + 2 48 1 + 8 56 27 + 13 52 36 + 6 68 30 + 47 47 13 + 49 58 10 + 27 43 9 + 37 31 14 + 57 29 18 + 63 23 2 + 53 12 6 + 32 12 7 + 36 26 18 + 21 24 28 + 17 34 3 + 12 24 13 + 24 58 19 + 27 69 10 + 15 77 9 + 62 77 20 + 49 73 25 + 67 5 25 + 56 39 36 + 37 47 6 + 37 56 5 + 57 68 15 + 47 16 25 + 44 17 9 + 46 13 8 + 49 11 18 + 49 42 13 + 53 43 14 + 61 52 3 + 57 48 23 + 56 37 6 + 55 54 26 + 15 47 16 + 14 37 11 + 11 31 7 + 16 22 41 + 4 18 35 + 28 18 26 + 26 52 9 + 26 35 15 + 31 67 3 + 15 19 1 + 22 22 2 + 18 24 22 + 26 27 27 + 25 24 20 + 22 27 11 + 25 21 12 + 19 21 10 + 20 26 9 + 18 18 17 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc4.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc4.txt new file mode 100644 index 0000000000000000000000000000000000000000..3faf64a16902da76036b6afb2ebe4ab1185ecb0f --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc4.txt @@ -0,0 +1,152 @@ + 150 200 999999 0 819.56 + 35 35 + 41 49 10 + 35 17 7 + 55 45 13 + 55 20 19 + 15 30 26 + 25 30 3 + 20 50 5 + 10 43 9 + 55 60 16 + 30 60 16 + 20 65 12 + 50 35 19 + 30 25 23 + 15 10 20 + 30 5 8 + 10 20 19 + 5 30 2 + 20 40 12 + 15 60 17 + 45 65 9 + 45 20 11 + 45 10 18 + 55 5 29 + 65 35 3 + 65 20 6 + 45 30 17 + 35 40 16 + 41 37 16 + 64 42 9 + 40 60 21 + 31 52 27 + 35 69 23 + 53 52 11 + 65 55 14 + 63 65 8 + 2 60 5 + 20 20 8 + 5 5 16 + 60 12 31 + 40 25 9 + 42 7 5 + 24 12 5 + 23 3 7 + 11 14 18 + 6 38 16 + 2 48 1 + 8 56 27 + 13 52 36 + 6 68 30 + 47 47 13 + 49 58 10 + 27 43 9 + 37 31 14 + 57 29 18 + 63 23 2 + 53 12 6 + 32 12 7 + 36 26 18 + 21 24 28 + 17 34 3 + 12 24 13 + 24 58 19 + 27 69 10 + 15 77 9 + 62 77 20 + 49 73 25 + 67 5 25 + 56 39 36 + 37 47 6 + 37 56 5 + 57 68 15 + 47 16 25 + 44 17 9 + 46 13 8 + 49 11 18 + 49 42 13 + 53 43 14 + 61 52 3 + 57 48 23 + 56 37 6 + 55 54 26 + 15 47 16 + 14 37 11 + 11 31 7 + 16 22 41 + 4 18 35 + 28 18 26 + 26 52 9 + 26 35 15 + 31 67 3 + 15 19 1 + 22 22 2 + 18 24 22 + 26 27 27 + 25 24 20 + 22 27 11 + 25 21 12 + 19 21 10 + 20 26 9 + 18 18 17 + 37 52 7 + 49 49 30 + 52 64 16 + 20 26 9 + 40 30 21 + 21 47 15 + 17 63 19 + 31 62 23 + 52 33 11 + 51 21 5 + 42 41 19 + 31 32 29 + 5 25 23 + 12 42 21 + 36 16 10 + 52 41 15 + 27 23 3 + 17 33 41 + 13 13 9 + 57 58 28 + 62 42 8 + 42 57 8 + 16 57 16 + 8 52 10 + 7 38 28 + 27 68 7 + 30 48 15 + 43 67 14 + 58 48 6 + 58 27 19 + 37 69 11 + 38 46 12 + 46 10 23 + 61 33 26 + 62 63 17 + 63 69 6 + 32 22 9 + 45 35 15 + 59 15 14 + 5 6 7 + 10 17 27 + 21 10 13 + 5 64 11 + 30 15 16 + 39 10 10 + 32 39 5 + 25 32 25 + 25 55 17 + 48 28 18 + 56 37 10 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc5.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc5.txt new file mode 100644 index 0000000000000000000000000000000000000000..3cacfb74613d58105d9417abfab50591b2461a5e --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc5.txt @@ -0,0 +1,201 @@ + 199 200 999999 0 1042.11 + 35 35 + 41 49 10 + 35 17 7 + 55 45 13 + 55 20 19 + 15 30 26 + 25 30 3 + 20 50 5 + 10 43 9 + 55 60 16 + 30 60 16 + 20 65 12 + 50 35 19 + 30 25 23 + 15 10 20 + 30 5 8 + 10 20 19 + 5 30 2 + 20 40 12 + 15 60 17 + 45 65 9 + 45 20 11 + 45 10 18 + 55 5 29 + 65 35 3 + 65 20 6 + 45 30 17 + 35 40 16 + 41 37 16 + 64 42 9 + 40 60 21 + 31 52 27 + 35 69 23 + 53 52 11 + 65 55 14 + 63 65 8 + 2 60 5 + 20 20 8 + 5 5 16 + 60 12 31 + 40 25 9 + 42 7 5 + 24 12 5 + 23 3 7 + 11 14 18 + 6 38 16 + 2 48 1 + 8 56 27 + 13 52 36 + 6 68 30 + 47 47 13 + 49 58 10 + 27 43 9 + 37 31 14 + 57 29 18 + 63 23 2 + 53 12 6 + 32 12 7 + 36 26 18 + 21 24 28 + 17 34 3 + 12 24 13 + 24 58 19 + 27 69 10 + 15 77 9 + 62 77 20 + 49 73 25 + 67 5 25 + 56 39 36 + 37 47 6 + 37 56 5 + 57 68 15 + 47 16 25 + 44 17 9 + 46 13 8 + 49 11 18 + 49 42 13 + 53 43 14 + 61 52 3 + 57 48 23 + 56 37 6 + 55 54 26 + 15 47 16 + 14 37 11 + 11 31 7 + 16 22 41 + 4 18 35 + 28 18 26 + 26 52 9 + 26 35 15 + 31 67 3 + 15 19 1 + 22 22 2 + 18 24 22 + 26 27 27 + 25 24 20 + 22 27 11 + 25 21 12 + 19 21 10 + 20 26 9 + 18 18 17 + 37 52 7 + 49 49 30 + 52 64 16 + 20 26 9 + 40 30 21 + 21 47 15 + 17 63 19 + 31 62 23 + 52 33 11 + 51 21 5 + 42 41 19 + 31 32 29 + 5 25 23 + 12 42 21 + 36 16 10 + 52 41 15 + 27 23 3 + 17 33 41 + 13 13 9 + 57 58 28 + 62 42 8 + 42 57 8 + 16 57 16 + 8 52 10 + 7 38 28 + 27 68 7 + 30 48 15 + 43 67 14 + 58 48 6 + 58 27 19 + 37 69 11 + 38 46 12 + 46 10 23 + 61 33 26 + 62 63 17 + 63 69 6 + 32 22 9 + 45 35 15 + 59 15 14 + 5 6 7 + 10 17 27 + 21 10 13 + 5 64 11 + 30 15 16 + 39 10 10 + 32 39 5 + 25 32 25 + 25 55 17 + 48 28 18 + 56 37 10 + 22 22 18 + 36 26 26 + 21 45 11 + 45 35 30 + 55 20 21 + 33 34 19 + 50 50 15 + 55 45 16 + 26 59 29 + 40 66 26 + 55 65 37 + 35 51 16 + 62 35 12 + 62 57 31 + 62 24 8 + 21 36 19 + 33 44 20 + 9 56 13 + 62 48 15 + 66 14 22 + 44 13 28 + 26 13 12 + 11 28 6 + 7 43 27 + 17 64 14 + 41 46 18 + 55 34 17 + 35 16 29 + 52 26 13 + 43 26 22 + 31 76 25 + 22 53 28 + 26 29 27 + 50 40 19 + 55 50 10 + 54 10 12 + 60 15 14 + 47 66 24 + 30 60 16 + 30 50 33 + 12 17 15 + 15 14 11 + 16 19 18 + 21 48 17 + 50 30 21 + 51 42 27 + 50 15 19 + 48 21 20 + 12 38 5 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc6.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc6.txt new file mode 100644 index 0000000000000000000000000000000000000000..449fd5c6edd716fedf83c6067ae3bdc302948e8b --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc6.txt @@ -0,0 +1,52 @@ + 50 160 200 10 1028.42 + 30 40 + 37 52 7 + 49 49 30 + 52 64 16 + 20 26 9 + 40 30 21 + 21 47 15 + 17 63 19 + 31 62 23 + 52 33 11 + 51 21 5 + 42 41 19 + 31 32 29 + 5 25 23 + 12 42 21 + 36 16 10 + 52 41 15 + 27 23 3 + 17 33 41 + 13 13 9 + 57 58 28 + 62 42 8 + 42 57 8 + 16 57 16 + 8 52 10 + 7 38 28 + 27 68 7 + 30 48 15 + 43 67 14 + 58 48 6 + 58 27 19 + 37 69 11 + 38 46 12 + 46 10 23 + 61 33 26 + 62 63 17 + 63 69 6 + 32 22 9 + 45 35 15 + 59 15 14 + 5 6 7 + 10 17 27 + 21 10 13 + 5 64 11 + 30 15 16 + 39 10 10 + 32 39 5 + 25 32 25 + 25 55 17 + 48 28 18 + 56 37 10 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc7.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc7.txt new file mode 100644 index 0000000000000000000000000000000000000000..1b8aa97fd732fca2b996c584f26864092e1f621e --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc7.txt @@ -0,0 +1,77 @@ + 75 140 160 10 1291.45 + 40 40 + 22 22 18 + 36 26 26 + 21 45 11 + 45 35 30 + 55 20 21 + 33 34 19 + 50 50 15 + 55 45 16 + 26 59 29 + 40 66 26 + 55 65 37 + 35 51 16 + 62 35 12 + 62 57 31 + 62 24 8 + 21 36 19 + 33 44 20 + 9 56 13 + 62 48 15 + 66 14 22 + 44 13 28 + 26 13 12 + 11 28 6 + 7 43 27 + 17 64 14 + 41 46 18 + 55 34 17 + 35 16 29 + 52 26 13 + 43 26 22 + 31 76 25 + 22 53 28 + 26 29 27 + 50 40 19 + 55 50 10 + 54 10 12 + 60 15 14 + 47 66 24 + 30 60 16 + 30 50 33 + 12 17 15 + 15 14 11 + 16 19 18 + 21 48 17 + 50 30 21 + 51 42 27 + 50 15 19 + 48 21 20 + 12 38 5 + 15 56 22 + 29 39 12 + 54 38 19 + 55 57 22 + 67 41 16 + 10 70 7 + 6 25 26 + 65 27 14 + 40 60 21 + 70 64 24 + 64 4 13 + 36 6 15 + 30 20 18 + 20 30 11 + 15 5 28 + 50 70 9 + 57 72 37 + 45 42 30 + 38 33 10 + 50 4 8 + 66 8 11 + 59 5 3 + 35 60 1 + 27 24 6 + 40 20 10 + 40 37 20 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc8.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc8.txt new file mode 100644 index 0000000000000000000000000000000000000000..03838873fea6c997640e3a9bf827dbc1191493e7 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc8.txt @@ -0,0 +1,102 @@ + 100 200 230 10 555.43 + 35 35 + 41 49 10 + 35 17 7 + 55 45 13 + 55 20 19 + 15 30 26 + 25 30 3 + 20 50 5 + 10 43 9 + 55 60 16 + 30 60 16 + 20 65 12 + 50 35 19 + 30 25 23 + 15 10 20 + 30 5 8 + 10 20 19 + 5 30 2 + 20 40 12 + 15 60 17 + 45 65 9 + 45 20 11 + 45 10 18 + 55 5 29 + 65 35 3 + 65 20 6 + 45 30 17 + 35 40 16 + 41 37 16 + 64 42 9 + 40 60 21 + 31 52 27 + 35 69 23 + 53 52 11 + 65 55 14 + 63 65 8 + 2 60 5 + 20 20 8 + 5 5 16 + 60 12 31 + 40 25 9 + 42 7 5 + 24 12 5 + 23 3 7 + 11 14 18 + 6 38 16 + 2 48 1 + 8 56 27 + 13 52 36 + 6 68 30 + 47 47 13 + 49 58 10 + 27 43 9 + 37 31 14 + 57 29 18 + 63 23 2 + 53 12 6 + 32 12 7 + 36 26 18 + 21 24 28 + 17 34 3 + 12 24 13 + 24 58 19 + 27 69 10 + 15 77 9 + 62 77 20 + 49 73 25 + 67 5 25 + 56 39 36 + 37 47 6 + 37 56 5 + 57 68 15 + 47 16 25 + 44 17 9 + 46 13 8 + 49 11 18 + 49 42 13 + 53 43 14 + 61 52 3 + 57 48 23 + 56 37 6 + 55 54 26 + 15 47 16 + 14 37 11 + 11 31 7 + 16 22 41 + 4 18 35 + 28 18 26 + 26 52 9 + 26 35 15 + 31 67 3 + 15 19 1 + 22 22 2 + 18 24 22 + 26 27 27 + 25 24 20 + 22 27 11 + 25 21 12 + 19 21 10 + 20 26 9 + 18 18 17 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc9.txt b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc9.txt new file mode 100644 index 0000000000000000000000000000000000000000..1910e87325a89771f512980c78148177ac49429a --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/ProblemInstances/VRP-instances/vrpnc9.txt @@ -0,0 +1,152 @@ + 150 200 200 10 909.68 + 35 35 + 41 49 10 + 35 17 7 + 55 45 13 + 55 20 19 + 15 30 26 + 25 30 3 + 20 50 5 + 10 43 9 + 55 60 16 + 30 60 16 + 20 65 12 + 50 35 19 + 30 25 23 + 15 10 20 + 30 5 8 + 10 20 19 + 5 30 2 + 20 40 12 + 15 60 17 + 45 65 9 + 45 20 11 + 45 10 18 + 55 5 29 + 65 35 3 + 65 20 6 + 45 30 17 + 35 40 16 + 41 37 16 + 64 42 9 + 40 60 21 + 31 52 27 + 35 69 23 + 53 52 11 + 65 55 14 + 63 65 8 + 2 60 5 + 20 20 8 + 5 5 16 + 60 12 31 + 40 25 9 + 42 7 5 + 24 12 5 + 23 3 7 + 11 14 18 + 6 38 16 + 2 48 1 + 8 56 27 + 13 52 36 + 6 68 30 + 47 47 13 + 49 58 10 + 27 43 9 + 37 31 14 + 57 29 18 + 63 23 2 + 53 12 6 + 32 12 7 + 36 26 18 + 21 24 28 + 17 34 3 + 12 24 13 + 24 58 19 + 27 69 10 + 15 77 9 + 62 77 20 + 49 73 25 + 67 5 25 + 56 39 36 + 37 47 6 + 37 56 5 + 57 68 15 + 47 16 25 + 44 17 9 + 46 13 8 + 49 11 18 + 49 42 13 + 53 43 14 + 61 52 3 + 57 48 23 + 56 37 6 + 55 54 26 + 15 47 16 + 14 37 11 + 11 31 7 + 16 22 41 + 4 18 35 + 28 18 26 + 26 52 9 + 26 35 15 + 31 67 3 + 15 19 1 + 22 22 2 + 18 24 22 + 26 27 27 + 25 24 20 + 22 27 11 + 25 21 12 + 19 21 10 + 20 26 9 + 18 18 17 + 37 52 7 + 49 49 30 + 52 64 16 + 20 26 9 + 40 30 21 + 21 47 15 + 17 63 19 + 31 62 23 + 52 33 11 + 51 21 5 + 42 41 19 + 31 32 29 + 5 25 23 + 12 42 21 + 36 16 10 + 52 41 15 + 27 23 3 + 17 33 41 + 13 13 9 + 57 58 28 + 62 42 8 + 42 57 8 + 16 57 16 + 8 52 10 + 7 38 28 + 27 68 7 + 30 48 15 + 43 67 14 + 58 48 6 + 58 27 19 + 37 69 11 + 38 46 12 + 46 10 23 + 61 33 26 + 62 63 17 + 63 69 6 + 32 22 9 + 45 35 15 + 59 15 14 + 5 6 7 + 10 17 27 + 21 10 13 + 5 64 11 + 30 15 16 + 39 10 10 + 32 39 5 + 25 32 25 + 25 55 17 + 48 28 18 + 56 37 10 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/README.md b/ProyectoFinal/AlgoritmoGenetico/malva/README.md new file mode 100644 index 0000000000000000000000000000000000000000..53d6d5d29a50f948ac47b3338c2857d4be082fe6 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/README.md @@ -0,0 +1,278 @@ +## What is Malva? + +Malva is a fork of the MALLBA project. MALLBA is an effort to develop, in an integrated way, a +library of skeletons for combinatorial optimization (including exact, heuristic and hybrid methods) +that can deal with parallelism in a user-friendly and, at the same time, efficient manner. +Its three target environments are sequential computers, LANs of workstations and WANs. The main features of MALLBA are: + +* Integration of all the skeletons under the same design principles. +* Facility to switch from sequential to parallel optimization engines. +By providing sequential implementations users obtain parallel implementations. +* Cooperation between engines makes possible to provide more powerful hybrid engines. +* Ready to use on commodity machines. +* Flexible and extensible software architecture. New skeletons can easily be added, alternative communication layers +can be used, etc. + +## How to install and compile Malva + +First of all, you have to install MPICH library. Get the instructions here: http://www.mpich.org/. In OSX, you can just +type: + + brew install mpich --disable-fortran + +Disabling Fortran is needed since we are working with C++ instead of Fortran. + +After that, you have to clone this repository using `git clone https://github.com/gabrielfagundez/malva`, and configure Malva modifying the `environment` file. + +Then, execute the following command: + + make all + +Your Malva directory should contain the following content after the make: + +``` + -rw-r--r-- 1 user users 378 sep 24 09:39 Makefile + drwxr-xr-x 4 user users 4096 sep 24 09:48 ProblemInstances + -rw-r--r-- 1 user users 345 sep 24 16:29 environment + drwxr-xr-x 2 user users 4096 sep 24 16:43 inc + drwxr-xr-x 2 user users 4096 sep 24 17:49 lib + drwxr-xr-x 5 user users 4096 sep 24 09:41 rep + drwxr-xr-x 2 user users 4096 sep 24 17:49 src +``` + +## Testing the installation + +Go to `MALLBA_DIR/rep_new/CHC` or `MALLBA_DIR/rep_new/GA` and execute `make SEQ` or `make LAN`. If you have in your console +the result of the execution, everything looks great! + +## Important notes + +The only new fully-functional algorithms are the GA and the CHC. + +## Architecture + +Mallba skeletons are based on the separation of two concepts: the concrete problem to be solved and the general +resolution method to be used. They can be seen as generic templates that just need to be instantiated with the +features of a problem in order to solve it. All features related to the selected generic resolution method and +its interaction with the concrete problem are implemented by the skeleton. While the particular features related +to the problem must be given by the user, the knowledge to parallelize the execution of the resolution method is +implemented in the skeleton, so that users do not need to deal with parallelism issues. + +The design of the Mallba library focuses on easy to use skeletons and general and efficient implementations. +To achieve both objectives, the C++ programming language was selected due to its high level, modularity, +flexibility and efficiency features. We have reduced to a minimum the use of inheritance and virtual methods in +order to provide better efficiency and ease of use. To instantiate most problems, a basic knowledge of C++ is enough, +and only sequential code without side effects is needed. + +Skeletons are implemented by a set of required and provided C++ classes that represent an abstraction of the entities +participating in the resolution method. The provided classes implement internal aspects of the skeleton in a +problem-independent way. The required classes specify information and behavior related to the problem. +This conceptual separation allows us to define required classes with a fixed interface but without any implementation, +so that provided classes can use required classes in a generic way. + +More specifically, each skeleton includes the Problem and Solution required classes, that encapsulate the +problem-dependent entities needed by the resolution method. The Problem class abstracts the features of the +problem that are relevant to the selected optimization method. The Solution class abstracts the features of the +feasible solutions that are relevant to the selected resolution method. Depending on the skeleton, other classes +may be required. On the other hand, each skeleton offers two provided classes: Solver and SetUpParams. The former +abstracts the selected resolution method. The later contains the setup parameters needed to perform the execution +(e.g. number of iterations, number of independent runs, parameters guiding the search, etc.). The Solver class provides +methods to run the resolution scheme and methods to consult its progress or change its state. The only information the +solver needs is an instance of the problem to solve and the setup parameters. In order to enable an skeleton to have +different solver engines, the Solver class defines a unique interface and provides several subclasses that provide +different sequential and parallel implementations (Solver_Seq, Solver_Lan and Solver_Wan). In Fig. 1 is shown the +common design of Mallba skeletons. + + + +## Implementation + +The implementation of each skeleton is contained in three files: + +* <skeleton>.hh: The file containing the definition of all classes (provides and requires). +* <skeleton>.pro.cc: The file containing the source code of the classes needed for the internal implementation of the method. +* <skeleton>.req.cc: The source file where all the required classes will be implemented. + +In additional, the user must configure the method parameters in the file <skeleton>.cfg. + +## Supported Algorithms + +### Genetic Algorithm + +A Genetic Algorithm is an evolutionary computation technique inspired by the principles of natural selection to search +a solution space. It evolves a population of individuals encoded as chromosomes by creating new generations of +offsprings through an iterative process until some convergence criteria or conditions are met. The best chromosome +generated is then decoded, providing the corresponding solution. The underlying reproduction process is mainly aimed +at improving the fitness of individuals, a measure of profit, utility or goodness to be maximized (or minimized) while +exploring the solution space. The algorithm applies stochastic operators such as selection, crossover, and mutation, +on an initially random population in order to compute a new generation of individuals. The whole process is sketched +in the following figure. + +``` + 1 t = 0 + 2 initialize P(t) + 3 evaluate structures in P(t) + 4 while not end do + 5 t = t + 1 + 6 select C(t) from P(t-1) + 7 recombine structures in C(t) forming C'(t) + 8 mutate structures in C'(t) forming C''(t) + 9 evaluate structures in C''(t) +10 replace P(t) from C''(t) and/or P(t-1) +``` + +It can be seen that the algorithm comprises three major stages: selection, reproduction and replacement. During the +selection stage, a temporary population is created in which the fittest individuals (those corresponding to the best +solutions contained in the population) have a higher number of instances than those less fit (natural selection). The +reproductive operators are applied to the individuals in this population yielding a new population. Finally, individuals +of the original population are substituted by the new created individuals. This replacement usually tries to keep the +best individuals deleting the worst ones. The whole process is repeated until a certain termination criterion is +achieved (usually after a given number of iterations). + +The Genetic Algorithm skeleton (GA) requires the classes: + +* Problem +* Solution +* Crossover +* Mutation + +The class Problem corresponds to the definition of a problem instance. The skeleton filler must provide a complete +definition of this class. + +The class Solution corresponds to the definition of a solution (feasible or not) of a problem instance. The skeleton +filler must provide a complete definition of the class Solution. + +The class Crossover corresponds to the definition of a crossover operator. The skeleton filler must provide a complete +definition of this class. + +And finally, the class Mutation corresponds to the definition of a mutation operator. The skeleton filler must provide +a complete definition of this class. + +In adition, the user must configure the following algorithm parameters (in file GA.cfg): + +* number of independent runs. +* number of generations. +* size of population. +* size of offsprings in each generation. +* replace mode (if replaces parents for offsprings, or only offsprings may be new parents). +* Selection operators parameters (selection of parents and selection of offsprings parameters). +* Intra operators parameters (crossover and mutation parameters). +* Inter operators (operators to apply between sub-populations) parameters: operator number, operator rate, number of individuals and selection of individual to send and replace. +* Parallel Configuracion: interval of generation to refresh global state, running mode (synchronized or asyncronized) and interval of generations to check solutions from other populations. + +There are several basic steps to running a problem solve with GA skeleton: + +* Change to the problem directory + + `cd Mallba/rep/GA/problem` + +* Compile skeleton. + + `make` + +* Configure algorithm parameters (GA.cfg file) + +* Run problem: +Sequential Version: + +``` +make SEQ + or +MainSeq GA.cfg_path instance_path res_file_path +``` + +Parallel Version: + +Configure Config.cfg file. +Configure pgfileLan (or pgfileWan) : machines where we run the program. +Run + +``` +make LAN + or +make WAN +``` + +### CHC + +A CHC is a non-traditional GA which combines a conservative selection strategy (that always preserves the best +individuals found so far) with a highly disruptive recombination (HUX) that produces offsprings that are maximally +different from their two parents. The traditional though of preferring a recombination operator with a low disrupting +properties may not hold when such a conservative selection strategy is used. On the contrary, certain highly disruptive +crossover operator provide more effective search in many problems, which represents the core idea behind the + +CHC search method. This algorithm introduce a new bias against mating individuals who are too similar (incest +prevention). Mutation is not performed, instead, a restart process re-introduces diversity whenever convergence is +detected. + +``` + 1 t = 0 + 2 initialize P(t) + 3 evaluate structures in P(t) + 4 while not end do + 5 t = t + 1 + 6 select: C(t) = P(t-1) + 7 recombine: C'(t) = 'incest prevention' + HUX(C'(t)) + 8 evaluate structures in C'(t) + 9 replace P(t) from C''(t) and P(t-1) +10 if convergence(P(t)) +11 diverge P(t) +``` + +The CHC method skeleton (CHC) requires the classes: + +* Problem +* Solution + +The class Problem corresponds to the definition of a problem instance. The skeleton filler must provide a complete +definition of this class. + +And finally, the class Solution corresponds to the definition of a solution (feasible or not) of a problem instance. +The skeleton filler must provide a complete definition of the class Solution. + +In adition, the user must configure the following algorithm parameters (in file CHC.cfg): + +* number of independent runs. +* number of generations. +* size of population. +* Selection operator parameters (selection of new parents and the diverge method that the algorithm uses whenever the +convergence is detected). +* Intra operators parameters (crossover and mutation parameters). +* Inter operators (operators to apply between sub-populations) parameters: operator number, operator rate, number of +individuals and selection of individual to send and replace. +* Parallel Configuracion: interval of generation to refresh global state, running mode (synchronized or asyncronized) +and interval of generations to check solutions from other populations. + +There are several basic steps to running a problem solve with CHC skeleton: + +* Change to the problem directory + + `cd Mallba/rep/CHC/problem` + +* Compile skeleton + + `make` + +* Configure algorithm parameters (CHC.cfg file) + +* Run problem: + +Sequential Version: + +``` +make SEQ + or +MainSeq GA.cfg_path instance_path res_file_path +``` + +Parallel Version: + +Configure Config.cfg file. +Configure pgfileLan (or pgfileWan) : machines where we run the program. +Run + +``` +make LAN + or +make WAN +``` diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/environment b/ProyectoFinal/AlgoritmoGenetico/malva/environment new file mode 100644 index 0000000000000000000000000000000000000000..4976de6761bf2491e7a5976290961d6410764b4b --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/environment @@ -0,0 +1,19 @@ +# Malva Configuration. +MALLBA_DIR=/ens/home01/g/gonzalo.menendez/AEPractico/malva + +# MPI library +MPI_BIN=/lib64/mpich/bin +# Malva information +MALLBA_INC=${MALLBA_DIR}/src +MALLBA_LIB=${MALLBA_DIR}/lib +MALLBA_SRC=${MALLBA_DIR}/src +MALLBA_REP=${MALLBA_DIR}/rep + +# Run variables +CXX=$(MPI_BIN)/mpic++ +RUN=$(MPI_BIN)/mpirun + +# Other options: -g for debugging and -pg for profiling +CPPFLAGS=-I$(MALLBA_INC) -Wno-deprecated -O3 +LDFLAGS=-L$(MALLBA_LIB) +LOADLIBES=-lmallba -lm diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba new file mode 100644 index 0000000000000000000000000000000000000000..5cd551cf2693e4b4f65d7954ec621454c2b20326 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/inc/Mallba @@ -0,0 +1 @@ +../src \ No newline at end of file diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/inc/inc.env b/ProyectoFinal/AlgoritmoGenetico/malva/inc/inc.env new file mode 100644 index 0000000000000000000000000000000000000000..3976b861255a9a072f55cd0a7978917ada9b23ad --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/inc/inc.env @@ -0,0 +1 @@ +ln -s ../src Mallba diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/lib/Makefile b/ProyectoFinal/AlgoritmoGenetico/malva/lib/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..5bacf25696f5e617bf9780a8d220fcdcea96ac80 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/lib/Makefile @@ -0,0 +1,8 @@ +all: + rm -f libmallba.a + ar -r libmallba.a ../src/*.o + ranlib libmallba.a + +clean: + rm -f libmallba.a + diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/lib/libmallba.a b/ProyectoFinal/AlgoritmoGenetico/malva/lib/libmallba.a new file mode 100644 index 0000000000000000000000000000000000000000..db7f3cab7df60324f9676e75019a0ef727333a3e Binary files /dev/null and b/ProyectoFinal/AlgoritmoGenetico/malva/lib/libmallba.a differ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/CHC.cfg b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/CHC.cfg new file mode 100644 index 0000000000000000000000000000000000000000..0f6c796c4402f0d45f08b79afee9b59fe36dd4bc --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/CHC.cfg @@ -0,0 +1,15 @@ +10 // number of independent runs +100 // number of generations +60 // number of individuals +1 // display state ? +Selection-Parameters // selections to apply +0.9 1 0.5 // selection parameter , diverge operator & its probability +Intra-Operators // operators to apply in the population +0 0.8 // crossover & its probability +Inter-Operators // operators to apply between this population and anothers +0 25 5 1 3 1 5 // operator number, operator rate, number of individuals, selection of indidivual to send and remplace +LAN-configuration +101 // refresh global state +1 // 0: running in asynchronized mode / 1: running in synchronized mode +1 // interval of generations to check solutions from other populations + diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/CHC.hh b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/CHC.hh new file mode 100644 index 0000000000000000000000000000000000000000..0c89fe4077468e8dfd5084c3c754a083e50b4978 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/CHC.hh @@ -0,0 +1,909 @@ +/********************************************************************************************************* +*** *** +*** CHC Skeleton v1.5 *** +*** Developed by: Gabriel Jesús Luque Polo *** +*** *** +*** Last Update: 30-01-2004 *** +*** *** +**********************************************************************************************************/ + +#ifndef INC_CHC +#define INC_CHC +#include "CHCstructures.hh" + +skeleton CHC +{ +#define MAX_USER_OP 5 +#define MAX_PROB_PER_OP 5 + + provides class SetUpParams; + provides class Statistics; + provides class Population; + provides class Intra_Operator; + provides class Crossover; + provides class Diverge; + provides class Inter_Operator; + provides class Migration; + provides class Selection; + provides class Selection_New_Population; + provides class Selection_Parents; + provides class Operator_Pool; + provides class Solver; + provides class Solver_Seq; + provides class Solver_Lan; + provides class Solver_Wan; + provides class StopCondition; + + requires class Problem; + requires class Solution; + requires class UserStatistics; + requires class User_Operator; + requires class StopCondition_1; + requires bool terminateQ (const Problem& pbm, const Solver& solver, const SetUpParams& setup); + +// Problem ---------------------------------------------------------------------------- + + requires class Problem + { + public: + Problem (); + ~Problem(); + + friend ostream& operator<< (ostream& os, const Problem& pbm); + friend istream& operator>> (istream& is, Problem& pbm); + + Problem& operator= (const Problem& pbm); + bool operator== (const Problem& pbm) const; + bool operator!= (const Problem& pbm) const; + + Direction direction () const; + int dimension() const; + + private: + + int _dimension; + }; + +//Solution ---------------------------------------------------------------------------- + + requires class Solution + { + public: + Solution (const Problem& pbm); + Solution (const Solution& sol); + ~Solution(); + + friend ostream& operator<< (ostream& os, const Solution& sol); + friend istream& operator>> (istream& is, Solution& sol); + friend NetStream& operator << (NetStream& ns, const Solution& sol); + friend NetStream& operator >> (NetStream& ns, Solution& sol); + + const Problem& pbm() const; + + Solution& operator= (const Solution& sol); + bool operator== (const Solution& sol) const; + bool operator!= (const Solution& sol) const; + + char *to_String() const; + void to_Solution(char *_cadena_); + + void initialize(); + double fitness () const; + unsigned int size() const; + + int lengthInBits() const; + void flip(const int index); + bool equalb(const int index,Solution &s); + void swap(const int index, Solution &s); + void invalid(); + + int& var(const int index); + Rarray<int>& array_var(); + + private: + Rarray<int> _var; + const Problem& _pbm; + + }; + +// UserStatistics ---------------------------------------------------------------------------- + + requires class UserStatistics + { + private: + struct user_stat + { + unsigned int trial; + unsigned long nb_evaluation_best_found_trial; + unsigned long nb_iteration_best_found_trial; + double best_cost_trial; + double worst_cost_trial; + float time_best_found_trial; + float time_spent_trial; + }; + + Rlist<struct user_stat> result_trials; + + public: + UserStatistics (); + ~UserStatistics(); + + friend ostream& operator<< (ostream& os, const UserStatistics& usertats); + + UserStatistics& operator= (const UserStatistics& userstats); + void update(const Solver& solver); + void clear(); + }; + +// Intra_Operator ( clase abstracta ) -------------------------------------------------------------- + + provides class Intra_Operator + { + protected: + unsigned int _number_operator; + float *probability; + + public: + Intra_Operator(const unsigned int _number_op); + virtual ~Intra_Operator(); + + static Intra_Operator *create(const unsigned int _number_op); + friend ostream& operator<< (ostream& os, const Intra_Operator& intra); + + virtual void execute(Rarray<Solution*>& sols) const=0; + virtual void setup(char line[MAX_BUFFER]) = 0; + unsigned int number_operator() const; + + virtual void RefreshState(const StateCenter& _sc) const=0; + virtual void UpdateFromState(const StateCenter& _sc)=0; + }; + +// Crossover ---------------------------------------------------------------------------------- + + provides class Crossover: public Intra_Operator + { + public: + Crossover(); + virtual ~Crossover(); + + friend ostream& operator << (ostream& os, const Crossover& cross); + + void cross(Solution &sol1,Solution &sol2) const; + virtual void execute(Rarray<Solution*>& sols) const; + virtual void setup(char line[MAX_BUFFER]); + + virtual void RefreshState(const StateCenter& _sc) const; + virtual void UpdateFromState(const StateCenter& _sc); + }; + +// Diverge ---------------------------------------------------------------------------------- + + provides class Diverge: public Intra_Operator + { + public: + Diverge(); + virtual ~Diverge(); + + friend ostream& operator<< (ostream& os, const Diverge& diverge); + + void diverge(Solution& s) const; + // applies mutation over all solutions in array sols + virtual void execute(Rarray<Solution*>& sols) const; + virtual void setup(char line[MAX_BUFFER]); + + virtual void RefreshState(const StateCenter& _sc) const; + virtual void UpdateFromState(const StateCenter& _sc); + }; + +// User_Operator ---------------------------------------------------------------------------------- + + requires class User_Operator: public Intra_Operator + { + public: + User_Operator(const unsigned int _number_op); + virtual ~User_Operator(); + + static Intra_Operator *create(const unsigned int _number_op); + friend ostream& operator<< (ostream& os, const User_Operator& User_Operator); + + // applies mutation over all solutions in array sols + virtual void execute(Rarray<Solution*>& sols) const; + virtual void setup(char line[MAX_BUFFER]); + + virtual void RefreshState(const StateCenter& _sc) const; + virtual void UpdateFromState(const StateCenter& _sc); + }; + +// StopCondition ----------------------------------------------------------------------------------- + provides class StopCondition + { + public: + StopCondition(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup)=0; + ~StopCondition(); + }; + +// StopCondition_1 ----------------------------------------------------------------------------------- + requires class StopCondition_1 : public StopCondition + { + public: + StopCondition_1(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_1(); + }; + +// SetUpParams ------------------------------------------------------------------------------- + + provides class SetUpParams + { + private: + unsigned int _independent_runs; + unsigned long _nb_evolution_steps; + unsigned long _nb_iteration_steps; + unsigned int _population_size; // number of individuals + bool _display_state; + + unsigned long _refresh_global_state; + bool _synchronized; + unsigned int _check_asynchronous; + + // selection of parents and offsprings + mutable unsigned int _select_parents; + mutable unsigned int _select_offsprings; + + Rlist<unsigned int> _intra_operators; + Rlist<unsigned int> _inter_operators; + + Operator_Pool& _pool; + + public: + SetUpParams (Operator_Pool& pool); + Operator_Pool& pool() const; + + friend ostream& operator<< (ostream& os, const SetUpParams& setup); + friend istream& operator>> (istream& is, SetUpParams& setup); + + const unsigned int independent_runs() const; + const unsigned long nb_evolution_steps() const; + const unsigned int population_size() const; + const bool display_state() const; + const unsigned long refresh_global_state() const; + const bool synchronized() const; + const unsigned int check_asynchronous() const; + + void independent_runs(const unsigned int val); + void nb_evolution_steps(const unsigned long val); + void population_size(const unsigned int val); + void display_state(const bool val); + void refresh_global_state(const unsigned long val); + void synchronized(const bool val); + void check_asynchronous(const unsigned int val); + + // gets the i-th operator of inter-population + const unsigned int inter_operator_index(const unsigned int index) const; + const unsigned int inter_operators_size() const; + + // gets the i-th operator of intra-population + const unsigned int intra_operator_index(const unsigned int index) const; + const unsigned int intra_operators_size() const; + + const unsigned int select_parents() const; + const unsigned int select_offsprings() const; + + void select_parents(const unsigned int val); + void select_offsprings(const unsigned int val); + + void RefreshState(const StateCenter& _sc) const; + void UpdateFromState(const StateCenter& _sc) const; + + ~SetUpParams(); + }; + +// Statistics --------------------------------------------------------------------------------- + + provides class Statistics + { + private: + struct stat + { + unsigned int trial; + unsigned long nb_generation; + unsigned long nb_evaluation; + double best_cost; + double global_best_cost; + double average_cost; + double standard_deviation; + }; + + Rlist<struct stat> stats_data; + + public: + Statistics(); + ~Statistics(); + + friend ostream& operator<< (ostream& os, const Statistics& stats); + + Statistics& operator= (const Statistics& stats); + void update(const Solver& solver); + void clear(); + }; + +// Population --------------------------------------------------------------------------------- + + provides class Population + { + private: + Rarray<Solution*> _parents; // individuals in population + Rarray<Solution*> _offsprings; // offsprings of current population + Rarray<Solution*> _new_parents; // individuals of previous population + Rarray<struct individual> _fitness_values; + Rarray<struct individual> _fitness_aux; + const SetUpParams& _setup; + unsigned int _upper_cost,_lower_cost; // lower and upper fitness of individuals in population + unsigned int _evaluations; + double _average_cost; + + public: + inline void Evaluate(Solution *s, struct individual & _f); + + Population(const Problem& pbm,const SetUpParams& setup); // crea un array de objetos population; + ~Population(); + + friend ostream& operator<< (ostream& os, const Population& population); + friend istream& operator>> (istream& is, Population& population); + Population& operator= (const Population& pop); + const SetUpParams& setup() const; + const Problem& pbm() const; + void initialize(); + + // Generate a new pool of individuals in population + void evolution(); + + // interchange solutions between island + void interchange(const unsigned long current_generation, NetStream& channel); + + // creates a array with fitness of all individuals in population and its position in the population + void evaluate_parents(); + + // creates a array with fitness of all individuals and offsprings in population and its position in the population + void evaluate_offsprings(); + + // selects parents to creates offsprings + void select_parents(); + + // selects individuals for the new population + void select_offsprings(); + + const Rarray<Solution*>& parents() const; + const Rarray<Solution*>& offsprings() const; + Rarray<struct individual>& fitness_values(); + + unsigned int upper_cost() const; + unsigned int lower_cost() const; + unsigned int evaluations() const; + Solution& solution(const unsigned int index) const; + double fitness(const unsigned int index) const; + + double best_cost() const; + double worst_cost() const; + Solution& best_solution() const; + Solution& worst_solution() const; + double average_cost() const; + double standard_deviation() const; + }; + +// Inter_Operator ( abstract )----------------------------------------------------------- + + provides class Inter_Operator + { + protected: + unsigned int migration_rate; + unsigned int migration_size; + unsigned int migration_selection_1; + unsigned int migration_selection_2; + unsigned int migration_selection_conf_1; + unsigned int migration_selection_conf_2; + + unsigned int _number_operator; + const Direction direction; + + public: + Inter_Operator(const unsigned int _number_op, const Direction dir); + virtual ~Inter_Operator(); + + friend ostream& operator<< (ostream& os, const Inter_Operator& inter); + + virtual void execute(Population& pop,const unsigned long current_generation,NetStream& _netstream,const bool synchronized,const unsigned int check_asyncrhonous) const=0; + virtual void setup(char line[MAX_BUFFER]); + unsigned int number_operator() const; + + virtual void RefreshState(const StateCenter& _sc) const; + virtual void UpdateFromState(const StateCenter& _sc); + }; + +// Migration: public Inter_Operator ----------------------------------------------------------- + + provides class Migration: public Inter_Operator + { + public: + Migration(const Direction dir); + virtual ~Migration(); + + friend ostream& operator<< (ostream& os, const Migration& migration); + + virtual void execute(Population& pop,const unsigned long current_generation,NetStream& _netstream,const bool synchronized,const unsigned int check_asyncrhonous) const; + }; + +// Selection --------------------------------------------------------- + + provides class Selection + { + protected: + unsigned int _number_selection; + const Direction direction; + + public: + + Selection(const Direction dir); + Selection(const unsigned int _number_sel, const Direction dir); + virtual ~Selection(); + + friend ostream& operator<< (ostream& os, const Selection& sel); + + virtual void prepare(Rarray<struct individual>& fitness_values,const bool remplace); // const; + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int dummy,const bool remplace) const; + unsigned int number_selection() const; + + virtual void setup(char line[MAX_BUFFER]); + virtual void RefreshState(const StateCenter& _sc) const; + virtual void UpdateFromState(const StateCenter& _sc); + + }; + +// Selection_Parents --------------------------------------------------------------------------------- + + provides class Selection_Parents: public Selection + { + private: + mutable unsigned int selection_position; + + public: + Selection_Parents(const Direction dir); + virtual ~Selection_Parents(); + + friend ostream& operator<< (ostream& os, const Selection_Parents& sel); + + virtual void prepare(Rarray<struct individual>& fitness_values,const bool remplace); // const; + + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int param,const bool remplace) const; + }; + +// Selection_New_Population --------------------------------------------------------------------------- + + provides class Selection_New_Population: public Selection + { + private: + mutable unsigned int selection_position; + mutable int d; + Intra_Operator *diverge; + float r; + + public: + Selection_New_Population(const Direction dir); + virtual ~Selection_New_Population(); + + friend ostream& operator<< (ostream& os, const Selection_New_Population& sel); + + virtual void prepare(Rarray<struct individual>& fitness_values,const bool remplace); // const; + + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int param,const bool remplace) const; + + virtual void setup(char line[MAX_BUFFER]); + virtual void RefreshState(const StateCenter& _sc) const; + virtual void UpdateFromState(const StateCenter& _sc); + }; + +// Selection_Tournament --------------------------------------------------------------------------------- + + provides class Selection_Tournament: public Selection + { + public: + Selection_Tournament(const Direction dir); + virtual ~Selection_Tournament(); + + friend ostream& operator<< (ostream& os, const Selection_Tournament& sel); + + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int tourment_size,const bool remplace) const; + }; + +// Selection_Roulette_Wheel --------------------------------------------------------------------------------- + + provides class Selection_Roulette_Wheel: public Selection + { + public: + Selection_Roulette_Wheel(const Direction); + virtual ~Selection_Roulette_Wheel(); + + friend ostream& operator<< (ostream& os, const Selection_Roulette_Wheel& sel); + + virtual void prepare(Rarray<struct individual>& fitness_values,const bool remplace); // const; + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int dummy,const bool remplace) const; + }; + +// Selection_Rank --------------------------------------------------------------------------------- + + provides class Selection_Rank: public Selection + { + public: + Selection_Rank(const Direction dir); + Selection_Rank(const unsigned int _number_sel, const Direction dir); + virtual ~Selection_Rank(); + + friend ostream& operator<< (ostream& os, const Selection_Rank& sel); + + virtual void prepare(Rarray<struct individual>& fitness_values,const bool remplace); // const; + virtual void reset(); + + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int portion,const bool remplace) const; + }; + +// Selection_Best --------------------------------------------------------------------------------- + + provides class Selection_Best: public Selection_Rank + { + private: + mutable unsigned int selection_best_position; + + public: + Selection_Best(const Direction); + virtual ~Selection_Best(); + + friend ostream& operator<< (ostream& os, const Selection_Best& sel); + + virtual void reset(); + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int position,const bool remplace) const; + }; + +// Selection_Worst --------------------------------------------------------------------------------- + + provides class Selection_Worst: public Selection_Rank + { + private: + mutable unsigned int selection_worst_position; + + public: + Selection_Worst(const Direction); + virtual ~Selection_Worst(); + + friend ostream& operator<< (ostream& os, const Selection_Worst& sel); + + virtual void reset(); + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int position,const bool remplace) const; + }; + +// Operator_Pool ------------------------------------------------------------------------- + + // pool with all operators and selections that can be chosen in the setup file + provides class Operator_Pool + { + private: + mutable Rlist<Intra_Operator> _intra_operators; + Rlist<Selection> _selectors; + Rlist<Inter_Operator> _inter_operators; + + public: + Operator_Pool(const Problem& pbm); + ~Operator_Pool(); + + Intra_Operator& intra_operator(const unsigned int index) const; + Rlist<Intra_Operator>& intra_operators() const; + Selection& selector(const unsigned int index) const; + const Rlist<Selection>& selectors() const; + Inter_Operator& inter_operator(const unsigned int index) const; + const Rlist<Inter_Operator>& inter_operators() const; + + }; + +// Solver --------------------------------------------------------------------------------- + + provides class Solver + { + protected: + const Problem& problem; + const SetUpParams& params; + UserStatistics _userstat; + Statistics _stat; + Population current_population; + StateCenter _sc; + + double best_cost; + double worst_cost; + Solution best_solution; + double average_cost; + double standard_deviation; + float total_time_spent; + float time_spent_in_trial; + float start_trial; + float start_global; + + bool _end_trial; + + State_Vble _current_trial; + State_Vble _current_iteration; + State_Vble _current_evaluations; + + State_Vble _current_best_solution; + State_Vble _current_best_cost; + State_Vble _current_worst_cost; + State_Vble _current_average_cost; + State_Vble _current_standard_deviation; + State_Vble _current_time_spent; + + State_Vble _best_solution_trial; + State_Vble _best_cost_trial; + State_Vble _worst_cost_trial; + State_Vble _iteration_best_found_in_trial; + State_Vble _evaluations_best_found_in_trial; + State_Vble _time_best_found_trial; + State_Vble _time_spent_trial; + + State_Vble _trial_best_found; + State_Vble _iteration_best_found; + State_Vble _evaluations_best_found; + State_Vble _global_best_solution; + State_Vble _global_best_cost; + State_Vble _global_worst_cost; + State_Vble _time_best_found; + + State_Vble _crossover_probability; // probability of applying the operator over population + State_Vble _diverge_probability; // probability of applying the operator over population + State_Vble _user_op_probability[MAX_USER_OP]; // probabilities of user operators + State_Vble _migration_rate; + State_Vble _migration_size; + State_Vble _migration_selection_1; + State_Vble _migration_selection_2; + State_Vble _migration_selection_conf_1; + State_Vble _migration_selection_conf_2; + State_Vble _select_parents; + State_Vble _select_offsprings; + State_Vble _parameter_select_new_pop; + + State_Vble _display_state; + + public: + Solver (const Problem& pbm, const SetUpParams& setup); + virtual ~Solver (); + + virtual int pid() const; + bool end_trial() const; + void end_trial(bool et); + + // Execution methods ----------------------------------------------------------------------- + + // Full execution + virtual void run () =0; + virtual void run (const unsigned long int nb_generations) =0; + virtual void run (const Population& pop,const unsigned long int nb_generations) =0; + + //Partial execution + virtual void StartUp()=0; + virtual void StartUp(const Population& pop)=0; + + virtual void DoStep()=0; + + // Statistics handling ---------------------------------------------------------------------- + + Statistics& statistics(); + UserStatistics& userstatistics (); + Population& population(); + const SetUpParams& setup() const; + const Problem& pbm() const; + + // State handling --------------------------------------------------------------------------- + + void RefreshState(); + void RefreshCfgState(); + void UpdateFromState(); + void UpdateFromCfgState(); + StateCenter* GetState(); + + unsigned int current_trial() const; + unsigned long current_iteration() const; + unsigned long current_evaluations() const; + Solution current_best_solution() const; + double current_best_cost() const; + double current_worst_cost() const; + double current_average_cost() const; + double current_standard_deviation() const; + float current_time_spent() const; + Solution best_solution_trial() const; + double best_cost_trial() const; + double worst_cost_trial() const; + unsigned int iteration_best_found_in_trial() const; + unsigned int evaluations_best_found_in_trial() const; + float time_best_found_trial() const; + float time_spent_trial() const; + unsigned int trial_best_found() const; + unsigned int iteration_best_found() const; + unsigned int evaluations_best_found() const; + Solution global_best_solution() const; + double global_best_cost() const; + double global_worst_cost() const; + float time_best_found() const; + int display_state() const; + + float *crossover_probability() const; + float *diverge_probability() const; + float *user_op_probability(const int index) const; + unsigned int migration_rate() const; + unsigned int migration_size() const; + unsigned int migration_selection_1() const; + unsigned int migration_selection_2() const; + unsigned int migration_selection_conf_1() const; + unsigned int migration_selection_conf_2() const; + unsigned int select_parents() const; + unsigned int select_offprings() const; + float parameter_select_new_pop() const; + + void current_trial(const unsigned int value); + void current_iteration(const unsigned long value); + void current_evaluations(const unsigned long value); + void current_best_solution(const Solution& sol); + void current_best_cost(const double value); + void current_worst_cost(const double value); + void current_average_cost(const double value); + void current_standard_deviation(const double value); + void current_time_spent(const float value); + void best_solution_trial(const Solution& sol); + void best_cost_trial(const double value); + void worst_cost_trial(const double value); + void iteration_best_found_in_trial(const unsigned int value); + void evaluations_best_found_in_trial(const unsigned int value); + void time_best_found_trial(const float value); + void time_spent_trial(const float value); + void trial_best_found(const unsigned int value); + void iteration_best_found(const unsigned int value); + void evaluations_best_found(const unsigned int value); + void global_best_solution(const Solution& sol); + void global_best_cost(const double value); + void global_worst_cost(const double value); + void time_best_found(const float value); + void display_state(const int value); + + void crossover_probability(const float *probability); + void diverge_probability(const float *probability); + void user_op_probability(const int index,const float *probability); + void migration_rate(const unsigned int rate); + void migration_size(const unsigned int size); + void migration_selection_1(const unsigned int seleciton_1); + void migration_selection_2(const unsigned int selection_2); + void migration_selection_conf_1(const unsigned int selection_conf_1); + void migration_selection_conf_2(const unsigned int selection_conf_2); + void select_parents(const unsigned int selection); + void select_offsprings(const unsigned int selection); + void parameter_select_new_pop(const float value); + + void KeepHistory(const Solution& best_sol,const double best_cost,const double worst_cost,const float time_spent_trial,const float total_time_spent); + + void show_state() const; + }; + + provides class Solver_Seq: public Solver + { + public: + Solver_Seq ( const Problem& pbm, const SetUpParams& setup); + virtual ~Solver_Seq (); + + // Execution methods ----------------------------------------------------------------------- + + // Full execution + virtual void run (); + virtual void run (const unsigned long int nb_generations); + virtual void run (const Population& pop,const unsigned long int nb_generations); + + //Partial execution + virtual void StartUp(); + virtual void StartUp(const Population& pop); + + virtual void DoStep(); + }; + + provides class Solver_Lan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state(); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned long _current_iteration; + unsigned long _current_evaluations; + double _best_cost_trial; + Solution _best_solution_trial; + double _worst_cost_trial; + float _time_best_found_in_trial; + unsigned long _iteration_best_found_in_trial; + unsigned long _evaluations_best_found_in_trial; + + // Termination phase // + bool final_phase; + int acum_evaluations; + int acum_iterations; + + public: + Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Lan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods ----------------------------------------------------------------------- + + // Full execution + virtual void run (); + virtual void run (const unsigned long int nb_generations); + virtual void run (const Population& pop,const unsigned long int nb_generations); + + //Partial execution + virtual void StartUp(); + virtual void StartUp(const Population& pop); + + virtual void DoStep(); + + void reset(); + }; + + provides class Solver_Wan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state(); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned long _current_iteration; + unsigned long _current_evaluations; + double _best_cost_trial; + Solution _best_solution_trial; + double _worst_cost_trial; + float _time_best_found_in_trial; + unsigned long _iteration_best_found_in_trial; + unsigned long _evaluations_best_found_in_trial; + + // Termination phase // + bool final_phase; + int acum_evaluations; + int acum_iterations; + + public: + Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Wan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods ----------------------------------------------------------------------- + + // Full execution + virtual void run (); + virtual void run (const unsigned long int nb_generations); + virtual void run (const Population& pop,const unsigned long int nb_generations); + + //Partial execution + virtual void StartUp(); + virtual void StartUp(const Population& pop); + + virtual void DoStep(); + + void reset(); + }; + +} + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/CHC.pro.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/CHC.pro.cc new file mode 100644 index 0000000000000000000000000000000000000000..65672fddd9a1410d56b382f5941777a301e2e85c --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/CHC.pro.cc @@ -0,0 +1,3033 @@ +#include "CHC.hh" + +skeleton CHC +{ +// StopCondition ------------------------------------------------------------------------------------- + + StopCondition::StopCondition() + {} + + StopCondition::~StopCondition() + {} + +// SetUpParams ----------------------------------------------------------- + + SetUpParams::SetUpParams (Operator_Pool& pool) + : _independent_runs(0), + _nb_evolution_steps(0), + _population_size(0), + _select_parents(6), // Selection of parents: Select all individuals. (fixed) + _select_offsprings(7), // Selection of offspring : Select the best individuals. (fixed) + _inter_operators(), + _intra_operators(), + _refresh_global_state(1), + _synchronized(0), + _check_asynchronous(1), + _display_state(0), + _pool(pool) + {} + + Operator_Pool& SetUpParams::pool() const + { + return _pool; + } + + istream& operator>> (istream& is, SetUpParams& setup) + { + char buffer[MAX_BUFFER]; // current line in the setup file + char command[50]; + long op; + int parameter; + short int nb_section=0; + short int nb_io = 0; + short int nb_param=0; + short int nb_LAN_param=0; + + while (is.getline(buffer,MAX_BUFFER,'\n')) + { + sscanf(buffer," %s ",command); + if (!(strcmp(command,"General"))) nb_section=0; + if (!(strcmp(command,"Selection-Parameters"))) nb_section=1; + if (!(strcmp(command,"Intra-Operators"))) nb_section=2; + if (!(strcmp(command,"Inter-Operators"))) nb_section=3; + if (!(strcmp(command,"LAN-configuration"))) nb_section=4; + + op=-1; + sscanf(buffer," %ld%*s ",&op); + if (op<0) continue; + switch (nb_section) + { + case 0: switch (nb_param) + { + case 0: setup.independent_runs(op); break; + case 1: setup.nb_evolution_steps(op); break; + case 2: setup.population_size(op); break; + case 3: setup.display_state(op); break; + } + nb_param++; + break; + case 1: setup.pool().selector(setup.select_offsprings()).setup(buffer); + break; + case 2: setup.pool().intra_operators().append(Intra_Operator::create(op)); + setup.pool().intra_operator(nb_io).setup(buffer); + setup._intra_operators.append(new unsigned int(nb_io)); + nb_io++; + break; + case 3: setup._inter_operators.append(new unsigned int(op)); + setup.pool().inter_operator(op).setup(buffer); + break; + case 4: if (nb_LAN_param>=3) break; + switch (nb_LAN_param) + { + case 0: setup.refresh_global_state(op); break; + case 1: setup.synchronized(op); break; + case 2: assert(op>0); + setup.check_asynchronous(op); break; + } + nb_LAN_param++; + break; + } + } + + return is; + } + + ostream& operator<< (ostream& os, const SetUpParams& setup) + { + os << "CONFIGURATION -------------------------------------------" << endl << endl; + os << "\t" << "Independent runs : " << setup.independent_runs() << endl + << "\t" << "Evolution steps: " << setup.nb_evolution_steps() << endl + << "\t" << "Size of Population: " << setup.population_size() << endl; + os << "\t" <<"With combination between parents and offsprings" << endl; + + os << "\t" << "Display State: " << setup.display_state() << endl << endl + << "\t" << "Selections:" << endl + << "\t" << "-----------" << endl << endl + << "\t" << "Selection parents -> " << setup.pool().selector(setup.select_parents()) << endl + << "\t" << "Selection offsprings -> " << setup.pool().selector(setup.select_offsprings()) << endl + << "\t" << "Intra_Operators: " << endl + << "\t" << "-----------" << endl << endl; + + for (int i=0;i<setup.intra_operators_size();i++) + os << "\t" << (setup.pool().intra_operator(setup.intra_operator_index(i))) << endl; + + os << endl << "\t" << "Inter_Operators: " << endl + << "\t" << "-----------" << endl << endl; + + for (int i=0;i<setup.inter_operators_size();i++) + os << "\t" << "Operator: " << setup.pool().inter_operator(setup.inter_operator_index(i)) << endl; + + os << endl << "\t" << "LAN configuration:" << endl + << "\t" << "----------------------" << endl << endl + << "\t" << "Refresh global state in number of generations: " << setup.refresh_global_state() << endl; + + if (setup.synchronized()) + os << "\t" << "Running in synchronous mode" << endl; + else + os << "\t" << "Running in asynchronous mode" << endl; + os << "\t" << "Interval for checking asynchronous receptions: " << setup.check_asynchronous() << endl << endl; + + os << endl << endl << "END CONFIGURATION -------------------------------------------" << endl << endl; + continue_question(); + return os; + } + + const unsigned int SetUpParams::independent_runs() const + { + return _independent_runs; + } + + const unsigned long SetUpParams::nb_evolution_steps() const + { + return _nb_evolution_steps; + } + + const unsigned int SetUpParams::population_size() const + { + return _population_size; + } + + const unsigned long SetUpParams::refresh_global_state() const + { + return _refresh_global_state; + } + + const bool SetUpParams::synchronized() const + { + return _synchronized; + } + + const unsigned int SetUpParams::check_asynchronous() const + { + return _check_asynchronous; + } + + const bool SetUpParams::display_state() const + { + return _display_state; + } + + void SetUpParams::independent_runs(const unsigned int val) + { + _independent_runs=val; + } + + void SetUpParams::nb_evolution_steps(const unsigned long val) + { + _nb_evolution_steps=val; + } + + void SetUpParams::population_size(const unsigned int val) + { + _population_size=val; + } + + void SetUpParams::display_state(const bool val) + { + _display_state=val; + } + + void SetUpParams::refresh_global_state(const unsigned long val) + { + _refresh_global_state=val; + } + + void SetUpParams::synchronized(const bool val) + { + _synchronized=val; + } + + void SetUpParams::check_asynchronous(const unsigned int val) + { + _check_asynchronous=val; + } + + const unsigned int SetUpParams::select_parents() const + { + return _select_parents; + } + + const unsigned int SetUpParams::select_offsprings() const + { + return _select_offsprings; + } + + void SetUpParams::select_parents(const unsigned int val) + { + _select_parents=val; + } + + void SetUpParams::select_offsprings(const unsigned int val) + { + _select_offsprings=val; + } + + const unsigned int SetUpParams::intra_operator_index(const unsigned int index) const + { + return _intra_operators[index]; + } + + const unsigned int SetUpParams::intra_operators_size() const + { + return _intra_operators.size(); + } + + const unsigned int SetUpParams::inter_operator_index(const unsigned int index) const + { + return _inter_operators[index]; + } + + const unsigned int SetUpParams::inter_operators_size() const + { + return _inter_operators.size(); + } + + void SetUpParams::RefreshState(const StateCenter& _sc) const + { + _sc.set_contents_state_variable("_select_parents",(char *)&_select_parents,1,sizeof(_select_parents)); + _sc.set_contents_state_variable("_select_offsprings",(char *)&_select_offsprings,1,sizeof(_select_offsprings)); + _sc.set_contents_state_variable("_display_state",(char *)&_display_state,1,sizeof(bool)); + } + + void SetUpParams::UpdateFromState(const StateCenter& _sc) const + { + unsigned long nbytes,length; + _sc.get_contents_state_variable("_select_parents",(char *)&_select_parents,nbytes,length); + _sc.get_contents_state_variable("_select_offsprings",(char *)&_select_offsprings,nbytes,length); + _sc.get_contents_state_variable("_display_state",(char *)&_display_state,nbytes,length); + } + + SetUpParams::~SetUpParams() + {} + +// Statistics ------------------------------------------------------ + + Statistics::Statistics() + {} + + ostream& operator<< (ostream& os, const Statistics& stats) + { + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF CURRENT TRIAL " << endl; + os << "------------------------------------------------------------------" << endl; + for (int i=0;i< stats.stats_data.size();i++) + { + os << endl + << " Trial: " << stats.stats_data[i].trial + << " Generation: " << stats.stats_data[i].nb_generation + << " Evaluation: " << stats.stats_data[i].nb_evaluation + << " Current best cost: " << stats.stats_data[i].best_cost + << " Global best cost: " << stats.stats_data[i].global_best_cost + << " Avg: " << stats.stats_data[i].average_cost + << " Std. Dev.: " << stats.stats_data[i].standard_deviation; + } + + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + Statistics& Statistics::operator= (const Statistics& stats) + { + stats_data = stats.stats_data; + return *this; + } + + void Statistics::update(const Solver& solver) + { + struct stat *new_stat=(struct stat *)malloc(sizeof(struct stat)); + + new_stat->trial=solver.current_trial(); + new_stat->nb_generation=solver.current_iteration(); + new_stat->nb_evaluation=solver.current_evaluations(); + new_stat->average_cost=solver.current_average_cost(); + new_stat->standard_deviation=solver.current_standard_deviation(); + new_stat->best_cost=solver.current_best_cost(); + new_stat->global_best_cost=solver.global_best_cost(); + + stats_data.append(*new_stat); + } + + void Statistics::clear() + { + stats_data.remove(); + } + + Statistics::~Statistics() + {} + +// Population ------------------------------------------------------ + + Population::Population(const Problem& pbm,const SetUpParams& setup) + :_parents(setup.population_size()), + _fitness_values(setup.population_size()), + _new_parents(setup.population_size()), + _offsprings(setup.population_size()), + _setup(setup), + _evaluations(0) + { + for (int i=0;i<_parents.size();i++) + { + _parents[i]=new Solution(pbm); + _new_parents[i]=new Solution(pbm); + _fitness_values[i].index = i; + _fitness_values[i].change = true; + } + for (int i=0;i<_offsprings.size();i++) + _offsprings[i]=new Solution(pbm); + + } + + void Population::Evaluate(Solution* sols,struct individual &_f) + { + if(_f.change) + { + _f.change = false; + _f.fitness = sols->fitness(); + _evaluations++; + } + } + + Population& Population::operator= (const Population& pop) + { + for (int i=0;i<_parents.size();i++) + { + *_parents[i]=*((pop.parents())[i]); + _fitness_values[i] = pop._fitness_values[i]; + _evaluations = pop._evaluations; + } + return (*this); + } + + istream& operator>> (istream& is, Population& population) + { + return is; + } + + ostream& operator<< (ostream& os, const Population& population) + { + os << "---------------------------------------------------------------" << endl; + os << " PRESENT POPULATION " << endl << endl; + for (int i=0;i<population._parents.size();i++) + os << *population._parents[i] << endl; + os << endl << "---------------------------------------------------------------" << endl; + return os; + } + + const SetUpParams& Population::setup() const + { + return _setup; + } + + void Population::initialize() + { + for (int i=0;i<_parents.size();i++) + { + _parents[i]->initialize(); + _fitness_values[i].index = i; + _fitness_values[i].change = true; + } + evaluate_parents(); + } + + void Population::evaluate_parents() + { + double upper_fitness=(infinity() * (-1)); + double lower_fitness=(infinity()); + double current_fitness; + double cost=0.0; + + for (int i=0;i<_fitness_values.size();i++) + { + Evaluate(_parents[_fitness_values[i].index],_fitness_values[i]); + current_fitness = _fitness_values[i].fitness; + + if (current_fitness > upper_fitness ) + { + _upper_cost=i; + upper_fitness = current_fitness; + } + + if (current_fitness < lower_fitness ) + { + _lower_cost=i; + lower_fitness = current_fitness; + } + + cost += current_fitness; + } + + _average_cost = cost / _fitness_values.size(); + } + + void Population::evaluate_offsprings() + { + int i=0; + + _fitness_aux=Rarray<struct individual>(_parents.size() + _offsprings.size()); + for (i=0;i<_parents.size();i++) + { + Evaluate(_parents[_fitness_values[i].index],_fitness_values[i]); + _fitness_aux[i] = _fitness_values[i]; + } + + for (int j=i;(j-i)<_offsprings.size();j++) + { + _fitness_aux[j].index=j; + _fitness_aux[j].change=true; + Evaluate(_offsprings[j-i],_fitness_aux[j]); + } + } + + void Population::evolution() + { + select_parents(); // selects individuals to apply operators + + // apply selected operators + for (int i=0;i<_setup.intra_operators_size();i++) + _setup.pool().intra_operator(_setup.intra_operator_index(i)).execute(_offsprings); + + evaluate_offsprings(); + select_offsprings(); // selects new individuals + evaluate_parents(); // calculates fitness of new individuals + } + + void Population::interchange(const unsigned long current_generation, NetStream& channel) + { + // apply selected operators + for (int i=0;i<_setup.inter_operators_size();i++) + _setup.pool().inter_operator(_setup.inter_operator_index(i)).execute((*this),current_generation,channel,_setup.synchronized(),_setup.check_asynchronous()); + } + + void Population::select_parents() + { + _setup.pool().selector(_setup.select_parents()).prepare(_fitness_values,false); + struct individual ind; + for (int i=0;i<_offsprings.size();i++) + { + ind = _setup.pool().selector(_setup.select_parents()).select_one(_parents,_offsprings,_fitness_values,0,false); + *_offsprings[i] = *_parents[ind.index]; + } + } + + void Population::select_offsprings() + { + _setup.pool().selector(_setup.select_offsprings()).prepare(_fitness_aux,false); + const int ps = _parents.size(); + Rarray<struct individual> aux(ps); + + for (int i=0;i<ps;i++) + { + aux[i] = _setup.pool().selector(_setup.select_offsprings()).select_one(_parents,_offsprings,_fitness_aux,0,false); + if(aux[i].index < ps) + { + *_new_parents[i] = *_parents[aux[i].index]; + aux[i].index = i; + } + else + { + *_new_parents[i] = *_offsprings[aux[i].index-ps]; + aux[i].index = i; + } + } + + Solution *interchange; + for (int i=0;i<ps;i++) + { + interchange=_parents[i]; + _parents[i]=_new_parents[i]; // interchanges pointers to solutions ( NO solutions !! ) + _new_parents[i]=interchange; + } + + for (int i=0;i<ps;i++) + { + _fitness_values[i] = aux[i]; + } + } + + const Rarray<Solution*>& Population::parents() const + { + return _parents; + } + + const Rarray<Solution*>& Population::offsprings() const + { + return _offsprings; + } + + Rarray<struct individual>& Population::fitness_values() + { + return _fitness_values; + } + + unsigned int Population::upper_cost() const + { + return _upper_cost; + } + + unsigned int Population::lower_cost() const + { + return _lower_cost; + } + + unsigned int Population::evaluations() const + { + return _evaluations; + } + + double Population::best_cost() const + { + if ((*_parents[0]).pbm().direction() == minimize) + return _fitness_values[_lower_cost].fitness; + else + return _fitness_values[_upper_cost].fitness; + } + + double Population::worst_cost() const + { + if ((*_parents[0]).pbm().direction() == minimize) + return _fitness_values[_upper_cost].fitness; + else + return _fitness_values[_lower_cost].fitness; + } + + Solution& Population::best_solution() const + { + if ((*_parents[0]).pbm().direction() == minimize) + return *_parents[_fitness_values[_lower_cost].index]; + else + return *_parents[_fitness_values[_upper_cost].index]; + } + + Solution& Population::worst_solution() const + { + if ((*_parents[0]).pbm().direction() == minimize) + return *_parents[_fitness_values[_upper_cost].index]; + else + return *_parents[_fitness_values[_lower_cost].index]; + } + + Solution& Population::solution(const unsigned int index) const + { + return *_parents[index]; + } + + double Population::fitness(const unsigned int index) const + { + return _fitness_values[index].fitness; + } + + double Population::average_cost() const + { + return _average_cost; + } + + double Population::standard_deviation() const + { + double standard=0.0; + for (int i=0;i<_fitness_values.size();i++) + standard += pow ((_fitness_values[i].fitness - _average_cost),2); + standard=sqrt(standard / (_fitness_values.size()-1)); + return standard; + } + + Population::~Population() + { + for (int i=0;i<_parents.size();i++) + delete(_parents[i]); + for (int i=0;i<_offsprings.size();i++) + delete(_offsprings[i]); + for (int j=0;j<_new_parents.size();j++) + delete(_new_parents[j]); + } + +// Intra_operator -------------------------------------------------------------- + + Intra_Operator::Intra_Operator(const unsigned int _number_op):_number_operator(_number_op),probability(NULL) + {} + + unsigned int Intra_Operator::number_operator() const + { + return _number_operator; + } + + Intra_Operator *Intra_Operator::create(unsigned int _number_op) + { + switch (_number_op) + { + case 0: return new Crossover();break; + case 1: return new Diverge();break; + default: return User_Operator::create(_number_op); break; + } + } + + ostream& operator<< (ostream& os, const Intra_Operator& intra) + { + switch (intra.number_operator()) + { + case 0: os << (Crossover&)intra;break; + case 1: os << (Diverge&)intra;break; + default: os << (User_Operator&)intra;break; + } + return os; + } + + Intra_Operator::~Intra_Operator() + {} + +// Crossover:Intra_operator ------------------------------------------------------------- + + Crossover::Crossover():Intra_Operator(0) + { + probability = new float[1]; + probability[0] = -1.0; + } + + void Crossover::cross(Solution& sol1,Solution& sol2) const // dadas dos soluciones de la poblacion, las cruza + { + int dh = 0; + + if(probability[0] <= 0.0) + { + probability[0] = sol1.lengthInBits()/4; + } + + for(int i = 0; i < sol1.lengthInBits();i++) + if(!sol1.equalb(i,sol2)) dh++; + + if((dh/2) > probability[0]) + { + for(int i = 0; i < sol1.lengthInBits();i++) + if((!sol1.equalb(i,sol2)) && (0.5 <= rand01())) + { + sol1.swap(i,sol2); + } + } + else + { + sol1.invalid(); + sol2.invalid(); + } + } + + void Crossover::execute(Rarray<Solution*>& sols) const + { + for(int i=0;i+1<sols.size();i=i+2) + cross(*sols[i],*sols[i+1]); + } + + ostream& operator<< (ostream& os, const Crossover& cross) + { + os << "Crossover."; + return os; + } + + void Crossover::RefreshState(const StateCenter& _sc) const + {} + + void Crossover::UpdateFromState(const StateCenter& _sc) + { + unsigned long nbytes,length; + _sc.get_contents_state_variable("_parameter_select_new_pop",(char *)probability,nbytes,length); + } + + void Crossover::setup(char line[MAX_BUFFER]) + { + int op; + sscanf(line," %d ",&op); + } + + Crossover::~Crossover() + { + delete [] probability; + } + + +// Diverge: Sub_operator ------------------------------------------------------------- + + Diverge::Diverge():Intra_Operator(1) + { + probability = new float[1]; + } + + void Diverge::diverge(Solution& sol) const + { + for(int i = 0; i < sol.lengthInBits(); i++) + if(rand01() < probability[0]) sol.flip(i); + } + + void Diverge::execute(Rarray<Solution*>& sols) const + { + for (int i=0;i<sols.size();i++) + diverge(*sols[i]); + } + + ostream& operator<< (ostream& os, const Diverge& diverge) + { + os << "Diverge." << " Probability: " << diverge.probability[0]; + return os; + } + + void Diverge::setup(char line[MAX_BUFFER]) + { + int op; + sscanf(line," %d %f ",&op,&probability[0]); + assert(probability[0]>=0); + } + + void Diverge::RefreshState(const StateCenter& _sc) const + { + _sc.set_contents_state_variable("_diverge_probability",(char *)probability,1,sizeof(float)); + } + + void Diverge::UpdateFromState(const StateCenter& _sc) + { + unsigned long nbytes,length; + _sc.get_contents_state_variable("_diverge_probability",(char *)probability,nbytes,length); + } + + Diverge::~Diverge() + { + delete [] probability; + } + + +// Inter_operator ------------------------------------------------------------------- + + Inter_Operator::Inter_Operator(const unsigned int _number_op,const Direction dir): + _number_operator(_number_op), + direction(dir), + migration_rate(1), + migration_size(1), + migration_selection_1(0), + migration_selection_2(0), + migration_selection_conf_1(0), + migration_selection_conf_2(0) + {} + + unsigned int Inter_Operator::number_operator() const + { + return _number_operator; + } + + void Inter_Operator::setup(char line[MAX_BUFFER]) + { + int op; + int new_migration_rate=1; + int new_migration_size=1; + int new_migration_selection_1=0; + int new_migration_selection_conf_1=0; + int new_migration_selection_2=0; + int new_migration_selection_conf_2=0; + + sscanf(line," %d %d %d %d %d %d %d ",&op,&new_migration_rate,&new_migration_size,&new_migration_selection_1,&new_migration_selection_conf_1,&new_migration_selection_2,&new_migration_selection_conf_2); + + assert(new_migration_rate>0); + assert(new_migration_size>0); + assert(new_migration_selection_1>=0); + assert(new_migration_selection_conf_1>=0); + assert(new_migration_selection_2>=0); + assert(new_migration_selection_conf_2>=0); + + migration_rate=new_migration_rate; + migration_size=new_migration_size; + migration_selection_1=new_migration_selection_1; + migration_selection_conf_1=new_migration_selection_conf_1; + migration_selection_2=new_migration_selection_2; + migration_selection_conf_2=new_migration_selection_conf_2; + } + + void Inter_Operator::RefreshState(const StateCenter& _sc) const + { + _sc.set_contents_state_variable("_migration_rate",(char *)&migration_rate,1,sizeof(migration_rate)); + _sc.set_contents_state_variable("_migration_size",(char *)&migration_size,1,sizeof(migration_size)); + _sc.set_contents_state_variable("_migration_selection_1",(char *)&migration_selection_1,1,sizeof(migration_selection_1)); + _sc.set_contents_state_variable("_migration_selection_2",(char *)&migration_selection_2,1,sizeof(migration_selection_2)); + _sc.set_contents_state_variable("_migration_selection_conf_1",(char *)&migration_selection_conf_1,1,sizeof(migration_selection_conf_1)); + _sc.set_contents_state_variable("_migration_selection_conf_2",(char *)&migration_selection_conf_2,1,sizeof(migration_selection_conf_2)); + } + + void Inter_Operator::UpdateFromState(const StateCenter& _sc) + { + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_rate",(char *)&migration_rate,nitems,length); + _sc.get_contents_state_variable("_migration_size",(char *)&migration_size,nitems,length); + _sc.get_contents_state_variable("_migration_selection_1",(char *)&migration_selection_1,nitems,length); + _sc.get_contents_state_variable("_migration_selection_2",(char *)&migration_selection_2,nitems,length); + _sc.get_contents_state_variable("_migration_selection_conf_1",(char *)&migration_selection_conf_1,nitems,length); + _sc.get_contents_state_variable("_migration_selection_conf_2",(char *)&migration_selection_conf_2,nitems,length); + } + + ostream& operator<< (ostream& os, const Inter_Operator& inter) + { + switch (inter.number_operator()) + { + case 0: os << (Migration&)inter;break; + } + return os; + } + + Inter_Operator::~Inter_Operator() + {} + +// Migration ------------------------------------------------------------ + + Migration::Migration(const Direction dir):Inter_Operator(0,dir) + {} + + void Migration::execute(Population& pop,const unsigned long current_generation,NetStream& _netstream,const bool synchronized,const unsigned int check_asynchronous) const + { + + Solution* solution_to_send; + Solution* solution_received; + Solution* solution_to_remplace; + bool need_to_revaluate=false; + int mypid; + + int nb_proc=_netstream.pnumber(); // Get the number of processes running + + mypid=_netstream.my_pid(); + + int to = (mypid + 1) % nb_proc; // Source (from) and Target (to) of processes + int from = (nb_proc + mypid - 1) % nb_proc; + + // process number 0 is only to store the global state + if (to==0) to=1; + if (from==0) from=nb_proc - 1; + + _netstream << set_target(to) << set_source(from) + << get_target(&to) << get_source(&from); + + if ( (current_generation % migration_rate) == 0 + && (current_generation!=pop.setup().nb_evolution_steps())) // in this generation this operator have to be applied + { + pop.setup().pool().selector(migration_selection_1).prepare(pop.fitness_values(),false); + + _netstream << pack_begin; + for (int i=0;i<migration_size;i++) + { + // select individual to send + solution_to_send = pop.parents()[pop.setup().pool().selector(migration_selection_1).select_one( + pop.parents(),pop.offsprings(),pop.fitness_values(),migration_selection_conf_1,false).index]; + + _netstream << *solution_to_send; + } + _netstream << pack_end; + + if (synchronized) // synchronous mode: blocked until data are received + { + pop.setup().pool().selector(migration_selection_2).prepare(pop.fitness_values(),true); + + _netstream << set_source(MPI_ANY_SOURCE); + int tipo = 0; + _netstream._wait2(any,tipo); + + if (tipo == 1){ + return; + } + + _netstream << wait(packed); + _netstream << pack_begin; + for (int i=0;i<migration_size;i++) + { + // select individual to be remplaced + struct individual ind; + ind = pop.setup().pool().selector(migration_selection_2).select_one( + pop.parents(),pop.offsprings(),pop.fitness_values(),migration_selection_conf_2,true); + solution_to_remplace = pop.parents()[ind.index]; + solution_received=new Solution(solution_to_remplace->pbm()); + _netstream >> *solution_received; + + // remplace policy + if ((solution_received->fitness()<=solution_to_remplace->fitness() && direction==minimize) + || (solution_received->fitness()>=solution_to_remplace->fitness() && direction==maximize)) + { + need_to_revaluate=true; + for(int j = 0; j < pop.parents().size(); j++) + { + if(pop.fitness_values()[j].index == ind.index) + { + pop.fitness_values()[j].change = true; + *pop.parents()[ind.index] = *solution_received; + } + } + } + delete(solution_received); + } + _netstream << pack_end; + + } + } // end if + + if (!synchronized && ((current_generation % check_asynchronous) ==0)) + { // asynchronous mode: if there are not data, continue; + // but, if there are data, i have to receive it + int pending=false; + _netstream._probe(packed,pending); + if (pending) + { + pop.setup().pool().selector(migration_selection_2).prepare(pop.fitness_values(),true); + + _netstream << pack_begin; + for (int i=0;i<migration_size;i++) + { + pending=false; + _netstream._probe(regular,pending); + if (!pending) break; + + // select individual to be remplaced + struct individual ind; + ind = pop.setup().pool().selector(migration_selection_2).select_one( + pop.parents(),pop.offsprings(),pop.fitness_values(),migration_selection_conf_2,true); + solution_to_remplace = pop.parents()[ind.index]; + solution_received=new Solution(solution_to_remplace->pbm()); + _netstream >> *solution_received; + + // remplace policy + if ((solution_received->fitness()<=solution_to_remplace->fitness() && direction==minimize) + || (solution_received->fitness()>=solution_to_remplace->fitness() && direction==maximize)) + { + need_to_revaluate=true; + for(int j = 0; j < pop.parents().size(); j++) + { + if(pop.fitness_values()[j].index == ind.index) + { + pop.fitness_values()[j].change = true; + *pop.parents()[ind.index] = *solution_received; + } + } + } + delete(solution_received); + } // end for + _netstream << pack_begin; + } // end if + } + + if (need_to_revaluate) pop.evaluate_parents(); + } + + ostream& operator<< (ostream& os, const Migration& migration) + { + os << "Migration." + << endl << "\t" << " Rate: " << migration.migration_rate + << endl << "\t" << " Size: " << migration.migration_size + << endl << "\t" << " Selection 1: " << migration.migration_selection_1 + << endl << "\t" << " Selection 1 Parameter: " << migration.migration_selection_conf_1 + << endl << "\t" << " Selection 2: " << migration.migration_selection_2 + << endl << "\t" << " Selection 2 Parameter: " << migration.migration_selection_conf_2; + return os; + } + + Migration::~Migration() + {} + +// Selection ------------------------------------------------------------ + + Selection::Selection(const Direction dir):_number_selection(0),direction(dir) + {} + + Selection::Selection(const unsigned int _number_sel, const Direction dir):_number_selection(_number_sel),direction(dir) + {} + + void Selection::prepare(Rarray<struct individual>& fitness_values,const bool remplace) + {} + + struct individual Selection::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int dummy,const bool remplace) const + { // select a random individual + return fitness_values[rand_int(0,fitness_values.size()-1)]; + } + + unsigned int Selection::number_selection() const + { + return _number_selection; + } + + ostream& operator<< (ostream& os, const Selection& sel) + { + switch (sel.number_selection()) + { + case 0: os << "Random Selection"; break; + case 1: os << (Selection_Tournament&)sel; break; + case 2: os << (Selection_Roulette_Wheel&)sel; break; + case 3: os << (Selection_Rank&)sel; break; + case 4: os << (Selection_Best&)sel; break; + case 5: os << (Selection_Worst&)sel; break; + case 6: os << (Selection_Parents&)sel; break; + case 7: os << (Selection_New_Population&)sel; break; + } + return os; + } + + void Selection::setup(char line[MAX_BUFFER]) + {} + + void Selection::RefreshState(const StateCenter& _sc) const + {} + + void Selection::UpdateFromState(const StateCenter& _sc) + {} + + + Selection::~Selection() + {} + +// Selection_Tournament---------------------------------------------------- + + Selection_Tournament::Selection_Tournament(const Direction dir):Selection(1,dir) + {} + + struct individual Selection_Tournament::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int tournament_size, const bool remplace) const + { + unsigned int best_sol=0; + double best_fitness=((-1) * direction * infinity()); + unsigned int index; + + if (remplace) best_fitness = -1 * best_fitness; + + unsigned int new_tournament_size=tournament_size; + if (tournament_size==0) new_tournament_size=1; + + for (int i=0;i<new_tournament_size;i++) + { + index=rand_int(0,fitness_values.size()-1); + + switch (direction) + { + case (minimize): if (((!remplace) && (fitness_values[index].fitness<best_fitness)) + || ((remplace) && (fitness_values[index].fitness>best_fitness))) + { + best_sol = index; + best_fitness = fitness_values[index].fitness; + } + break; + case (maximize): if (((!remplace) && (fitness_values[index].fitness>best_fitness)) + || ((remplace) && (fitness_values[index].fitness<best_fitness))) + { + best_sol = index; + best_fitness = fitness_values[index].fitness; + } + break; + } + } + + return fitness_values[best_sol]; + } + + ostream& operator<< (ostream& os, const Selection_Tournament& sel) + { + os << "Tournament Selection."; + return os; + } + + Selection_Tournament::~Selection_Tournament() + {} + +// Selection_Roulette_Wheel --------------------------------------------------- + + Selection_Roulette_Wheel::Selection_Roulette_Wheel(const Direction dir):Selection(2,dir) + {} + + void Selection_Roulette_Wheel::prepare(Rarray<struct individual>& fitness_values,const bool remplace) + { + + double overall_fitness=0.0; + + // inverts fitness values to select less fitness individuals with a high probability + if ((direction==maximize && (remplace)) || ((direction==minimize) && (!(remplace)))) + { + // fitness assigned if the fitness value is 0 in this case + double value_if_zero=DBL_MAX; + unsigned int nb_zeros=0; + + for (int i=0;i<fitness_values.size();i++) + { + if (fitness_values[i].fitness!=0) + value_if_zero-=fitness_values[i].fitness; + else + nb_zeros++; + } + + value_if_zero=value_if_zero/nb_zeros; + + // Warning !! if fitness is 0 (1/0 ?) + for (int i=0;i<fitness_values.size();i++) + { + if (fitness_values[i].fitness!=0) + fitness_values[i].sel_parameter = (1 / fitness_values[i].fitness ); + else + fitness_values[i].sel_parameter = value_if_zero; + overall_fitness+= fitness_values[i].sel_parameter; + } + } + else + { + for (int i=0;i<fitness_values.size();i++) + { + fitness_values[i].sel_parameter = fitness_values[i].fitness; + overall_fitness+= fitness_values[i].sel_parameter; + } + + } + + if (overall_fitness>DBL_MAX) overall_fitness=DBL_MAX; + + // calculate relative fitness + double previous=0.0; + for (int i=0;i<fitness_values.size();i++) + { + fitness_values[i].sel_parameter = (fitness_values[i].sel_parameter / overall_fitness) + previous; + previous = fitness_values[i].sel_parameter; + } + } + + struct individual Selection_Roulette_Wheel::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int dummy, const bool remplace) const + { + double random_selected=rand01(); + int i=0; + + while (random_selected > fitness_values[i].sel_parameter ) + i++; + + return fitness_values[i]; + } + + ostream& operator<< (ostream& os, const Selection_Roulette_Wheel& sel) + { + os << "Roulette Wheel Selection."; + return os; + } + + Selection_Roulette_Wheel::~Selection_Roulette_Wheel() + {} + +// Selection_Rank -------------------------------------------------- + + int lessF(const struct individual &i1,const struct individual &i2) + { + return i1.fitness < i2.fitness; + } + + int greaterF(const struct individual &i1,const struct individual &i2) + { + return i1.fitness > i2.fitness; + } + + Selection_Rank::Selection_Rank(const Direction dir):Selection(3,dir) + {} + + Selection_Rank::Selection_Rank(const unsigned int _number_sel, const Direction dir):Selection(_number_sel,dir) + {} + + void Selection_Rank::reset() + {} + + void Selection_Rank::prepare(Rarray<struct individual>& fitness_values,const bool remplace) + { + reset(); + + // sort individuals + if (((direction==maximize) && (!(remplace))) || ((direction==minimize) && (remplace))) + fitness_values.sort(lessF); + else + fitness_values.sort(greaterF); + } + + struct individual Selection_Rank::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int portion,const bool remplace) const + { + + unsigned int new_portion=portion; + if (portion==0 || portion>100) new_portion=100; + + return fitness_values[rand_int(0,(( fitness_values.size() * new_portion )/ 100)-1)]; + } + + ostream& operator<< (ostream& os, const Selection_Rank& sel) + { + os << "Rank-Ordered Selection."; + return os; + } + + Selection_Rank::~Selection_Rank() + {} + +// Selection_Best -------------------------------------------------- + + Selection_Best::Selection_Best(const Direction dir):Selection_Rank(4,dir),selection_best_position(0) + {} + + struct individual Selection_Best::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int position,const bool remplace) const + { + int position_to_return=position-1; + if (position_to_return<0) + { + position_to_return = selection_best_position; + selection_best_position++; + } + + position_to_return=(int)position_to_return % fitness_values.size(); + + return fitness_values[position_to_return]; + } + + void Selection_Best::reset() + { + selection_best_position=0; + } + + ostream& operator<< (ostream& os, const Selection_Best& sel) + { + os << "Selection of best ordered individuals."; + return os; + } + + Selection_Best::~Selection_Best() + {} + +// Selection_Worst -------------------------------------------------- + + Selection_Worst::Selection_Worst(const Direction dir):Selection_Rank(5,dir),selection_worst_position(0) + {} + + struct individual Selection_Worst::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int position,const bool remplace) const + { + int position_to_return=position-1; + if (position_to_return<0) + { + position_to_return = selection_worst_position; + selection_worst_position++; + } + + position_to_return=(int)position_to_return % fitness_values.size(); + + int index=(fitness_values.size()-1) - position_to_return; + return fitness_values[index]; + } + + void Selection_Worst::reset() + { + selection_worst_position=0; + } + + ostream& operator<< (ostream& os, const Selection_Worst& sel) + { + os << "Selection of worst ordered individuals."; + return os; + } + + Selection_Worst::~Selection_Worst() + {} + +// Selection_Parents --------------------------------------------------------------------------------- + + Selection_Parents::Selection_Parents(const Direction dir):Selection(6,dir),selection_position(0) + {} + + Selection_Parents::~Selection_Parents() + {} + + ostream& operator<< (ostream& os, const Selection_Parents& sel) + { + os << "CHC Selection: Parents Selection."; + return os; + } + + void Selection_Parents::prepare(Rarray<struct individual>& fitness_values,const bool remplace) // const + { + selection_position = 0; + int limit1,limit2; + register int max = fitness_values.size(); + + struct individual interchange; + + for (int i=0;i<max*3;i++) + { + limit1 = rand_int(0,max-1); + limit2 = rand_int(0,max-1); + interchange=fitness_values[limit1]; + fitness_values[limit1]=fitness_values[limit2]; + fitness_values[limit2]=interchange; + } + } + + struct individual Selection_Parents::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int param,const bool remplace) const + { + int index = selection_position; + selection_position++; + + index = index % fitness_values.size(); + + return fitness_values[index]; + } + +// Selection_New_Population --------------------------------------------------------------------------- + + Selection_New_Population::Selection_New_Population(const Direction dir) + :Selection(7,dir) + ,diverge(NULL) + ,d(-1) + {} + + Selection_New_Population::~Selection_New_Population() + { + if(diverge != NULL) delete diverge; + } + + ostream& operator<< (ostream& os, const Selection_New_Population& sel) + { + os << "CHC Selection: New Population Selection." << " Diverge Operator: " << *sel.diverge; + return os; + } + + + void Selection_New_Population::prepare(Rarray<struct individual>& fitness_values,const bool remplace) // const + { + selection_position = 0; + + // sort individuals + if (((direction==maximize) && (!(remplace))) || ((direction==minimize) && (remplace))) + fitness_values.sort(greaterF); + else + fitness_values.sort(lessF); + } + + struct individual Selection_New_Population::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int param,const bool remplace) const + { + bool change = false; + if(d == -1) d = to_select_1[0]->lengthInBits() / 4; + + if(selection_position == 0) + { + for(int i= 0; i < to_select_1.size(); i++) + if(fitness_values[i].index > (to_select_1.size()-1)) change = true; + if(change) selection_position++; + else selection_position--; + } + + if(selection_position == -1) + { + d--; + if(d < 0) + { + selection_position--; + d = (int) (r * (1.0-r) * to_select_1[0]->lengthInBits()); + } + else selection_position = 1; + } + + if(selection_position == -2) + { + assert(diverge != NULL); + for(int i = 1; i < to_select_1.size(); i++) + { + if(rand01() < r) ((Diverge *)diverge)->diverge(*to_select_1[i]); + } + for(int i= 0; i < fitness_values.size(); i++) + if(fitness_values[i].index < (to_select_1.size()-1)) fitness_values[i].change = true; + + selection_position = 1; + } + + if(selection_position > 0) + { + int index = selection_position-1; + selection_position++; + return fitness_values[index]; + } + } + + void Selection_New_Population::setup(char line[MAX_BUFFER]) + { + int div; + float div_par; + + sscanf(line," %f %d %f ",&r,&div, &div_par); + assert(r>=0); + + sprintf(line,"%d %f ",div,div_par); + + diverge = Intra_Operator::create(div); + assert(diverge != NULL); + + diverge->setup(line); + } + + void Selection_New_Population::RefreshState(const StateCenter& _sc) const + { + _sc.set_contents_state_variable("_parameter_select_new_pop",(char *)&r,1,sizeof(float)); + } + + void Selection_New_Population::UpdateFromState(const StateCenter& _sc) + { + unsigned long nbytes,length; + _sc.get_contents_state_variable("_parameter_select_new_pop",(char *)&r,nbytes,length); + } + +// Operator_Pool ------------------------------------------------------------------------ + + Operator_Pool::Operator_Pool(const Problem& pbm) + { + // introduces all operators and selections in lists + + // Index to be chosen in setup file + //------------------------------------- + // The Intra_Operators are introduced dimanicly in setup + + _selectors.append(new Selection(pbm.direction())); // 0 + _selectors.append(new Selection_Tournament(pbm.direction())); // 1 + _selectors.append(new Selection_Roulette_Wheel(pbm.direction())); // 2 + _selectors.append(new Selection_Rank(pbm.direction())); // 3 + _selectors.append(new Selection_Best(pbm.direction())); // 4 + _selectors.append(new Selection_Worst(pbm.direction())); // 5 + _selectors.append(new Selection_Parents(pbm.direction())); // 6 + _selectors.append(new Selection_New_Population(pbm.direction())); // 7 + + _inter_operators.append(new Migration(pbm.direction())); // 0 + } + + Intra_Operator& Operator_Pool::intra_operator(const unsigned int index) const + { + assert(index < _intra_operators.size()); + return _intra_operators[index]; + } + + Rlist<Intra_Operator>& Operator_Pool::intra_operators() const + { + return _intra_operators; + } + + Selection& Operator_Pool::selector(const unsigned int index) const + { + assert(index < _selectors.size()); + return _selectors[index]; + } + + const Rlist<Selection>& Operator_Pool::selectors() const + { + return _selectors; + } + + Inter_Operator& Operator_Pool::inter_operator(const unsigned int index) const + { + assert(index < _inter_operators.size()); + return _inter_operators[index]; + } + + const Rlist<Inter_Operator>& Operator_Pool::inter_operators() const + { + return _inter_operators; + } + + Operator_Pool::~Operator_Pool() + {} + +// Solver (superclasse)--------------------------------------------------- + + Solver::Solver (const Problem& pbm, const SetUpParams& setup) + : problem(pbm), + params(setup), + _stat(), + _userstat(), + _sc(), + current_population(pbm,setup), + best_cost((-1) * pbm.direction() * infinity()), + worst_cost((-1) * best_cost), + best_solution(problem), + average_cost(0.0), + standard_deviation(0.0), + time_spent_in_trial(0.0), + total_time_spent(0.0), + start_trial(0.0), + start_global(0.0), + _current_trial("_current_trial",_sc), + _current_iteration("_current_iteration",_sc), + _current_evaluations("_current_evaluations",_sc), + _current_best_solution("_current_best_solution",_sc), + _current_best_cost("_current_best_cost",_sc), + _current_worst_cost("_current_worst_cost",_sc), + _current_average_cost("_current_average_cost",_sc), + _current_standard_deviation("_current_standard_deviation",_sc), + _current_time_spent("_current_time_spent",_sc), + _best_solution_trial("_best_sol_trial",_sc), + _best_cost_trial("_best_cost_trial",_sc), + _worst_cost_trial("_worst_cost_trial",_sc), + _iteration_best_found_in_trial("_iteration_best_found_in_trial",_sc), + _evaluations_best_found_in_trial("_evaluations_best_found_in_trial",_sc), + _time_best_found_trial("_time_best_found_trial",_sc), + _time_spent_trial("_time_spent_trial",_sc), + _trial_best_found("_trial_best_found",_sc), + _iteration_best_found("_iteration_best_found",_sc), + _evaluations_best_found("_evaluations_best_found",_sc), + _global_best_solution("_global_best_solution",_sc), + _global_best_cost("_global_best_cost",_sc), + _global_worst_cost("_global_worst_cost",_sc), + _time_best_found("_time_best_found",_sc), + _crossover_probability("_crossover_probability",_sc), + _diverge_probability("_diverge_probability",_sc), + _migration_rate("_migration_rate",_sc), + _migration_size("_migration_size",_sc), + _migration_selection_1("_migration_selection_1",_sc), + _migration_selection_2("_migration_selection_2",_sc), + _migration_selection_conf_1("_migration_selection_conf_1",_sc), + _migration_selection_conf_2("_migration_selection_conf_2",_sc), + _select_parents("_select_parents",_sc), + _select_offsprings("_select_offsprings",_sc), + _parameter_select_new_pop("_parameter_select_new_pop",_sc), + _display_state("_display_state",_sc) + { + current_trial(0); + current_iteration(0); + current_evaluations(0); + current_best_solution(best_solution); + current_best_cost(best_cost); + current_worst_cost(worst_cost); + current_average_cost(average_cost); + current_standard_deviation(standard_deviation); + current_time_spent(total_time_spent); + best_solution_trial(best_solution); + best_cost_trial(best_cost); + worst_cost_trial(worst_cost); + iteration_best_found_in_trial(0); + evaluations_best_found_in_trial(0); + time_best_found_trial(time_spent_in_trial); + time_spent_trial(time_spent_in_trial); + trial_best_found(0); + iteration_best_found(0); + evaluations_best_found(0); + global_best_solution(best_solution); + global_best_cost(best_cost); + global_worst_cost(worst_cost); + time_best_found(total_time_spent); + + float prob[MAX_PROB_PER_OP] = {0.0}; + crossover_probability(prob); + diverge_probability(prob); + + char aux[] = "_user_op_probability"; + char nombre[30]; + for(int i = 0; i < MAX_USER_OP; i++) + { + sprintf(nombre,"%s%d",aux,i); + _user_op_probability[i].set_name((char *)nombre); + _sc.add(_user_op_probability[i]); + user_op_probability(i,prob); + } + + migration_rate(0); + migration_size(0); + migration_selection_1(0); + migration_selection_2(0); + migration_selection_conf_1(0); + migration_selection_conf_2(0); + select_parents(0); + select_offsprings(0); + parameter_select_new_pop(0.0); + display_state(setup.display_state()); + } + + int Solver::pid() const + { + return 0; + } + + bool Solver::end_trial() const + { + return _end_trial; + } + + void Solver::end_trial(bool et) + { + _end_trial = et; + } + + unsigned int Solver::current_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _current_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned long Solver::current_iteration() const + { + unsigned long value=0; + unsigned long nitems,length; + _current_iteration.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned long Solver::current_evaluations() const + { + unsigned long value=0; + unsigned long nitems,length; + _current_evaluations.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::current_best_solution() const + { + Solution sol(problem); + unsigned long nitems,length; + char data_stored[_current_best_solution.get_nitems() + _current_best_solution.get_length()]; + _current_best_solution.get_contents(data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::current_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _current_best_cost.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::current_worst_cost() const + { + double value=0.0; + unsigned long nitems,length; + _current_worst_cost.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::current_average_cost() const + { + double value=0.0; + unsigned long nitems,length; + _current_average_cost.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::current_standard_deviation() const + { + double value=0.0; + unsigned long nitems,length; + _current_standard_deviation.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::current_time_spent() const + { + float value=0.0; + unsigned long nitems,length; + _current_time_spent.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::best_solution_trial() const + { + Solution sol(problem); + char data_stored[_best_solution_trial.get_nitems() + _best_solution_trial.get_length()]; + unsigned long nitems,length; + _best_solution_trial.get_contents(data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::best_cost_trial() const + { + double value=0.0; + unsigned long nitems,length; + _best_cost_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::worst_cost_trial() const + { + double value=0.0; + unsigned long nitems,length; + _worst_cost_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found_in_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found_in_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::evaluations_best_found_in_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _evaluations_best_found_in_trial.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_spent_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_spent_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::trial_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _trial_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::evaluations_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _evaluations_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::global_best_solution() const + { + Solution sol(problem); + char data_stored[_global_best_solution.get_nitems() + _global_best_solution.get_length()]; + unsigned long nitems,length; + _global_best_solution.get_contents(data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::global_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _global_best_cost.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::global_worst_cost() const + { + double value=0.0; + unsigned long nitems,length; + _global_worst_cost.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + int Solver::display_state() const + { + int value=0; + unsigned long nitems,length; + _display_state.get_contents((char *)&value, nitems, length); + return value; + } + + float *Solver::crossover_probability() const + { + float *current_probability = new float[MAX_PROB_PER_OP]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_crossover_probability",(char *)¤t_probability,nitems,length); + return current_probability; + } + + float *Solver::diverge_probability() const + { + float *current_probability = new float[MAX_PROB_PER_OP]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_diverge_probability",(char *)¤t_probability,nitems,length); + return current_probability; + } + + float *Solver::user_op_probability(const int index) const + { + float *current_probability = new float[MAX_PROB_PER_OP]; + unsigned long nitems,length; + char aux[30] = "_user_op_probability"; + sprintf(aux,"%s%d",aux,index); + + _sc.get_contents_state_variable(aux,(char *)¤t_probability,nitems,length); + return current_probability; + } + + unsigned int Solver::migration_rate() const + { + unsigned int rate=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_rate",(char *)&rate,nitems,length); + return rate; + } + + unsigned int Solver::migration_size() const + { + unsigned int size=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_size",(char *)&size,nitems,length); + return size; + } + + unsigned int Solver::migration_selection_1() const + { + unsigned int selection_1=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_selection_1",(char *)&selection_1,nitems,length); + return selection_1; + } + + unsigned int Solver::migration_selection_2() const + { + unsigned int selection_2=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_selection_2",(char *)&selection_2,nitems,length); + return selection_2; + } + + unsigned int Solver::migration_selection_conf_1() const + { + unsigned int selection_conf_1=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_selection_conf_1",(char *)&selection_conf_1,nitems,length); + return selection_conf_1; + } + + unsigned int Solver::migration_selection_conf_2() const + { + unsigned int selection_conf_2=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_selection_conf_2",(char *)&selection_conf_2,nitems,length); + return selection_conf_2; + } + + unsigned int Solver::select_parents() const + { + unsigned int select_parents=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_select_parents",(char *)&select_parents,nitems,length); + return select_parents; + } + + unsigned int Solver::select_offprings() const + { + unsigned int select_offsprings=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_select_offsprings",(char *)&select_offsprings,nitems,length); + return select_offsprings; + } + + float Solver::parameter_select_new_pop() const + { + float parameter_select_new_pop; + unsigned long nitems,length; + _sc.get_contents_state_variable("_parameter_select_new_pop",(char *)¶meter_select_new_pop,nitems,length); + return parameter_select_new_pop; + } + + void Solver::current_trial(const unsigned int value) + { + _current_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::current_iteration(const unsigned long value) + { + _current_iteration.set_contents((char *)&value,1,sizeof(long)); + } + + void Solver::current_evaluations(const unsigned long value) + { + _current_evaluations.set_contents((char *)&value,1,sizeof(long)); + } + + void Solver::current_best_solution(const Solution& sol) + { + _current_best_solution.set_contents(sol.to_String(),1,sol.size()); + } + + void Solver::current_best_cost(const double value) + { + _current_best_cost.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::current_worst_cost(const double value) + { + _current_worst_cost.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::current_average_cost(const double value) + { + _current_average_cost.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::current_standard_deviation(const double value) + { + _current_standard_deviation.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::current_time_spent(const float value) + { + _current_time_spent.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::best_solution_trial(const Solution& sol) + { + _best_solution_trial.set_contents(sol.to_String(),1,sol.size()); + } + + void Solver::best_cost_trial(const double value) + { + _best_cost_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::worst_cost_trial(const double value) + { + _worst_cost_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::iteration_best_found_in_trial(const unsigned int value) + { + _iteration_best_found_in_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::evaluations_best_found_in_trial(const unsigned int value) + { + _evaluations_best_found_in_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::time_best_found_trial(const float value) + { + _time_best_found_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::time_spent_trial(const float value) + { + _time_spent_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::trial_best_found(const unsigned int value) + { + _trial_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::iteration_best_found(const unsigned int value) + { + _iteration_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::evaluations_best_found(const unsigned int value) + { + _evaluations_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::global_best_solution(const Solution& sol) + { + _global_best_solution.set_contents(sol.to_String(),1,sol.size()); + } + + void Solver::global_best_cost(const double value) + { + _global_best_cost.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::global_worst_cost(const double value) + { + _global_worst_cost.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::time_best_found(const float value) + { + _time_best_found.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::display_state(const int value) + { + _display_state.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::crossover_probability(const float *new_probability) + { + _sc.set_contents_state_variable("_crossover_probability",(char *)new_probability,MAX_PROB_PER_OP,sizeof(float)); + } + + void Solver::diverge_probability(const float *new_probability) + { + _sc.set_contents_state_variable("_diverge_probability",(char *)new_probability,MAX_PROB_PER_OP,sizeof(float)); + } + + void Solver::user_op_probability(const int index, const float *new_probability) + { + char aux[30] = "_user_op_probability"; + sprintf(aux,"%s%d",aux,index); + + _sc.set_contents_state_variable(aux,(char *)new_probability,MAX_PROB_PER_OP,sizeof(float)); + } + + void Solver::migration_rate(const unsigned int rate) + { + _sc.set_contents_state_variable("_migration_rate",(char *)&rate,1,sizeof(int)); + } + + void Solver::migration_size(const unsigned int size) + { + _sc.set_contents_state_variable("_migration_size",(char *)&size,1,sizeof(int)); + } + + void Solver::migration_selection_1(const unsigned int selection_1) + { + _sc.set_contents_state_variable("_migration_selection_1",(char *)&selection_1,1,sizeof(int)); + } + + void Solver::migration_selection_2(const unsigned int selection_2) + { + _sc.set_contents_state_variable("_migration_selection_2",(char *)&selection_2,1,sizeof(int)); + } + + void Solver::migration_selection_conf_1(const unsigned int selection_conf_1) + { + _sc.set_contents_state_variable("_migration_selection_conf_1",(char *)&selection_conf_1,1,sizeof(int)); + } + + void Solver::migration_selection_conf_2(const unsigned int selection_conf_2) + { + _sc.set_contents_state_variable("_migration_selection_conf_2",(char *)&selection_conf_2,1,sizeof(int)); + } + + void Solver::select_parents(const unsigned int selection) + { + _sc.set_contents_state_variable("_select_parents",(char *)&selection,1,sizeof(int)); + } + + void Solver::select_offsprings(const unsigned int selection) + { + _sc.set_contents_state_variable("_select_offsprings",(char *)&selection,1,sizeof(int)); + } + + void Solver::parameter_select_new_pop(const float value) + { + _sc.set_contents_state_variable("_parameter_select_new_pop",(char *)&value,1,sizeof(float)); + } + + Statistics& Solver::statistics() + { + return _stat; + } + + UserStatistics& Solver::userstatistics() + { + return _userstat; + } + + Population& Solver::population() + { + return current_population; + } + + const SetUpParams& Solver::setup() const + { + return params; + } + + const Problem& Solver::pbm() const + { + return problem; + } + + void Solver::KeepHistory(const Solution& best_sol,const double best_cost,const double worst_cost,const float time_spent_in_trial,const float total_time_spent) + { + bool betterG=false; + bool worseG=false; + bool betterT=false; + bool worseT=false; + + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_spent_in_trial < time_best_found())); + worseG = (worst_cost > global_worst_cost()); + betterT = (best_cost < best_cost_trial() || (best_cost == best_cost_trial() && time_spent_in_trial < time_best_found_trial())); + worseT = (worst_cost > worst_cost_trial()); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_spent_in_trial < time_best_found())); + worseG = (worst_cost < global_worst_cost()); + betterT = (best_cost > best_cost_trial() || (best_cost == best_cost_trial() && time_spent_in_trial < time_best_found_trial())); + worseT = (worst_cost < worst_cost_trial()); + break; + } + + if (betterT) + { + best_solution_trial(best_sol); + best_cost_trial(best_cost); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_in_trial(current_iteration()); + evaluations_best_found_in_trial(current_evaluations()); + if (betterG) + { + global_best_solution(best_sol); + global_best_cost(best_cost); + time_best_found(time_spent_in_trial); + trial_best_found(current_trial()); + iteration_best_found(current_iteration()); + evaluations_best_found(current_evaluations()); + } + } + + if (worseT) + { + worst_cost_trial(worst_cost); + if (worseG) + global_worst_cost(worst_cost); + } + } + + StateCenter *Solver::GetState() + { + return &_sc; + } + + void Solver::RefreshState() + { + current_best_solution(best_solution); + current_best_cost(best_cost); + current_worst_cost(worst_cost); + current_average_cost(average_cost); + current_standard_deviation(standard_deviation); + current_time_spent(total_time_spent); + time_spent_trial(time_spent_in_trial); + KeepHistory(best_solution,best_cost,worst_cost,time_spent_in_trial,total_time_spent); + } + + void Solver::RefreshCfgState() + { + for (int i=0;i<params.pool().intra_operators().size();i++) + params.pool().intra_operator(i).RefreshState(_sc); + for (int i=0;i<params.pool().inter_operators().size();i++) + params.pool().inter_operator(i).RefreshState(_sc); + for (int i=0;i<params.pool().selectors().size();i++) + params.pool().selector(i).RefreshState(_sc); + params.RefreshState(_sc); + } + + void Solver::UpdateFromState() + { + best_solution=current_best_solution(); + best_cost=current_best_cost(); + worst_cost=current_worst_cost(); + average_cost=current_average_cost(); + standard_deviation=current_standard_deviation(); + total_time_spent=current_time_spent(); + time_spent_in_trial=time_spent_trial(); + KeepHistory(best_solution,best_cost,worst_cost,time_spent_in_trial,total_time_spent); + } + + void Solver::UpdateFromCfgState() + { + for (int i=0;i<params.pool().intra_operators().size();i++) + params.pool().intra_operator(i).UpdateFromState(_sc); + for (int i=0;i<params.pool().inter_operators().size();i++) + params.pool().inter_operator(i).UpdateFromState(_sc); + for (int i=0;i<params.pool().selectors().size();i++) + params.pool().selector(i).UpdateFromState(_sc); + params.UpdateFromState(_sc); + } + + void Solver::show_state() const + { + cout << endl << " Current State ---------------------------------------------" << endl; +/* cout << endl << "Selection parents -> " << select_parents(); + cout << endl << "Parameter of selection: " << parameter_select_parents(); + cout << endl << "Selection offsprings -> " << select_offprings(); + cout << endl << "Parameter of selection: " << parameter_select_offsprings() << endl; + cout << endl << "Crossover_probability: " << crossover_probability(); + cout << endl << "Mutation_probability: " << mutation_probability(); + cout << endl << "User_Operator_probability: " << user_op_probability(0); + cout << endl << "Migration_rate: " << migration_rate(); + cout << endl << "Migration_size: " << migration_size(); + cout << endl << "Migration_selection_1: " << migration_selection_1(); + cout << endl << "Migration_selection_conf_1: " << migration_selection_conf_1(); + cout << endl << "Migration_selection_2: " << migration_selection_2(); + cout << endl << "Migration_selection_conf_2: " << migration_selection_conf_2() << endl; +*/ cout << endl << "Current trial: " << current_trial(); + cout << endl << "Current iteration: " << current_iteration(); + cout << endl << "Current evaluations: " << current_evaluations(); + cout << endl << "Current best cost: " << current_best_cost(); + cout << endl << "Current worst cost: " << current_worst_cost(); + cout << endl << "Current Average cost: " << current_average_cost(); + cout << endl << "Current Standard Deviation: " << current_standard_deviation(); + cout << endl << endl << "Trial: "; + cout << endl << "Best cost trial: " << best_cost_trial(); + cout << endl << "Worst cost trial: " << worst_cost_trial(); + cout << endl << "Iteration best found in trial: " << iteration_best_found_in_trial(); + cout << endl << "Time best found trial: " << time_best_found_trial(); + cout << endl << "Time spent in trial: " << time_spent_trial(); + cout << endl << endl << "Global: "; + cout << endl << "Global best cost: " << global_best_cost(); + cout << endl << "Global worst cost: " << global_worst_cost(); + cout << endl << "Trial best found: " << trial_best_found(); + cout << endl << "Iteration best found: " << iteration_best_found(); + cout << endl << "Time best found: " << time_best_found(); +// cout << endl << endl << "Best Solution: " << endl << global_best_solution(); + cout << endl << endl << "Current time spent (so far): " << current_time_spent() << endl; + } + + Solver::~Solver() + { + _sc.removeAll(); + } + +// Solver sequencial ----------------------------------------------------- + + Solver_Seq::Solver_Seq (const Problem& pbm, const SetUpParams& setup) + : Solver(pbm,setup) + { + random_seed(time(0)); + _end_trial=true; + } + + Solver_Seq::~Solver_Seq () + {} + + void Solver_Seq::StartUp() + { + Population pop(problem,params); + pop.initialize(); + StartUp(pop); + } + + void Solver_Seq::StartUp(const Population& pop) + { + start_trial=_used_time(); + start_global=total_time_spent; + + current_trial(current_trial()+1); + current_iteration(0); + current_evaluations(pop.evaluations()); + + // initialize state variables in the current trial + + Solution initial_solution(problem); + + time_spent_in_trial=0.0; + best_cost_trial((-1) * problem.direction() * infinity()); + worst_cost_trial((-1) * best_cost_trial()); + best_solution_trial(initial_solution); + time_best_found_trial(0.0); + + current_population=pop; + current_population.evaluate_parents(); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + UpdateFromCfgState(); + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + void Solver_Seq::DoStep() + { + + current_iteration(current_iteration()+1); + current_population.evolution(); + current_evaluations(current_population.evaluations()); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + if( (current_iteration() % params.refresh_global_state()) == 0) + UpdateFromCfgState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + void Solver_Seq::run () + { + while (current_trial() < params.independent_runs() ) + run(params.nb_evolution_steps()); + } + + void Solver_Seq::run (const unsigned long int nb_generations) + { + StartUp(); + while ((current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + + } + + void Solver_Seq::run (const Population& pop,const unsigned long int nb_generations) + { + StartUp(pop); + while ((current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + + } + + // Solver LAN ------------------------------------------------------------ + + Solver_Lan::Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0),acum_iterations(0) + { + + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + // random_seed(time(0) + (mypid+1)); + } + + Solver_Lan::~Solver_Lan () + { + NetStream::finalize(); + } + + int Solver_Lan::pid() const + { + return mypid; + } + + NetStream& Solver_Lan::netstream() + { + return _netstream; + } + + void Solver_Lan::StartUp() + { + Population pop(problem,params); + pop.initialize(); + StartUp(pop); + } + + void Solver_Lan::StartUp(const Population& pop) + { + _netstream << barrier; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + acum_iterations = 0; + + start_trial=_used_time(); + start_global=total_time_spent; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + current_evaluations(pop.evaluations()); + + // initialize state variables in the current trial + + Solution initial_solution(problem); + + time_spent_in_trial=0.0; + best_cost_trial((-1) * problem.direction() * infinity()); + worst_cost_trial((-1) * best_cost_trial()); + best_solution_trial(initial_solution); + iteration_best_found_in_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current_population=pop; + current_population.evaluate_parents(); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + } + } + + void Solver_Lan::DoStep() + { + current_iteration(current_iteration()+1); + current_population.evolution(); + current_evaluations(current_population.evaluations()); + + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(regular, pending); + if(pending) + final_phase = true; + //////////////////////// + + current_population.interchange(current_iteration(),_netstream); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + // in this iteration i have to send data about my local state to the global state + if ((int)current_iteration() % params.refresh_global_state() ==0) + { + send_local_state_to(mypid); + UpdateFromCfgState(); + } + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + + + void Solver_Lan::send_local_state_to(int _mypid) { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_evaluations() + << best_solution_trial() + << current_best_solution() + << best_cost_trial() + << worst_cost_trial() + << time_best_found_trial() + << current_best_cost() + << current_worst_cost() + << current_average_cost() + << current_standard_deviation() + << iteration_best_found_in_trial() + << evaluations_best_found_in_trial() + << pack_end; + } + + int Solver_Lan::receive_local_state() { + int r_pid=0; + + _netstream._wait(packed); + + _netstream << pack_begin + >> r_pid + >> _current_trial + >> _current_iteration + >> _current_evaluations + >> _best_solution_trial + >> best_solution + >> _best_cost_trial + >> _worst_cost_trial + >> _time_best_found_in_trial + >> best_cost + >> worst_cost + >> average_cost + >> standard_deviation + >> _iteration_best_found_in_trial + >> _evaluations_best_found_in_trial + << pack_end; + return r_pid; + } + + void Solver_Lan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + _netstream << set_source(MPI_ANY_SOURCE); + + while (!_end_trial) + { + received_pid=0; + received_pid=receive_local_state(); + + current_trial(_current_trial); + + // refresh the global state with received data ( a local state ) + current_iteration(_iteration_best_found_in_trial); + current_evaluations(_evaluations_best_found_in_trial); + KeepHistory(_best_solution_trial,_best_cost_trial,_worst_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + // the process that has send data has finished the current trial + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && terminateQ(problem,*this,params)) + { + acum_iterations = params.nb_evolution_steps() * nb_finalized_processes; + acum_evaluations = acum_iterations* params.population_size() + + nb_finalized_processes*params.population_size(); + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << 1; + } + final_phase = true; + } + nb_finalized_processes++; + acum_iterations += _iteration_best_found_in_trial; + acum_evaluations += _evaluations_best_found_in_trial; + } + if (nb_finalized_processes==nb_proc-1) + _end_trial=true; + + current_iteration(_current_iteration); + current_evaluations(_current_evaluations); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + RefreshState(); + RefreshCfgState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualizaci�n de las estad�sticas // Termination phase // + iteration_best_found_in_trial(acum_iterations/(_netstream.pnumber()-1)); + evaluations_best_found_in_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = best_cost_trial(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + { + iteration_best_found(iteration_best_found_in_trial()); + evaluations_best_found(evaluations_best_found_in_trial()); + } + + RefreshState(); + RefreshCfgState(); + + _stat.update(*this); + _userstat.update(*this); + + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Lan::run () + { + while (current_trial() < params.independent_runs()) + run(params.nb_evolution_steps()); + } + + void Solver_Lan::run (const unsigned long int nb_generations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Population& pop,const unsigned long int nb_generations) + { + StartUp(pop); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::reset() + { + Solution left_solution(problem); + int i; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> i; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } + + // Solver WAN ------------------------------------------------------------ + + Solver_Wan::Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0),acum_iterations(0) + { + + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + // random_seed(time(0) + (mypid+1)); + } + + Solver_Wan::~Solver_Wan () + { + NetStream::finalize(); + } + + int Solver_Wan::pid() const + { + return mypid; + } + + NetStream& Solver_Wan::netstream() + { + return _netstream; + } + + void Solver_Wan::StartUp() + { + Population pop(problem,params); + pop.initialize(); + StartUp(pop); + } + + void Solver_Wan::StartUp(const Population& pop) + { + _netstream << barrier; + + // Termination phase // + final_phase = false; + acum_evaluations = 0; + acum_iterations = 0; + + start_trial=_used_time(); + start_global=total_time_spent; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + current_evaluations(pop.evaluations()); + + // initialize state variables in the current trial + + Solution initial_solution(problem); + + time_spent_in_trial=0.0; + best_cost_trial((-1) * problem.direction() * infinity()); + worst_cost_trial((-1) * best_cost_trial()); + best_solution_trial(initial_solution); + iteration_best_found_in_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current_population=pop; + current_population.evaluate_parents(); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + } + } + + void Solver_Wan::DoStep() + { + current_iteration(current_iteration()+1); + current_population.evolution(); + current_evaluations(current_population.evaluations()); + + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(regular, pending); + if(pending) + final_phase = true; + //////////////////////// + + current_population.interchange(current_iteration(),_netstream); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + // in this iteration i have to send data about my local state to the global state + if ((int)current_iteration() % params.refresh_global_state() ==0) + { + send_local_state_to(mypid); + UpdateFromCfgState(); + } + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + + + void Solver_Wan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_evaluations() + << best_cost_trial() + << best_solution_trial() + << iteration_best_found_in_trial() + << evaluations_best_found_in_trial() + << time_best_found_trial() + << worst_cost_trial() + << current_best_cost() + << current_best_solution() + << current_worst_cost() + << current_average_cost() + << current_standard_deviation() + << pack_end; + } + + int Solver_Wan::receive_local_state() + { + int r_pid=0; + + _netstream._wait(packed); + + _netstream << pack_begin + >> r_pid + >> _current_trial + >> _current_iteration + >> _current_evaluations + >> _best_cost_trial + >> _best_solution_trial + >> _iteration_best_found_in_trial + >> _evaluations_best_found_in_trial + >> _time_best_found_in_trial + >> _worst_cost_trial + >> best_cost + >> best_solution + >> worst_cost + >> average_cost + >> standard_deviation + << pack_end; + return r_pid; + } + + void Solver_Wan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + _netstream << set_source(MPI_ANY_SOURCE); + + while (!_end_trial) + { + received_pid=0; + received_pid=receive_local_state(); + + current_trial(_current_trial); + + // refresh the global state with received data ( a local state ) + current_iteration(_iteration_best_found_in_trial); + current_evaluations(_evaluations_best_found_in_trial); + KeepHistory(_best_solution_trial,_best_cost_trial,_worst_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + // the process that has send data has finished the current trial + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && terminateQ(problem,*this,params)) + { + acum_iterations = params.nb_evolution_steps() * nb_finalized_processes; + acum_evaluations = acum_iterations* params.population_size() + + nb_finalized_processes*params.population_size(); + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << 1; + } + final_phase = true; + } + nb_finalized_processes++; + acum_iterations += _iteration_best_found_in_trial; + acum_evaluations += _evaluations_best_found_in_trial; + } + if (nb_finalized_processes==nb_proc-1) + _end_trial=true; + + current_iteration(_current_iteration); + current_evaluations(_current_evaluations); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + RefreshState(); + RefreshCfgState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Update Stats // Termination phase // + iteration_best_found_in_trial(acum_iterations/(_netstream.pnumber()-1)); + evaluations_best_found_in_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = best_cost_trial(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + { + iteration_best_found(iteration_best_found_in_trial()); + evaluations_best_found(evaluations_best_found_in_trial()); + } + + RefreshState(); + RefreshCfgState(); + + _stat.update(*this); + _userstat.update(*this); + + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Wan::run () + { + while (current_trial() < params.independent_runs()) + run(params.nb_evolution_steps()); + } + + void Solver_Wan::run (const unsigned long int nb_generations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Population& pop,const unsigned long int nb_generations) + { + StartUp(pop); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::reset() + { + Solution left_solution(problem); + int i; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> i; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + + } + _netstream << barrier; + } + +} + + diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/CHC.pro.o b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/CHC.pro.o new file mode 100644 index 0000000000000000000000000000000000000000..41f66470a6785a1cd1b0639260dbc9f227f6ad39 Binary files /dev/null and b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/CHC.pro.o differ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/CHC.req.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/CHC.req.cc new file mode 100644 index 0000000000000000000000000000000000000000..df05c01fec88760531488a5f2bb22cb7abd1e435 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/CHC.req.cc @@ -0,0 +1,332 @@ +#ifndef INC_REQ_CHC +#define INC_REQ_CHC +#include "CHC.hh" +#include <math.h> + +skeleton CHC +{ + + // Problem --------------------------------------------------------------- + + Problem::Problem ():_dimension(0) + {} + + ostream& operator<< (ostream& os, const Problem& pbm) + { + os << endl << endl << "Number of Variables " << pbm._dimension + << endl; + return os; + } + + istream& operator>> (istream& is, Problem& pbm) + { + char buffer[MAX_BUFFER]; + int i; + + is.getline(buffer,MAX_BUFFER,'\n'); + sscanf(buffer,"%d",&pbm._dimension); + + return is; + } + + Problem& Problem::operator= (const Problem& pbm) + { + return *this; + } + + bool Problem::operator== (const Problem& pbm) const + { + if (_dimension!=pbm.dimension()) return false; + return true; + } + + bool Problem::operator!= (const Problem& pbm) const + { + return !(*this == pbm); + } + + Direction Problem::direction() const + { + return maximize; + //return minimize; + } + + int Problem::dimension() const + { + return _dimension; + } + + Problem::~Problem() + {} + + // Solution -------------------------------------------------------------- + + Solution::Solution (const Problem& pbm):_pbm(pbm),_var(pbm.dimension()) + {} + + + const Problem& Solution::pbm() const + { + return _pbm; + } + + Solution::Solution(const Solution& sol):_pbm(sol.pbm()) + { + *this=sol; + } + + + istream& operator>> (istream& is, Solution& sol) + { + for (int i=0;i<sol.pbm().dimension();i++) + is >> sol._var[i]; + + return is; + } + + ostream& operator<< (ostream& os, const Solution& sol) + { + for (int i=0;i<sol.pbm().dimension();i++) + os << " " << sol._var[i]; + return os; + } + + NetStream& operator << (NetStream& ns, const Solution& sol) + { + for (int i=0;i<sol._var.size();i++) + ns << sol._var[i]; + return ns; + } + + + NetStream& operator >> (NetStream& ns, Solution& sol) + { + for (int i=0;i<sol._var.size();i++) + ns >> sol._var[i]; + return ns; + } + + + Solution& Solution::operator= (const Solution &sol) + { + _var=sol._var; + return *this; + } + + + bool Solution::operator== (const Solution& sol) const + { + if (sol.pbm() != _pbm) return false; + return true; + } + + bool Solution::operator!= (const Solution& sol) const + { + return !(*this == sol); + } + + void Solution::initialize() + { + for (int i=0;i<_pbm.dimension();i++) + _var[i]=rand_int(0,1); + } + + + double Solution::fitness () const + { + double fitness = 0.0; + + if(_var[0] == 2) return 0.0; + + for (int i=0;i<_var.size();i++) + fitness += _var[i]; + + return fitness; + } + + + char *Solution::to_String() const + { + return (char *)_var.get_first(); + } + + + void Solution::to_Solution(char *_string_) + { + int *ptr=(int *)_string_; + for (int i=0;i<_pbm.dimension();i++) + { + _var[i]=*ptr; + ptr++; + } + } + + unsigned int Solution::size() const + { + return (_pbm.dimension() * sizeof(int)); + } + + int Solution::lengthInBits() const + { + return _pbm.dimension(); + } + + void Solution::flip(const int index) + { + _var[index] = 1 - _var[index]; + } + + bool Solution::equalb(const int index,Solution &s) + { + return _var[index] == s._var[index]; + } + + void Solution::swap(const int index, Solution &s) + { + int aux = s._var[index]; + s._var[index] = _var[index]; + _var[index] = aux; + } + + void Solution::invalid() + { + _var[0] = 2; + } + + int& Solution::var(const int index) + { + return _var[index]; + } + + + Rarray<int>& Solution::array_var() + { + return _var; + } + + Solution::~Solution() + {} + + // UserStatistics ------------------------------------------------------- + + UserStatistics::UserStatistics () + {} + + ostream& operator<< (ostream& os, const UserStatistics& userstat) + { + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF TRIALS " << endl; + os << "------------------------------------------------------------------" << endl; + + for (int i=0;i< userstat.result_trials.size();i++) + { + os << endl + << userstat.result_trials[i].trial + << "\t" << userstat.result_trials[i].best_cost_trial + << "\t\t" << userstat.result_trials[i].worst_cost_trial + << "\t\t\t" << userstat.result_trials[i].nb_evaluation_best_found_trial + << "\t\t\t" << userstat.result_trials[i].nb_iteration_best_found_trial + << "\t\t\t" << userstat.result_trials[i].time_best_found_trial + << "\t\t" << userstat.result_trials[i].time_spent_trial; + } + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + UserStatistics& UserStatistics::operator= (const UserStatistics& userstats) + { + result_trials=userstats.result_trials; + return (*this); + } + + void UserStatistics::update(const Solver& solver) + { + if( (solver.pid()!=0) || (solver.end_trial()!=true) + || ((solver.current_iteration()!=solver.setup().nb_evolution_steps()) + && !terminateQ(solver.pbm(),solver,solver.setup()))) + return; + + struct user_stat *new_stat; + + if ((new_stat=(struct user_stat *)malloc(sizeof(struct user_stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluation_best_found_trial = solver.evaluations_best_found_in_trial(); + new_stat->nb_iteration_best_found_trial = solver.iteration_best_found_in_trial(); + new_stat->worst_cost_trial = solver.worst_cost_trial(); + new_stat->best_cost_trial = solver.best_cost_trial(); + new_stat->time_best_found_trial = solver.time_best_found_trial(); + new_stat->time_spent_trial = solver.time_spent_trial(); + + result_trials.append(*new_stat); + } + + void UserStatistics::clear() + { + result_trials.remove(); + } + + UserStatistics::~UserStatistics() + { + result_trials.remove(); + } + + // User_Operator:Intra_operator --------------------------------------------------------- + + User_Operator::User_Operator(const unsigned int _number_op):Intra_Operator(_number_op) + {} + + void User_Operator::execute(Rarray<Solution*>& sols) const + {} + + void User_Operator::setup(char line[MAX_BUFFER]) + {} + + Intra_Operator *User_Operator::create(const unsigned int _number_op) + { + return new User_Operator(_number_op); + } + + ostream& operator<< (ostream& os, const User_Operator& u_op) + { + os << "User Operator."; + return os; + } + + void User_Operator::RefreshState(const StateCenter& _sc) const + {} + + void User_Operator::UpdateFromState(const StateCenter& _sc) + {} + + User_Operator::~User_Operator() + {} + + +// StopCondition_1 ------------------------------------------------------------------------------------- + + StopCondition_1::StopCondition_1():StopCondition() + {} + + bool StopCondition_1::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return ((int)solver.best_cost_trial() == pbm.dimension()); + } + + StopCondition_1::~StopCondition_1() + {} + + + //------------------------------------------------------------------------ + // Specific methods ------------------------------------------------------ + //------------------------------------------------------------------------ + + bool terminateQ (const Problem& pbm, const Solver& solver, + const SetUpParams& setup) + { + StopCondition_1 stop; + return stop.EvaluateCondition(pbm,solver,setup); + } +} +#endif + diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/CHC.req.o b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/CHC.req.o new file mode 100644 index 0000000000000000000000000000000000000000..5120ba4992fe5f72ea6118d14c689c490b673b40 Binary files /dev/null and b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/CHC.req.o differ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/CHCstructures.hh b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/CHCstructures.hh new file mode 100644 index 0000000000000000000000000000000000000000..70aba854025619b1cfde91817e9f99ef79c108a6 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/CHCstructures.hh @@ -0,0 +1,29 @@ +#ifndef INC_CHC_mallba_hh +#define INC_CHC_mallba_hh + +#include <iostream> +#include <fstream> +#include <math.h> +#include <limits.h> +#include <float.h> +#include <Rlist.h> +#include <Rarray.h> +#include <Messages.h> +#include <mallba.hh> +#include <States.hh> +#include <random.hh> +#include <time.hh> +#include <netstream.hh> +#include <assert.h> + +using namespace std; + +struct individual // index of a individual in the population and its fitness +{ + int index; + double fitness; + double sel_parameter; + bool change; +}; + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/Config.cfg b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/Config.cfg new file mode 100644 index 0000000000000000000000000000000000000000..b34042ed91bb7878723705342d69af63f13dec97 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/Config.cfg @@ -0,0 +1,3 @@ +CHC.cfg +../../ProblemInstances/ONEMAX-instances/onemax10.txt +res/om10.chc.lan.txt diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/MainLan b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/MainLan new file mode 100644 index 0000000000000000000000000000000000000000..f71c6e405ea5e9ef5a0fe9ad9c3c33807afa6d2a Binary files /dev/null and b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/MainLan differ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/MainLan.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/MainLan.cc new file mode 100644 index 0000000000000000000000000000000000000000..279b550e51fff6cd85ba1fb85ade32eccef30a4d --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/MainLan.cc @@ -0,0 +1,49 @@ +#include <iostream> +#include <fstream> +#include "CHC.hh" + +using namespace std; + +int main (int argc, char** argv) +{ + using skeleton CHC; + char path[MAX_BUFFER] = ""; + + system("clear"); + + strcat(path,argv[1]); + ifstream f(path); + if(!f) show_message(10); + + f.getline(path,MAX_BUFFER,'\n'); + ifstream f1(path); + if(!f1) show_message(11); + + f.getline(path,MAX_BUFFER,'\n'); + ifstream f2(path); + if(!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + Operator_Pool pool(pbm); + SetUpParams cfg(pool); + f1 >> cfg; + + Solver_Lan solver(pbm,cfg,argc,argv); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solucion: " << solver.global_best_solution() << " Fitness: " << solver.global_best_solution().fitness(); + + f.getline(path,MAX_BUFFER,'\n'); + ofstream fexit(path); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + cout << endl << endl << " :( ---------------------- THE END --------------- :) " << endl; + } + return(0); +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/MainLan.o b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/MainLan.o new file mode 100644 index 0000000000000000000000000000000000000000..719588ecb004d2c7131a859e6905d3a50cbaa302 Binary files /dev/null and b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/MainLan.o differ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/MainSeq b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/MainSeq new file mode 100644 index 0000000000000000000000000000000000000000..eb6ade233d92ae2f16601f662f46bad816b80747 Binary files /dev/null and b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/MainSeq differ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/MainSeq.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/MainSeq.cc new file mode 100644 index 0000000000000000000000000000000000000000..4c291f8536235167c501b779e8c92cc95536233f --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/MainSeq.cc @@ -0,0 +1,43 @@ +#include <iostream> +#include <fstream> +#include "CHC.hh" + +int main (int argc, char** argv) +{ + using skeleton CHC; + + system("clear"); + + if(argc < 4) + show_message(1); + + ifstream f1(argv[1]); + if (!f1) show_message(11); + + ifstream f2(argv[2]); + if (!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + Operator_Pool pool(pbm); + SetUpParams cfg(pool); + f1 >> cfg; + + Solver_Seq solver(pbm,cfg); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solution" << solver.global_best_solution() << endl + << " Fitness: " << solver.global_best_solution().fitness() << endl; + cout << "\n\n :( ---------------------- THE END --------------- :) "; + + ofstream fexit(argv[3]); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + } + return(0); +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/MainSeq.o b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/MainSeq.o new file mode 100644 index 0000000000000000000000000000000000000000..2f4acd33d6c1a0632a10acbd32adcc384510244b Binary files /dev/null and b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/MainSeq.o differ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/MainWan.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/MainWan.cc new file mode 100644 index 0000000000000000000000000000000000000000..4ee19e551feb1537b218110610efe0beeaeda53f --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/MainWan.cc @@ -0,0 +1,52 @@ +#include "CHC.hh" + +int main (int argc, char** argv) +{ + using skeleton CHC; + char path[MAX_BUFFER]; + int len; + int longitud; + + system("clear"); + + get_path(argv[0],path); + len = strlen(path); + longitud = MAX_BUFFER - len; + + strcat(path,"Config.cfg"); + ifstream f(path); + if(!f) show_message(10); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f1(path); + if(!f1) show_message(11); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f2(path); + if(!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + Operator_Pool pool(pbm); + SetUpParams cfg(pool); + f1 >> cfg; + + + Solver_Lan solver(pbm,cfg,argc,argv); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solucion: " << solver.global_best_solution() << " Fitness: " << solver.global_best_solution().fitness(); + + f.getline(&(path[len]),longitud,'\n'); + ofstream fexit(path); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + cout << endl << endl << " :( ---------------------- THE END --------------- :) " << endl; + } + return(0); +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/Makefile b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..3225d38fd55374c615954159aa5522c857cfa145 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/Makefile @@ -0,0 +1,24 @@ +include ../../environment + +all: MainSeq MainLan + +clean: + rm -f MainLan MainSeq *.o *% *~ + +MainSeq: CHC.req.o CHC.pro.o MainSeq.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainLan: CHC.req.o CHC.pro.o MainLan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainWan: CHC.req.o CHC.pro.o MainWan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +LAN: + $(RUN) -np 10 ./MainLan Config.cfg + +WAN: + $(RUN) -v -p4pg pgfileWan MainWan + +SEQ: + ./MainSeq CHC.cfg ../../ProblemInstances/ONEMAX-instances/onemax10.txt res/sol.txt diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/res/empty.txt b/ProyectoFinal/AlgoritmoGenetico/malva/rep/CHC/res/empty.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/Config.cfg b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/Config.cfg new file mode 100644 index 0000000000000000000000000000000000000000..ad19d328a359ff31b8991f4f76696811bb90321e --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/Config.cfg @@ -0,0 +1,3 @@ +newGA.cfg +../../ProblemInstances/ONEMAX-instances/onemax10.txt +res/om10.newga.lan.txt diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/MainLan b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/MainLan new file mode 100644 index 0000000000000000000000000000000000000000..4412f1cad77b8b6332c1c698973a12e75d51ddba Binary files /dev/null and b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/MainLan differ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/MainLan.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/MainLan.cc new file mode 100644 index 0000000000000000000000000000000000000000..494e82e0c3d235cd88c33a595277af29f7f4e148 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/MainLan.cc @@ -0,0 +1,53 @@ +#include "newGA.hh" + +int main (int argc, char** argv) +{ + using skeleton newGA; + + char path[MAX_BUFFER]; + int len; + int longitud; + + system("clear"); + + get_path(argv[0],path); + len = strlen(path); + longitud = MAX_BUFFER - len; + + strcat(path,"Config.cfg"); + ifstream f(path); + if(!f) show_message(10); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f1(path); + if(!f1) show_message(11); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f2(path); + if(!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + Operator_Pool pool(pbm); + SetUpParams cfg(pool); + f1 >> cfg; + + + Solver_Lan solver(pbm,cfg,argc,argv); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solution: " << solver.global_best_solution() << " Fitness: " << solver.global_best_solution().fitness(); + + f.getline(&(path[len]),longitud,'\n'); + ofstream fexit(path); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + cout << endl << endl << " :( ---------------------- THE END --------------- :) " << endl; + } + return(0); +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/MainLan.o b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/MainLan.o new file mode 100644 index 0000000000000000000000000000000000000000..9385dd20caa64bf3c0a87783a4225bf3b2e79568 Binary files /dev/null and b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/MainLan.o differ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/MainSeq b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/MainSeq new file mode 100644 index 0000000000000000000000000000000000000000..da4383cc2eb7ad38bb626ee134b3475b21c1aae0 Binary files /dev/null and b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/MainSeq differ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/MainSeq.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/MainSeq.cc new file mode 100644 index 0000000000000000000000000000000000000000..d4a7c14ce97eeaa129e3f34238fa18ec8972cede --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/MainSeq.cc @@ -0,0 +1,41 @@ +#include "newGA.hh" + +int main (int argc, char** argv) +{ + using skeleton newGA; + + system("clear"); + + if(argc < 4) + show_message(1); + + ifstream f1(argv[1]); + if (!f1) show_message(11); + + ifstream f2(argv[2]); + if (!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + Operator_Pool pool(pbm); + SetUpParams cfg(pool); + f1 >> cfg; + + Solver_Seq solver(pbm,cfg); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solution: " << solver.global_best_solution() + << " Fitness: " << solver.global_best_solution().fitness() << endl; + cout << "\n\n :( ---------------------- THE END --------------- :) "; + + ofstream fexit(argv[3]); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + } + return(0); +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/MainSeq.o b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/MainSeq.o new file mode 100644 index 0000000000000000000000000000000000000000..155133b817cf52480267b552dd709539a640c87c Binary files /dev/null and b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/MainSeq.o differ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/Makefile b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..71b1892f1c23a348b3791c8361321077fe48e29c --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/Makefile @@ -0,0 +1,24 @@ +include ../../environment + +all: MainLan MainSeq + +clean: + rm -f MainLan MainSeq MainWan *.o *% *~ + +MainLan: newGA.req.o newGA.pro.o MainLan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainWan: newGA.req.o newGA.pro.o MainWan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainSeq: newGA.req.o newGA.pro.o MainSeq.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +LAN: + $(RUN) -np 10 ./MainLan Config.cfg + +WAN: + $(RUN) -v -p4pg pgfileWan MainWan + +SEQ: + ./MainSeq newGA.cfg ../../ProblemInstances/ONEMAX-instances/onemax10.txt res/sol.txt \ No newline at end of file diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/asignacion_colores.csv b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/asignacion_colores.csv new file mode 100644 index 0000000000000000000000000000000000000000..83840363d469cec56434d0f6c25e841eb42688df --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/asignacion_colores.csv @@ -0,0 +1,10 @@ +1,5 +2,5 +3,5 +4,5 +5,5 +6,5 +7,5 +8,0 +9,4 +10,4 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/datos_cantidad_empleados b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/datos_cantidad_empleados new file mode 100644 index 0000000000000000000000000000000000000000..7813681f5b41c028345ca62a2be376bae70b7f61 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/datos_cantidad_empleados @@ -0,0 +1 @@ +5 \ No newline at end of file diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/datos_cantidad_tareas b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/datos_cantidad_tareas new file mode 100644 index 0000000000000000000000000000000000000000..301160a93062df23030a69f4b5e4d9bf71866ee9 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/datos_cantidad_tareas @@ -0,0 +1 @@ +8 \ No newline at end of file diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/datos_empleados b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/datos_empleados new file mode 100644 index 0000000000000000000000000000000000000000..f7cc5e5ffd3d2a61ae5180d3f7da918b35f73197 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/datos_empleados @@ -0,0 +1,4 @@ +e1 e2 e3 e4 e5 +4 5 5 3 3 +0.05 0.20 0.30 0.95 0.50 +120 200 210 230 180 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/datos_tareas b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/datos_tareas new file mode 100644 index 0000000000000000000000000000000000000000..589272f5c15492f95741ff1b7c8bd9669e9d4993 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/datos_tareas @@ -0,0 +1,3 @@ +20 +t1 t2 t3 t4 t5 t6 t7 t8 +16 28 11 51 2 23 43 15 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/ejercicio2.py b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/ejercicio2.py new file mode 100644 index 0000000000000000000000000000000000000000..6705a027263a0079907ffb4f8b9905db20c4001a --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/ejercicio2.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import sys +import random +import math +import os + +try: + #Sanity check + if (len(sys.argv)<4): + print "Ejecutar con la siguiente linea: ./ejercicio2 <ruta_tareas> <ruta_empleados> <ruta_solucion>" + sys.exit(1) + + ruta_tareas=sys.argv[1] + ruta_empleados=sys.argv[2] + ruta_solucion=sys.argv[3] + + os.system("make clean") + os.system("make all") + os.system("make SEQ") + + #os.system("python verificador.py " + ruta_tareas + " " + ruta_empleados + " " + ruta_solucion) + + """ + habilidad_empleados=[] + sueldo_diario_empleado=[] + dedicacion_diaria_diponible_empleado=[] + esfuerzo_requerido_tarea=[] + nombres_tareas=[] + nombre_empleados=[] + costo_proyecto=0 + tiempo_solucion_proyecto=0 + + # se sabe que son 3 lineas + archivo_tareas=open(ruta_tareas) + lineasTareas=archivo_tareas.readlines() + deadLine=lineasTareas[0] + nombres_tareas=lineasTareas[1].strip().split(" ") + esfuerzo_requerido_tarea=lineasTareas[2].strip().split(" ") + + # se sabe que son 4 lineas + archivo_empleados=open(ruta_empleados) + lineasEmpleados=archivo_empleados.readlines() + nombre_empleados=lineasEmpleados[0].strip().split(" ") + dedicacion_diaria_diponible_empleado=lineasEmpleados[1].strip().split(" ") + habilidad_empleados=lineasEmpleados[2].strip().split(" ") + sueldo_diario_empleado=lineasEmpleados[3].strip().split(" ") + + # se convierten a entero + dedicacion_diaria_diponible_empleado = map(int, dedicacion_diaria_diponible_empleado) + sueldo_diario_empleado = map(int, sueldo_diario_empleado) + deadLine=int(deadLine) + esfuerzo_requerido_tarea = map(int, esfuerzo_requerido_tarea) + + # se convierte a float + habilidad_empleados = map(float, habilidad_empleados) + + # se levanta la solucion del archivo + matriz_solucion=[] + + archivo_solucion=open(ruta_solucion) + + solucion_empleados_tareas=[] + solucion_empleados=[] + solucion_tareas=[] + + for line in archivo_solucion.readlines(): + empleados_tareas=line.strip().split(" ") + if( not (empleados_tareas[0] in nombre_empleados)): + print "No existe en la instancia el empleado: " + empleados_tareas[0] + sys.exit(1) + solucion_empleados.append(empleados_tareas[0]) + for i in range(1,len(empleados_tareas)): + if( not (empleados_tareas[i] in nombres_tareas)): + print "No existe en la instancia la terea: " + empleados_tareas[i] + sys.exit(1) + solucion_tareas.append(empleados_tareas[i]) + + + for i in range(0,len(solucion_empleados)): + for j in range(i+1,len(solucion_empleados)): + if(solucion_empleados[i]==solucion_empleados[j]): + print "Empleado repetido: " + solucion_empleados[i] + sys.exit(1) + + for i in range(0,len(solucion_tareas)): + for j in range(i+1,len(solucion_tareas)): + if(solucion_tareas[i]==solucion_tareas[j]): + print "Tarea asignada más de una vez: " + solucion_tareas[i] + sys.exit(1) + + + # todas las tareas asignadas + if(len(solucion_tareas)!=len(nombres_tareas)): + print "La cantidad de tareas asignadas es distinta a la cantidad de tareas de la instancia." + sys.exit(1) + + for i in range(0,len(nombres_tareas)): + if( not (nombres_tareas[i] in solucion_tareas)): + print "Tarea no asignada " + nombres_tareas[i] + sys.exit(1) + + costo_total=0 + archivo_solucion=open(ruta_solucion) + maximo_tiempo=0 + tiempo_en_dias=0 + # se hacen los calculos con la informacion en los archivos + for line in archivo_solucion.readlines(): + empleados_tareas=line.strip().split(" ") + indice_empleado = nombre_empleados.index(empleados_tareas[0]) + tiempo_en_horas=0 + for i in range(1,len(empleados_tareas)): + indice_tarea = nombres_tareas.index(empleados_tareas[i]) + tiempo_en_horas=tiempo_en_horas+(esfuerzo_requerido_tarea[indice_tarea] / (0.5 + habilidad_empleados[indice_empleado])) + tiempo_en_dias= int(math.ceil(tiempo_en_horas/dedicacion_diaria_diponible_empleado[indice_empleado])) + costo_total=costo_total+sueldo_diario_empleado[indice_empleado]*tiempo_en_dias + if(tiempo_en_dias>maximo_tiempo): + maximo_tiempo=tiempo_en_dias + + if(maximo_tiempo<=deadLine): + # todo OK! + print costo_total,maximo_tiempo + else: + print "No cumple con el tiempo máximo de finalización ({0} > {1}).".format(maximo_tiempo, deadLine) + sys.exit(1) + + """ + +except IOError as error: + print error diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/generador.py b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/generador.py new file mode 100644 index 0000000000000000000000000000000000000000..c699bd6a516ed41a7dbdc0e2b81d2065bda67dfe --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/generador.py @@ -0,0 +1,143 @@ +import sys +import random +import math +from collections import defaultdict + +try: + #Constantes + mayor_duracion_horas_tarea=200 + menor_duracion_horas_tarea=12 + mayor_disponibilidad_diaria_horas_empleado=10 + menor_disponibilidad_diaria_horas_empleado=1 + sueldo_hora_base_empleado_sin_experiencia=110 + sueldo_valor_maximo_bono_por_buen_empleado_hora=23 + deadline_dias=0 + + #Sanity check + if (len(sys.argv)<4): + print "Ejecutar con la siguiente linea: ./generador <cant_tereas> <cant_empleados> <archivo_salida>" + sys.exit(1) + + cantidad_tareas=int(sys.argv[1]) + cantidad_empleados=int(sys.argv[2]) + archivo_salida=sys.argv[3] + + if (cantidad_tareas<1): + print "La cantidad de tareas debe ser mayor o igual a 1." + sys.exit(1) + + + if (cantidad_empleados<1): + print "La cantidad de empleados debe ser mayor o igual a 1." + sys.exit(1) + + if (cantidad_empleados>cantidad_tareas): + print "La cantidad de empleados debe ser menor a la cantidad de tareas." + sys.exit(1) + + + #VARIABLES: + + #habilidades de los empleados valor entre 0 y 1 + habilidad_empleados=[] + sueldo_semanal_empleado=[] + dedicacion_diaria_diponible_empleado=[] + esfuerzo_requerido_tarea=[] + + for i in range(0,cantidad_empleados): + dedicacion_diaria_diponible_empleado.append(random.randint(menor_disponibilidad_diaria_horas_empleado,mayor_disponibilidad_diaria_horas_empleado)) + + for i in range(0,cantidad_empleados): + habilidad_empleados.append(round(random.uniform(0, 1),2)) + + #los empleados cobran un bono (random) de rendimiento + #empleados con habilidad 0 cobran el sueldo de horas base por la cantidad de horas semanales + #empleados con habilidad mayor a 0 cobran un plus por habilidad proporcional a su habilidad + #empleado con habilidad 1 cobra aproximadamente el doble que el de experiencia 0 + for i in range(0,cantidad_empleados): + bono_por_buen_empleado=random.randint(0,sueldo_valor_maximo_bono_por_buen_empleado_hora) + sueldo_base=sueldo_hora_base_empleado_sin_experiencia+bono_por_buen_empleado + plus_por_experiencia=sueldo_hora_base_empleado_sin_experiencia*habilidad_empleados[i] + sueldo_semanal_empleado.append(int(math.ceil((sueldo_base+plus_por_experiencia)*dedicacion_diaria_diponible_empleado[i]))) + + for i in range(0,cantidad_tareas): + esfuerzo_requerido_tarea.append(random.randint(menor_duracion_horas_tarea,mayor_duracion_horas_tarea)) + + ###################### + #calculo del deadline + ###################### + + + tiempo_ocupado_empleado = {} + for indice_empleado in range(0,cantidad_empleados): + tiempo_ocupado_empleado[indice_empleado]=0 + + tiempo_en_horas=0 + tiempo_en_dias_con_decimales=0 + indice_empleado_menor_tiempo=0 + for indice_tarea in range(0,cantidad_tareas): + minimo_tiempo=sys.float_info.max + for indice_empleado in range(0,cantidad_empleados): + tiempo_en_horas=(esfuerzo_requerido_tarea[indice_tarea] / (0.5 + habilidad_empleados[indice_empleado])) + tiempo_en_dias_con_decimales= tiempo_en_horas/dedicacion_diaria_diponible_empleado[indice_empleado] + tiempo_en_el_que_termina_si_se_le_da_esta_tarea=tiempo_ocupado_empleado[indice_empleado]+tiempo_en_dias_con_decimales + if(tiempo_en_el_que_termina_si_se_le_da_esta_tarea < minimo_tiempo): + indice_empleado_menor_tiempo=indice_empleado + minimo_tiempo=tiempo_en_el_que_termina_si_se_le_da_esta_tarea + tiempo_ocupado_empleado[indice_empleado_menor_tiempo]=minimo_tiempo + + + deadline_dias=0 + #busca maxima duracion + for indice_empleado in range(0,cantidad_empleados): + if(tiempo_ocupado_empleado[indice_empleado]>deadline_dias): + deadline_dias=tiempo_ocupado_empleado[indice_empleado] + + #print tiempo_ocupado_empleado + #se redondean los dias para pagar el dia entero a los que trabajan menos + deadline_dias=int(math.ceil(deadline_dias))*1.2 + + #archivo de salida de empleados + archivo = open ("%s_empleados"%archivo_salida, "w") + archivo.write("e%d"%1) + for i in range(1,cantidad_empleados): + #nombre del empleado + archivo.write(" e%d"%(i+1)) + archivo.write("\n") + archivo.write("%d"%dedicacion_diaria_diponible_empleado[0]) + for i in range(1,cantidad_empleados): + archivo.write(" %d"%dedicacion_diaria_diponible_empleado[i]) + archivo.write("\n") + archivo.write("%.2f"%habilidad_empleados[0]) + for i in range(1,cantidad_empleados): + archivo.write(" %.2f"%habilidad_empleados[i]) + archivo.write("\n") + archivo.write("%d"%sueldo_semanal_empleado[0]) + for i in range(1,cantidad_empleados): + archivo.write(" %d"%sueldo_semanal_empleado[i]) + + #archivo de salida de tareas + archivo = open ("%s_tareas"%archivo_salida, "w") + archivo.write("%d"%deadline_dias) + archivo.write("\n") + archivo.write("t%d"%1) + for i in range(1,cantidad_tareas): + #nombre de la tarea + archivo.write(" t%d"%(i+1)) + archivo.write("\n") + archivo.write("%d"%esfuerzo_requerido_tarea[0]) + for i in range(1,cantidad_tareas): + archivo.write(" %d"%esfuerzo_requerido_tarea[i]) + + + #archivo cantidad de tareas + archivo = open ("%s_cantidad_tareas"%archivo_salida, "w") + archivo.write("%d"%cantidad_tareas) + + #archivo cantidad de trabajos + archivo = open ("%s_cantidad_empleados"%archivo_salida, "w") + archivo.write("%d"%cantidad_empleados) + + +except IOError as error: + print error diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.cfg b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.cfg new file mode 100644 index 0000000000000000000000000000000000000000..c7caf7a288f728c5dade1cf41a5313771d977886 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.cfg @@ -0,0 +1,18 @@ +10 // number of independent runs +100 // number of generations +60 // number of individuals +100 // size of offsprings in each generation +1 // if replaces parents for offsprings, or only offsprings may be new parents +1 // display state ? +Selections // selections to apply +1 3 // selection of parents +2 0 // selection of offsprings +Intra-Operators // operators to apply in the population +0 0.6 // crossover & its probability +1 1.0 0.01 // mutation & its probability +Inter-Operators // operators to apply between this population and anothers +0 10 5 1 3 1 5 // operator number, operator rate, number of individuals, selection of indidivual to send and remplace +LAN-configuration +1 // refresh global state +0 // 0: running in asynchronized mode / 1: running in synchronized mode +1 // interval of generations to check solutions from other populations diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.hh b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.hh new file mode 100644 index 0000000000000000000000000000000000000000..552b2648923ec9383125099fb7ad87e4f924c4a9 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.hh @@ -0,0 +1,868 @@ +/********************************************************************************************************* +*** *** +*** new Genetic Algorithm Skeleton v1.5 *** +*** Developed by: Gabriel Jesús Luque Polo *** +*** Last Update: 27-01-2003 *** +*** *** +*** tabular size = 4 *** +**********************************************************************************************************/ + +#ifndef INC_newGA +#define INC_newGA +#include "newGAstructures.hh" + +skeleton newGA +{ +// Si se definen más de 5 nuevos operadores por parte del usuario, se debe cambiar esta constante. +#define MAX_OP_USER 5 +// Si se algún operador tiene más de 5 parámetros se debe modificar esta variable +#define MAX_PROB_PER_OP 5 + + provides class SetUpParams; + provides class Statistics; + provides class Population; + provides class Inter_Operator; + provides class Migration; + provides class Selection; + provides class Selection_Tournament; + provides class Selection_Roulette_Wheel; + provides class Selection_Rank; + provides class Selection_Best; + provides class Selection_Worst; + provides class Operator_Pool; + provides class Solver; + provides class Solver_Seq; + provides class Solver_Lan; + provides class Solver_Wan; + provides class StopCondition; + + requires class Problem; + requires class Solution; + requires class UserStatistics; + requires class Intra_Operator; + requires class Crossover; + requires class Mutation; + requires class StopCondition_1; + requires bool terminateQ (const Problem& pbm, const Solver& solver, const SetUpParams& setup); + +// Problem ---------------------------------------------------------------------------- + + requires class Problem + { + public: + Problem(); + ~Problem(); + + friend ostream& operator<< (ostream& os, const Problem& pbm); + friend istream& operator>> (istream& is, Problem& pbm); + + Problem& operator= (const Problem& pbm); + bool operator== (const Problem& pbm) const; + bool operator!= (const Problem& pbm) const; + + Direction direction () const; + + int cantDias() const; + int cantEmpleados() const; + int dimension() const; + + Empleado * empleados() const; + int * tareasEsf() const; + int * tareasIndex() const; + int ** limite_barrios() const; + const char* getfield(char* line, int num); + + private: + int _cantDias; + Empleado * _empleados; + int * _tareasEsf; + int * _tareasIndex; + int _cantEmpleados; + int _dimension; + int ** _limite_barrios; + }; + +//Solution ---------------------------------------------------------------------------- + + requires class Solution + { + public: + Solution (const Problem& pbm); + Solution (const Solution& sol); + ~Solution(); + + friend ostream& operator<< (ostream& os, const Solution& sol); + friend istream& operator>> (istream& is, Solution& sol); + friend NetStream& operator << (NetStream& ns, const Solution& sol); + friend NetStream& operator >> (NetStream& ns, Solution& sol); + + const Problem& pbm() const; + + Solution& operator= (const Solution& sol); + bool operator== (const Solution& sol) const; + bool operator!= (const Solution& sol) const; + + char *to_String() const; + void to_Solution(char *_cadena_); + + void initialize(); + double fitness (); + unsigned int size() const; + + int& var(const int index); + Rarray<int>& array_var(); + + private: + Rarray<int> _var; + const Problem& _pbm; + }; + +// UserStatistics ---------------------------------------------------------------------------- + + requires class UserStatistics + { + private: + struct user_stat + { + unsigned int trial; + unsigned long nb_evaluation_best_found_trial; + unsigned long nb_iteration_best_found_trial; + double best_cost_trial; + double worst_cost_trial; + float time_best_found_trial; + float time_spent_trial; + }; + + Rlist<struct user_stat> result_trials; + + public: + UserStatistics (); + ~UserStatistics(); + + friend ostream& operator<< (ostream& os, const UserStatistics& usertats); + + UserStatistics& operator= (const UserStatistics& userstats); + void update(const Solver& solver); + void clear(); + }; + +// Intra_Operator ( clase abstracta ) -------------------------------------------------------------- + + requires class Intra_Operator + { + protected: + unsigned int _number_operator; + float *probability; + + public: + Intra_Operator(const unsigned int _number_op); + virtual ~Intra_Operator(); + + static Intra_Operator *create(const unsigned int _number_op); + friend ostream& operator<< (ostream& os, const Intra_Operator& intra); + + virtual void execute(Rarray<Solution*>& sols) const=0; + virtual void setup(char line[MAX_BUFFER]) = 0; + unsigned int number_operator() const; + + virtual void RefreshState(const StateCenter& _sc) const=0; + virtual void UpdateFromState(const StateCenter& _sc)=0; + }; + +// Crossover ---------------------------------------------------------------------------------- + + requires class Crossover: public Intra_Operator + { + public: + Crossover(); + virtual ~Crossover(); + + friend ostream& operator << (ostream& os, const Crossover& cross); + + void cross(Solution &sol1,Solution &sol2) const; + virtual void execute(Rarray<Solution*>& sols) const; + virtual void setup(char line[MAX_BUFFER]); + + virtual void RefreshState(const StateCenter& _sc) const; + virtual void UpdateFromState(const StateCenter& _sc); + }; + +// Mutation ---------------------------------------------------------------------------------- + + requires class Mutation: public Intra_Operator + { + public: + Mutation(); + virtual ~Mutation(); + + friend ostream& operator<< (ostream& os, const Mutation& mutation); + + void mutate(Solution& sol) const; + // applies mutation over all solutions in array sols + virtual void execute(Rarray<Solution*>& sols) const; + virtual void setup(char line[MAX_BUFFER]); + + virtual void RefreshState(const StateCenter& _sc) const; + virtual void UpdateFromState(const StateCenter& _sc); + + }; + +// StopCondition ---------------------------------------------------------------------------------- + provides class StopCondition + { + public: + StopCondition(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup)=0; + ~StopCondition(); + }; + +// StopCondition_1 {subclase------------------------------------------------------------------------- + + requires class StopCondition_1 : public StopCondition + { + public: + StopCondition_1(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_1(); + }; +// SetUpParams ------------------------------------------------------------------------------- + + provides class SetUpParams + { + private: + unsigned int _independent_runs; + unsigned long _nb_evolution_steps; + unsigned int _population_size; // number of individuals + unsigned int _population_additional_size; // size of offspring in each generation + bool _combine; // combines parents and offsprings to select new parents ? + bool _display_state; + + unsigned long _refresh_global_state; + bool _synchronized; + unsigned int _check_asynchronous; + + // selection of parents and offsprings + mutable unsigned int _select_parents; + mutable unsigned int _select_offsprings; + mutable unsigned int _parameter_select_parents; + mutable unsigned int _parameter_select_offsprings; + + Rlist<unsigned int> _intra_operators; + Rlist<unsigned int> _inter_operators; + + Operator_Pool& _pool; + + public: + SetUpParams (Operator_Pool& pool); + Operator_Pool& pool() const; + + friend ostream& operator<< (ostream& os, const SetUpParams& setup); + friend istream& operator>> (istream& is, SetUpParams& setup); + + const unsigned int independent_runs() const; + const unsigned long nb_evolution_steps() const; + const unsigned int population_size() const; + const unsigned int population_additional_size() const; + const bool combine() const; + const bool display_state() const; + const unsigned long refresh_global_state() const; + const bool synchronized() const; + const unsigned int check_asynchronous() const; + + void independent_runs(const unsigned int val); + void nb_evolution_steps(const unsigned long val); + void population_size(const unsigned int val); + void population_additional_size(const unsigned int val); + void combine(const bool val); + void display_state(const bool val); + void refresh_global_state(const unsigned long val); + void synchronized(const bool val); + void check_asynchronous(const unsigned int val); + + // gets the i-th operator of inter-population + const unsigned int inter_operator_index(const unsigned int index) const; + const unsigned int inter_operators_size() const; + + // gets the i-th operator of intra-population + const unsigned int intra_operator_index(const unsigned int index) const; + const unsigned int intra_operators_size() const; + + const unsigned int select_parents() const; + const unsigned int select_offsprings() const; + const unsigned int parameter_select_parents() const; + const unsigned int parameter_select_offsprings() const; + + void select_parents(const unsigned int val); + void select_offsprings(const unsigned int val); + void parameter_select_parents(const unsigned int val); + void parameter_select_offsprings(const unsigned int val); + + void RefreshState(const StateCenter& _sc) const; + void UpdateFromState(const StateCenter& _sc) const; + + ~SetUpParams(); + }; + +// Statistics --------------------------------------------------------------------------------- + + provides class Statistics + { + private: + struct stat + { + unsigned int trial; + unsigned long nb_generation; + unsigned long nb_evaluation; + double best_cost; + double global_best_cost; + double average_cost; + double standard_deviation; + }; + + Rlist<struct stat> stats_data; + + public: + Statistics(); + ~Statistics(); + + friend ostream& operator<< (ostream& os, const Statistics& stats); + + Statistics& operator= (const Statistics& stats); + void update(const Solver& solver); + void clear(); + }; + +// Population --------------------------------------------------------------------------------- + + provides class Population + { + private: + Rarray<Solution*> _parents; // individuals in population + Rarray<Solution*> _offsprings; // offsprings of current population + Rarray<Solution*> _new_parents; // individuals of previous population + Rarray<struct individual> _fitness_values; + Rarray<struct individual> _fitness_aux; + const SetUpParams& _setup; + unsigned int _upper_cost,_lower_cost; // lower and upper fitness of individuals in population + unsigned long _evaluations; + double _average_cost; + + inline void Evaluate(Solution* sols,struct individual &_f); + + public: + Population(const Problem& pbm,const SetUpParams& setup); // crea un array de objetos population; + ~Population(); + + friend ostream& operator<< (ostream& os, const Population& population); + friend istream& operator>> (istream& is, Population& population); + Population& operator= (const Population& pop); + const SetUpParams& setup() const; + void initialize(); + + // Generate a new pool of individuals in population + void evolution(); + + // interchange solutions between island + void interchange(const unsigned long current_generation, NetStream& channel); + + // creates a array with fitness of all individuals in population and its position in the population + void evaluate_parents(); + + // creates a array with fitness of all individuals and offsprings in population and its position in the population + void evaluate_offsprings(); + + // selects parents to creates offsprings + void select_parents(); + + // selects individuals for the new population + void select_offsprings(); + + const Rarray<Solution*>& parents() const; + const Rarray<Solution*>& offsprings() const; + Rarray<struct individual>& fitness_values(); + + unsigned int upper_cost() const; + unsigned int lower_cost() const; + unsigned int evaluations() const; + Solution& solution(const unsigned int index) const; + double fitness(const unsigned int index) const; + + double best_cost() const; + double worst_cost() const; + Solution& best_solution() const; + Solution& worst_solution() const; + double average_cost() const; + double standard_deviation() const; + }; + +// Inter_Operator ( abstract )----------------------------------------------------------- + + provides class Inter_Operator + { + protected: + unsigned int migration_rate; + unsigned int migration_size; + unsigned int migration_selection_1; + unsigned int migration_selection_2; + unsigned int migration_selection_conf_1; + unsigned int migration_selection_conf_2; + + unsigned int _number_operator; + const Direction direction; + + public: + Inter_Operator(const unsigned int _number_op, const Direction dir); + virtual ~Inter_Operator(); + + friend ostream& operator<< (ostream& os, const Inter_Operator& inter); + + virtual void execute(Population& pop,const unsigned long current_generation,NetStream& _netstream,const bool synchronized,const unsigned int check_asyncrhonous) const=0; + virtual void setup(char line[MAX_BUFFER]); + unsigned int number_operator() const; + + virtual void RefreshState(const StateCenter& _sc) const; + virtual void UpdateFromState(const StateCenter& _sc); + }; + +// Migration: public Inter_Operator ----------------------------------------------------------- + + provides class Migration: public Inter_Operator + { + public: + Migration(const Direction dir); + virtual ~Migration(); + + friend ostream& operator<< (ostream& os, const Migration& migration); + + virtual void execute(Population& pop,const unsigned long current_generation,NetStream& _netstream,const bool synchronized,const unsigned int check_asyncrhonous) const; + }; + +// Selection ( Makes a random selection ) ----------------------------------------- + + provides class Selection + { + protected: + unsigned int _number_selection; + const Direction direction; + + public: + + Selection(const Direction dir); + Selection(const unsigned int _number_sel, const Direction dir); + virtual ~Selection(); + + friend ostream& operator<< (ostream& os, const Selection& sel); + + virtual void prepare(Rarray<struct individual>& fitness_values,const bool remplace); // const; + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int dummy,const bool remplace) const; + unsigned int number_selection() const; + }; + +// Selection_Tournament --------------------------------------------------------------------------------- + + provides class Selection_Tournament: public Selection + { + public: + Selection_Tournament(const Direction dir); + virtual ~Selection_Tournament(); + + friend ostream& operator<< (ostream& os, const Selection_Tournament& sel); + + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int tourment_size,const bool remplace) const; + }; + +// Selection_Roulette_Wheel --------------------------------------------------------------------------------- + + provides class Selection_Roulette_Wheel: public Selection + { + public: + Selection_Roulette_Wheel(const Direction); + virtual ~Selection_Roulette_Wheel(); + + friend ostream& operator<< (ostream& os, const Selection_Roulette_Wheel& sel); + + virtual void prepare(Rarray<struct individual>& fitness_values,const bool remplace); // const; + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int dummy,const bool remplace) const; + }; + +// Selection_Rank --------------------------------------------------------------------------------- + + provides class Selection_Rank: public Selection + { + public: + Selection_Rank(const Direction dir); + Selection_Rank(const unsigned int _number_sel, const Direction dir); + virtual ~Selection_Rank(); + + friend ostream& operator<< (ostream& os, const Selection_Rank& sel); + + virtual void prepare(Rarray<struct individual>& fitness_values,const bool remplace); // const; + virtual void reset(); + + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int portion,const bool remplace) const; + }; + +// Selection_Best --------------------------------------------------------------------------------- + + provides class Selection_Best: public Selection_Rank + { + private: + mutable unsigned int selection_best_position; + + public: + Selection_Best(const Direction); + virtual ~Selection_Best(); + + friend ostream& operator<< (ostream& os, const Selection_Best& sel); + + virtual void reset(); + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int position,const bool remplace) const; + }; + +// Selection_Worst --------------------------------------------------------------------------------- + + provides class Selection_Worst: public Selection_Rank + { + private: + mutable unsigned int selection_worst_position; + + public: + Selection_Worst(const Direction); + virtual ~Selection_Worst(); + + friend ostream& operator<< (ostream& os, const Selection_Worst& sel); + + virtual void reset(); + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int position,const bool remplace) const; + }; + +// Operator_Pool ------------------------------------------------------------------------- + + // pool with all operators and selections that can be chosen in the setup file + provides class Operator_Pool + { + private: + mutable Rlist<Intra_Operator> _intra_operators; + Rlist<Selection> _selectors; + Rlist<Inter_Operator> _inter_operators; + + public: + Operator_Pool(const Problem& pbm); + ~Operator_Pool(); + + Intra_Operator& intra_operator(const unsigned int index) const; + Rlist<Intra_Operator>& intra_operators() const; + Selection& selector(const unsigned int index) const; + const Rlist<Selection>& selectors() const; + Inter_Operator& inter_operator(const unsigned int index) const; + const Rlist<Inter_Operator>& inter_operators() const; + + }; + +// Solver --------------------------------------------------------------------------------- + + provides class Solver + { + protected: + const Problem& problem; + const SetUpParams& params; + UserStatistics _userstat; + Statistics _stat; + Population current_population; + StateCenter _sc; + + double best_cost; + double worst_cost; + Solution best_solution; + double average_cost; + double standard_deviation; + float total_time_spent; + float time_spent_in_trial; + float start_trial; + float start_global; + + bool _end_trial; + + State_Vble _current_trial; + State_Vble _current_iteration; + State_Vble _current_evaluations; + + State_Vble _current_best_solution; + State_Vble _current_best_cost; + State_Vble _current_worst_cost; + State_Vble _current_average_cost; + State_Vble _current_standard_deviation; + State_Vble _current_time_spent; + + State_Vble _best_solution_trial; + State_Vble _best_cost_trial; + State_Vble _worst_cost_trial; + State_Vble _iteration_best_found_in_trial; + State_Vble _evaluations_best_found_in_trial; + State_Vble _time_best_found_trial; + State_Vble _time_spent_trial; + + State_Vble _trial_best_found; + State_Vble _iteration_best_found; + State_Vble _evaluations_best_found; + State_Vble _global_best_solution; + State_Vble _global_best_cost; + State_Vble _global_worst_cost; + State_Vble _time_best_found; + + State_Vble _crossover_probability; // probability of applying the operator over population + State_Vble _mutation_probability; // probability of applying the operator over population + State_Vble _user_op_probability[MAX_OP_USER]; // probabilities of user operators + State_Vble _migration_rate; + State_Vble _migration_size; + State_Vble _migration_selection_1; + State_Vble _migration_selection_2; + State_Vble _migration_selection_conf_1; + State_Vble _migration_selection_conf_2; + State_Vble _select_parents; + State_Vble _select_offsprings; + State_Vble _parameter_select_parents; + State_Vble _parameter_select_offsprings; + + State_Vble _display_state; + + + public: + Solver (const Problem& pbm, const SetUpParams& setup); + virtual ~Solver (); + + virtual int pid() const; + bool end_trial() const; + void end_trial(bool et); + + // Execution methods ----------------------------------------------------------------------- + + // Full execution + virtual void run () =0; + virtual void run (const unsigned long int nb_generations) =0; + virtual void run (const Population& pop,const unsigned long int nb_generations) =0; + + //Partial execution + virtual void StartUp()=0; + virtual void StartUp(const Population& pop)=0; + + virtual void DoStep()=0; + + // Statistics handling ---------------------------------------------------------------------- + + Statistics& statistics(); + UserStatistics& userstatistics (); + Population& population(); + const SetUpParams& setup() const; + const Problem& pbm() const; + + // State handling --------------------------------------------------------------------------- + + void RefreshState(); + void RefreshCfgState(); + void UpdateFromState(); + void UpdateFromCfgState(); + StateCenter* GetState(); + + unsigned int current_trial() const; + unsigned long current_iteration() const; + unsigned long current_evaluations() const; + Solution current_best_solution() const; + double current_best_cost() const; + double current_worst_cost() const; + double current_average_cost() const; + double current_standard_deviation() const; + float current_time_spent() const; + Solution best_solution_trial() const; + double best_cost_trial() const; + double worst_cost_trial() const; + unsigned int iteration_best_found_in_trial() const; + unsigned int evaluations_best_found_in_trial() const; + float time_best_found_trial() const; + float time_spent_trial() const; + unsigned int trial_best_found() const; + unsigned int iteration_best_found() const; + unsigned int evaluations_best_found() const; + Solution global_best_solution() const; + double global_best_cost() const; + double global_worst_cost() const; + float time_best_found() const; + int display_state() const; + + float *crossover_probability() const; + float *mutation_probability() const; + float *user_op_probability(const int index) const; + unsigned int migration_rate() const; + unsigned int migration_size() const; + unsigned int migration_selection_1() const; + unsigned int migration_selection_2() const; + unsigned int migration_selection_conf_1() const; + unsigned int migration_selection_conf_2() const; + unsigned int select_parents() const; + unsigned int select_offprings() const; + unsigned int parameter_select_parents() const; + unsigned int parameter_select_offsprings() const; + + void current_trial(const unsigned int value); + void current_iteration(const unsigned long value); + void current_evaluations(const unsigned long value); + void current_best_solution(const Solution& sol); + void current_best_cost(const double value); + void current_worst_cost(const double value); + void current_average_cost(const double value); + void current_standard_deviation(const double value); + void current_time_spent(const float value); + void best_solution_trial(const Solution& sol); + void best_cost_trial(const double value); + void worst_cost_trial(const double value); + void iteration_best_found_in_trial(const unsigned int value); + void evaluations_best_found_in_trial(const unsigned int value); + void time_best_found_trial(const float value); + void time_spent_trial(const float value); + void trial_best_found(const unsigned int value); + void iteration_best_found(const unsigned int value); + void evaluations_best_found(const unsigned int value); + void global_best_solution(const Solution& sol); + void global_best_cost(const double value); + void global_worst_cost(const double value); + void time_best_found(const float value); + void display_state(const int value); + + void crossover_probability(const float *probability); + void mutation_probability(const float *probability); + void user_op_probability(const int index,const float *probability); + void migration_rate(const unsigned int rate); + void migration_size(const unsigned int size); + void migration_selection_1(const unsigned int seleciton_1); + void migration_selection_2(const unsigned int selection_2); + void migration_selection_conf_1(const unsigned int selection_conf_1); + void migration_selection_conf_2(const unsigned int selection_conf_2); + void select_parents(const unsigned int selection); + void select_offsprings(const unsigned int selection); + void parameter_select_parents(const unsigned int value); + void parameter_select_offsprings(const unsigned int value); + + void show_state() const; + void KeepHistory(const Solution& best_sol,const double best_cost,const double worst_cost,const float time_spent_trial,const float total_time_spent); + }; + + provides class Solver_Seq: public Solver + { + public: + Solver_Seq ( const Problem& pbm, const SetUpParams& setup); + virtual ~Solver_Seq (); + + // Execution methods ----------------------------------------------------------------------- + + // Full execution + virtual void run (); + virtual void run (const unsigned long int nb_generations); + virtual void run (const Population& pop,const unsigned long int nb_generations); + + //Partial execution + virtual void StartUp(); + virtual void StartUp(const Population& pop); + + virtual void DoStep(); + }; + + provides class Solver_Lan: public Solver + { + private: + NetStream _netstream; + int mypid; + + int receive_local_state(); + + unsigned int _current_trial; + unsigned long _current_iteration; + unsigned long _current_evaluations; + double _best_cost_trial; + Solution _best_solution_trial; + double _worst_cost_trial; + float _time_best_found_in_trial; + unsigned long _iteration_best_found_in_trial; + unsigned long _evaluations_best_found_in_trial; + + // Termination phase // + bool final_phase; + unsigned long acum_iterations; + unsigned long acum_evaluations; + + + public: + Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Lan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods ----------------------------------------------------------------------- + + // Full execution + virtual void run (); + virtual void run (const unsigned long int nb_generations); + virtual void run (const Population& pop,const unsigned long int nb_generations); + + //Partial execution + virtual void StartUp(); + virtual void StartUp(const Population& pop); + + virtual void DoStep(); + + //Communication + void send_local_state_to(int _mypid); + void check_for_refresh_global_state(); + void reset(); + }; + + provides class Solver_Wan: public Solver + { + private: + NetStream _netstream; + int mypid; + + int receive_local_state(); + + unsigned int _current_trial; + unsigned long _current_iteration; + unsigned long _current_evaluations; + double _best_cost_trial; + Solution _best_solution_trial; + double _worst_cost_trial; + float _time_best_found_in_trial; + unsigned long _iteration_best_found_in_trial; + unsigned long _evaluations_best_found_in_trial; + + // Termination phase // + bool final_phase; + unsigned long acum_iterations; + unsigned long acum_evaluations; + + public: + Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Wan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods ----------------------------------------------------------------------- + + // Full execution + virtual void run (); + virtual void run (const unsigned long int nb_generations); + virtual void run (const Population& pop,const unsigned long int nb_generations); + + //Partial execution + virtual void StartUp(); + virtual void StartUp(const Population& pop); + + virtual void DoStep(); + + //Communication + void send_local_state_to(int _mypid); + void check_for_refresh_global_state(); + void reset(); + }; + +} + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.pro.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.pro.cc new file mode 100644 index 0000000000000000000000000000000000000000..dfdd244b4322ca4b6ef4b9066b857263a7a4c784 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.pro.cc @@ -0,0 +1,2831 @@ +#include "newGA.hh" + +skeleton newGA +{ + +// StopCondition ------------------------------------------------------------------------------------- + + StopCondition::StopCondition() + {} + + StopCondition::~StopCondition() + {} + +// SetUpParams ----------------------------------------------------------- + + SetUpParams::SetUpParams (Operator_Pool& pool) + : _independent_runs(0), + _nb_evolution_steps(0), + _population_size(0), + _population_additional_size(0), + _select_parents(0), + _select_offsprings(0), + _parameter_select_parents(0), + _parameter_select_offsprings(0), // Parameter of selection is fixed to 0 + _inter_operators(), + _intra_operators(), + _combine(1), + _refresh_global_state(1), + _synchronized(0), + _check_asynchronous(1), + _display_state(0), + _pool(pool) + {} + + Operator_Pool& SetUpParams::pool() const + { + return _pool; + } + + istream& operator>> (istream& is, SetUpParams& setup) + { + char buffer[MAX_BUFFER]; // current line in the setup file + char command[50]; + long op; + int parameter; + short int nb_section=0; + short int nb_io = 0; + short int nb_selection = 0; + short int nb_param=0; + short int nb_LAN_param=0; + + while (is.getline(buffer,MAX_BUFFER,'\n')) + { + sscanf(buffer," %s ",command); + if (!(strcmp(command,"General"))) nb_section=0; + if (!(strcmp(command,"Selections"))) nb_section=1; + if (!(strcmp(command,"Intra-Operators"))) nb_section=2; + if (!(strcmp(command,"Inter-Operators"))) nb_section=3; + if (!(strcmp(command,"LAN-configuration"))) nb_section=4; + + op=-1; + sscanf(buffer," %ld%*s ",&op); + if (op<0) continue; + switch (nb_section) + { + case 0: switch (nb_param) + { + case 0: setup.independent_runs(op); break; + case 1: setup.nb_evolution_steps(op); break; + case 2: setup.population_size(op); break; + case 3: setup.population_additional_size(op); break; + case 4: setup.combine(op); break; + case 5: setup.display_state(op); break; + } + nb_param++; + break; + case 1: op=-1; // creates the chosen selection method + parameter=0; + sscanf(buffer," %d %d",&op,¶meter); + if (nb_selection>=2) break; + assert(parameter>=0); + if (nb_selection==0) + { + setup.select_parents(op); + setup.parameter_select_parents(parameter); + } + else + { + setup.select_offsprings(op); + setup.parameter_select_offsprings(parameter); + } + nb_selection++; + break; + case 2: setup.pool().intra_operators().append(Intra_Operator::create(op)); + setup.pool().intra_operator(nb_io).setup(buffer); + setup._intra_operators.append(new unsigned int(nb_io)); + nb_io++; + break; + case 3: setup._inter_operators.append(new unsigned int(op)); + setup.pool().inter_operator(op).setup(buffer); + break; + case 4: if (nb_LAN_param>=3) break; + switch (nb_LAN_param) + { + case 0: setup.refresh_global_state(op); break; + case 1: setup.synchronized(op); break; + case 2: assert(op>0); + setup.check_asynchronous(op); break; + } + nb_LAN_param++; + break; + } + } + + return is; + } + + ostream& operator<< (ostream& os, const SetUpParams& setup) + { + os << "CONFIGURATION -------------------------------------------" << endl << endl; + os << "\t" << "Independent runs : " << setup.independent_runs() << endl + << "\t" << "Evolution steps: " << setup.nb_evolution_steps() << endl + << "\t" << "Size of Population: " << setup.population_size() << endl + << "\t" << "Size of Additional population: " << setup.population_additional_size() << endl; + if (setup.combine()) + os << "\t" <<"With combination between parents and offsprings" << endl; + else + os << "\t" <<"Without combination between parents and offsprings" << endl; + + os << "\t" << "Display State: " << setup.display_state() << endl << endl + << "\t" << "Selections:" << endl + << "\t" << "-----------" << endl << endl + << "\t" << "Selection parents -> " << setup.pool().selector(setup.select_parents()) << endl + << "\t" << "Parameter of selection: " << setup.parameter_select_parents() << endl + << "\t" << "Selection offsprings -> " << setup.pool().selector(setup.select_offsprings()) << endl + << "\t" << "Parameter of selection: " << setup.parameter_select_offsprings() << endl << endl + << "\t" << "Intra_Operators: " << endl + << "\t" << "-----------" << endl << endl; + + for (int i=0;i<setup.intra_operators_size();i++) + os << "\t" << (setup.pool().intra_operator(setup.intra_operator_index(i))) << endl; + + os << endl << "\t" << "Inter_Operators: " << endl + << "\t" << "-----------" << endl << endl; + + for (int i=0;i<setup.inter_operators_size();i++) + os << "\t" << "Operator: " << setup.pool().inter_operator(setup.inter_operator_index(i)) << endl; + + os << endl << "\t" << "LAN configuration:" << endl + << "\t" << "----------------------" << endl << endl + << "\t" << "Refresh global state in number of generations: " << setup.refresh_global_state() << endl; + + if (setup.synchronized()) + os << "\t" << "Running in synchronous mode" << endl; + else + os << "\t" << "Running in asynchronous mode" << endl; + os << "\t" << "Interval for checking asynchronous receptions: " << setup.check_asynchronous() << endl << endl; + + os << endl << endl << "END CONFIGURATION -------------------------------------------" << endl << endl; + return os; + } + + const unsigned int SetUpParams::independent_runs() const + { + return _independent_runs; + } + + const unsigned long SetUpParams::nb_evolution_steps() const + { + return _nb_evolution_steps; + } + + const unsigned int SetUpParams::population_size() const + { + return _population_size; + } + + const unsigned int SetUpParams::population_additional_size() const + { + return _population_additional_size; + } + + const bool SetUpParams::combine() const + { + return _combine; + } + + const unsigned long SetUpParams::refresh_global_state() const + { + return _refresh_global_state; + } + + const bool SetUpParams::synchronized() const + { + return _synchronized; + } + + const unsigned int SetUpParams::check_asynchronous() const + { + return _check_asynchronous; + } + + const bool SetUpParams::display_state() const + { + return _display_state; + } + + void SetUpParams::independent_runs(const unsigned int val) + { + _independent_runs=val; + } + + void SetUpParams::nb_evolution_steps(const unsigned long val) + { + _nb_evolution_steps=val; + } + + void SetUpParams::population_size(const unsigned int val) + { + _population_size=val; + } + + void SetUpParams::population_additional_size(const unsigned int val) + { + _population_additional_size=val; + } + + void SetUpParams::combine(const bool val) + { + _combine=val; + } + + void SetUpParams::display_state(const bool val) + { + _display_state=val; + } + + void SetUpParams::refresh_global_state(const unsigned long val) + { + _refresh_global_state=val; + } + + void SetUpParams::synchronized(const bool val) + { + _synchronized=val; + } + + void SetUpParams::check_asynchronous(const unsigned int val) + { + _check_asynchronous=val; + } + + const unsigned int SetUpParams::select_parents() const + { + return _select_parents; + } + + const unsigned int SetUpParams::select_offsprings() const + { + return _select_offsprings; + } + + const unsigned int SetUpParams::parameter_select_parents() const + { + return _parameter_select_parents; + } + + const unsigned int SetUpParams::parameter_select_offsprings() const + { + return _parameter_select_offsprings; + } + + void SetUpParams::select_parents(const unsigned int val) + { + _select_parents=val; + } + + void SetUpParams::select_offsprings(const unsigned int val) + { + _select_offsprings=val; + } + + void SetUpParams::parameter_select_parents(const unsigned int val) + { + _parameter_select_parents=val; + } + + void SetUpParams::parameter_select_offsprings(const unsigned int val) + { + _parameter_select_offsprings=val; + } + + const unsigned int SetUpParams::intra_operator_index(const unsigned int index) const + { + return _intra_operators[index]; + } + + const unsigned int SetUpParams::intra_operators_size() const + { + return _intra_operators.size(); + } + + const unsigned int SetUpParams::inter_operator_index(const unsigned int index) const + { + return _inter_operators[index]; + } + + const unsigned int SetUpParams::inter_operators_size() const + { + return _inter_operators.size(); + } + + void SetUpParams::RefreshState(const StateCenter& _sc) const + { + _sc.set_contents_state_variable("_select_parents",(char *)&_select_parents,1,sizeof(_select_parents)); + _sc.set_contents_state_variable("_parameter_select_parents",(char *)&_parameter_select_parents,1,sizeof(_parameter_select_parents)); + _sc.set_contents_state_variable("_select_offsprings",(char *)&_select_offsprings,1,sizeof(_select_offsprings)); + _sc.set_contents_state_variable("_parameter_select_offsprings",(char *)&_parameter_select_offsprings,1,sizeof(_parameter_select_offsprings)); + _sc.set_contents_state_variable("_display_state",(char *)&_display_state,1,sizeof(bool)); + } + + void SetUpParams::UpdateFromState(const StateCenter& _sc) const + { + unsigned long nbytes,length; + _sc.get_contents_state_variable("_select_parents",(char *)&_select_parents,nbytes,length); + _sc.get_contents_state_variable("_parameter_select_parents",(char *)&_parameter_select_parents,nbytes,length); + _sc.get_contents_state_variable("_select_offsprings",(char *)&_select_offsprings,nbytes,length); + _sc.get_contents_state_variable("_parameter_select_offsprings",(char *)&_parameter_select_offsprings,nbytes,length); + _sc.get_contents_state_variable("_display_state",(char *)&_display_state,nbytes,length); + } + + SetUpParams::~SetUpParams() + {} + +// Statistics ------------------------------------------------------ + + Statistics::Statistics() + {} + + ostream& operator<< (ostream& os, const Statistics& stats) + { + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF CURRENT TRIAL " << endl; + os << "------------------------------------------------------------------" << endl; + for (int i=0;i< stats.stats_data.size();i++) + { + os << endl + << " Trial: " << stats.stats_data[i].trial + << " Generation: " << stats.stats_data[i].nb_generation + << " Evaluation: " << stats.stats_data[i].nb_evaluation + << " Current best cost: " << stats.stats_data[i].best_cost + << " Global best cost: " << stats.stats_data[i].global_best_cost + << " Avg: " << stats.stats_data[i].average_cost + << " Std. Dev.: " << stats.stats_data[i].standard_deviation; + } + + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + Statistics& Statistics::operator= (const Statistics& stats) + { + stats_data = stats.stats_data; + return *this; + } + + void Statistics::update(const Solver& solver) + { + struct stat *new_stat=(struct stat *)malloc(sizeof(struct stat)); + + new_stat->trial=solver.current_trial(); + new_stat->nb_generation=solver.current_iteration(); + new_stat->nb_evaluation=solver.current_evaluations(); + new_stat->average_cost=solver.current_average_cost(); + new_stat->standard_deviation=solver.current_standard_deviation(); + new_stat->best_cost=solver.current_best_cost(); + new_stat->global_best_cost=solver.global_best_cost(); + + stats_data.append(*new_stat); + } + + void Statistics::clear() + { + stats_data.remove(); + } + + Statistics::~Statistics() + {} + +// Population ------------------------------------------------------ + + Population::Population(const Problem& pbm,const SetUpParams& setup) + :_parents(setup.population_size()), + _fitness_values(setup.population_size()), + _new_parents(setup.population_size()), + _offsprings(setup.population_additional_size()), + _setup(setup), + _evaluations(0) + { + for (int i=0;i<_parents.size();i++) + { + _parents[i]=new Solution(pbm); + _new_parents[i]=new Solution(pbm); + _fitness_values[i].index = i; + _fitness_values[i].change = true; + } + for (int i=0;i<_offsprings.size();i++) + _offsprings[i]=new Solution(pbm); + + } + + void Population::Evaluate(Solution* sols,struct individual &_f) + { + if(_f.change) + { + _f.change = false; + _f.fitness = sols->fitness(); + _evaluations++; + } + } + + Population& Population::operator= (const Population& pop) + { + for (int i=0;i<_parents.size();i++) + { + *_parents[i]=*((pop.parents())[i]); + _fitness_values[i] = pop._fitness_values[i]; + _evaluations = pop._evaluations; + } + return (*this); + } + + istream& operator>> (istream& is, Population& population) + { + return is; + } + + ostream& operator<< (ostream& os, const Population& population) + { + os << "---------------------------------------------------------------" << endl; + os << " PRESENT POPULATION " << endl << endl; + for (int i=0;i<population._parents.size();i++) + os << *population._parents[i] << endl; + os << endl << "---------------------------------------------------------------" << endl; + return os; + } + + const SetUpParams& Population::setup() const + { + return _setup; + } + + void Population::initialize() + { + for (int i=0;i<_parents.size();i++) + { + _parents[i]->initialize(); + _fitness_values[i].index = i; + _fitness_values[i].change = true; + } + evaluate_parents(); + } + + void Population::evaluate_parents() + { + double upper_fitness=(infinity() * (-1)); + double lower_fitness=(infinity()); + double current_fitness; + double cost=0.0; + + for (int i=0;i<_fitness_values.size();i++) + { + Evaluate(_parents[_fitness_values[i].index],_fitness_values[i]); + current_fitness = _fitness_values[i].fitness; + + if (current_fitness > upper_fitness ) + { + _upper_cost=i; + upper_fitness = current_fitness; + } + + if (current_fitness < lower_fitness ) + { + _lower_cost=i; + lower_fitness = current_fitness; + } + + cost += current_fitness; + } + + _average_cost = cost / _fitness_values.size(); + } + + void Population::evaluate_offsprings() + { + int i=0; + if (_setup.combine()) // new individuals selected between current individuals and offsprings + { + _fitness_aux=Rarray<struct individual>(_parents.size() + _offsprings.size()); + for (i=0;i<_parents.size();i++) + { + Evaluate(_parents[_fitness_values[i].index],_fitness_values[i]); + _fitness_aux[i] = _fitness_values[i]; + } + + for (int j=i;(j-i)<_offsprings.size();j++) + { + _fitness_aux[j].index=j; + _fitness_aux[j].change=true; + Evaluate(_offsprings[j-i],_fitness_aux[j]); + } + } + else // new individuals selected only between offsprings + { + _fitness_aux=Rarray<struct individual>(_offsprings.size()); + for (i=0;i<_offsprings.size();i++) + { + _fitness_aux[i].index=i; + _fitness_aux[i].change=true; + Evaluate(_offsprings[i],_fitness_aux[i]); + } + } + } + + void Population::evolution() + { + select_parents(); // selects individuals to apply operators + + // apply selected operators + for (int i=0;i<_setup.intra_operators_size();i++) + _setup.pool().intra_operator(_setup.intra_operator_index(i)).execute(_offsprings); + + evaluate_offsprings(); + select_offsprings(); // selects new individuals + evaluate_parents(); // calculates fitness of new individuals + } + + void Population::interchange(const unsigned long current_generation, NetStream& channel) + { + // apply selected operators + for (int i=0;i<_setup.inter_operators_size();i++) + _setup.pool().inter_operator(_setup.inter_operator_index(i)).execute((*this),current_generation,channel,_setup.synchronized(),_setup.check_asynchronous()); + } + + void Population::select_parents() + { + _setup.pool().selector(_setup.select_parents()).prepare(_fitness_values,false); + struct individual ind; + for (int i=0;i<_offsprings.size();i++) + { + ind = _setup.pool().selector(_setup.select_parents()).select_one(_parents,_offsprings,_fitness_values,_setup.parameter_select_parents(),false); + *_offsprings[i] = *_parents[ind.index]; + } + } + + void Population::select_offsprings() + { + _setup.pool().selector(_setup.select_offsprings()).prepare(_fitness_aux,false); + const int ps = _parents.size(); + Rarray<struct individual> aux(ps); + + for (int i=0;i<ps;i++) + { + if (_setup.combine()) + { + aux[i] = _setup.pool().selector(_setup.select_offsprings()).select_one(_parents,_offsprings,_fitness_aux,_setup.parameter_select_offsprings(),false); + if(aux[i].index < ps) + { + *_new_parents[i] = *_parents[aux[i].index]; + aux[i].index = i; + } + else + { + *_new_parents[i] = *_offsprings[aux[i].index-ps]; + aux[i].index = i; + } + } + else + { + aux[i]=_setup.pool().selector(_setup.select_offsprings()).select_one(_offsprings,_offsprings,_fitness_aux,_setup.parameter_select_offsprings(),false); + *_parents[i] = *_offsprings[aux[i].index]; + aux[i].index = i; + } + } + + if (_setup.combine()) // interchanges current and new parents in the population + { + Solution *interchange; + for (int i=0;i<ps;i++) + { + interchange=_parents[i]; + _parents[i]=_new_parents[i]; // interchanges pointers to solutions ( NO solutions !! ) + _new_parents[i]=interchange; + } + } + for (int i=0;i<ps;i++) + { + _fitness_values[i] = aux[i]; + } + } + + const Rarray<Solution*>& Population::parents() const + { + return _parents; + } + + const Rarray<Solution*>& Population::offsprings() const + { + return _offsprings; + } + + Rarray<struct individual>& Population::fitness_values() + { + return _fitness_values; + } + + unsigned int Population::upper_cost() const + { + return _upper_cost; + } + + unsigned int Population::lower_cost() const + { + return _lower_cost; + } + + unsigned int Population::evaluations() const + { + return _evaluations; + } + + double Population::best_cost() const + { + if ((*_parents[0]).pbm().direction() == minimize) + return _fitness_values[_lower_cost].fitness; + else + return _fitness_values[_upper_cost].fitness; + } + + double Population::worst_cost() const + { + if ((*_parents[0]).pbm().direction() == minimize) + return _fitness_values[_upper_cost].fitness; + else + return _fitness_values[_lower_cost].fitness; + } + + Solution& Population::best_solution() const + { + if ((*_parents[0]).pbm().direction() == minimize) + return *_parents[_fitness_values[_lower_cost].index]; + else + return *_parents[_fitness_values[_upper_cost].index]; + } + + Solution& Population::worst_solution() const + { + if ((*_parents[0]).pbm().direction() == minimize) + return *_parents[_fitness_values[_upper_cost].index]; + else + return *_parents[_fitness_values[_lower_cost].index]; + } + + Solution& Population::solution(const unsigned int index) const + { + return *_parents[index]; + } + + double Population::fitness(const unsigned int index) const + { + return _fitness_values[index].fitness; + } + + double Population::average_cost() const + { + return _average_cost; + } + + double Population::standard_deviation() const + { + double standard=0.0; + for (int i=0;i<_fitness_values.size();i++) + standard += pow ((_fitness_values[i].fitness - _average_cost),2); + standard=sqrt(standard / (_fitness_values.size()-1)); + return standard; + } + + Population::~Population() + { + for (int i=0;i<_parents.size();i++) + delete(_parents[i]); + for (int i=0;i<_offsprings.size();i++) + delete(_offsprings[i]); + for (int j=0;j<_new_parents.size();j++) + delete(_new_parents[j]); + } + + +// Inter_operator ------------------------------------------------------------------- + + Inter_Operator::Inter_Operator(const unsigned int _number_op,const Direction dir): + _number_operator(_number_op), + direction(dir), + migration_rate(1), + migration_size(1), + migration_selection_1(0), + migration_selection_2(0), + migration_selection_conf_1(0), + migration_selection_conf_2(0) + {} + + unsigned int Inter_Operator::number_operator() const + { + return _number_operator; + } + + void Inter_Operator::setup(char line[MAX_BUFFER]) + { + int op; + int new_migration_rate=1; + int new_migration_size=1; + int new_migration_selection_1=0; + int new_migration_selection_conf_1=0; + int new_migration_selection_2=0; + int new_migration_selection_conf_2=0; + + sscanf(line," %d %d %d %d %d %d %d ",&op,&new_migration_rate,&new_migration_size,&new_migration_selection_1,&new_migration_selection_conf_1,&new_migration_selection_2,&new_migration_selection_conf_2); + + assert(new_migration_rate>0); + assert(new_migration_size>0); + assert(new_migration_selection_1>=0); + assert(new_migration_selection_conf_1>=0); + assert(new_migration_selection_2>=0); + assert(new_migration_selection_conf_2>=0); + + migration_rate=new_migration_rate; + migration_size=new_migration_size; + migration_selection_1=new_migration_selection_1; + migration_selection_conf_1=new_migration_selection_conf_1; + migration_selection_2=new_migration_selection_2; + migration_selection_conf_2=new_migration_selection_conf_2; + } + + void Inter_Operator::RefreshState(const StateCenter& _sc) const + { + _sc.set_contents_state_variable("_migration_rate",(char *)&migration_rate,1,sizeof(migration_rate)); + _sc.set_contents_state_variable("_migration_size",(char *)&migration_size,1,sizeof(migration_size)); + _sc.set_contents_state_variable("_migration_selection_1",(char *)&migration_selection_1,1,sizeof(migration_selection_1)); + _sc.set_contents_state_variable("_migration_selection_2",(char *)&migration_selection_2,1,sizeof(migration_selection_2)); + _sc.set_contents_state_variable("_migration_selection_conf_1",(char *)&migration_selection_conf_1,1,sizeof(migration_selection_conf_1)); + _sc.set_contents_state_variable("_migration_selection_conf_2",(char *)&migration_selection_conf_2,1,sizeof(migration_selection_conf_2)); + } + + void Inter_Operator::UpdateFromState(const StateCenter& _sc) + { + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_rate",(char *)&migration_rate,nitems,length); + _sc.get_contents_state_variable("_migration_size",(char *)&migration_size,nitems,length); + _sc.get_contents_state_variable("_migration_selection_1",(char *)&migration_selection_1,nitems,length); + _sc.get_contents_state_variable("_migration_selection_2",(char *)&migration_selection_2,nitems,length); + _sc.get_contents_state_variable("_migration_selection_conf_1",(char *)&migration_selection_conf_1,nitems,length); + _sc.get_contents_state_variable("_migration_selection_conf_2",(char *)&migration_selection_conf_2,nitems,length); + } + + ostream& operator<< (ostream& os, const Inter_Operator& inter) + { + switch (inter.number_operator()) + { + case 0: os << (Migration&)inter;break; + } + return os; + } + + Inter_Operator::~Inter_Operator() + {} + +// Migration ------------------------------------------------------------ + + Migration::Migration(const Direction dir):Inter_Operator(0,dir) + {} + + void Migration::execute(Population& pop,const unsigned long current_generation,NetStream& _netstream,const bool synchronized,const unsigned int check_asynchronous) const + { + + Solution* solution_to_send; + Solution* solution_received; + Solution* solution_to_remplace; + bool need_to_revaluate=false; + int mypid; + + int nb_proc=_netstream.pnumber(); // Get the number of processes running + + mypid=_netstream.my_pid(); + + int to = (mypid + 1) % nb_proc; // Source (from) and Target (to) of processes + int from = (nb_proc + mypid - 1) % nb_proc; + + // process number 0 is only to store the global state + if (to==0) to=1; + if (from==0) from=nb_proc - 1; + + _netstream << set_target(to) << set_source(from) + << get_target(&to) << get_source(&from); + + if ( (current_generation % migration_rate) == 0 + && (current_generation!=pop.setup().nb_evolution_steps())) // in this generation this operator have to be applied + { + pop.setup().pool().selector(migration_selection_1).prepare(pop.fitness_values(),false); + + _netstream << pack_begin; + for (int i=0;i<migration_size;i++) + { + // select individual to send + solution_to_send = pop.parents()[pop.setup().pool().selector(migration_selection_1).select_one( + pop.parents(),pop.offsprings(),pop.fitness_values(),migration_selection_conf_1,false).index]; + + _netstream << *solution_to_send; + } + _netstream << pack_end; + + if (synchronized) // synchronous mode: blocked until data are received + { + pop.setup().pool().selector(migration_selection_2).prepare(pop.fitness_values(),true); + + _netstream << set_source(MPI_ANY_SOURCE); + int tipo = 0; + _netstream._wait2(any,tipo); + + if (tipo == 1){ + return; + } + + _netstream << wait(packed); + _netstream << pack_begin; + for (int i=0;i<migration_size;i++) + { + // select individual to be remplaced + struct individual ind; + ind = pop.setup().pool().selector(migration_selection_2).select_one( + pop.parents(),pop.offsprings(),pop.fitness_values(),migration_selection_conf_2,true); + solution_to_remplace = pop.parents()[ind.index]; + solution_received=new Solution(solution_to_remplace->pbm()); + _netstream >> *solution_received; + + // remplace policy + if ((solution_received->fitness()<=solution_to_remplace->fitness() && direction==minimize) + || (solution_received->fitness()>=solution_to_remplace->fitness() && direction==maximize)) + { + need_to_revaluate=true; + for(int j = 0; j < pop.parents().size(); j++) + { + if(pop.fitness_values()[j].index == ind.index) + { + pop.fitness_values()[j].change = true; + *pop.parents()[ind.index] = *solution_received; + } + } + } + delete(solution_received); + } + _netstream << pack_end; + + } + } // end if + + if (!synchronized && ((current_generation % check_asynchronous) ==0)) + { // asynchronous mode: if there are not data, continue; + // but, if there are data, i have to receive it + int pending=false; + _netstream._probe(packed,pending); + if (pending) + { + pop.setup().pool().selector(migration_selection_2).prepare(pop.fitness_values(),true); + + _netstream << pack_begin; + for (int i=0;i<migration_size;i++) + { + pending=false; + _netstream._probe(regular,pending); + if (!pending) break; + + // select individual to be remplaced + struct individual ind; + ind = pop.setup().pool().selector(migration_selection_2).select_one( + pop.parents(),pop.offsprings(),pop.fitness_values(),migration_selection_conf_2,true); + solution_to_remplace = pop.parents()[ind.index]; + solution_received=new Solution(solution_to_remplace->pbm()); + _netstream >> *solution_received; + + // remplace policy + if ((solution_received->fitness()<=solution_to_remplace->fitness() && direction==minimize) + || (solution_received->fitness()>=solution_to_remplace->fitness() && direction==maximize)) + { + need_to_revaluate=true; + for(int j = 0; j < pop.parents().size(); j++) + { + if(pop.fitness_values()[j].index == ind.index) + { + pop.fitness_values()[j].change = true; + *pop.parents()[ind.index] = *solution_received; + } + } + } + delete(solution_received); + } // end for + _netstream << pack_begin; + } // end if + } + + if (need_to_revaluate) pop.evaluate_parents(); + } + + ostream& operator<< (ostream& os, const Migration& migration) + { + os << "Migration." + << endl << "\t" << " Rate: " << migration.migration_rate + << endl << "\t" << " Size: " << migration.migration_size + << endl << "\t" << " Selection 1: " << migration.migration_selection_1 + << endl << "\t" << " Selection 1 Parameter: " << migration.migration_selection_conf_1 + << endl << "\t" << " Selection 2: " << migration.migration_selection_2 + << endl << "\t" << " Selection 2 Parameter: " << migration.migration_selection_conf_2; + return os; + } + + Migration::~Migration() + {} + +// Selection ------------------------------------------------------------ + + Selection::Selection(const Direction dir):_number_selection(0),direction(dir) + {} + + Selection::Selection(const unsigned int _number_sel, const Direction dir):_number_selection(_number_sel),direction(dir) + {} + + void Selection::prepare(Rarray<struct individual>& fitness_values,const bool remplace) + {} + + struct individual Selection::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int dummy,const bool remplace) const + { // select a random individual + return fitness_values[rand_int(0,fitness_values.size()-1)]; + } + + unsigned int Selection::number_selection() const + { + return _number_selection; + } + + ostream& operator<< (ostream& os, const Selection& sel) + { + switch (sel.number_selection()) + { + case 0: os << "Random Selection"; break; + case 1: os << (Selection_Tournament&)sel; break; + case 2: os << (Selection_Roulette_Wheel&)sel; break; + case 3: os << (Selection_Rank&)sel; break; + case 4: os << (Selection_Best&)sel; break; + case 5: os << (Selection_Worst&)sel; break; + } + return os; + } + + Selection::~Selection() + {} + +// Selection_Tournament---------------------------------------------------- + + Selection_Tournament::Selection_Tournament(const Direction dir):Selection(1,dir) + {} + + struct individual Selection_Tournament::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int tournament_size, const bool remplace) const + { + unsigned int best_sol=0; + double best_fitness=((-1) * direction * infinity()); + unsigned int index; + + if (remplace) best_fitness = -1 * best_fitness; + + unsigned int new_tournament_size=tournament_size; + if (tournament_size==0) new_tournament_size=1; + + for (int i=0;i<new_tournament_size;i++) + { + index=rand_int(0,fitness_values.size()-1); + + switch (direction) + { + case (minimize): if (((!remplace) && (fitness_values[index].fitness<best_fitness)) + || ((remplace) && (fitness_values[index].fitness>best_fitness))) + { + best_sol = index; + best_fitness = fitness_values[index].fitness; + } + break; + case (maximize): if (((!remplace) && (fitness_values[index].fitness>best_fitness)) + || ((remplace) && (fitness_values[index].fitness<best_fitness))) + { + best_sol = index; + best_fitness = fitness_values[index].fitness; + } + break; + } + } + + return fitness_values[best_sol]; + } + + ostream& operator<< (ostream& os, const Selection_Tournament& sel) + { + os << "Tournament Selection."; + return os; + } + + Selection_Tournament::~Selection_Tournament() + {} + +// Selection_Roulette_Wheel --------------------------------------------------- + + Selection_Roulette_Wheel::Selection_Roulette_Wheel(const Direction dir):Selection(2,dir) + {} + + void Selection_Roulette_Wheel::prepare(Rarray<struct individual>& fitness_values,const bool remplace) + { + double overall_fitness=0.0; + + // inverts fitness values to select less fitness individuals with a high probability + if ((direction==maximize && (remplace)) || ((direction==minimize) && (!(remplace)))) + { + // fitness assigned if the fitness value is 0 in this case + double value_if_zero=DBL_MAX; + unsigned int nb_zeros=0; + + for (int i=0;i<fitness_values.size();i++) + { + if (fitness_values[i].fitness!=0) + value_if_zero-=fitness_values[i].fitness; + else + nb_zeros++; + } + + value_if_zero=value_if_zero/nb_zeros; + + // Warning !! if fitness is 0 (1/0 ?) + for (int i=0;i<fitness_values.size();i++) + { + if (fitness_values[i].fitness!=0) + fitness_values[i].sel_parameter = (1 / fitness_values[i].fitness ); + else + fitness_values[i].sel_parameter = value_if_zero; + overall_fitness+= fitness_values[i].sel_parameter; + } + } + else + { + for (int i=0;i<fitness_values.size();i++) + { + fitness_values[i].sel_parameter = fitness_values[i].fitness; + overall_fitness+= fitness_values[i].sel_parameter; + } + + } + + if (overall_fitness>DBL_MAX) overall_fitness=DBL_MAX; + + // calculate relative fitness + double previous=0.0; + for (int i=0;i<fitness_values.size();i++) + { + fitness_values[i].sel_parameter = (fitness_values[i].sel_parameter / overall_fitness) + previous; + previous = fitness_values[i].sel_parameter; + } + } + + struct individual Selection_Roulette_Wheel::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int dummy, const bool remplace) const + { + double random_selected=rand01(); + int i=0; + + while (random_selected > fitness_values[i].sel_parameter ) + i++; + + return fitness_values[i]; + } + + ostream& operator<< (ostream& os, const Selection_Roulette_Wheel& sel) + { + os << "Roulette Wheel Selection."; + return os; + } + + Selection_Roulette_Wheel::~Selection_Roulette_Wheel() + {} + +// Selection_Rank -------------------------------------------------- + + int lessF(const struct individual &i1,const struct individual &i2) + { + return i1.fitness < i2.fitness; + } + + int greaterF(const struct individual &i1,const struct individual &i2) + { + return i1.fitness > i2.fitness; + } + + Selection_Rank::Selection_Rank(const Direction dir):Selection(3,dir) + {} + + Selection_Rank::Selection_Rank(const unsigned int _number_sel, const Direction dir):Selection(_number_sel,dir) + {} + + void Selection_Rank::reset() + {} + + void Selection_Rank::prepare(Rarray<struct individual>& fitness_values,const bool remplace) + { + reset(); + + // sort individuals + if (((direction==maximize) && (!(remplace))) || ((direction==minimize) && (remplace))) + fitness_values.sort(greaterF); + else + fitness_values.sort(lessF); + } + + struct individual Selection_Rank::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int portion,const bool remplace) const + { + + unsigned int new_portion=portion; + if (portion==0 || portion>100) new_portion=100; + + return fitness_values[rand_int(0,(( fitness_values.size() * new_portion )/ 100)-1)]; + } + + ostream& operator<< (ostream& os, const Selection_Rank& sel) + { + os << "Rank-Ordered Selection."; + return os; + } + + Selection_Rank::~Selection_Rank() + {} + +// Selection_Best -------------------------------------------------- + + Selection_Best::Selection_Best(const Direction dir):Selection_Rank(4,dir),selection_best_position(0) + {} + + struct individual Selection_Best::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int position,const bool remplace) const + { + int position_to_return=position-1; + if (position_to_return<0) + { + position_to_return = selection_best_position; + selection_best_position++; + } + + position_to_return=(int)position_to_return % fitness_values.size(); + + return fitness_values[position_to_return]; + } + + void Selection_Best::reset() + { + selection_best_position=0; + } + + ostream& operator<< (ostream& os, const Selection_Best& sel) + { + os << "Selection of best ordered individuals."; + return os; + } + + Selection_Best::~Selection_Best() + {} + +// Selection_Worst -------------------------------------------------- + + Selection_Worst::Selection_Worst(const Direction dir):Selection_Rank(5,dir),selection_worst_position(0) + {} + + struct individual Selection_Worst::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int position,const bool remplace) const + { + int position_to_return=position-1; + if (position_to_return<0) + { + position_to_return = selection_worst_position; + selection_worst_position++; + } + + position_to_return=(int)position_to_return % fitness_values.size(); + + int index=(fitness_values.size()-1) - position_to_return; + return fitness_values[index]; + } + + void Selection_Worst::reset() + { + selection_worst_position=0; + } + + ostream& operator<< (ostream& os, const Selection_Worst& sel) + { + os << "Selection of worst ordered individuals."; + return os; + } + + Selection_Worst::~Selection_Worst() + {} + +// Operator_Pool ------------------------------------------------------------------------ + + Operator_Pool::Operator_Pool(const Problem& pbm) + { + // introduces all operators and selections in lists + + // Index to be chosen in setup file + //------------------------------------- + // The Intra_Operators are introduced dimanicly in setup + + _selectors.append(new Selection(pbm.direction())); // 0 + _selectors.append(new Selection_Tournament(pbm.direction())); // 1 + _selectors.append(new Selection_Roulette_Wheel(pbm.direction())); // 2 + _selectors.append(new Selection_Rank(pbm.direction())); // 3 + _selectors.append(new Selection_Best(pbm.direction())); // 4 + _selectors.append(new Selection_Worst(pbm.direction())); // 5 + + _inter_operators.append(new Migration(pbm.direction())); // 0 + } + + Intra_Operator& Operator_Pool::intra_operator(const unsigned int index) const + { + assert(index < _intra_operators.size()); + return _intra_operators[index]; + } + + Rlist<Intra_Operator>& Operator_Pool::intra_operators() const + { + return _intra_operators; + } + + Selection& Operator_Pool::selector(const unsigned int index) const + { + assert(index < _selectors.size()); + return _selectors[index]; + } + + const Rlist<Selection>& Operator_Pool::selectors() const + { + return _selectors; + } + + Inter_Operator& Operator_Pool::inter_operator(const unsigned int index) const + { + assert(index < _inter_operators.size()); + return _inter_operators[index]; + } + + const Rlist<Inter_Operator>& Operator_Pool::inter_operators() const + { + return _inter_operators; + } + + Operator_Pool::~Operator_Pool() + {} + +// Solver (superclasse)--------------------------------------------------- + + Solver::Solver (const Problem& pbm, const SetUpParams& setup) + : problem(pbm), + params(setup), + _stat(), + _userstat(), + _sc(), + current_population(pbm,setup), + best_cost((-1) * pbm.direction() * infinity()), + worst_cost((-1) * best_cost), + best_solution(problem), + average_cost(0.0), + standard_deviation(0.0), + time_spent_in_trial(0.0), + total_time_spent(0.0), + start_trial(0.0), + start_global(0.0), + _current_trial("_current_trial",_sc), + _current_iteration("_current_iteration",_sc), + _current_evaluations("_current_evaluations",_sc), + _current_best_solution("_current_best_solution",_sc), + _current_best_cost("_current_best_cost",_sc), + _current_worst_cost("_current_worst_cost",_sc), + _current_average_cost("_current_average_cost",_sc), + _current_standard_deviation("_current_standard_deviation",_sc), + _current_time_spent("_current_time_spent",_sc), + _best_solution_trial("_best_sol_trial",_sc), + _best_cost_trial("_best_cost_trial",_sc), + _worst_cost_trial("_worst_cost_trial",_sc), + _iteration_best_found_in_trial("_iteration_best_found_in_trial",_sc), + _evaluations_best_found_in_trial("_evaluations_best_found_in_trial",_sc), + _time_best_found_trial("_time_best_found_trial",_sc), + _time_spent_trial("_time_spent_trial",_sc), + _trial_best_found("_trial_best_found",_sc), + _iteration_best_found("_iteration_best_found",_sc), + _evaluations_best_found("_evaluations_best_found",_sc), + _global_best_solution("_global_best_solution",_sc), + _global_best_cost("_global_best_cost",_sc), + _global_worst_cost("_global_worst_cost",_sc), + _time_best_found("_time_best_found",_sc), + _crossover_probability("_crossover_probability",_sc), + _mutation_probability("_mutation_probability",_sc), + _migration_rate("_migration_rate",_sc), + _migration_size("_migration_size",_sc), + _migration_selection_1("_migration_selection_1",_sc), + _migration_selection_2("_migration_selection_2",_sc), + _migration_selection_conf_1("_migration_selection_conf_1",_sc), + _migration_selection_conf_2("_migration_selection_conf_2",_sc), + _select_parents("_select_parents",_sc), + _select_offsprings("_select_offsprings",_sc), + _parameter_select_parents("_parameter_select_parents",_sc), + _parameter_select_offsprings("_parameter_select_offsprings",_sc), + _display_state("_display_state",_sc) + { + current_trial(0); + current_iteration(0); + current_evaluations(0); + current_best_solution(best_solution); + current_best_cost(best_cost); + current_worst_cost(worst_cost); + current_average_cost(average_cost); + current_standard_deviation(standard_deviation); + current_time_spent(total_time_spent); + best_solution_trial(best_solution); + best_cost_trial(best_cost); + worst_cost_trial(worst_cost); + iteration_best_found_in_trial(0); + evaluations_best_found_in_trial(0); + time_best_found_trial(time_spent_in_trial); + time_spent_trial(time_spent_in_trial); + trial_best_found(0); + iteration_best_found(0); + evaluations_best_found(0); + global_best_solution(best_solution); + global_best_cost(best_cost); + global_worst_cost(worst_cost); + time_best_found(total_time_spent); + + float prob[MAX_PROB_PER_OP] = {0.0}; + crossover_probability(prob); + mutation_probability(prob); + + char aux[] = "_user_op_probability"; + char nombre[30]; + for(int i = 0; i < MAX_OP_USER; i++) + { + sprintf(nombre,"%s%d",aux,i); + _user_op_probability[i].set_name((char *)nombre); + _sc.add(_user_op_probability[i]); + user_op_probability(i,prob); + } + + migration_rate(0); + migration_size(0); + migration_selection_1(0); + migration_selection_2(0); + migration_selection_conf_1(0); + migration_selection_conf_2(0); + select_parents(0); + select_offsprings(0); + parameter_select_parents(0); + parameter_select_offsprings(0); + display_state(setup.display_state()); + } + + int Solver::pid() const + { + return 0; + } + + bool Solver::end_trial() const + { + return _end_trial; + } + + void Solver::end_trial(bool et) + { + _end_trial = et; + } + + unsigned int Solver::current_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _current_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned long Solver::current_iteration() const + { + unsigned long value=0; + unsigned long nitems,length; + _current_iteration.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned long Solver::current_evaluations() const + { + unsigned long value=0; + unsigned long nitems,length; + _current_evaluations.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::current_best_solution() const + { + Solution sol(problem); + unsigned long nitems,length; + char data_stored[_current_best_solution.get_nitems() + _current_best_solution.get_length()]; + _current_best_solution.get_contents(data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::current_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _current_best_cost.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::current_worst_cost() const + { + double value=0.0; + unsigned long nitems,length; + _current_worst_cost.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::current_average_cost() const + { + double value=0.0; + unsigned long nitems,length; + _current_average_cost.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::current_standard_deviation() const + { + double value=0.0; + unsigned long nitems,length; + _current_standard_deviation.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::current_time_spent() const + { + float value=0.0; + unsigned long nitems,length; + _current_time_spent.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::best_solution_trial() const + { + Solution sol(problem); + char data_stored[_best_solution_trial.get_nitems() + _best_solution_trial.get_length()]; + unsigned long nitems,length; + _best_solution_trial.get_contents(data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::best_cost_trial() const + { + double value=0.0; + unsigned long nitems,length; + _best_cost_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::worst_cost_trial() const + { + double value=0.0; + unsigned long nitems,length; + _worst_cost_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found_in_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found_in_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::evaluations_best_found_in_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _evaluations_best_found_in_trial.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_spent_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_spent_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::trial_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _trial_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::evaluations_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _evaluations_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::global_best_solution() const + { + Solution sol(problem); + char data_stored[_global_best_solution.get_nitems() + _global_best_solution.get_length()]; + unsigned long nitems,length; + _global_best_solution.get_contents(data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::global_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _global_best_cost.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::global_worst_cost() const + { + double value=0.0; + unsigned long nitems,length; + _global_worst_cost.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + int Solver::display_state() const + { + int value=0; + unsigned long nitems,length; + _display_state.get_contents((char *)&value, nitems, length); + return value; + } + + float *Solver::crossover_probability() const + { + float *current_probability = new float[MAX_PROB_PER_OP]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_crossover_probability",(char *)¤t_probability,nitems,length); + return current_probability; + } + + float *Solver::mutation_probability() const + { + float *current_probability = new float[MAX_PROB_PER_OP]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_mutation_probability",(char *)¤t_probability,nitems,length); + return current_probability; + } + + float *Solver::user_op_probability(const int index) const + { + float *current_probability = new float[MAX_PROB_PER_OP]; + unsigned long nitems,length; + char aux[30] = "_user_op_probability"; + sprintf(aux,"%s%d",aux,index); + + _sc.get_contents_state_variable(aux,(char *)¤t_probability,nitems,length); + return current_probability; + } + + unsigned int Solver::migration_rate() const + { + unsigned int rate=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_rate",(char *)&rate,nitems,length); + return rate; + } + + unsigned int Solver::migration_size() const + { + unsigned int size=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_size",(char *)&size,nitems,length); + return size; + } + + unsigned int Solver::migration_selection_1() const + { + unsigned int selection_1=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_selection_1",(char *)&selection_1,nitems,length); + return selection_1; + } + + unsigned int Solver::migration_selection_2() const + { + unsigned int selection_2=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_selection_2",(char *)&selection_2,nitems,length); + return selection_2; + } + + unsigned int Solver::migration_selection_conf_1() const + { + unsigned int selection_conf_1=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_selection_conf_1",(char *)&selection_conf_1,nitems,length); + return selection_conf_1; + } + + unsigned int Solver::migration_selection_conf_2() const + { + unsigned int selection_conf_2=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_selection_conf_2",(char *)&selection_conf_2,nitems,length); + return selection_conf_2; + } + + unsigned int Solver::select_parents() const + { + unsigned int select_parents=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_select_parents",(char *)&select_parents,nitems,length); + return select_parents; + } + + unsigned int Solver::select_offprings() const + { + unsigned int select_offsprings=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_select_offsprings",(char *)&select_offsprings,nitems,length); + return select_offsprings; + } + + unsigned int Solver::parameter_select_parents() const + { + unsigned int parameter_select_parents; + unsigned long nitems,length; + _sc.get_contents_state_variable("_parameter_select_parents",(char *)¶meter_select_parents,nitems,length); + return parameter_select_parents; + } + + unsigned int Solver::parameter_select_offsprings() const + { + unsigned int parameter_select_offsprings; + unsigned long nitems,length; + _sc.get_contents_state_variable("_parameter_select_offsprings",(char *)¶meter_select_offsprings,nitems,length); + return parameter_select_offsprings; + } + + void Solver::current_trial(const unsigned int value) + { + _current_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::current_iteration(const unsigned long value) + { + _current_iteration.set_contents((char *)&value,1,sizeof(long)); + } + + void Solver::current_evaluations(const unsigned long value) + { + _current_evaluations.set_contents((char *)&value,1,sizeof(long)); + } + + void Solver::current_best_solution(const Solution& sol) + { + _current_best_solution.set_contents(sol.to_String(),1,sol.size()); + } + + void Solver::current_best_cost(const double value) + { + _current_best_cost.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::current_worst_cost(const double value) + { + _current_worst_cost.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::current_average_cost(const double value) + { + _current_average_cost.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::current_standard_deviation(const double value) + { + _current_standard_deviation.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::current_time_spent(const float value) + { + _current_time_spent.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::best_solution_trial(const Solution& sol) + { + _best_solution_trial.set_contents(sol.to_String(),1,sol.size()); + } + + void Solver::best_cost_trial(const double value) + { + _best_cost_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::worst_cost_trial(const double value) + { + _worst_cost_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::iteration_best_found_in_trial(const unsigned int value) + { + _iteration_best_found_in_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::evaluations_best_found_in_trial(const unsigned int value) + { + _evaluations_best_found_in_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::time_best_found_trial(const float value) + { + _time_best_found_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::time_spent_trial(const float value) + { + _time_spent_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::trial_best_found(const unsigned int value) + { + _trial_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::iteration_best_found(const unsigned int value) + { + _iteration_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::evaluations_best_found(const unsigned int value) + { + _evaluations_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::global_best_solution(const Solution& sol) + { + _global_best_solution.set_contents(sol.to_String(),1,sol.size()); + } + + void Solver::global_best_cost(const double value) + { + _global_best_cost.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::global_worst_cost(const double value) + { + _global_worst_cost.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::time_best_found(const float value) + { + _time_best_found.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::display_state(const int value) + { + _display_state.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::crossover_probability(const float *new_probability) + { + _sc.set_contents_state_variable("_crossover_probability",(char *)new_probability,MAX_PROB_PER_OP,sizeof(float)); + } + + void Solver::mutation_probability(const float *new_probability) + { + _sc.set_contents_state_variable("_mutation_probability",(char *)new_probability,MAX_PROB_PER_OP,sizeof(float)); + } + + void Solver::user_op_probability(const int index, const float *new_probability) + { + char aux[30] = "_user_op_probability"; + sprintf(aux,"%s%d",aux,index); + + _sc.set_contents_state_variable(aux,(char *)new_probability,MAX_PROB_PER_OP,sizeof(float)); + } + + void Solver::migration_rate(const unsigned int rate) + { + _sc.set_contents_state_variable("_migration_rate",(char *)&rate,1,sizeof(int)); + } + + void Solver::migration_size(const unsigned int size) + { + _sc.set_contents_state_variable("_migration_size",(char *)&size,1,sizeof(int)); + } + + void Solver::migration_selection_1(const unsigned int selection_1) + { + _sc.set_contents_state_variable("_migration_selection_1",(char *)&selection_1,1,sizeof(int)); + } + + void Solver::migration_selection_2(const unsigned int selection_2) + { + _sc.set_contents_state_variable("_migration_selection_2",(char *)&selection_2,1,sizeof(int)); + } + + void Solver::migration_selection_conf_1(const unsigned int selection_conf_1) + { + _sc.set_contents_state_variable("_migration_selection_conf_1",(char *)&selection_conf_1,1,sizeof(int)); + } + + void Solver::migration_selection_conf_2(const unsigned int selection_conf_2) + { + _sc.set_contents_state_variable("_migration_selection_conf_2",(char *)&selection_conf_2,1,sizeof(int)); + } + + void Solver::select_parents(const unsigned int selection) + { + _sc.set_contents_state_variable("_select_parents",(char *)&selection,1,sizeof(int)); + } + + void Solver::select_offsprings(const unsigned int selection) + { + _sc.set_contents_state_variable("_select_offsprings",(char *)&selection,1,sizeof(int)); + } + + void Solver::parameter_select_parents(const unsigned int value) + { + _sc.set_contents_state_variable("_parameter_select_parents",(char *)&value,1,sizeof(int)); + } + + void Solver::parameter_select_offsprings(const unsigned int value) + { + _sc.set_contents_state_variable("_parameter_select_offsprings",(char *)&value,1,sizeof(int)); + } + + Statistics& Solver::statistics() + { + return _stat; + } + + UserStatistics& Solver::userstatistics() + { + return _userstat; + } + + Population& Solver::population() + { + return current_population; + } + + const SetUpParams& Solver::setup() const + { + return params; + } + + const Problem& Solver::pbm() const + { + return problem; + } + + void Solver::KeepHistory(const Solution& best_sol,const double best_cost,const double worst_cost,const float time_spent_in_trial,const float total_time_spent) + { + bool betterG=false; + bool worseG=false; + bool betterT=false; + bool worseT=false; + + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_spent_in_trial < time_best_found())); + worseG = (worst_cost > global_worst_cost()); + betterT = (best_cost < best_cost_trial() || (best_cost == best_cost_trial() && time_spent_in_trial < time_best_found_trial())); + worseT = (worst_cost > worst_cost_trial()); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_spent_in_trial < time_best_found())); + worseG = (worst_cost < global_worst_cost()); + betterT = (best_cost > best_cost_trial() || (best_cost == best_cost_trial() && time_spent_in_trial < time_best_found_trial())); + worseT = (worst_cost < worst_cost_trial()); + break; + } + + if (betterT) + { + best_solution_trial(best_sol); + best_cost_trial(best_cost); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_in_trial(current_iteration()); + evaluations_best_found_in_trial(current_evaluations()); + if (betterG) + { + global_best_solution(best_sol); + global_best_cost(best_cost); + time_best_found(time_spent_in_trial); + trial_best_found(current_trial()); + iteration_best_found(current_iteration()); + evaluations_best_found(current_evaluations()); + } + } + + if (worseT) + { + worst_cost_trial(worst_cost); + if (worseG) + global_worst_cost(worst_cost); + } + } + + StateCenter *Solver::GetState() + { + return &_sc; + } + + void Solver::RefreshState() + { + current_best_solution(best_solution); + current_best_cost(best_cost); + current_worst_cost(worst_cost); + current_average_cost(average_cost); + current_standard_deviation(standard_deviation); + current_time_spent(total_time_spent); + time_spent_trial(time_spent_in_trial); + KeepHistory(best_solution,best_cost,worst_cost,time_spent_in_trial,total_time_spent); + } + + void Solver::RefreshCfgState() + { + for (int i=0;i<params.pool().intra_operators().size();i++) + params.pool().intra_operator(i).RefreshState(_sc); + for (int i=0;i<params.pool().inter_operators().size();i++) + params.pool().inter_operator(i).RefreshState(_sc); + params.RefreshState(_sc); + } + + void Solver::UpdateFromState() + { + best_solution=current_best_solution(); + best_cost=current_best_cost(); + worst_cost=current_worst_cost(); + average_cost=current_average_cost(); + standard_deviation=current_standard_deviation(); + total_time_spent=current_time_spent(); + time_spent_in_trial=time_spent_trial(); + KeepHistory(best_solution,best_cost,worst_cost,time_spent_in_trial,total_time_spent); + } + + void Solver::UpdateFromCfgState() + { + for (int i=0;i<params.pool().intra_operators().size();i++) + params.pool().intra_operator(i).UpdateFromState(_sc); + for (int i=0;i<params.pool().inter_operators().size();i++) + params.pool().inter_operator(i).UpdateFromState(_sc); + params.UpdateFromState(_sc); + } + + void Solver::show_state() const + { + cout << endl << " Current State ---------------------------------------------" << endl; +/* cout << endl << "Selection parents -> " << select_parents(); + cout << endl << "Parameter of selection: " << parameter_select_parents(); + cout << endl << "Selection offsprings -> " << select_offprings(); + cout << endl << "Parameter of selection: " << parameter_select_offsprings() << endl; + cout << endl << "Crossover_probability: " << crossover_probability(); + cout << endl << "Mutation_probability: " << mutation_probability(); + cout << endl << "User_Operator_probability: " << user_op_probability(0); + cout << endl << "Migration_rate: " << migration_rate(); + cout << endl << "Migration_size: " << migration_size(); + cout << endl << "Migration_selection_1: " << migration_selection_1(); + cout << endl << "Migration_selection_conf_1: " << migration_selection_conf_1(); + cout << endl << "Migration_selection_2: " << migration_selection_2(); + cout << endl << "Migration_selection_conf_2: " << migration_selection_conf_2() << endl; +*/ cout << endl << "Current trial: " << current_trial(); + cout << endl << "Current iteration: " << current_iteration(); + cout << endl << "Current evaluations: " << current_evaluations(); + cout << endl << "Current best cost: " << current_best_cost(); + cout << endl << "Current worst cost: " << current_worst_cost(); + cout << endl << "Current Average cost: " << current_average_cost(); + cout << endl << "Current Standard Deviation: " << current_standard_deviation(); + cout << endl << endl << "Trial: "; + cout << endl << "Best cost trial: " << best_cost_trial(); + cout << endl << "Worst cost trial: " << worst_cost_trial(); + cout << endl << "Iteration best found in trial: " << iteration_best_found_in_trial(); + cout << endl << "Evaluations best found in trial: " << evaluations_best_found_in_trial(); + cout << endl << "Time best found trial: " << time_best_found_trial(); + cout << endl << "Time spent in trial: " << time_spent_trial(); + cout << endl << endl << "Global: "; + cout << endl << "Global best cost: " << global_best_cost(); + cout << endl << "Global worst cost: " << global_worst_cost(); + cout << endl << "Trial best found: " << trial_best_found(); + cout << endl << "Iteration best found: " << iteration_best_found(); + cout << endl << "Evaluations best found: " << evaluations_best_found(); + cout << endl << "Time best found: " << time_best_found(); +// cout << endl << endl << "Best Solution: " << endl << global_best_solution(); + cout << endl << endl << "Current time spent (so far): " << current_time_spent() << endl; + } + + Solver::~Solver() + { + _sc.removeAll(); + } + +// Solver sequencial ----------------------------------------------------- + + Solver_Seq::Solver_Seq (const Problem& pbm, const SetUpParams& setup) + : Solver(pbm,setup) + { + random_seed(time(0)); + _end_trial=true; + } + + Solver_Seq::~Solver_Seq () + {} + + void Solver_Seq::StartUp() + { + Population pop(problem,params); + pop.initialize(); + StartUp(pop); + } + + void Solver_Seq::StartUp(const Population& pop) + { + start_trial=_used_time(); + start_global=total_time_spent; + + current_trial(current_trial()+1); + current_iteration(0); + current_evaluations(pop.evaluations()); + + // initialize state variables in the current trial + + Solution initial_solution(problem); + + time_spent_in_trial=0.0; + best_cost_trial((-1) * problem.direction() * infinity()); + worst_cost_trial((-1) * best_cost_trial()); + best_solution_trial(initial_solution); + time_best_found_trial(0.0); + + current_population=pop; + current_population.evaluate_parents(); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + void Solver_Seq::DoStep() + { + + current_iteration(current_iteration()+1); + current_population.evolution(); + current_evaluations(current_population.evaluations()); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + if( (current_iteration() % params.refresh_global_state()) == 0) + UpdateFromCfgState(); + + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + void Solver_Seq::run () + { + while (current_trial() < params.independent_runs()) + run(params.nb_evolution_steps()); + } + + void Solver_Seq::run (const unsigned long int nb_generations) + { + StartUp(); + while ((current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + + } + + void Solver_Seq::run (const Population& pop,const unsigned long int nb_generations) + { + StartUp(pop); + while ((current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + + } + + // Solver LAN ------------------------------------------------------------ + + Solver_Lan::Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0),acum_iterations(0) + + { + + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + // random_seed(time(0) + (mypid+1)); + } + + Solver_Lan::~Solver_Lan () + { + NetStream::finalize(); + } + + int Solver_Lan::pid() const + { + return mypid; + } + + NetStream& Solver_Lan::netstream() + { + return _netstream; + } + + void Solver_Lan::StartUp() + { + Population pop(problem,params); + pop.initialize(); + StartUp(pop); + } + + void Solver_Lan::StartUp(const Population& pop) + { + _netstream << barrier; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + acum_iterations = 0; + + start_trial=_used_time(); + start_global=total_time_spent; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + current_evaluations(pop.evaluations()); + + // initialize state variables in the current trial + + Solution initial_solution(problem); + + time_spent_in_trial=0.0; + best_cost_trial((-1) * problem.direction() * infinity()); + worst_cost_trial((-1) * best_cost_trial()); + best_solution_trial(initial_solution); + iteration_best_found_in_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current_population=pop; + current_population.evaluate_parents(); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + } + } + + void Solver_Lan::DoStep() + { + current_iteration(current_iteration()+1); + current_population.evolution(); + current_evaluations(current_population.evaluations()); + + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(regular, pending); + if(pending) + final_phase = true; + //////////////////////// + + current_population.interchange(current_iteration(),_netstream); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + // in this iteration i have to send data about my local state to the global state + if ((int)current_iteration() % params.refresh_global_state() ==0) + { + send_local_state_to(mypid); + UpdateFromCfgState(); + } + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + + + void Solver_Lan::send_local_state_to(int _mypid) { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_evaluations() + << best_solution_trial() + << current_best_solution() + << best_cost_trial() + << worst_cost_trial() + << time_best_found_trial() + << current_best_cost() + << current_worst_cost() + << current_average_cost() + << current_standard_deviation() + << iteration_best_found_in_trial() + << evaluations_best_found_in_trial() + << pack_end; + } + + int Solver_Lan::receive_local_state() { + int r_pid=0; + + _netstream._wait(packed); + + _netstream << pack_begin + >> r_pid + >> _current_trial + >> _current_iteration + >> _current_evaluations + >> _best_solution_trial + >> best_solution + >> _best_cost_trial + >> _worst_cost_trial + >> _time_best_found_in_trial + >> best_cost + >> worst_cost + >> average_cost + >> standard_deviation + >> _iteration_best_found_in_trial + >> _evaluations_best_found_in_trial + << pack_end; + return r_pid; + } + + void Solver_Lan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + _netstream << set_source(MPI_ANY_SOURCE); + + while (!_end_trial) + { + received_pid=0; + received_pid=receive_local_state(); + + current_trial(_current_trial); + + // refresh the global state with received data ( a local state ) + current_iteration(_iteration_best_found_in_trial); + current_evaluations(_evaluations_best_found_in_trial); + KeepHistory(_best_solution_trial,_best_cost_trial,_worst_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + // the process that has send data has finished the current trial + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && terminateQ(problem,*this,params)) + { + acum_iterations = params.nb_evolution_steps() * nb_finalized_processes; + acum_evaluations = acum_iterations* params.population_additional_size() + + nb_finalized_processes*params.population_size(); + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << 1; + } + final_phase = true; + } + nb_finalized_processes++; + acum_iterations += _iteration_best_found_in_trial; + acum_evaluations += _evaluations_best_found_in_trial; + } + if (nb_finalized_processes==nb_proc-1) + _end_trial=true; + + current_iteration(_current_iteration); + current_evaluations(_current_evaluations); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + RefreshState(); + RefreshCfgState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualizaci�n de las estad�sticas // Termination phase // + iteration_best_found_in_trial(acum_iterations/(_netstream.pnumber()-1)); + evaluations_best_found_in_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = best_cost_trial(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + { + iteration_best_found(iteration_best_found_in_trial()); + evaluations_best_found(evaluations_best_found_in_trial()); + } + + RefreshState(); + RefreshCfgState(); + + _stat.update(*this); + _userstat.update(*this); + + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Lan::run () + { + while (current_trial() < params.independent_runs()) + run(params.nb_evolution_steps()); + } + + void Solver_Lan::run (const unsigned long int nb_generations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Population& pop,const unsigned long int nb_generations) + { + StartUp(pop); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::reset() + { + Solution left_solution(problem); + int i; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> i; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } + + // Solver WAN ------------------------------------------------------------ + + Solver_Wan::Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0),acum_iterations(0) + { + + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + // random_seed(time(0) + (mypid+1)); + } + + Solver_Wan::~Solver_Wan () + { + NetStream::finalize(); + } + + int Solver_Wan::pid() const + { + return mypid; + } + + NetStream& Solver_Wan::netstream() + { + return _netstream; + } + + void Solver_Wan::StartUp() + { + Population pop(problem,params); + pop.initialize(); + StartUp(pop); + } + + void Solver_Wan::StartUp(const Population& pop) + { + _netstream << barrier; + + // Termination phase // + final_phase = false; + acum_evaluations = 0; + acum_iterations = 0; + + start_trial=_used_time(); + start_global=total_time_spent; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + current_evaluations(pop.evaluations()); + + // initialize state variables in the current trial + + Solution initial_solution(problem); + + time_spent_in_trial=0.0; + best_cost_trial((-1) * problem.direction() * infinity()); + worst_cost_trial((-1) * best_cost_trial()); + best_solution_trial(initial_solution); + iteration_best_found_in_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current_population=pop; + current_population.evaluate_parents(); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + } + } + + void Solver_Wan::DoStep() + { + current_iteration(current_iteration()+1); + current_population.evolution(); + current_evaluations(current_population.evaluations()); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(regular, pending); + if(pending) + final_phase = true; + //////////////////////// + + current_population.interchange(current_iteration(),_netstream); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + // in this iteration i have to send data about my local state to the global state + if ((int)current_iteration() % params.refresh_global_state() ==0) + { + send_local_state_to(mypid); + UpdateFromCfgState(); + } + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + + + void Solver_Wan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_evaluations() + << best_cost_trial() + << best_solution_trial() + << iteration_best_found_in_trial() + << evaluations_best_found_in_trial() + << time_best_found_trial() + << worst_cost_trial() + << current_best_cost() + << current_best_solution() + << current_worst_cost() + << current_average_cost() + << current_standard_deviation() + << pack_end; + } + + int Solver_Wan::receive_local_state() + { + int r_pid=0; + + _netstream._wait(packed); + + _netstream << pack_begin + >> r_pid + >> _current_trial + >> _current_iteration + >> _current_evaluations + >> _best_cost_trial + >> _best_solution_trial + >> _iteration_best_found_in_trial + >> _evaluations_best_found_in_trial + >> _time_best_found_in_trial + >> _worst_cost_trial + >> best_cost + >> best_solution + >> worst_cost + >> average_cost + >> standard_deviation + << pack_end; + return r_pid; + } + + void Solver_Wan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + _netstream << set_source(MPI_ANY_SOURCE); + + while (!_end_trial) + { + received_pid=0; + received_pid=receive_local_state(); + + current_trial(_current_trial); + + // refresh the global state with received data ( a local state ) + current_iteration(_iteration_best_found_in_trial); + current_evaluations(_evaluations_best_found_in_trial); + KeepHistory(_best_solution_trial,_best_cost_trial,_worst_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + // the process that has send data has finished the current trial + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && terminateQ(problem,*this,params)) + { + acum_iterations = params.nb_evolution_steps() * nb_finalized_processes; + acum_evaluations = acum_iterations* params.population_additional_size() + + nb_finalized_processes*params.population_size(); + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << 1; + } + final_phase = true; + } + nb_finalized_processes++; + acum_iterations += _iteration_best_found_in_trial; + acum_evaluations += _evaluations_best_found_in_trial; + } + if (nb_finalized_processes==nb_proc-1) + _end_trial=true; + + current_iteration(_current_iteration); + current_evaluations(_current_evaluations); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + RefreshState(); + RefreshCfgState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Update Stats // Termination phase // + iteration_best_found_in_trial(acum_iterations/(_netstream.pnumber()-1)); + evaluations_best_found_in_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = best_cost_trial(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + { + iteration_best_found(iteration_best_found_in_trial()); + evaluations_best_found(evaluations_best_found_in_trial()); + } + + RefreshState(); + RefreshCfgState(); + + _stat.update(*this); + _userstat.update(*this); + + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Wan::run () + { + while (current_trial() < params.independent_runs()) + run(params.nb_evolution_steps()); + } + + void Solver_Wan::run (const unsigned long int nb_generations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Population& pop,const unsigned long int nb_generations) + { + StartUp(pop); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::reset() + { + Solution left_solution(problem); + int i; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> i ; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + + } + _netstream << barrier; + } + +} + + diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.pro.o b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.pro.o new file mode 100644 index 0000000000000000000000000000000000000000..8a79374826a57f9269ae72e0a8447080a445c8b4 Binary files /dev/null and b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.pro.o differ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.req.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.req.cc new file mode 100644 index 0000000000000000000000000000000000000000..653d43b819666278652d4834d7116555127fdffd --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.req.cc @@ -0,0 +1,778 @@ +#ifndef INC_REQ_newGA +#define INC_REQ_newGA +#include "newGA.hh" +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sstream> +#include <algorithm> + +skeleton newGA +{ + + // Problem --------------------------------------------------------------- + + Problem::Problem ():_dimension(0),_limite_barrios(NULL),_tareasEsf(NULL),_tareasIndex(NULL),_empleados(NULL),_cantDias(0),_cantEmpleados(0) + { + //cout << "uf6"; + } + + ostream& operator<< (ostream& os, const Problem& pbm) + { + os << endl << endl << "Number of Variables " << pbm._dimension + << endl; + + //Imprimo el arreglo con los limites de barrios + os<<"Limites de barrios: "<<endl<<endl; + for (int i=0;i<pbm._dimension;i++){ + os<<i<<": "; + int indice=0; + while (pbm._limite_barrios[i][indice]!=-1){ + os<<pbm._limite_barrios[i][indice]<<","; + indice++; + } + os<<endl; + } + os<<endl; + return os; + } + + + + istream& operator>> (istream& is, Problem& pbm) + { + + char buffer[MAX_BUFFER]; + int i; + + //is.getline(buffer,MAX_BUFFER,'\n'); + //sscanf(buffer,"%d",&pbm._dimension); + + //CARGAR DATO CANT Tareas + ifstream inFile; + inFile.open("datos_cantidad_tareas"); + if (!inFile) + { + cerr << "Unable to open file datafile.txt"; + exit(1); // call system to stop + } + string x; + getline(inFile,x); + pbm._dimension = stoi(x); + inFile.close(); + + //Pido memoria para almacenar los limites de los barrios + pbm._limite_barrios=new int *[pbm._dimension]; + for (int i=0;i<pbm._dimension;i++) + { + pbm._limite_barrios[i]=new int [10]; + for (int j=0;j<10;j++) + pbm._limite_barrios[i][j]=-1; + } + + //CARGAR DATO CANT EMPLEADOS + inFile; + inFile.open("datos_cantidad_empleados"); + if (!inFile) + { + cerr << "Unable to open file datafile.txt"; + exit(1); // call system to stop + } + //string x; + getline(inFile,x); + pbm._cantEmpleados = stoi(x); + inFile.close(); + //INICIALIZAR DATOS TAREAS ESFUERZO + pbm._tareasEsf=new int [pbm._dimension]; + for (int ii=0;ii<pbm._dimension;ii++) + { + pbm._tareasEsf[ii]=0; + } + + + //CARGAR DATOS TAREAS ESFUERZO + + inFile.open("datos_tareas"); + if (!inFile) + { + cerr << "Unable to open file datafile.txt"; + exit(1); // call system to stop + } + string line2; + getline(inFile,line2); + pbm._cantDias = stoi(line2); + getline(inFile, line2); + getline(inFile, line2); + + int n = line2.length(); + char char_array[n+1]; + int len=1; + int t=0; + int z=0; + for(int i=0; i<=line2.length(); i++) + { + if(line2[i] == ' '|| i==line2.length()) + { + string rr = line2.substr(z,len); + pbm._tareasEsf[t] = stoi(rr); + //cout << rr << " "; + t=t+1; + z=i+1; + len=1; + //s.erase(i,1); + } + else len=len+1; + } + inFile.close(); + + + pbm._tareasIndex = new int[pbm._dimension]; + for (int i = 0 ; i != pbm._dimension ; i++) + { + pbm._tareasIndex[i] = i; + } + sort(pbm._tareasIndex, pbm._tareasIndex + pbm._dimension,[&](const int& a, const int& b) { return (pbm._tareasEsf[a] < pbm._tareasEsf[b]); }); + /* + for (int i = 0 ; i != pbm._dimension ; i++) + { + cout << pbm._tareasIndex[i] << " "; + } + exit(0); + */ + + //INICIALIZAR EMPLEADOS + pbm._empleados=new Empleado [pbm._cantEmpleados]; + for (int zz=0;zz<pbm._cantEmpleados;zz++) + { + + pbm._empleados[zz]._sueldo = 0; + pbm._empleados[zz]._habilidad=0; + pbm._empleados[zz]._horas=0; + } + + //CARGAS DATOS EMPLEADOS + + string line23; + inFile.open("datos_empleados"); + getline(inFile, line23); + getline(inFile, line23); + int no = line23.length(); + char_array[n+1]; + len=1; + t=0; + z=0; + for(int i=0; i<=line23.length(); i++) + { + if(line23[i] == ' ' || i==line23.length()) + { + string rrr = line23.substr(z,len); + pbm._empleados[t]._horas = stoi(rrr); + //cout << rr << " "; + t=t+1; + z=i+1; + len=1; + //s.erase(i,1); + } + else len=len+1; + } + cout << pbm._empleados[0]._horas <<" " << pbm._empleados[1]._horas <<" " << pbm._empleados[2]._horas <<" " << pbm._empleados[3]._horas << " " << pbm._empleados[4]._horas << " " << endl; + + getline(inFile, line23); + no = line23.length(); + char_array[n+1]; + len=1; + t=0; + z=0; + // cout << line23; + for(int i=0; i<=line23.length(); i++) + { + if(line23[i] == ' ' || i==line23.length()) + { + string rrr = line23.substr(z,len); + pbm._empleados[t]._habilidad = stof(rrr); + //cout << rrr << " "; + t=t+1; + z=i+1; + len=1; + //s.erase(i,1); + } + else len=len+1; + } + cout << pbm._empleados[0]._habilidad <<" " << pbm._empleados[1]._habilidad <<" " << pbm._empleados[2]._habilidad <<" " << pbm._empleados[3]._habilidad << " " << pbm._empleados[4]._habilidad << " " << endl; + + getline(inFile, line23); + no = line23.length(); + char_array[n+1]; + len=1; + t=0; + z=0; + for(int i=0; i<=line23.length(); i++) + { + if(line23[i] == ' ' || i==line23.length()) + { + string rrr = line23.substr(z,len); + pbm._empleados[t]._sueldo = stoi(rrr); + //cout << rr << " "; + t=t+1; + z=i+1; + len=1; + //s.erase(i,1); + } + else len=len+1; + } + cout << pbm._empleados[0]._sueldo <<" " << pbm._empleados[1]._sueldo <<" " << pbm._empleados[2]._sueldo <<" " << pbm._empleados[3]._sueldo << " " << pbm._empleados[4]._sueldo << " " << endl; + //assert(false); + inFile.close(); + + /* + //Cargo el archivo con los limites de los barrios + FILE* stream = fopen("limite_barrios.csv", "r"); + + char line[1024]; + while (fgets(line, 1024, stream)) + { + char* tmp = strdup(line); + const char * barrio = pbm.getfield(tmp,1); + int barrio_int=atoi(barrio); + tmp = strdup(line); + const char * limite= pbm.getfield(tmp,2); + int i=0; + while (limite!=NULL) + { + pbm._limite_barrios[barrio_int-1][i]=atoi(limite)-1; + i++; + tmp = strdup(line); + limite=pbm.getfield(tmp,i+2); + } + free(tmp); + } + */ + cout<<pbm; + return is; + } + + //Funcion para leer el archivo CSV + const char* Problem::getfield(char* line, int num) + { + const char* tok; + for (tok = strtok(line, ","); + tok && *tok; + tok = strtok(NULL, ",\n")) + { + if (!--num) + return tok; + } + return NULL; + } + + int ** Problem::limite_barrios() const{ + return _limite_barrios; + } + + + bool Problem::operator== (const Problem& pbm) const + { + if (_dimension!=pbm.dimension()) return false; + return true; + } + + bool Problem::operator!= (const Problem& pbm) const + { + return !(*this == pbm); + } + + Direction Problem::direction() const + { + //return maximize; + return minimize; + } + + int Problem::dimension() const + { + return _dimension; + } + int Problem::cantEmpleados() const + { + return _cantEmpleados; + } + int Problem::cantDias() const + { + return _cantDias; + } + + int * Problem::tareasEsf() const + { + return _tareasEsf; + } + + int * Problem::tareasIndex() const + { + return _tareasIndex; + } + + Empleado *Problem::empleados() const + { + return _empleados; + } + + Problem::~Problem() + { + //Libero la memoria pedida para almacenar los limites de los barrios + for (int i=0;i<_dimension;i++) + delete [] _limite_barrios[i]; + delete [] _limite_barrios; + delete [] _empleados; + delete [] _tareasEsf; + } + + // Solution -------------------------------------------------------------- + + Solution::Solution (const Problem& pbm):_pbm(pbm),_var(pbm.dimension()) + {} + + const Problem& Solution::pbm() const + { + return _pbm; + } + + Solution::Solution(const Solution& sol):_pbm(sol.pbm()) + { + *this=sol; + } + + istream& operator>> (istream& is, Solution& sol) + { + for (int i=0;i<sol.pbm().dimension();i++) + is >> sol._var[i]; + return is; + } + + ostream& operator<< (ostream& os, const Solution& sol) + { + + //for (int i=0;i<sol.pbm().dimension();i++) + // os << " " << sol._var[i]; + stringstream ss; + + ofstream outfile("solution"); + + os << endl; + + for (int j = 0; j < sol.pbm().cantEmpleados(); j++) + { + bool found1 = false; + for (int i = 0; i < sol.pbm().dimension(); i++) + { + if (sol._var[i] == j) + { + if (!found1) + { + ss << "e" << j + 1; + found1 = true; + } + + ss << " t" << sol.pbm().tareasIndex()[i] + 1; + } + } + + if (found1) + { + ss << endl; + } + } + + outfile << ss.str(); + outfile.close(); + + os << ss.str(); + + return os; + } + + NetStream& operator << (NetStream& ns, const Solution& sol) + { + for (int i=0;i<sol._var.size();i++) + ns << sol._var[i]; + return ns; + } + + NetStream& operator >> (NetStream& ns, Solution& sol) + { + for (int i=0;i<sol._var.size();i++) + ns >> sol._var[i]; + return ns; + } + + Solution& Solution::operator= (const Solution &sol) + { + _var=sol._var; + return *this; + } + + bool Solution::operator== (const Solution& sol) const + { + if (sol.pbm() != _pbm) return false; + for(int i = 0; i < _var.size(); i++) + if(_var[i] != sol._var[i]) return false; + return true; + } + + bool Solution::operator!= (const Solution& sol) const + { + return !(*this == sol); + } + + void Solution::initialize() + { + //cout << _pbm.dimension(); + for (int i=0;i<_pbm.dimension();i++) + { + _var[i]=rand_int(0,_pbm.cantEmpleados() - 1); + //_var[i]=rand_int(0,3); + } + } + + double Solution::fitness () + { + + double fitness = 0.0; + double* horasTrabajados = new double[_pbm.cantEmpleados()]; + for (int q=0; q < _pbm.cantEmpleados(); q++) + { + horasTrabajados[q] = 0; + } + + for (int i=0;i< _pbm.dimension();i++) + { + Empleado tipo = _pbm.empleados()[_var[i]]; + double horasReq = ((double)_pbm.tareasEsf()[_pbm.tareasIndex()[i]]/(double)(0.5+tipo._habilidad)); + horasTrabajados[_var[i]] += horasReq; + + } + + + for (int j = 0; j < _pbm.cantEmpleados(); j++) + { + double diasTrabajadosTemp = (double)horasTrabajados[j] / (double)_pbm.empleados()[j]._horas; + fitness += (double)diasTrabajadosTemp * (double)_pbm.empleados()[j]._sueldo; + if (isnan(fitness)) + exit(0); + if (diasTrabajadosTemp > _pbm.cantDias()) + { + fitness += 100000; + } + } + + return fitness; + + } + + char *Solution::to_String() const + { + return (char *)_var.get_first(); + } + + void Solution::to_Solution(char *_string_) + { + int *ptr=(int *)_string_; + for (int i=0;i<_pbm.dimension();i++) + { + _var[i]=*ptr; + ptr++; + } + } + + unsigned int Solution::size() const + { + return (_pbm.dimension() * sizeof(int)); + } + + + int& Solution::var(const int index) + { + return _var[index]; + } + + + Rarray<int>& Solution::array_var() + { + return _var; + } + + Solution::~Solution() + {} + + // UserStatistics ------------------------------------------------------- + + UserStatistics::UserStatistics () + {} + + ostream& operator<< (ostream& os, const UserStatistics& userstat) + { + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF TRIALS " << endl; + os << "------------------------------------------------------------------" << endl; + + for (int i=0;i< userstat.result_trials.size();i++) + { + os << endl + << userstat.result_trials[i].trial + << "\t" << userstat.result_trials[i].best_cost_trial + << "\t\t" << userstat.result_trials[i].worst_cost_trial + << "\t\t\t" << userstat.result_trials[i].nb_evaluation_best_found_trial + << "\t\t\t" << userstat.result_trials[i].nb_iteration_best_found_trial + << "\t\t\t" << userstat.result_trials[i].time_best_found_trial + << "\t\t" << userstat.result_trials[i].time_spent_trial; + } + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + UserStatistics& UserStatistics::operator= (const UserStatistics& userstats) + { + result_trials=userstats.result_trials; + return (*this); + } + + void UserStatistics::update(const Solver& solver) + { + if( (solver.pid()!=0) || (solver.end_trial()!=true) + || ((solver.current_iteration()!=solver.setup().nb_evolution_steps()) + && !terminateQ(solver.pbm(),solver,solver.setup()))) + return; + + struct user_stat *new_stat; + + if ((new_stat=(struct user_stat *)malloc(sizeof(struct user_stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluation_best_found_trial = solver.evaluations_best_found_in_trial(); + new_stat->nb_iteration_best_found_trial = solver.iteration_best_found_in_trial(); + new_stat->worst_cost_trial = solver.worst_cost_trial(); + new_stat->best_cost_trial = solver.best_cost_trial(); + new_stat->time_best_found_trial = solver.time_best_found_trial(); + new_stat->time_spent_trial = solver.time_spent_trial(); + + result_trials.append(*new_stat); + } + + void UserStatistics::clear() + { + result_trials.remove(); + } + + UserStatistics::~UserStatistics() + { + result_trials.remove(); + } + +// Intra_operator -------------------------------------------------------------- + + Intra_Operator::Intra_Operator(const unsigned int _number_op):_number_operator(_number_op),probability(NULL) + {} + + unsigned int Intra_Operator::number_operator() const + { + return _number_operator; + } + + Intra_Operator *Intra_Operator::create(const unsigned int _number_op) + { + switch (_number_op) + { + case 0: return new Crossover;break; + case 1: return new Mutation();break; + } + } + + ostream& operator<< (ostream& os, const Intra_Operator& intra) + { + switch (intra.number_operator()) + { + case 0: os << (Crossover&)intra;break; + case 1: os << (Mutation&)intra;break; + } + return os; + } + + Intra_Operator::~Intra_Operator() + {} + +// Crossover:Intra_operator ------------------------------------------------------------- + + Crossover::Crossover():Intra_Operator(0) + { + probability = new float[1]; + } + + void Crossover::cross(Solution& sol1,Solution& sol2) const // dadas dos soluciones de la poblacion, las cruza + { + //Usamos cruzamiento de dos puntos (2PX) + int i=0; + Rarray<int> aux(sol1.pbm().dimension()); + aux=sol2.array_var(); + + /* + if (current_time_spent() < 1000000) + { + int limit=rand_int((0,sol1.pbm().dimension()-1)); + + for (i=0;i<limit;i++) + sol2.var(i)=sol1.var(i); + for (i=0;i<limit;i++) + sol1.var(i)=aux[i]; + } + if (current_time_spent() >= 1000000) + {*/ + int limit=rand_int((sol1.pbm().dimension()/2)+1,sol1.pbm().dimension()-1); + int limit2=rand_int(0,limit-1); + + for (i=0;i<limit2;i++) + sol2.var(i)=sol1.var(i); + for (i=0;i<limit2;i++) + sol1.var(i)=aux[i]; + for (i=limit;i<sol1.pbm().dimension();i++) + sol2.var(i)=sol1.var(i); + for (i=limit;i<sol1.pbm().dimension();i++) + sol1.var(i)=aux[i]; + //} + } + + void Crossover::execute(Rarray<Solution*>& sols) const + { + for (int i=0;i+1<sols.size();i=i+2) + if (rand01()<=probability[0]) cross(*sols[i],*sols[i+1]); + } + + ostream& operator<< (ostream& os, const Crossover& cross) + { + os << "Crossover." << " Probability: " + << cross.probability[0] + << endl; + return os; + } + + void Crossover::RefreshState(const StateCenter& _sc) const + { + _sc.set_contents_state_variable("_crossover_probability",(char *)probability,1,sizeof(float)); + } + + void Crossover::UpdateFromState(const StateCenter& _sc) + { + unsigned long nbytes,length; + _sc.get_contents_state_variable("_crossover_probability",(char *)probability,nbytes,length); + } + + void Crossover::setup(char line[MAX_BUFFER]) + { + int op; + sscanf(line," %d %f ",&op,&probability[0]); + assert(probability[0]>=0); + } + + Crossover::~Crossover() + { + delete [] probability; + } + + // Mutation: Sub_operator ------------------------------------------------------------- + + Mutation::Mutation():Intra_Operator(1) + { + probability = new float[2]; + } + + void Mutation::mutate(Solution& sol) const + { + for (int i=0;i<sol.pbm().dimension();i++) + { + if (rand01()<=probability[1]) + { + //La mutacion modifica un gen aleatoriamente con probabilidad uniforme en {0,3} + int temp = rand_int(0,sol.pbm().cantEmpleados() - 1); + sol.var(i)= temp; + //sol.var(i)=rand_int(0,3); + } + } + } + + void Mutation::execute(Rarray<Solution*>& sols) const + { + for (int i=0;i<sols.size();i++) + if(rand01() <= probability[0]) mutate(*sols[i]); + } + + ostream& operator<< (ostream& os, const Mutation& mutation) + { + os << "Mutation." << " Probability: " << mutation.probability[0] + << " Probability1: " << mutation.probability[1] + << endl; + return os; + } + + void Mutation::setup(char line[MAX_BUFFER]) + { + int op; + sscanf(line," %d %f %f ",&op,&probability[0],&probability[1]); + assert(probability[0]>=0); + assert(probability[1]>=0); + } + + void Mutation::RefreshState(const StateCenter& _sc) const + { + _sc.set_contents_state_variable("_mutation_probability",(char *)probability,2,sizeof(probability)); + } + + void Mutation::UpdateFromState(const StateCenter& _sc) + { + unsigned long nbytes,length; + _sc.get_contents_state_variable("_mutation_probability",(char *)probability,nbytes,length); + } + + Mutation::~Mutation() + { + delete [] probability; + } + +// StopCondition_1 ------------------------------------------------------------------------------------- + + StopCondition_1::StopCondition_1():StopCondition() + {} + + bool StopCondition_1::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + bool fin=(int) (solver.current_time_spent() - solver.time_best_found_trial()) > 20000000; + //Condicion de parada. Si el fitness es 0 terminamos la ejecucion. + //bool fin=(int)solver.best_cost_trial() == 0; + //cout << pbm.cantEmpleados(); + /*if (fin){ + //Escribo el resultado en el archivo de salida + FILE * pFile; + pFile = fopen ("asignacion_colores.csv","w"); + for (int i=0;i<pbm.dimension();i++){ + fprintf (pFile, "%d,%d\n",i+1,solver.best_solution_trial().var(i)); + } + fclose (pFile); + }*/ + //return (fin); + return fin; + + } + + StopCondition_1::~StopCondition_1() + {} + + //------------------------------------------------------------------------ + // Specific methods ------------------------------------------------------ + //------------------------------------------------------------------------ + + bool terminateQ (const Problem& pbm, const Solver& solver, + const SetUpParams& setup) + { + StopCondition_1 stop; + return stop.EvaluateCondition(pbm,solver,setup); + } +} +#endif + diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.req.o b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.req.o new file mode 100644 index 0000000000000000000000000000000000000000..b38ae8dbb12876fd40eff199783aea8c7db92186 Binary files /dev/null and b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGA.req.o differ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGAstructures.hh b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGAstructures.hh new file mode 100644 index 0000000000000000000000000000000000000000..d542639f222df0d80bef4ac47ef28b5d9c878b26 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/newGAstructures.hh @@ -0,0 +1,60 @@ +#ifndef INC_newGA_mallba_hh +#define INC_newGA_mallba_hh + + +#include <iostream> +#include <fstream> +#include <math.h> +#include <limits.h> +#include <float.h> +#include <Rlist.h> +#include <Rarray.h> +#include <Messages.h> +#include <mallba.hh> +#include <States.hh> +#include <random.hh> +#include <time.hh> +#include <netstream.hh> +#include <assert.h> + +using namespace std; + +#ifndef _INDIVIDUAL_ +#define _INDIVIDUAL_ + +struct individual // index of a individual in the population and its fitness +{ + int index; + double fitness; + double sel_parameter; + bool change; +}; +struct Empleado // index of a individual in the population and its fitness +{ + int _horas; + float _habilidad; + double _sueldo; +}; + + +/*int lessF(const struct individual &i1,const struct individual &i2) +{ + return i1.fitness < i2.fitness; +} + +int lessS(const struct individual &i1,const struct individual &i2) +{ + return i1.sel_parameter < i2.sel_parameter; +} + +int greaterF(const struct individual &i1,const struct individual &i2) +{ + return i1.fitness > i2.fitness; +} + +int greaterS(const struct individual &i1,const struct individual &i2) +{ + return i1.sel_parameter > i2.sel_parameter; +}*/ +#endif +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/res/datos_cantidad_empleados b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/res/datos_cantidad_empleados new file mode 100644 index 0000000000000000000000000000000000000000..7813681f5b41c028345ca62a2be376bae70b7f61 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/res/datos_cantidad_empleados @@ -0,0 +1 @@ +5 \ No newline at end of file diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/res/datos_cantidad_tareas b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/res/datos_cantidad_tareas new file mode 100644 index 0000000000000000000000000000000000000000..301160a93062df23030a69f4b5e4d9bf71866ee9 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/res/datos_cantidad_tareas @@ -0,0 +1 @@ +8 \ No newline at end of file diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/res/datos_empleados b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/res/datos_empleados new file mode 100644 index 0000000000000000000000000000000000000000..f7cc5e5ffd3d2a61ae5180d3f7da918b35f73197 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/res/datos_empleados @@ -0,0 +1,4 @@ +e1 e2 e3 e4 e5 +4 5 5 3 3 +0.05 0.20 0.30 0.95 0.50 +120 200 210 230 180 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/res/datos_tareas b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/res/datos_tareas new file mode 100644 index 0000000000000000000000000000000000000000..589272f5c15492f95741ff1b7c8bd9669e9d4993 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/res/datos_tareas @@ -0,0 +1,3 @@ +20 +t1 t2 t3 t4 t5 t6 t7 t8 +16 28 11 51 2 23 43 15 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/res/empty.txt b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/res/empty.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/res/sol.txt b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/res/sol.txt new file mode 100644 index 0000000000000000000000000000000000000000..94d8af392a9a33d04b7d961d7eabcdded57dc43a --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/res/sol.txt @@ -0,0 +1,16 @@ + +--------------------------------------------------------------- + STATISTICS OF TRIALS +------------------------------------------------------------------ + +1 10029.7 210883 1060 10 1591 14184 +2 10010.4 210882 5560 55 6233 12361 +3 10010.4 210656 4160 41 8672 14731 +4 10009.9 210921 160 1 106 9399 +5 10010.4 210807 4660 46 4349 9349 +6 10010.4 210921 760 7 657 9224 +7 10016.5 210990 3060 30 5449 11825 +8 10015.4 210452 4960 49 5341 10215 +9 10035.1 210876 5960 59 5591 9491 +10 10017.7 210873 360 3 295 9422 +------------------------------------------------------------------ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/solution b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/solution new file mode 100644 index 0000000000000000000000000000000000000000..534d0b7a1dbc05e068cc2ef7d4af1f20ef8ed28c --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/solution @@ -0,0 +1,3 @@ +e1 t3 t1 +e3 t5 t6 t4 +e4 t8 t2 t7 diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/verificador.py b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/verificador.py new file mode 100644 index 0000000000000000000000000000000000000000..0924a327b9ff14cc512ce6195fef79c66afcd093 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/GA/verificador.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import sys +import random +import math + +try: + #Sanity check + if (len(sys.argv)<4): + print "Ejecutar con la siguiente linea: ./validador <ruta_tareas> <ruta_empleados> <ruta_solucion>" + sys.exit(1) + + ruta_tareas=sys.argv[1] + ruta_empleados=sys.argv[2] + ruta_solucion=sys.argv[3] + habilidad_empleados=[] + sueldo_diario_empleado=[] + dedicacion_diaria_diponible_empleado=[] + esfuerzo_requerido_tarea=[] + nombres_tareas=[] + nombre_empleados=[] + costo_proyecto=0 + tiempo_solucion_proyecto=0 + + # se sabe que son 3 lineas + archivo_tareas=open(ruta_tareas) + lineasTareas=archivo_tareas.readlines() + deadLine=lineasTareas[0] + nombres_tareas=lineasTareas[1].strip().split(" ") + esfuerzo_requerido_tarea=lineasTareas[2].strip().split(" ") + + # se sabe que son 4 lineas + archivo_empleados=open(ruta_empleados) + lineasEmpleados=archivo_empleados.readlines() + nombre_empleados=lineasEmpleados[0].strip().split(" ") + dedicacion_diaria_diponible_empleado=lineasEmpleados[1].strip().split(" ") + habilidad_empleados=lineasEmpleados[2].strip().split(" ") + sueldo_diario_empleado=lineasEmpleados[3].strip().split(" ") + + # se convierten a entero + dedicacion_diaria_diponible_empleado = map(int, dedicacion_diaria_diponible_empleado) + sueldo_diario_empleado = map(int, sueldo_diario_empleado) + deadLine=int(deadLine) + esfuerzo_requerido_tarea = map(int, esfuerzo_requerido_tarea) + + # se convierte a float + habilidad_empleados = map(float, habilidad_empleados) + + # se levanta la solucion del archivo + matriz_solucion=[] + + archivo_solucion=open(ruta_solucion) + + solucion_empleados_tareas=[] + solucion_empleados=[] + solucion_tareas=[] + + for line in archivo_solucion.readlines(): + empleados_tareas=line.strip().split(" ") + if( not (empleados_tareas[0] in nombre_empleados)): + print "No existe en la instancia el empleado: " + empleados_tareas[0] + sys.exit(1) + solucion_empleados.append(empleados_tareas[0]) + for i in range(1,len(empleados_tareas)): + if( not (empleados_tareas[i] in nombres_tareas)): + print "No existe en la instancia la terea: " + empleados_tareas[i] + sys.exit(1) + solucion_tareas.append(empleados_tareas[i]) + + + for i in range(0,len(solucion_empleados)): + for j in range(i+1,len(solucion_empleados)): + if(solucion_empleados[i]==solucion_empleados[j]): + print "Empleado repetido: " + solucion_empleados[i] + sys.exit(1) + + for i in range(0,len(solucion_tareas)): + for j in range(i+1,len(solucion_tareas)): + if(solucion_tareas[i]==solucion_tareas[j]): + print "Tarea asignada más de una vez: " + solucion_tareas[i] + sys.exit(1) + + + # todas las tareas asignadas + if(len(solucion_tareas)!=len(nombres_tareas)): + print "La cantidad de tareas asignadas es distinta a la cantidad de tareas de la instancia." + sys.exit(1) + + for i in range(0,len(nombres_tareas)): + if( not (nombres_tareas[i] in solucion_tareas)): + print "Tarea no asignada " + nombres_tareas[i] + sys.exit(1) + + costo_total=0 + archivo_solucion=open(ruta_solucion) + maximo_tiempo=0 + tiempo_en_dias=0 + # se hacen los calculos con la informacion en los archivos + for line in archivo_solucion.readlines(): + empleados_tareas=line.strip().split(" ") + indice_empleado = nombre_empleados.index(empleados_tareas[0]) + tiempo_en_horas=0 + for i in range(1,len(empleados_tareas)): + indice_tarea = nombres_tareas.index(empleados_tareas[i]) + tiempo_en_horas=tiempo_en_horas+(esfuerzo_requerido_tarea[indice_tarea] / (0.5 + habilidad_empleados[indice_empleado])) + tiempo_en_dias= int(math.ceil(tiempo_en_horas/dedicacion_diaria_diponible_empleado[indice_empleado])) + costo_total=costo_total+sueldo_diario_empleado[indice_empleado]*tiempo_en_dias + if(tiempo_en_dias>maximo_tiempo): + maximo_tiempo=tiempo_en_dias + + if(maximo_tiempo<=deadLine): + # todo OK! + print costo_total,maximo_tiempo + else: + print "No cumple con el tiempo máximo de finalización ({0} > {1}).".format(maximo_tiempo, deadLine) + sys.exit(1) + +except IOError as error: + print error diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/Makefile b/ProyectoFinal/AlgoritmoGenetico/malva/rep/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..2b7ed1503e73358a5787a7ed1eabcc8c12de78fd --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/Makefile @@ -0,0 +1,6 @@ +all: + (cd CHC ; make) + (cd GA ; make) +clean: + (cd CHC ; make clean) + (cd GA ; make clean) \ No newline at end of file diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/Config.cfg b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/Config.cfg new file mode 100644 index 0000000000000000000000000000000000000000..c515435da2092c6d52b8ecdc12a01334e495d199 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/Config.cfg @@ -0,0 +1,3 @@ +SA.cfg +Instance Problem Path +Result File Path diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/MainLan.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/MainLan.cc new file mode 100644 index 0000000000000000000000000000000000000000..8949422e10f93211d953aba1308c203d13f30f0a --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/MainLan.cc @@ -0,0 +1,53 @@ +#include "SA.hh" +#include <iostream.h> +#include <fstream.h> + +int main (int argc, char** argv) +{ + using skeleton SA; + char path[MAX_BUFFER]; + int len; + int longitud; + + system("clear"); + + get_path(argv[0],path); + len = strlen(path); + longitud = MAX_BUFFER - len; + + strcat(path,"Config.cfg"); + ifstream f(path); + if(!f) show_message(10); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f1(path); + if(!f1) show_message(11); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f2(path); + if(!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + SetUpParams cfg; + f1 >> cfg; + + + Solver_Lan solver(pbm,cfg,argc,argv); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solucion: " << solver.global_best_solution() << " Fitness: " << solver.global_best_solution().fitness(); + + f.getline(&(path[len]),longitud,'\n'); + ofstream fexit(path); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + cout << endl << endl << " :( ---------------------- THE END --------------- :) " << endl; + } + return(0); +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/MainSeq.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/MainSeq.cc new file mode 100644 index 0000000000000000000000000000000000000000..41d8a720793c0d10b14e1d5dfa05b7f11e9c4dda --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/MainSeq.cc @@ -0,0 +1,42 @@ +#include "SA.hh" +#include <iostream.h> +#include <fstream.h> + +int main (int argc, char** argv) +{ + using skeleton SA; + + system("clear"); + + if(argc < 4) + show_message(1); + + ifstream f1(argv[1]); + if (!f1) show_message(11); + + ifstream f2(argv[2]); + if (!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + SetUpParams cfg; + f1 >> cfg; + + Solver_Seq solver(pbm,cfg); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << solver.global_best_solution() + << " Fitness: " << solver.global_best_solution().fitness() << endl; + cout << "\n\n :( ---------------------- THE END --------------- :) "; + + ofstream fexit(argv[3]); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + } + return(0); +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/MainWan.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/MainWan.cc new file mode 100644 index 0000000000000000000000000000000000000000..8949422e10f93211d953aba1308c203d13f30f0a --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/MainWan.cc @@ -0,0 +1,53 @@ +#include "SA.hh" +#include <iostream.h> +#include <fstream.h> + +int main (int argc, char** argv) +{ + using skeleton SA; + char path[MAX_BUFFER]; + int len; + int longitud; + + system("clear"); + + get_path(argv[0],path); + len = strlen(path); + longitud = MAX_BUFFER - len; + + strcat(path,"Config.cfg"); + ifstream f(path); + if(!f) show_message(10); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f1(path); + if(!f1) show_message(11); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f2(path); + if(!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + SetUpParams cfg; + f1 >> cfg; + + + Solver_Lan solver(pbm,cfg,argc,argv); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solucion: " << solver.global_best_solution() << " Fitness: " << solver.global_best_solution().fitness(); + + f.getline(&(path[len]),longitud,'\n'); + ofstream fexit(path); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + cout << endl << endl << " :( ---------------------- THE END --------------- :) " << endl; + } + return(0); +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/Makefile b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..43b74faaa879f5b52178056e8783eeeca26c3c39 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/Makefile @@ -0,0 +1,22 @@ +include ../../../environment + +all: MainSeq MainLan MainWan + +clean: + rm -f MainLan MainSeq MainWan *.o *% *~ + +MainLan: SA.req.o SA.pro.o StopCondition.o MainLan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainWan: SA.req.o SA.pro.o StopCondition.o MainWan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainSeq: SA.req.o SA.pro.o StopCondition.o MainSeq.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +LAN: + $(RUN) -v -p4pg pgfileLan MainLan +WAN: + $(RUN) -v -p4pg pgfileWan MainWan +SEQ: + ./MainSeq SA.cfg ../../../ProblemInstances/instance.txt res/res.txt diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/SA.cfg b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/SA.cfg new file mode 100644 index 0000000000000000000000000000000000000000..290f7e98c2c700b4ec7b5587eb489ad5c2f27704 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/SA.cfg @@ -0,0 +1,9 @@ + // number of independent runs + // number of evaluations + // Markov-Chain Length (temperature is updated in every number of evaluations) + // temperature Decay + // display state ? +LAN-configuration + // the global state is updated in this number of evaluations + // 0: asynchronized mode // 1: synchronized mode + // interval of iterations to cooperate (if 0 no cooperation) diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/SA.hh b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/SA.hh new file mode 100644 index 0000000000000000000000000000000000000000..9c7901a634f3ca445bf1fc7a268360c776baae5f --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/SA.hh @@ -0,0 +1,478 @@ +#ifndef INC_SA +#define INC_SA + +#include "Mallba/mallba.hh" +#include "Mallba/States.hh" +#include "Mallba/Rarray.h" +#include "Mallba/time.hh" +#include "Mallba/netstream.hh" +#include <math.h> +#include <string.h> + +skeleton SA +{ + + provides class SetUpParams; + provides class Statistics; + provides class Move; + provides class StopCondition; + provides class Solver; + provides class Solver_Seq; + provides class Solver_Lan; + provides class Solver_Wan; + + requires class Problem; + requires class Solution; + requires class StopCondition_1; + requires class StopCondition_2; + requires class StopCondition_3; + requires class DefaultMove; + requires class UserStatistics; + requires bool TerminateQ (const Problem& pbm, const Solver& solver, const SetUpParams& setup); + +// Problem ---------------------------------------------------------------------------- + + requires class Problem + { + public: + Problem (); + ~Problem (); + + friend ostream& operator<< (ostream& os, const Problem& pbm); + friend istream& operator>> (istream& is, Problem& pbm); + + Problem& operator= (const Problem& pbm); + bool operator== (const Problem& pbm) const; + bool operator!= (const Problem& pbm) const; + + Direction direction () const; + + }; + +//Solution ---------------------------------------------------------------------------- + + requires class Solution + { + public: + Solution (const Problem& pbm); + Solution (const Solution& sol); + ~Solution(); + + friend ostream& operator<< (ostream& os, const Solution& sol); + friend istream& operator>> (istream& is, Solution& sol); + friend NetStream& operator << (NetStream& ns, const Solution& sol); + friend NetStream& operator >> (NetStream& ns, Solution& sol); + + const Problem& pbm() const; + + Solution& operator= (const Solution& sol); + bool operator== (const Solution& sol) const; + bool operator!= (const Solution& sol) const; + + char *to_String() const; + void to_Solution(char *_vertex_); + unsigned int size() const; + + void initialize(); + double fitness () const; + + private: + const Problem& _pbm; + }; + +// UserStatistics ---------------------------------------------------------------------------- + + requires class UserStatistics + { + private: + struct user_stat + { + unsigned int trial; + double initial_temperature; + double temperature_best_found_trial; + unsigned long nb_evaluation_best_found_trial; + double best_cost_trial; + float time_best_found_trial; + float time_spent_trial; + }; + + Rlist<struct user_stat> result_trials; + + public: + UserStatistics (); + ~UserStatistics(); + + friend ostream& operator<< (ostream& os, const UserStatistics& usertats); + + UserStatistics& operator= (const UserStatistics& userstats); + void update(const Solver& solver); + void clear(); + }; + +// Move ---------------------------------------------------------------------------------- + + provides class Move + { + public: + Move() {} + virtual ~Move() {} + + virtual void Apply(Solution& sol) const = 0; + }; + +// DefaultMove ---------------------------------------------------------------------------------- + + requires class DefaultMove: public Move + { + public: + DefaultMove(); + ~DefaultMove(); + + void Apply(Solution& sol) const; + }; + +// SetUpParams ------------------------------------------------------------------------------- + + provides class SetUpParams + { + private: + unsigned int _independent_runs; + unsigned long _max_evaluations; + unsigned int _MarkovChain_length; + double _temperature_decay; + bool _display_state; + + // for LAN execution configuration + unsigned long _refresh_global_state; + bool _synchronized; + unsigned int _cooperation; + + public: + SetUpParams (); + + friend ostream& operator<< (ostream& os, const SetUpParams& setup); + friend istream& operator>> (istream& is, SetUpParams& setup); + + const unsigned int independent_runs() const; + const unsigned long max_evaluations() const; + const unsigned int MarkovChain_length() const; + const double temperature_decay() const; + const bool display_state() const; + const unsigned long refresh_global_state() const; + const bool synchronized() const; + const unsigned int cooperation() const; + + void independent_runs(const unsigned int val); + void max_evaluations(const unsigned long val); + void MarkovChain_length(const unsigned int val); + void temperature_decay(const double val); + void display_state(const bool val); + void refresh_global_state(const unsigned long val); + void synchronized(const bool val); + void cooperation(const unsigned int val); + + ~SetUpParams(); + }; + +// Statistics --------------------------------------------------------------------------------- + + provides class Statistics + { + private: + struct stat + { + unsigned int trial; + unsigned long nb_evaluations; + double best_cost; + double current_cost; + }; + + Rlist<struct stat> stats_data; + + public: + Statistics(); + + friend ostream& operator<< (ostream& os, const Statistics& stats); + + Statistics& operator= (const Statistics& stats); + void update(const Solver& solver); + void clear(); + + ~Statistics(); + }; + +// Solver --------------------------------------------------------------------------------- + + provides class Solver + { + protected: + const Problem& problem; + const SetUpParams& params; + UserStatistics _userstat; + Statistics _stat; + Move* move; + Solution current; + double curfit; + Solution tentative; + double currentTemperature; + unsigned int k; // to control temperature update. + StateCenter _sc; + + float total_time_spent; + float time_spent_in_trial; + float start_trial; + float start_global; + + bool _end_trial; + + State_Vble _current_trial; + State_Vble _current_iteration; + State_Vble _current_best_solution; + State_Vble _current_best_cost; + State_Vble _current_solution; + State_Vble _current_cost; + + State_Vble _current_time_spent; + State_Vble _initial_temperature_trial; + State_Vble _time_best_found_trial; + State_Vble _iteration_best_found_trial; + State_Vble _temperature_best_found_trial; + State_Vble _time_spent_trial; + + State_Vble _trial_best_found; + State_Vble _iteration_best_found; + State_Vble _global_best_solution; + State_Vble _global_best_cost; + State_Vble _time_best_found; + + State_Vble _temperature; + State_Vble _display_state; + + const Direction _direction; + + bool AcceptQ(double tent, double cur, double temperature); + double Set_Initial_Temperature(const Problem& pbm); + void KeepHistory(const Solution& sol, const double curfit,const float time_spent_trial,const float total_time_spent); + + double UpdateT(double temp, int K); + + public: + // Constructor - Destructor ------------------------- + + Solver (const Problem& pbm, const SetUpParams& setup); + virtual ~Solver (); + virtual int pid() const; + bool end_trial() const; + + // Execution methods -------------------------------- + + // Full execution + virtual void run () =0; + virtual void run (unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol, unsigned long int nb_evaluations) =0; + + virtual void run (const double initialTemperature) =0; + virtual void run (const Solution& sol,const double initialTemperature) =0; + virtual void run (const double initialTemperature, unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations) =0; + + // Partial execution + virtual void StartUp () =0; + virtual void StartUp (const Solution& sol) =0; + virtual void StartUp (const double initialTemperature) =0; + virtual void StartUp (const Solution& sol, const double initialTemperature) =0; + virtual void DoStep () =0; + + // Statistics handling ------------------------------ + + const Statistics& statistics() const; + const UserStatistics& userstatistics () const; + const SetUpParams& setup() const; + const Problem& pbm() const; + + // State handling ----------------------------------- + + void RefreshState(); + void UpdateFromState(); + StateCenter* GetState(); + + unsigned int current_trial() const; + unsigned long current_iteration() const; + Solution current_best_solution() const; + Solution current_solution() const; + double current_best_cost() const; + double current_cost() const; + float current_time_spent() const; + float time_best_found_trial() const; + double initial_temperature_trial() const; + unsigned int iteration_best_found_trial() const; + double temperature_best_found_trial() const; + float time_spent_trial() const; + unsigned int trial_best_found() const; + unsigned int iteration_best_found() const; + Solution global_best_solution() const; + double global_best_cost() const; + float time_best_found() const; + double temperature() const; + int display_state() const; + + void current_trial(const unsigned int value); + void current_iteration(const unsigned long value); + void current_best_solution(const Solution& sol); + void current_best_cost(const double value); + void current_solution(const Solution& sol); + void current_cost(const double value); + void current_time_spent(const float value); + void time_best_found_trial(const float value); + void initial_temperature_trial(const double temperature); + void iteration_best_found_trial(const unsigned int value); + void temperature_best_found_trial(const double value); + void time_spent_trial(const float value); + void trial_best_found(const unsigned int value); + void iteration_best_found(const unsigned int value); + void global_best_solution(const Solution& sol); + void global_best_cost(const double value); + void time_best_found(const float value); + void temperature(const double value); + void display_state(const int value); + void show_state() const; + + // State handling ----------------------------------- + void SetMove(Move* mov); + }; + + provides class Solver_Seq: public Solver + { + public: + // Constructor - Destructor ------------------------- + + Solver_Seq ( const Problem& pbm, const SetUpParams& setup); + virtual ~Solver_Seq (); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + }; + + provides class Solver_Lan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + + public: + Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Lan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + + provides class Solver_Wan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + + public: + Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Wan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + +}; + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/SA.req.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/SA.req.cc new file mode 100644 index 0000000000000000000000000000000000000000..65328019b498310ed56b81f2ec58559fe54aa39f --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/SA.req.cc @@ -0,0 +1,222 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** User-required classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** *** +*** *** +************************************************/ + +#include <iostream.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "StopCondition.hh" + +skeleton SA { + + +// Problem --------------------------------------------------------------- + Problem::Problem () + {} + + ostream& operator<< (ostream& os, const Problem& pbm) + { + return os; + } + + istream& operator>> (istream& is, Problem& pbm) + { + return is; + } + + Problem& Problem::operator= (const Problem& pbm) + { + return *this; + } + + bool Problem::operator== (const Problem& pbm) const + { + return true; + } + + bool Problem::operator!= (const Problem& pbm) const + { + return !(*this == pbm); + } + + Direction Problem::direction() const + { + //return maximize; + return minimize; + } + + Problem::~Problem() + {} + +// Solution -------------------------------------------------------------- + Solution::Solution (const Problem& pbm):_pbm(pbm) + {} + + const Problem& Solution::pbm() const + { + return _pbm; + } + + Solution::Solution(const Solution& sol):_pbm(sol.pbm()) + { + *this=sol; + } + + istream& operator>> (istream& is, Solution& sol) + { + return is; + } + + ostream& operator<< (ostream& os, const Solution& sol) + { + return os; + } + + NetStream& operator << (NetStream& ns, const Solution& sol) + { + return ns; + } + + NetStream& operator >> (NetStream& ns, Solution& sol) + { + return ns; + } + + Solution& Solution::operator= (const Solution &sol) + { + return *this; + } + + bool Solution::operator== (const Solution& sol) const + { + if (sol.pbm() != _pbm) return false; + return true; + } + + bool Solution::operator!= (const Solution& sol) const + { + return !(*this == sol); + } + + void Solution::initialize() + {} + + double Solution::fitness () const + { + return 0.0; + } + + char *Solution::to_String() const + { + return NULL; + } + + void Solution::to_Solution(char *_routes_) + {} + + unsigned int Solution::size() const + { + return 0; + } + + Solution::~Solution() + {} + +// UserStatistics ------------------------------------------------------- + + UserStatistics::UserStatistics () + {} + + ostream& operator<< (ostream& os, const UserStatistics& userstat) + { + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF TRIALS " << endl; + os << "------------------------------------------------------------------" << endl; + + for (int i=0;i< userstat.result_trials.size();i++) + { + os << endl + << "\t" << userstat.result_trials[i].trial + << "\t" << userstat.result_trials[i].best_cost_trial + << "\t\t" << userstat.result_trials[i].nb_evaluation_best_found_trial + << "\t\t" << userstat.result_trials[i].initial_temperature + << "\t\t" << userstat.result_trials[i].temperature_best_found_trial + << "\t\t" << userstat.result_trials[i].time_best_found_trial + << "\t\t" << userstat.result_trials[i].time_spent_trial; + } + + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + + UserStatistics& UserStatistics::operator= (const UserStatistics& userstats) + { + result_trials=userstats.result_trials; + return (*this); + } + + + void UserStatistics::update(const Solver& solver) + { + if ((solver.pid()!=0) || (solver.end_trial()!=true) + || ((solver.current_iteration()!=solver.setup().max_evaluations()) + && !TerminateQ(solver.pbm(),solver,solver.setup()))) + return; + + struct user_stat *new_stat; + if ((new_stat=(struct user_stat *)malloc(sizeof(struct user_stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluation_best_found_trial= solver.iteration_best_found_trial(); + new_stat->initial_temperature=solver.initial_temperature_trial(); + new_stat->temperature_best_found_trial=solver.temperature_best_found_trial(); + new_stat->best_cost_trial = solver.current_best_cost(); + new_stat->time_best_found_trial= solver.time_best_found_trial(); + new_stat->time_spent_trial = solver.time_spent_trial(); + result_trials.append(*new_stat); + } + + void UserStatistics::clear() + { + result_trials.remove(); + } + + UserStatistics::~UserStatistics() + { + result_trials.remove(); + } + +// DefaultMove ------------------------------------------------------- + + + DefaultMove::DefaultMove() + {} + + DefaultMove::~DefaultMove() + {} + + void DefaultMove::Apply (Solution& sol) const + { + // Body of operator + } + + //------------------------------------------------------------------------ + // Specific methods ------------------------------------------------------ + //------------------------------------------------------------------------ + + bool TerminateQ (const Problem& pbm, const Solver& solver, + const SetUpParams& setup) + { + + StopCondition_1 stop; + return stop.EvaluateCondition(pbm,solver,setup); + } +} + + diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/StopCondition.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/StopCondition.cc new file mode 100644 index 0000000000000000000000000000000000000000..79e3342a1e450975eede655a28080d3ec9d92f74 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/StopCondition.cc @@ -0,0 +1,52 @@ +#include "StopCondition.hh" +skeleton SA +{ + +// StopCondition ------------------------------------------------------------------------------------- + + StopCondition::StopCondition() + {} + + StopCondition::~StopCondition() + {} + +// StopCondition_1 ------------------------------------------------------------------------------------- + + StopCondition_1::StopCondition_1():StopCondition() + {} + + bool StopCondition_1::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return false; + } + + StopCondition_1::~StopCondition_1() + {} + +// StopCondition_2 ------------------------------------------------------------------------------------- + + StopCondition_2::StopCondition_2():StopCondition() + {} + + bool StopCondition_2::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return (solver.global_best_cost()>8.5); + } + + StopCondition_2::~StopCondition_2() + {} + +// StopCondition_3 ------------------------------------------------------------------------------------- + + StopCondition_3::StopCondition_3():StopCondition() + {} + + bool StopCondition_3::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return ((solver.current_trial()==setup.independent_runs()) && (solver.current_iteration()==setup.max_evaluations())); + } + + StopCondition_3::~StopCondition_3() + {} + +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/StopCondition.hh b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/StopCondition.hh new file mode 100644 index 0000000000000000000000000000000000000000..04ef770d9cac5bb9ef69aae7d085e3ae2166e187 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/StopCondition.hh @@ -0,0 +1,41 @@ +#ifndef stop_condition +#define stop_condition + +#include "SA.hh" +skeleton SA +{ + + provides class StopCondition + { + public: + StopCondition(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup)=0; + ~StopCondition(); + }; + + requires class StopCondition_1 : public StopCondition + { + public: + StopCondition_1(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_1(); + }; + + requires class StopCondition_2 : public StopCondition + { + public: + StopCondition_2(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_2(); + }; + + requires class StopCondition_3 : public StopCondition + { + public: + StopCondition_3(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_3(); + }; +} + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/AdjKeys.cpp b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/AdjKeys.cpp new file mode 100644 index 0000000000000000000000000000000000000000..64d179a34f0fc3f11f987bb86813c46090fdeb4a --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/AdjKeys.cpp @@ -0,0 +1,286 @@ +/*********************************************************************** + * File: AdjKeys.cpp + * Author: Lishan Li + * Date: May, 2003 + * + * Description: It provides implementation of all the functions declared + * in the header file AdjKeys.h. + ***********************************************************************/ + +#include "AdjKeys.h" + +/********************************************* + * Purpose: allocate memory and initialization + *********************************************/ + +AdjKeys::AdjKeys(int * parent1, int * parent2, int nbOfFrag):nof(nbOfFrag) +{ + offSpring = new int[nof]; + share = new bool[nof]; + remaining = new int[nof]; + + aKeys = new int *[nof]; + for(int i = 0; i < nof; i++) + { + aKeys[i] = new int[4]; // [0] and [1] for parent1; [2] and [3] for parent2 + for(int j = 0; j < 4; j++) + aKeys[i][j] = -1; // initialize to -1 + } + + for(int k = 0; k < nof; k++) + { + offSpring[k] = -1; + share[k] = false; + remaining[k] = 0; + } + startKey = parent1[0]; // start key point to the first fragment of parent1 + makeAdjKeysTable(parent1, parent2); +} + +/************************* + * Purpose: release memory + *************************/ + +AdjKeys::~AdjKeys() +{ + for(int i = 0; i < nof; i++) + delete [] aKeys[i]; + + delete [] aKeys; + delete [] remaining; + delete [] share; + delete [] offSpring; +} + +/**************************************************** + * Purpose: create an adjacency table for two parents + ****************************************************/ + +void AdjKeys::makeAdjKeysTable(int * parent1, int * parent2) +{ + initAdjacentcy(parent1, 1); + initAdjacentcy(parent2, 2); + + setSharing(); +// printInfo(); +} + +/******************************************* + * Purpose: initialize a parent's adjacency + *******************************************/ + +void AdjKeys::initAdjacentcy(int * parent, int pid) +{ + int indStart; + if(pid == 1) + indStart = 0; // because aKeys[][0] and aKeys[][1] for parent1 + else + indStart = 2; // because aKeys[][2] and aKeys[][3] for parent2 + + int m = 0; + for(int i = 0; i < nof; i++) + { + int key = parent[m]; + + if(m == 0) // deal with the first fragment + { + aKeys[key][indStart] = parent[m+1]; + incrementRemaining(key); + } + else if(m == nof-1) // deal with the last fragment + { + aKeys[key][indStart] = parent[m-1]; + incrementRemaining(key); + } + else // deal with the middle fragments + { + aKeys[key][indStart] = parent[m-1]; + incrementRemaining(key); + aKeys[key][indStart+1] = parent[m+1]; + incrementRemaining(key); + } + m++; + } +} + +/*********************************************** + * Purpose: return number of remaining fragments + ***********************************************/ + +int AdjKeys::getRemaining(int id) +{ + return remaining[id]; +} + +/************************************************** + * Purpose: decrement number of remaining fragments + **************************************************/ + +void AdjKeys::decrementRemaining(int id) +{ + remaining[id]--; +} + +/************************************************** + * Purpose: increment number of remaining fragments + **************************************************/ + +void AdjKeys::incrementRemaining(int id) +{ + remaining[id]++; +} + +/**************************************************** + * Purpose: set the share to be true if the fragments + * are ajdacent to both parents. + ****************************************************/ + +void AdjKeys::setSharing() +{ + for(int i = 0; i < nof; i++) + { + if(aKeys[i][0] == aKeys[i][2] || aKeys[i][0] == aKeys[i][3]) + { + share[i] = true; + remaining[i]--; + } + if(aKeys[i][1] != -1) + { + if(aKeys[i][1] == aKeys[i][2] || aKeys[i][1] == aKeys[i][3]) + { + share[i] = true; + remaining[i]--; + } + } + } +} + +/************************************ + * Purpose: check the sharing status + ************************************/ + +bool AdjKeys::hasSharing(int id) +{ + return share[id]; +} + +/***************************************************** + * Purpose: print the detail information in this class + *****************************************************/ + +void AdjKeys::printInfo() +{ + for(int i = 0; i < nof; i++) + { + cout << aKeys[i][0] << ", " << aKeys[i][1] << ", " + << aKeys[i][2] << ", " << aKeys[i][3] << "\t"; + + cout << "sharing = " << share[i] << ", " << " remain = " << remaining[i] << endl; + } +} + +/***************************************************************** + * Purpose: reset the adjacent key to be -1 if it is already taken + *****************************************************************/ + +void AdjKeys::deleteTakenKey(int takenKey) +{ + int p, q; + for(p = 0; p < nof; p++) + { + if(takenKey != p) + { + bool exist = false; + for(q = 0; q < 4; q++) + { + if(aKeys[p][q] != -1 && aKeys[p][q] == takenKey) + { + aKeys[p][q] = -1; + exist = true; + } + } + if(exist) + decrementRemaining(p); + } + } +} + +/*********************************************************** + * Purpose: performs the actual edge-recombination operation + ***********************************************************/ + +void AdjKeys::recombine() +{ + int currKey = startKey; + offSpring[0] = currKey; + deleteTakenKey(currKey); + + int i; + // produce offspring based on adjacent keys + + for(i = 1; i < nof; i++) + { + int flag = false; + int tempKeys[4] = {-1, -1, -1, -1}; + int w = 0; + for(int j = 0; j < 4; j++) + { + int t = aKeys[currKey][j]; + if(t != -1 && hasSharing(t)) + { + currKey = t; + flag = true; + break; + } + else + { + if(t != -1) + tempKeys[w++] = t; + continue; + } + } + if(!flag) + { + if(w != 0) + { + int tk = tempKeys[0]; + int moreAdjLeft = getRemaining(tk); + currKey = tk; + for(int v = 1; v < w; v++) + { + tk = tempKeys[v]; + int adjLeft = getRemaining(tk); + if(adjLeft > moreAdjLeft) + { + moreAdjLeft = adjLeft; + currKey = tk; + } + } + } + else + break; + } + offSpring[i] = currKey; + deleteTakenKey(currKey); + } + + if(i < nof) // handle special case + { + for(int x = 0; x < nof; x++) + { + if(getRemaining(x) != 0) + { + for(int y = 0; y < 4; y++) + { + if(aKeys[x][y] != -1) + { + offSpring[i++] = aKeys[x][y]; + deleteTakenKey(aKeys[x][y]); + } + } + } + } + } +} + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/AdjKeys.h b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/AdjKeys.h new file mode 100644 index 0000000000000000000000000000000000000000..cf440b2e7612f37b2d6280b2ea1b3736d88a8d52 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/AdjKeys.h @@ -0,0 +1,45 @@ +/********************************************************************* + * File: AdjKeys.h + * Author: Lishan Li + * Date: May, 2003 + * + * Description: AdjKeys class is a helper class for Edge-recombination + * crossover operator + *********************************************************************/ + +#ifndef ADJKEYS_H +#define ADJKEYS_H + +#include <iostream> +#include <string> + +using namespace std; + +class AdjKeys +{ +public: + int startKey; + int * offSpring; // store offspring generate by crossover operator + + AdjKeys(int * parent1, int * parent2, int nbOfFrag); + ~AdjKeys(); + void makeAdjKeysTable(int * parent1, int * parent2); + void initAdjacentcy(int * parent, int pid); + void recombine(); + void deleteTakenKey(int takenKey); + int getRemaining(int id); + void setSharing(); + bool hasSharing(int id); + void decrementRemaining(int id); + void incrementRemaining(int id); + void printInfo(); +private: + int ** aKeys; // store adjacent keys for both parents + bool * share; // store sharing info for both parents + int * remaining; // store remaining fragments + int nof; +}; + +#endif + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/AlignedPair.h b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/AlignedPair.h new file mode 100644 index 0000000000000000000000000000000000000000..a5d087202c74e4e615f93e484e5da1823ced1cf7 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/AlignedPair.h @@ -0,0 +1,39 @@ +/********************************************************************* + * File: AlignedPair.h + * Author: Lishan Li + * Date: May, 2003 + * + * Description: AlignedPair class is a helper class that wraps an + * alignment of two sequences + *********************************************************************/ + +#ifndef ALIGNEDPAIR_H +#define ALIGNEDPAIR_H + +#include <iostream> +#include <string> + +using namespace std; + +class AlignedPair +{ +public: + string s; // to store sequence s after alignment + string t; // to store sequence t after alignment + + AlignedPair() {} + AlignedPair(const string &s, const string &t) + { + this->s = s; + this->t = t; + } + + void printAlign() + { + cout << s << "\n" << t << endl << endl; + } +}; + +#endif + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/Config.cfg b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/Config.cfg new file mode 100644 index 0000000000000000000000000000000000000000..8175e18307a3cb93a5f4d9cd80ea972a1fd6980b --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/Config.cfg @@ -0,0 +1,3 @@ +SA.cfg +../../../ProblemInstances/DNAFA-instances/pbm.txt +res/dna.sa.lan.txt diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/ConsensusBuilder.cpp b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/ConsensusBuilder.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ad8879ea58862e0c54e0d9fe56b11d65f0ffa267 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/ConsensusBuilder.cpp @@ -0,0 +1,286 @@ +/*********************************************************************** + * File: ConsensusBuilder.cpp + * Author: Lishan Li + * Date: May, 2003 + * + * Description: It provides implementation of all the functions declared + * in the header file ConsensusBuilder.h. + ***********************************************************************/ + +#include "ConsensusBuilder.h" + +int Global_cutoff; + +/***************************************************** + * Purpose: build the initial consensuses from contigs + *****************************************************/ + +ConsensusBuilder::ConsensusBuilder(vector<string> &SACons) +{ + consensus = SACons; + scpList = new List1<SubConsensusPair>(); +} + +/************************* + * Purpose: release memory + *************************/ + +ConsensusBuilder::~ConsensusBuilder() +{ + delete scpList; +} + +/********************************************** + * Purpose: postprocess four types of consensus + **********************************************/ + +void ConsensusBuilder::buildConsensus() +{ + if(consensus.size() > 1) + { +// cout << endl << "case FF" << endl; +/**/ cerr << "case FF" << endl; + buildSubConsensus(FF); // both from forward strand +/**/ cerr << "End case FF" << endl; + if(consensus.size() > 1) + { +// cout << endl << "case FR" << endl; +/**/ cerr << "case FR" << endl; + buildSubConsensus(FR); // first from forward, second from reverse complement +/**/ cerr << "End case FR" << endl; + if(consensus.size() > 1) + { +// cout << endl << "case RF" << endl; +/**/ cerr << "case RF" << endl; + buildSubConsensus(RF); // first from reverse complement, second from forward +/**/ cerr << "End case RF" << endl; + if(consensus.size() > 1) + { +// cout << endl << "case RR" << endl;; +/**/ cerr << "case RR" << endl; + buildSubConsensus(RR); // both from reverse complement +/**/ cerr << "End case RR" << endl; + } + } + } + } +} + +/********************************************** + * Purpose: initialize four types of consensus + **********************************************/ + +void ConsensusBuilder::initST(int type) +{ + vector<string> rc; + for(int k = 0; k < consensus.size(); k++) + rc.push_back(Util::rcSequence(consensus[k])); + + s.clear(); + t.clear(); + switch(type) + { + case FF: + s = t = consensus; + break; + case FR: + s = consensus; + t = rc; + break; + case RF: + s = rc; + t = consensus; + break; + case RR: + s = t = rc; + break; + } +} + +/******************************************************** + * Purpose: detects the overlap for all possible pair of + * consensus and stores the overlap score in a + * sorted linked list in descending order. + ********************************************************/ + +void ConsensusBuilder::buildSubConsensus(int type) +{ +// cout << "\nCurrent consensus (" << type << ")" << endl; + //print(); + initST(type); + + for(int i = 0; i < s.size(); i++) + { + for(int j = i+1; j < s.size(); j++) // compute half of pairs only + { + SGA *sga = new SGA(s[i], t[j]); // eg. w1 and w2 +/**/ cerr << "Building Matrix " << i << " " << j << endl; + sga->buildMatrix(); + sga->findBestScore(); + int score = sga->getBestScore(); + delete sga; +/**/ cerr << "End Building Matrix " << i << " " << j << endl; + + if(score >= Global_cutoff) + { + scpList->insert(SubConsensusPair(i, j, score)); + scpList->insert(SubConsensusPair(j, i, score)); + } + } + } +// scpList->printList(); +/**/ cerr << "Updating Consensus" << endl; + updateConsensus(type); +/**/ cerr << "End Updating Consensus" << endl; +} + +/************************************************************ + * Purpose: update consensus information by aligning possible + * overlapping consensuses. + ************************************************************/ + +void ConsensusBuilder::updateConsensus(int type) +{ + vector<string> tempLayout; + vector<string> tepCon = consensus; + consensus.clear(); + + ListNode<SubConsensusPair>* tempNode = scpList->header->next; + + while(tempNode != NULL) + { + int cid1 = tempNode->data.cid1; + int cid2 = tempNode->data.cid2; + char direction = 'F'; // forward + + tempLayout.push_back(s[cid1]); + tempLayout.push_back(t[cid2]); + if(type == FR) + direction = 'R'; // reverse complement + + tepCon.at(cid1) = ""; + tepCon.at(cid2) = ""; + remove(scpList, cid1); + bool found = true; + while(found) + { + ListNode<SubConsensusPair>* nextNode = search(scpList, cid2); + if(nextNode == NULL) + found = false; + else + { + cid1 = cid2; + cid2 = nextNode->data.cid2; + + if(type == FR && direction == 'R') + { + tempLayout.push_back(s[cid2]); // s[cid2] = Util::rcSequence(t[cid2]) + direction = 'F'; + } + else if (type == FR && direction == 'F') + { + tempLayout.push_back(t[cid2]); + direction = 'R'; + } + else if (type == RF && direction == 'F') + { + tempLayout.push_back(s[cid2]); + direction = 'R'; + } + else + { + tempLayout.push_back(t[cid2]); + direction = 'F'; + } + + tepCon.at(cid2) = ""; + remove(scpList, cid1); + } + } + + if(tempLayout.size() > 1) + { + LayoutBuilder layoutBuilder(tempLayout); + layoutBuilder.findAlignments(); + // layoutBuilder.printAlignments(); + layoutBuilder.buildLayout(); +// cout << endl << "Merging =>"<< endl << endl; + layoutBuilder.printLayout(); + layoutBuilder.findConsensus(); + layoutBuilder.printConsensus(); + consensus.push_back(layoutBuilder.getConsensus()); + } + else + consensus.push_back(tempLayout.at(0)); + + tempLayout.clear(); + tempNode = scpList->header->next; + } + + for(int m = 0; m < tepCon.size(); m++) + { + if(tepCon.at(m) != "") + consensus.push_back(tepCon.at(m)); + } +} + +/************************************************************ + * Purpose: removes SubConsensusPair objects that contain the + * given id from the linked list. + ************************************************************/ + +void ConsensusBuilder::remove(List1<SubConsensusPair>* list, int cid) +{ + List1<SubConsensusPair>* temp = list; + ListNode<SubConsensusPair>* tempCurr = temp->header->next; + ListNode<SubConsensusPair>* tempPrev = temp->header; + + while(tempCurr != NULL) + { + if(tempCurr->data.cid1 == cid || tempCurr->data.cid2 == cid ) + { + ListNode<SubConsensusPair>* oldNode = tempCurr; + tempPrev->next = tempCurr->next; + tempCurr = tempCurr->next; + delete oldNode; + (temp->len)--; + } + else + { + tempPrev = tempCurr; + if(tempCurr != NULL) + tempCurr = tempCurr->next; + } + } +} + +/************************************************************ + * Purpose: find the SubConsensusPair object that contain the + * given id in the linked list. + ************************************************************/ + +ListNode<SubConsensusPair>* ConsensusBuilder::search(List1<SubConsensusPair>* list, int cid) +{ + ListNode<SubConsensusPair>* curr; + + for(curr = list->header->next; curr != NULL; curr = curr->next) + { + if(curr->data.cid1 == cid) // found + return curr; + } + return NULL; +} + +/*********************************** + * Purpose: prints current consensus + ***********************************/ + +void ConsensusBuilder::print() +{ +/* for(int j = 0; j < consensus.size(); j++) + cout << endl << "Cons #" << j << " => " << consensus.at(j); + cout << endl; +*/} + +/************************************ End of File **************************************/ + diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/ConsensusBuilder.h b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/ConsensusBuilder.h new file mode 100644 index 0000000000000000000000000000000000000000..ea813d30173bbbac56ca291db5f4b424edbac019 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/ConsensusBuilder.h @@ -0,0 +1,53 @@ +/********************************************************************* + * File: ConsensusBuilder.h + * Author: Lishan Li + * Date: May, 2003 + * + * Description: This ConsensusBuilder class is used to determine the + * sequence for contigs. + *********************************************************************/ + +#ifndef CONSENSUSBUILDER_H +#define CONSENSUSBUILDER_H + +#pragma warning(disable: 4786) + +#include <iostream> +#include <string> +#include <vector> +#include "list.h" +#include "Util.h" +#include "ContigBuilder.h" +#include "LayoutBuilder.h" +#include "scp.h" + +using namespace std; + +class ConsensusBuilder +{ +public: + // F - forward; R - reverse complement + enum TableType { FF, FR, RF, RR }; + + ConsensusBuilder(vector<string> &SACons); + ~ConsensusBuilder(); + + void initLayout(); // initialize layout + void buildConsensus(); + void updateConsensus(int type); + void remove(List1<SubConsensusPair> * list, int cid); + ListNode<SubConsensusPair> * search(List1<SubConsensusPair> * list, int cid); + vector<string> getConsensus() { return consensus; } + void print(); +private: + void buildSubConsensus(int type); + void initST(int type); + + List1<SubConsensusPair>* scpList; // a list of SubConsensusPair objects + vector<string> consensus; + vector<string> s, t; +}; + +#endif + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/ContigBuilder.cpp b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/ContigBuilder.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dd7dc6f2cb48a1c26cfdb7775c80f8308ef9dd93 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/ContigBuilder.cpp @@ -0,0 +1,238 @@ +/*********************************************************************** + * File: ContigBuilder.cpp + * Author: Lishan Li + * Date: May, 2003 + * + * Description: It provides implementation of all the functions declared + * in the header file ContigBuilder.h. + ***********************************************************************/ + +#include "ContigBuilder.h" + +/****************************************************** + * Purpose: initialize fragment order and overlap score + ******************************************************/ + +ContigBuilder::ContigBuilder(int * order, int ** s, const SA::Problem *pbm):_pbm(pbm) +{ + fragOrder = order; + score = s; +} + +/******************************************************* + * Purpose: construct contigs based on the overlap score + * of adjacent fragments + *******************************************************/ + +void ContigBuilder::buildContigs() +{ + vector<int> tempOrder; + + int id1 = fragOrder[0]; + tempOrder.push_back(id1+1); // +1 because 0 has no negative number + int direction = 1; + + for(int i = 1; i < _pbm->numOfFragments; i++) + { + int id2 = fragOrder[i]; + // cout << "score[" << id1 << "][" << id2 << "] = " << score[id1][id2] << endl; + + int sign = direction * score[id1][id2]; + + if(abs(score[id1][id2]) >= _pbm->cutoff) // default cutoff = 30bps + { + if(sign > 0) // from same strand + { + tempOrder.push_back(id2+1); + direction = 1; + } + else // from different strand + { + tempOrder.push_back(-(id2+1)); + direction = -1; + } + id1 = id2; + } + else + { + allContigs.push_back(tempOrder); // a new contig is formed + tempOrder.clear(); + id1 = id2; + tempOrder.push_back(id1+1); + direction = 1; + } + } + allContigs.push_back(tempOrder); +} + +/******************************************************* + * Purpose: merge two contigs and update the orientation + * accordingly + *******************************************************/ + +void ContigBuilder::mergeTwoContig(int cid1, int cid2) +{ + vector<int> fids1 = allContigs.at(cid1); + vector<int> fids2 = allContigs.at(cid2); + + int fid1 = fids1.at(fids1.size()-1); + int fid2 = fids2.at(0); + int sign = fid1 * fid2; + + bool type = score[abs(fid1)-1][abs(fid2)-1] > 0; + + bool flag = (!type && sign < 0) || (type && sign > 0); // flag = true => not change + + for(int i = 0; i < fids2.size(); i++) + { + if(flag) // don't change + allContigs.at(cid1).push_back(fids2.at(i)); + else // change + allContigs.at(cid1).push_back(-fids2.at(i)); + } + + allContigs.erase(allContigs.begin() + cid2); +} + +/***************************************************** + * Purpose: merge contigs that satisfy the predefined + * threshold + *****************************************************/ + +void ContigBuilder::mergeContigs() +{ + while(allContigs.size() >= 2) + { + int bestScore = _pbm->cutoff; + int cid_i = -1; + int cid_j = -1; + + for(int i = 0; i < allContigs.size()-1; i++) + { + vector<int> tempi = allContigs.at(i); + int fidi_First = abs(tempi.at(0)) - 1; + int fidi_Last = abs(tempi.at(tempi.size()-1)) - 1; + + for(int j = i+1; j < allContigs.size(); j++) + { + vector<int> tempj = allContigs.at(j); + + int fidj_First = abs(tempj.at(0)) - 1; + int fidj_Last = abs(tempj.at(tempj.size()-1)) - 1; + + if(abs(score[fidi_Last][fidj_First]) >= bestScore) // put contig_j after contig_i + { + bestScore = abs(score[fidi_Last][fidj_First]); + cid_i = i; + cid_j = j; + } + if(abs(score[fidj_Last][fidi_First]) > bestScore) // put contig_j before contig_i + { + bestScore = abs(score[fidj_Last][fidi_First]); + cid_i = j; + cid_j = i; + } + } + } + + if(cid_i != -1 && cid_j != -1) + mergeTwoContig(cid_i, cid_j); + else + break; + } + cerr << endl << "*** *** *** *** SA Contigs ( " << allContigs.size() << " ) *** *** *** ***" << endl << endl; +} + +/******************************************* + * Purpose: build consensus for each contigs + *******************************************/ + +void ContigBuilder::buildConsensus() +{ + vector< vector<string> > fragLayouts; + for(int i = 0; i < allContigs.size(); i++) + fragLayouts.push_back(getPreLayoutFrags(allContigs.at(i))); + + vector<string> SACons; + cerr << endl << "*** *** *** *** SA Contigs ( " << fragLayouts.size() << " ) *** *** *** ***" << endl << endl; + + for(int j = 0; j < fragLayouts.size(); j++) + { + vector<string> layout = fragLayouts.at(j); + +// cout << endl << "Fragments Layout (" << j << ") =>" << endl << endl; + + if(layout.size() > 1) + { + LayoutBuilder layoutBuilder(layout); + layoutBuilder.findAlignments(); + // layoutBuilder.printAlignments(); + layoutBuilder.buildLayout(); + layoutBuilder.printLayout(); + layoutBuilder.findConsensus(); + layoutBuilder.printConsensus(); + SACons.push_back(layoutBuilder.getConsensus()); + } + else + { + SACons.push_back(layout.at(0)); +// cout << layout.at(0) << endl; + } + } + ConsensusBuilder * cb = new ConsensusBuilder(SACons); +/**/ cerr << "Building Consensus" << endl; + cb->buildConsensus(); +/**/ cerr << "End Building Consensus" << endl; + + vector<string> finalCons = cb->getConsensus(); + cerr << endl << "*** *** *** *** Final Contigs ( " << finalCons.size() << " ) *** *** *** ***" << endl << endl; +/* for(int k = 0; k < finalCons.size(); k++) + { + cout << ">Contig #" << k << endl; + cout << finalCons.at(k) << endl; + } + cout << endl << "*****************************************************" << endl; +*/ delete cb; +} + +/******************************************************** + * Purpose: returns a vector of fragments associated with + * the fragment order + ********************************************************/ + +vector<string> ContigBuilder::getPreLayoutFrags(vector<int> order) +{ + vector<string> preLayoutFrags; + + for(int i = 0; i < order.size(); i++) + { + int fid = order.at(i); + if( fid > 0) // -1 because +1 when insert + preLayoutFrags.push_back(_pbm->fragments->at(fid-1)); + else + preLayoutFrags.push_back(_pbm->rcFragments->at(abs(fid)-1)); + } +// cout << endl; + return preLayoutFrags; +} + +/*********************************************** + * Purpose: print fragment order for each contig + ***********************************************/ + +void ContigBuilder::printOrder() +{ +/* cout << endl << "Contig size = " << allContigs.size() << endl; + + for(int i = 0; i < allContigs.size(); i++) + { + vector<int> temp = allContigs.at(i); + for(int j = 0; j < temp.size(); j++) + cout << temp.at(j) << ", "; + cout << endl; + } + cout << endl; +*/} + +/************************************ End of File **************************************/ + diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/ContigBuilder.h b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/ContigBuilder.h new file mode 100644 index 0000000000000000000000000000000000000000..f169c0059fa9e6aa633aa1505b67f9176a6172bc --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/ContigBuilder.h @@ -0,0 +1,49 @@ +/********************************************************************* + * File: ContigBuilder.h + * Author: Lishan Li + * Date: May, 2003 + * + * Description: This ContigBuilder class is used to process contigs + * formed from SA. + *********************************************************************/ + +#ifndef CONTIGBUILDER_H +#define CONTIGBUILDER_H + +#pragma warning(disable: 4786) + +#include <iostream> +#include <string> +#include <vector> + +#include "Util.h" +#include "ConsensusBuilder.h" + +#include "SA.hh" + +using namespace std; + +class ContigBuilder +{ +public: + ContigBuilder(int * order, int ** s, const SA::Problem *pbm); // constructor + ~ContigBuilder() { } // destructor + + void buildContigs(); + void buildConsensus(); + void mergeContigs(); + void mergeTwoContig(int cid1, int cid2); + void print(); + void printOrder(); + vector<string> getPreLayoutFrags(vector<int> order); + vector< vector<int> > getAllContigs() { return allContigs; } +private: + int * fragOrder; // fragment order generated by SA + int ** score; // pointer to score in OverlapDetector class + vector< vector<int> > allContigs; // set of contigs + const SA::Problem *_pbm; +}; + +#endif + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/LayoutBuilder.cpp b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/LayoutBuilder.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d3ab188b6b90286399f9ef94d5379ea62b440849 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/LayoutBuilder.cpp @@ -0,0 +1,423 @@ +/*********************************************************************** + * File: LayoutBuilder.cpp + * Author: Lishan Li + * Date: May, 2003 + * + * Description: It provides implementation of all the functions declared + * in the header file LayoutBuilder.h. + ***********************************************************************/ + +#include "LayoutBuilder.h" + +/********************************************* + * Purpose: allocate memory and initialization + *********************************************/ + +LayoutBuilder::LayoutBuilder(const vector<string> & frags) +{ + preLayoutFrags = frags; + fragmentsLayout = new string[frags.size()]; + semiAlign = new AlignedPair[frags.size()-1]; +} + +/************************* + * Purpose: release memory + *************************/ + +LayoutBuilder::~LayoutBuilder() +{ + delete [] semiAlign; + delete [] fragmentsLayout; +} + +/************************************************************ + * Purpose: count number of gaps in front of a given fragment + ************************************************************/ + +int countStartGaps(const string &str) +{ + int count = 0; + for(int i = 0; i < str.length(); i++) + { + if(str.at(i) != '-') + break; + else + count++; + } + return count; +} + +/************************************************************** + * Purpose: count number of gaps at the end of a given fragment + **************************************************************/ + +int countEndGaps(const string &str) +{ + int count = 0; + for(int i = str.length() - 1; i >= 0; i--) + { + if(str.at(i) != '-') + break; + else + count++; + } + return count; +} + +/********************************************************** + * Purpose: count number of nucleotides in a given fragment + **********************************************************/ + +int countNonGapChar(const string &str) +{ + int count = 0; + for(int i = 0; i < str.length(); i++) + { + if(str.at(i) != '-') + count++; + } + return count; +} + +/**************************************** + * Purpose: create a given number of gaps + ****************************************/ + +string addGaps(int num) +{ + string gapStr = ""; + for(int i = 0; i < num; i++) + gapStr += "-"; + + return gapStr; +} + +/********************************************************** + * Purpose: count number of middle gaps in a given fragment + **********************************************************/ + +int* findMiddleGaps(const string &str, int count) +{ + int *midGapCounts = new int[count]; + int len = str.length(); + + for(int i = 0; i < count; i++) + { + midGapCounts[i] = 0; + } + + int k = 0; + for(int j = 0; j < len; j++) + { + if(str[j+1] == '-') + { + midGapCounts[k]++; + } + else + k++; + } + + return midGapCounts; +} + +/******************************************** + * Purpose: return the first non-gap position + ********************************************/ + +int findFirstNonGapPos(const string &str) +{ + for(int i = 0; i < str.length(); i++) + { + if(str.at(i) != '-') + return i; + } + return -1; +} + +/****************************************************************** + * Purpose: compute pairwise alignments for given ordered fragments + ******************************************************************/ + +void LayoutBuilder::findAlignments() +{ + for(int k = 0; k < preLayoutFrags.size()-1; k++) + { + string s = preLayoutFrags[k]; + string t = preLayoutFrags[k+1]; + SGA sga(s, t); + sga.buildMatrix(); + sga.findBestScore(); + sga.align(); + + AlignedPair aResult(sga.align_s, sga.align_t); + semiAlign[k] = aResult; + } +} + +/************************************************************* + * Purpose: insert number of gaps in front of a given fragment + *************************************************************/ + +void LayoutBuilder::insertStartGaps(int id, int numOfGaps) +{ + string temp = fragmentsLayout[id]; + string startGaps = ""; + for(int i = 0; i < numOfGaps; i++) + startGaps += "-"; + fragmentsLayout[id] = startGaps + temp; +} + +/*********************************************************** + * Purpose: insert number of gaps in the middle of fragments + ***********************************************************/ + +void LayoutBuilder::insertMiddleGaps(const string &str1, const string &str2, int k, int prev) +{ + int nonGapCount = countNonGapChar(str1); + int *midGapCounts1 = findMiddleGaps(str1, nonGapCount-1); + int *midGapCounts2 = findMiddleGaps(str2, nonGapCount-1); + + int pos = findFirstNonGapPos(fragmentsLayout[prev]); + + for(int w = 0; w < nonGapCount-1; w++) + { + pos += 1; + if(midGapCounts1[w] != 0 || midGapCounts2[w] != 0) + { + int gapDiff = abs(midGapCounts1[w] - midGapCounts2[w]); + int move = 0; + string gaps = ""; + for(int u = 0; u < gapDiff; u++) + gaps += "-"; + + if(midGapCounts1[w] > midGapCounts2[w]) + { + fragmentsLayout[k].insert(pos, gaps); + move = midGapCounts1[w]; + } + else if (midGapCounts1[w] < midGapCounts2[w]) + { + for(int v = 0; v < k; v++) + fragmentsLayout[v].insert(pos, gaps); + move = midGapCounts2[w]; + } + pos += move; + } + } + delete [] midGapCounts1; + delete [] midGapCounts2; +} + +/*************************************************************** + * Purpose: insert number of gaps at the end of a given fragment + ***************************************************************/ + +void LayoutBuilder::insertEndGaps(int id, int numOfGaps) +{ + string temp = fragmentsLayout[id]; + string endGaps = ""; + for(int i = 0; i < numOfGaps; i++) + endGaps += "-"; + fragmentsLayout[id] = temp + endGaps; +} + +/************************************************************** + * Purpose: extract fragment excluding starting and ending gaps + **************************************************************/ + +string LayoutBuilder::extractMiddleSeq(const string &str) +{ + int startGapCount = countStartGaps(str); + int endGapCount = countEndGaps(str); + int num = str.length() - startGapCount - endGapCount; + return str.substr(startGapCount, num); +} + +/************************************ + * Purpose: check if it is ending gap + ************************************/ + +bool LayoutBuilder::isEndGap(int i, int col) +{ + string middle = extractMiddleSeq(fragmentsLayout[i]); + int firstNonGap = findFirstNonGapPos(fragmentsLayout[i]); + + if(col < firstNonGap || col > firstNonGap + middle.length() - 1) + return true; + else + return false; +} + +/************************************************ + * Purpose: progressively build a fragment layout + ************************************************/ + +void LayoutBuilder::buildLayout() +{ + int j = 0; + fragmentsLayout[j++] = semiAlign[0].s; + fragmentsLayout[j++] = semiAlign[0].t; + + for(int i = 1; i < preLayoutFrags.size()-1; i++) + { + fragmentsLayout[j] = semiAlign[i].t; + + /* handle starting gaps */ + + string s_temp = semiAlign[i].s; + + int s_startGaps = countStartGaps(fragmentsLayout[j-1]); + int stemp_startGaps = countStartGaps(s_temp); + int startGapDiff = abs(s_startGaps - stemp_startGaps); + + if(startGapDiff > 0) + { + if(stemp_startGaps > s_startGaps) + { + for(int m = 0; m < j; m++) + insertStartGaps(m, startGapDiff); + } + else + insertStartGaps(j, startGapDiff); + } + + /* handle middle gaps */ + + string s_middle = extractMiddleSeq(fragmentsLayout[j-1]); + string stemp_middle = extractMiddleSeq(s_temp); + + insertMiddleGaps(s_middle, stemp_middle, j, j-1); + + /* handle end gaps */ + + int s_endGaps = countEndGaps(fragmentsLayout[j-1]); + int stemp_endGaps = countEndGaps(s_temp); + int endGapDiff = abs(s_endGaps - stemp_endGaps); + + if(endGapDiff > 0) + { + if(stemp_endGaps > s_endGaps) + { + for(int m = 0; m < j; m++) + insertEndGaps(m, endGapDiff); + } + else + insertEndGaps(j, endGapDiff); + } + j++; + } +} + +/*********************************************** + * Purpose: find majority of a particular column + ***********************************************/ + +char LayoutBuilder::majorityVote(int col) +{ + int count[5] = { 0, 0, 0, 0, 0 }; + char nucleotide[5] = {'A', 'T', 'C', 'G', '-'}; + char majority1 = 'A'; + char majority2 = 'A'; + + for(int i = 0; i < preLayoutFrags.size(); i++) + { + if(fragmentsLayout[i].at(col) == 'A') + count[0]++; + else if(fragmentsLayout[i].at(col) == 'T') + count[1]++; + else if(fragmentsLayout[i].at(col) == 'C') + count[2]++; + else if(fragmentsLayout[i].at(col) == 'G') + count[3]++; + else if(fragmentsLayout[i].at(col) == '-') + count[4]++; + } + int max = count[0]; + for(int j = 1; j < 5; j++) + { + if(count[j] > max) + { + majority2 = majority1; + max = count[j]; + majority1 = nucleotide[j]; + } + } + bool endGap = true; + if(majority1 == '-') + { + for(int i = 0; i < preLayoutFrags.size() && endGap; i++) + { + if(fragmentsLayout[i].at(col) == '-') + { + endGap = isEndGap(i, col); + } + } + + if(endGap) + return majority2; + } + return majority1; +} + +/*************************************** + * Purpose: find majority of all columns + ***************************************/ + +void LayoutBuilder::findMajority() +{ + int length = fragmentsLayout[0].length(); + + majority = ""; + for(int i = 0; i < length; i++) + { + char c = majorityVote(i); + majority += c; + } +} + +/******************************************** + * Purpose: determine sequence for the layout + ********************************************/ + +void LayoutBuilder::findConsensus() +{ + findMajority(); + consensus = ""; + for(int i = 0; i < majority.length(); i++) + { + if(majority.at(i) != '-') + consensus += majority.at(i); + } +} + +/*************************************************** + * Purpose: print info about all pairs of alignments + ***************************************************/ + +void LayoutBuilder::printAlignments() +{ + for(int j = 0; j < preLayoutFrags.size()-1; j++) + semiAlign[j].printAlign(); +} + +/*********************** + * Purpose: print layout + ***********************/ + +void LayoutBuilder::printLayout() +{ + for(int i = 0; i < preLayoutFrags.size(); i++) + cout << fragmentsLayout[i] << endl; + cout << endl; +} + +/************************** + * Purpose: print consensus + **************************/ + +void LayoutBuilder::printConsensus() +{ + cout << consensus << endl; +} + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/LayoutBuilder.h b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/LayoutBuilder.h new file mode 100644 index 0000000000000000000000000000000000000000..3e611f53952a7da75652d424400e0019beca0509 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/LayoutBuilder.h @@ -0,0 +1,53 @@ +/********************************************************************* + * File: LayoutBuilder.h + * Author: Lishan Li + * Date: May, 2003 + * + * Description: This LayoutBuilder class builds a layout for a contig. + * The contig consists of an ordered set of contiguous + * overlapping fragments. + *********************************************************************/ + +#ifndef LAYOUTBUILDER_H +#define LAYOUTBUILDER_H + +#pragma warning(disable: 4786) + +#include <iostream> +#include <string> +#include <vector> +#include "sga.h" +#include "AlignedPair.h" + +using namespace std; + +class LayoutBuilder +{ +public: + LayoutBuilder(const vector<string> & frags); // constructor + ~LayoutBuilder(); // destructor + void findAlignments(); // compute the alignments using SGA + void buildLayout(); // progressively build layout + void insertStartGaps(int id, int numOfGaps); // insert '-' at the beginning of fragments + void insertMiddleGaps(const string &str1, const string &str2, int k, int prev); + void insertEndGaps(int id, int numOfGaps); // insert '-' at the end of fragments + string extractMiddleSeq(const string &str); + bool isEndGap(int i, int col); + void findMajority(); // find majorities of the layout + char majorityVote(int col); // find majority of a particular column + void findConsensus(); + void printLayout(); + void printConsensus(); + void printAlignments(); + string getConsensus() { return consensus; } +private: + vector<string> preLayoutFrags; // ordered fragments + AlignedPair * semiAlign; // store pairwise alignment result + string * fragmentsLayout; // store layout + string majority; + string consensus; +}; + +#endif + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/MainLan.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/MainLan.cc new file mode 100644 index 0000000000000000000000000000000000000000..2b937bd6a96b813bb2905d3ba431d1685b52ddf4 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/MainLan.cc @@ -0,0 +1,57 @@ +#include "SA.hh" +#include "ContigBuilder.h" +#include <iostream.h> +#include <fstream.h> + +extern int Global_cutoff; + +int main (int argc, char** argv) +{ + using skeleton SA; + char path[MAX_BUFFER]; + int len; + int longitud; + + system("clear"); + + get_path(argv[0],path); + len = strlen(path); + longitud = MAX_BUFFER - len; + + strcat(path,"Config.cfg"); + ifstream f(path); + if(!f) show_message(10); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f1(path); + if(!f1) show_message(11); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f2(path); + if(!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + Global_cutoff = pbm.cutoff; + + SetUpParams cfg; + f1 >> cfg; + + + Solver_Lan solver(pbm,cfg,argc,argv); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solucion: " << solver.global_best_solution() << " Fitness: " << solver.global_best_solution().fitness(); + + f.getline(&(path[len]),longitud,'\n'); + ofstream fexit(path); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + cout << endl << endl << " :( ---------------------- THE END --------------- :) " << endl; + } + return(0); +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/MainSeq.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/MainSeq.cc new file mode 100644 index 0000000000000000000000000000000000000000..488096d30ae1e582256f58600c5ec2acdd236d67 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/MainSeq.cc @@ -0,0 +1,48 @@ +#include "SA.hh" +#include "ContigBuilder.h" +#include <iostream.h> +#include <fstream.h> + +extern int Global_cutoff; + +int main (int argc, char** argv) +{ + using skeleton SA; + + system("clear"); + + if(argc < 4) + show_message(1); + + ifstream f1(argv[1]); + if (!f1) show_message(11); + + ifstream f2(argv[2]); + if (!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + +//cout << pbm; + Global_cutoff = pbm.cutoff; + + SetUpParams cfg; + f1 >> cfg; + + Solver_Seq solver(pbm,cfg); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << solver.global_best_solution() + << " Fitness: " << solver.global_best_solution().fitness() << endl; + cout << "\n\n :( ---------------------- THE END --------------- :) "; + + ofstream fexit(argv[3]); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + } + return(0); +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/Makefile b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..275b8575ae0fe807091339652a9cc8f4ad0ddf40 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/Makefile @@ -0,0 +1,25 @@ +include ../../../environment + +all: MainSeq MainLan + +clean: + rm -f MainLan MainSeq *.o *% *~ + +MainLan: SA.req.o SA.pro.o StopCondition.o MainLan.o OverlapDetector.o sga.o AdjKeys.o ContigBuilder.o ConsensusBuilder.o LayoutBuilder.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainWan: SA.req.o SA.pro.o StopCondition.o MainWan.o OverlapDetector.o sga.o AdjKeys.o ContigBuilder.o ConsensusBuilder.o LayoutBuilder.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainSeq: SA.req.o SA.pro.o StopCondition.o MainSeq.o OverlapDetector.o sga.o AdjKeys.o ContigBuilder.o ConsensusBuilder.o LayoutBuilder.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainScore: SA.req.o SA.pro.o StopCondition.o MainScore.o OverlapDetector.o sga.o AdjKeys.o ContigBuilder.o ConsensusBuilder.o LayoutBuilder.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +LAN: + $(RUN) -v -p4pg pgfileLan MainLan +WAN: + $(RUN) -v -p4pg pgfileWan MainWan +SEQ: + ./MainSeq SA.cfg ../../../ProblemInstances/DNAFA-instances/pbm.txt res/dna.sa.seq.txt diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/OverlapDetector.cpp b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/OverlapDetector.cpp new file mode 100644 index 0000000000000000000000000000000000000000..49b81ec13a45fd66e46cd17e0fd1cef7b5bca870 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/OverlapDetector.cpp @@ -0,0 +1,130 @@ +/*********************************************************************** + * File: OverlapDetector.cpp + * Author: Lishan Li + * Date: May, 2003 + * + * Description: It provides implementation of all the functions declared + * in the header file OverlapDetector.h. + ***********************************************************************/ + +#include "OverlapDetector.h" + +/************************** + * Purpose: allocate memory + **************************/ + +OverlapDetector::OverlapDetector(int nof):nbOfFrag(nof) +{ + score = new int*[nof]; + for(int i = 0; i < nof; i++) + score[i] = new int[nof]; +} + +/************************** + * Purpose: release memory + **************************/ + +OverlapDetector::~OverlapDetector() +{ + for(int j = 0; j < nbOfFrag; j++) + delete [] score[j]; + delete [] score; +} + +/********************************************************** + * Purpose: construct a score table to store overlap length + * of all possible pair of fragments + **********************************************************/ + +void OverlapDetector::buildScoresTable(vector<string>* fragments, vector<string>* rcFragments) +{ + for(int i = 0; i < nbOfFrag; i++) + { + string rcFrags = rcFragments->at(i); + + for(int j = i+1; j < nbOfFrag; j++) + { + SGA sga1(fragments->at(i), fragments->at(j)); // eg. w1 and w2 + sga1.buildMatrix(); + sga1.findBestScore(); + int score1 = sga1.getBestScore(); + + SGA sga2(rcFrags, fragments->at(j)); // eg. rcw1 and w2 + sga2.buildMatrix(); + sga2.findBestScore(); + int score2 = sga2.getBestScore(); + + if(score2 > score1) // store the larger one + score[j][i] = score[i][j] = -score2; + else + score[j][i] = score[i][j] = score1; + } + } +} + +/*************************** + * Purpose: for testing use + ***************************/ + +void OverlapDetector::readScoreTable() +{ + string inputFile = string(getenv("HOME")) + "/Mallba/ProblemInstances/DNAFA-instances/score.txt"; + ifstream inFile(inputFile.c_str(), ios::in); + if( !inFile ) + { + cout << "\n\t\t*** The file " << inputFile + << " doesn't exist! ***" << endl << endl; + exit(1); + } + +/* char seps[] = " \t\n"; + char oneLine[2000]; + int i = 0; + inFile.getline(oneLine, 2000); + while(inFile.getline(oneLine, 2000)) + { + int j = 0; + char * token = strtok(oneLine, seps); + + while (token != NULL) + { + score[i][j] = atoi(token); + token = strtok(NULL, seps); + j++; + } + i++; + }*/ + for(int i = 0; i < nbOfFrag; i++) + for(int j= 0; j < nbOfFrag; j++) + inFile >> score[i][j]; + inFile.close(); +} + +/************************************ + * Purpose: print overlap score table + ************************************/ + +void OverlapDetector::printScoreTable() +{ +// cout << endl << "*** *** *** *** Overlap Score Table *** *** *** ***" << endl << endl; + +// cout << " "; +// for(int k = 0; k < nbOfFrag; k++) +// cout << setw(5) << setiosflags(ios::right) << "F" << k; + + for(int i = 0; i < nbOfFrag; i++) + { + cout << endl; +// cout << "F" << i << " "; + for(int j = 0; j < nbOfFrag; j++) + { + if(i == j) + cout << setw(5) << setiosflags(ios::right) << "0 "; + else + cout << setw(5) << setiosflags(ios::right) << score[i][j] << " "; + } + } +// cout << endl << endl << "*****************************************************" << endl; +} + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/OverlapDetector.h b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/OverlapDetector.h new file mode 100644 index 0000000000000000000000000000000000000000..a0a0594582c45a89b93fd955505748386cd7357d --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/OverlapDetector.h @@ -0,0 +1,45 @@ +/*************************************************************** + * File: OverlapDetector.h + * Author: Lishan Li + * Date: May, 2003 + * + * Description: This OverlapDetector class is used to detect the + * similarity of all possible pair of fragments. The + * overlap length between any two fragments is stored + * in a two dimentional array called score. + ***************************************************************/ + +#ifndef OVERLAPDETECTOR_H +#define OVERLAPDETECTOR_H + +#pragma warning(disable: 4786) + +#include <iostream> +#include <fstream> +#include <iomanip> +#include <stdlib.h> +#include <string> +#include <vector> + +#include "sga.h" + +using namespace std; + + +class OverlapDetector +{ +public: + OverlapDetector(int nof); // constructor + ~OverlapDetector(); // destructor + void buildScoresTable(vector<string>*, vector<string>*); // build overlap score table for fragments + void readScoreTable(); + void printScoreTable(); + int ** getScoreTable() { return score; } +private: + int ** score; // to store the overlap length of all possible pair of fragments + int nbOfFrag; // Number of Fragments +}; + +#endif + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/SA.cfg b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/SA.cfg new file mode 100644 index 0000000000000000000000000000000000000000..739dc527253b58bd7f99914ebf8e494823154c93 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/SA.cfg @@ -0,0 +1,9 @@ +10 // number of independent runs +25600 // number of evaluations +256 // Markov-Chain Length +.99 // temperature Decay +1 // display state ? +LAN-configuration +200000 // the global state is updated in this number of evaluations +0 // 0: asynchronized mode // 1: synchronized mode +200 // interval of iterations to cooperate ( if 0 no cooperation) diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/SA.hh b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/SA.hh new file mode 100644 index 0000000000000000000000000000000000000000..c8d691493345603aa20caebeadca031d235b62f8 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/SA.hh @@ -0,0 +1,494 @@ +#ifndef INC_SA +#define INC_SA + +#include "Mallba/mallba.hh" +#include "Mallba/States.hh" +#include "Mallba/Rarray.h" +#include "Mallba/time.hh" +#include "Mallba/netstream.hh" +#include <math.h> +#include <string.h> +#include <vector> +#include "OverlapDetector.h" + +using namespace std; + +skeleton SA +{ + + provides class SetUpParams; + provides class Statistics; + provides class Move; + provides class StopCondition; + provides class Solver; + provides class Solver_Seq; + provides class Solver_Lan; + provides class Solver_Wan; + + requires class Problem; + requires class Solution; + requires class StopCondition_1; + requires class StopCondition_2; + requires class StopCondition_3; + requires class DefaultMove; + requires class UserStatistics; + requires bool TerminateQ (const Problem& pbm, const Solver& solver, const SetUpParams& setup); + +// Problem ---------------------------------------------------------------------------- + + requires class Problem + { + public: + Problem (); + ~Problem (); + + friend ostream& operator<< (ostream& os, const Problem& pbm); + friend istream& operator>> (istream& is, Problem& pbm); + + Problem& operator= (const Problem& pbm); + bool operator== (const Problem& pbm) const; + bool operator!= (const Problem& pbm) const; + + Direction direction () const; + + int numOfFragments; // number of fragments^M + double avgLength; // average length of the input fragments^M + int cutoff; // overlap threshold^M + int * fragmentLength; // fragments' lengths^M + vector<string>* fragments; // forward direction of the fragments^M + vector<string>* description; // description of the fragments (Nombre Del Fragmento)^M + vector<string>* rcFragments; // reverse complement of the fragments + OverlapDetector *detector; + }; + +//Solution ---------------------------------------------------------------------------- + + requires class Solution + { + public: + Solution (const Problem& pbm); + Solution (const Solution& sol); + ~Solution(); + + friend ostream& operator<< (ostream& os, const Solution& sol); + friend istream& operator>> (istream& is, Solution& sol); + friend NetStream& operator << (NetStream& ns, const Solution& sol); + friend NetStream& operator >> (NetStream& ns, Solution& sol); + + const Problem& pbm() const; + + Solution& operator= (const Solution& sol); + bool operator== (const Solution& sol) const; + bool operator!= (const Solution& sol) const; + + char *to_String() const; + void to_Solution(char *_vertex_); + unsigned int size() const; + + void initialize(); + double fitness (); + int& fragment(const int index); + int* fragments(); + + private: + int * fragOrder; // an order of an individual ^M + const Problem& _pbm; + + }; + +// UserStatistics ---------------------------------------------------------------------------- + + requires class UserStatistics + { + private: + struct user_stat + { + unsigned int trial; + double initial_temperature; + double temperature_best_found_trial; + unsigned long nb_evaluation_best_found_trial; + double best_cost_trial; + float time_best_found_trial; + float time_spent_trial; + }; + + Rlist<struct user_stat> result_trials; + + public: + UserStatistics (); + ~UserStatistics(); + + friend ostream& operator<< (ostream& os, const UserStatistics& usertats); + + UserStatistics& operator= (const UserStatistics& userstats); + void update(const Solver& solver); + void clear(); + }; + +// Move ---------------------------------------------------------------------------------- + + provides class Move + { + public: + Move() {} + virtual ~Move() {} + + virtual void Apply(Solution& sol) const = 0; + }; + +// DefaultMove ---------------------------------------------------------------------------------- + + requires class DefaultMove: public Move + { + public: + DefaultMove(); + ~DefaultMove(); + + void Apply(Solution& sol) const; + }; + +// SetUpParams ------------------------------------------------------------------------------- + + provides class SetUpParams + { + private: + unsigned int _independent_runs; + unsigned long _max_evaluations; + unsigned int _MarkovChain_length; + double _temperature_decay; + bool _display_state; + + // for LAN execution configuration + unsigned long _refresh_global_state; + bool _synchronized; + unsigned int _cooperation; + + public: + SetUpParams (); + + friend ostream& operator<< (ostream& os, const SetUpParams& setup); + friend istream& operator>> (istream& is, SetUpParams& setup); + + const unsigned int independent_runs() const; + const unsigned long max_evaluations() const; + const unsigned int MarkovChain_length() const; + const double temperature_decay() const; + const bool display_state() const; + const unsigned long refresh_global_state() const; + const bool synchronized() const; + const unsigned int cooperation() const; + + void independent_runs(const unsigned int val); + void max_evaluations(const unsigned long val); + void MarkovChain_length(const unsigned int val); + void temperature_decay(const double val); + void display_state(const bool val); + void refresh_global_state(const unsigned long val); + void synchronized(const bool val); + void cooperation(const unsigned int val); + + ~SetUpParams(); + }; + +// Statistics --------------------------------------------------------------------------------- + + provides class Statistics + { + private: + struct stat + { + unsigned int trial; + unsigned long nb_evaluations; + double best_cost; + double current_cost; + }; + + Rlist<struct stat> stats_data; + + public: + Statistics(); + + friend ostream& operator<< (ostream& os, const Statistics& stats); + + Statistics& operator= (const Statistics& stats); + void update(const Solver& solver); + void clear(); + + ~Statistics(); + }; + +// Solver --------------------------------------------------------------------------------- + + provides class Solver + { + protected: + const Problem& problem; + const SetUpParams& params; + UserStatistics _userstat; + Statistics _stat; + Move* move; + Solution current; + double curfit; + Solution tentative; + double currentTemperature; + unsigned int k; // to control temperature update. + StateCenter _sc; + + float total_time_spent; + float time_spent_in_trial; + float start_trial; + float start_global; + + bool _end_trial; + + State_Vble _current_trial; + State_Vble _current_iteration; + State_Vble _current_best_solution; + State_Vble _current_best_cost; + State_Vble _current_solution; + State_Vble _current_cost; + + State_Vble _current_time_spent; + State_Vble _initial_temperature_trial; + State_Vble _time_best_found_trial; + State_Vble _iteration_best_found_trial; + State_Vble _temperature_best_found_trial; + State_Vble _time_spent_trial; + + State_Vble _trial_best_found; + State_Vble _iteration_best_found; + State_Vble _global_best_solution; + State_Vble _global_best_cost; + State_Vble _time_best_found; + + State_Vble _temperature; + State_Vble _display_state; + + const Direction _direction; + + bool AcceptQ(double tent, double cur, double temperature); + double Set_Initial_Temperature(const Problem& pbm); + void KeepHistory(const Solution& sol, const double curfit,const float time_spent_trial,const float total_time_spent); + + double UpdateT(double temp, int K); + + public: + // Constructor - Destructor ------------------------- + + Solver (const Problem& pbm, const SetUpParams& setup); + virtual ~Solver (); + virtual int pid() const; + bool end_trial() const; + + // Execution methods -------------------------------- + + // Full execution + virtual void run () =0; + virtual void run (unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol, unsigned long int nb_evaluations) =0; + + virtual void run (const double initialTemperature) =0; + virtual void run (const Solution& sol,const double initialTemperature) =0; + virtual void run (const double initialTemperature, unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations) =0; + + // Partial execution + virtual void StartUp () =0; + virtual void StartUp (const Solution& sol) =0; + virtual void StartUp (const double initialTemperature) =0; + virtual void StartUp (const Solution& sol, const double initialTemperature) =0; + virtual void DoStep () =0; + + // Statistics handling ------------------------------ + + const Statistics& statistics() const; + const UserStatistics& userstatistics () const; + const SetUpParams& setup() const; + const Problem& pbm() const; + + // State handling ----------------------------------- + + void RefreshState(); + void UpdateFromState(); + StateCenter* GetState(); + + unsigned int current_trial() const; + unsigned long current_iteration() const; + Solution current_best_solution() const; + Solution current_solution() const; + double current_best_cost() const; + double current_cost() const; + float current_time_spent() const; + float time_best_found_trial() const; + double initial_temperature_trial() const; + unsigned int iteration_best_found_trial() const; + double temperature_best_found_trial() const; + float time_spent_trial() const; + unsigned int trial_best_found() const; + unsigned int iteration_best_found() const; + Solution global_best_solution() const; + double global_best_cost() const; + float time_best_found() const; + double temperature() const; + int display_state() const; + + void current_trial(const unsigned int value); + void current_iteration(const unsigned long value); + void current_best_solution(const Solution& sol); + void current_best_cost(const double value); + void current_solution(const Solution& sol); + void current_cost(const double value); + void current_time_spent(const float value); + void time_best_found_trial(const float value); + void initial_temperature_trial(const double temperature); + void iteration_best_found_trial(const unsigned int value); + void temperature_best_found_trial(const double value); + void time_spent_trial(const float value); + void trial_best_found(const unsigned int value); + void iteration_best_found(const unsigned int value); + void global_best_solution(const Solution& sol); + void global_best_cost(const double value); + void time_best_found(const float value); + void temperature(const double value); + void display_state(const int value); + void show_state() const; + + // State handling ----------------------------------- + void SetMove(Move* mov); + }; + + provides class Solver_Seq: public Solver + { + public: + // Constructor - Destructor ------------------------- + + Solver_Seq ( const Problem& pbm, const SetUpParams& setup); + virtual ~Solver_Seq (); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + }; + + provides class Solver_Lan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + + public: + Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Lan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + + provides class Solver_Wan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + + public: + Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Wan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + +}; + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/SA.pro.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/SA.pro.cc new file mode 100644 index 0000000000000000000000000000000000000000..a89284b0f375e8968fdc58653931017d8798a8ba --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/SA.pro.cc @@ -0,0 +1,1808 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** Provided classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** *** +************************************************/ + +#include <iostream.h> +#include <math.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "Mallba/time.hh" + +skeleton SA +{ + +// SetUpParams ----------------------------------------------------------- + + SetUpParams::SetUpParams (): + _independent_runs(0), + _max_evaluations(0), + _MarkovChain_length(0), + _temperature_decay(0), + _refresh_global_state(0), + _synchronized(0), + _display_state(0), + _cooperation(0) + {} + + istream& operator>> (istream& is, SetUpParams& setup) + { + char buffer[MAX_BUFFER]; // current line in the setup file + char command[50]; + int op; + double dop; + short int nb_param=0; + short int nb_section=0; + short int nb_LAN_param=0; + + while (is.getline(buffer,MAX_BUFFER,'\n')) + { + sscanf(buffer," %s ",command); + + if (!(strcmp(command,"General"))) nb_section=0; + if (!(strcmp(command,"LAN-configuration"))) nb_section=1; + + if (nb_param==3 && nb_section==0) + { + dop=-1; + sscanf(buffer," %lf ",&dop); + if (dop<0) continue; + } + else + { + op=-1; + sscanf(buffer," %ld%*s ",&op); + if (op<0) continue; + } + + switch (nb_section) + { + case 0: switch (nb_param) + { + case 0: setup.independent_runs(op); break; + case 1: setup.max_evaluations(op); break; + case 2: setup.MarkovChain_length(op); break; + case 3: setup.temperature_decay(dop); break; + case 4: setup.display_state(op); break; + } + nb_param++; + break; + case 1: if (nb_LAN_param>=3) break; + if (nb_LAN_param==0) setup.refresh_global_state(op); + if (nb_LAN_param==1) setup.synchronized(op); + if (nb_LAN_param==2) setup.cooperation(op); + nb_LAN_param++; + break; + } // end switch + } // end while + return is; + } + + ostream& operator<< (ostream& os, const SetUpParams& setup) + { + os << "CONFIGURATION -------------------------------------------" << endl << endl; + os << "\t" << "Independent runs : " << setup.independent_runs() << endl + << "\t" << "Evaluation steps: " << setup.max_evaluations() << endl + << "\t" << "Markov-Chain Length: " << setup.MarkovChain_length() << endl + << "\t" << "Temperature Decay: " << setup.temperature_decay() << endl; + + if (setup.display_state()) + os << "\t" << "Display state" << endl; + else + os << "\t" << "Not display state" << endl; + os << endl << "\t" << "LAN configuration:" << endl + << "\t" << "----------------------" << endl << endl + << "\t" << "Refresh global state in number of generations: " << setup.refresh_global_state() << endl; + + if (setup.synchronized()) + os << "\t" << "Running in synchronous mode" << endl; + else + os << "\t" << "Running in asynchronous mode" << endl; + + if (!setup.cooperation()) + os << "\t" << "Running without cooperation" << endl << endl; + else + os << "\t" << "Running with cooperation in " << setup.cooperation() << " iterations. " << endl << endl; + + os << endl << endl << "END CONFIGURATION -------------------------------------------" << endl << endl; + return os; + } + + const unsigned int SetUpParams::independent_runs() const + { + return _independent_runs; + } + + const unsigned long SetUpParams::max_evaluations() const + { + return _max_evaluations; + } + + const unsigned int SetUpParams::MarkovChain_length() const + { + return _MarkovChain_length; + } + + const double SetUpParams::temperature_decay() const + { + return _temperature_decay; + } + + const bool SetUpParams::display_state() const + { + return _display_state; + } + + const unsigned long SetUpParams::refresh_global_state() const + { + return _refresh_global_state; + } + + const bool SetUpParams::synchronized() const + { + return _synchronized; + } + + const unsigned int SetUpParams::cooperation() const + { + return _cooperation; + } + + void SetUpParams::independent_runs(const unsigned int val) + { + _independent_runs = val; + } + + void SetUpParams::max_evaluations(const unsigned long val) + { + _max_evaluations= val; + } + void SetUpParams::MarkovChain_length(const unsigned int val) + { + _MarkovChain_length= val; + } + void SetUpParams::temperature_decay(const double val) + { + _temperature_decay= val; + } + + void SetUpParams::display_state(const bool val) + { + _display_state=val; + } + + void SetUpParams::refresh_global_state(const unsigned long val) + { + _refresh_global_state=val; + } + + void SetUpParams::synchronized(const bool val) + { + _synchronized=val; + } + + void SetUpParams::cooperation(const unsigned int val) + { + _cooperation=val; + } + + SetUpParams::~SetUpParams() + {} + +// Statistics ------------------------------------------------------ + + Statistics::Statistics() + {} + + ostream& operator<< (ostream& os, const Statistics& stats) + { + int j; + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF CURRENT TRIAL " << endl; + os << "------------------------------------------------------------------" << endl; + for (int i=0;i< stats.stats_data.size();i++) + { + os << endl + << " Evaluations: " << stats.stats_data[i].nb_evaluations + << " Best: " << stats.stats_data[i].best_cost + << " Current: " << stats.stats_data[i].current_cost; + } + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + Statistics& Statistics::operator= (const Statistics& stats) + { + stats_data = stats.stats_data; + return *this; + } + + void Statistics::update(const Solver& solver) + { + /* struct stat *new_stat; + if ((new_stat=(struct stat *)malloc(sizeof(struct stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluations= solver.current_iteration(); + new_stat->best_cost = solver.current_best_cost(); + new_stat->current_cost = solver.current_cost(); + stats_data.append(*new_stat); */ + } + + Statistics::~Statistics() + { + stats_data.remove(); + } + + void Statistics::clear() + { + stats_data.remove(); + } + +// Solver (superclass)--------------------------------------------------- + + Solver::Solver (const Problem& pbm, const SetUpParams& setup) + : problem(pbm), + params(setup), + _stat(), + _userstat(), + _sc(), + _direction(pbm.direction()), + current(pbm), + tentative(pbm), + currentTemperature(0.0), + time_spent_in_trial(0.0), + total_time_spent(0.0), + start_trial(0.0), + start_global(0.0), + _current_trial("_current_trial",_sc), + _current_iteration("_current_iteration",_sc), + _current_best_solution("_current_best_solution",_sc), + _current_best_cost("_current_best_cost",_sc), + _current_solution("_current_solution",_sc), + _current_cost("_current_cost",_sc), + _current_time_spent("_current_time_spent",_sc), + _initial_temperature_trial("_initial_temperature_trial",_sc), + _time_best_found_trial("_time_best_found_trial",_sc), + _iteration_best_found_trial("_iteration_best_found_trial",_sc), + _temperature_best_found_trial("_temperature_best_found_trial",_sc), + _time_spent_trial("_time_spent_trial",_sc), + _trial_best_found("_trial_best_found",_sc), + _iteration_best_found("_iteration_best_found;",_sc), + _global_best_solution("_global_best_solution",_sc), + _global_best_cost("_global_best_cost",_sc), + _time_best_found("_time_best_found",_sc), + _temperature("_temperature",_sc), + _display_state("_display_state",_sc) + { + current_trial(0); + current_iteration(0); + current_best_solution(current), + current_best_cost((-1) * pbm.direction() * infinity()); + current_solution(current); + current_cost((-1) * pbm.direction() * infinity()); + current_time_spent(total_time_spent); + initial_temperature_trial(0); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(0); + temperature_best_found_trial(0.0); + time_spent_trial(time_spent_in_trial); + trial_best_found(0); + iteration_best_found(0); + global_best_solution(current); + global_best_cost((-1) * pbm.direction() * infinity()); + time_best_found(total_time_spent); + temperature(currentTemperature); + display_state(setup.display_state()); + + move = new DefaultMove; + } + + int Solver::pid() const + { + return 0; + } + + bool Solver::end_trial() const + { + return _end_trial; + } + + unsigned int Solver::current_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_trial",(char *)&value, nitems, length); + return value; + } + + unsigned long Solver::current_iteration() const + { + unsigned long value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_iteration",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_best_solution() const + { + Solution sol(problem); + unsigned long nitems,length; + char data_stored[_current_best_solution.get_nitems() + _current_best_solution.get_length()]; + _sc.get_contents_state_variable("_current_best_solution", data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::current_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_best_cost",(char *)&value, nitems, length); + return value; + } + + double Solver::current_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_cost",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_solution() const + { + Solution sol(problem); + char data_stored[_current_solution.get_nitems() + _current_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_solution",data_stored, nitems, length); + sol.to_Solution((char *)data_stored); + return sol; + } + + float Solver::current_time_spent() const + { + float value=0.0; + unsigned long nitems,length; + _current_time_spent.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::initial_temperature_trial() const + { + double value=0.0; + unsigned long nitems,length; + _initial_temperature_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature_best_found_trial() const + { + double value=0.0; + unsigned long nitems,length; + _temperature_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_spent_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_spent_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::trial_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _trial_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::global_best_solution() const + { + Solution sol(problem); + char data_stored[_global_best_solution.get_nitems() + _global_best_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_solution",data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::global_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_cost",(char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_temperature",(char *)&value, nitems, length); + return value; + } + + int Solver::display_state() const + { + int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_display_state",(char *)&value, nitems, length); + return value; + } + + void Solver::current_trial(const unsigned int value) + { + _sc.set_contents_state_variable("_current_trial",(char *)&value,1,sizeof(int)); + } + + void Solver::current_iteration(const unsigned long value) + { + _sc.set_contents_state_variable("_current_iteration",(char *)&value,1,sizeof(long)); + } + + void Solver::current_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_best_cost(const double value) + { + _sc.set_contents_state_variable("_current_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_cost(const double value) + { + _sc.set_contents_state_variable("_current_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_time_spent(const float value) + { + _current_time_spent.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::time_best_found_trial(const float value) + { + _time_best_found_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::iteration_best_found_trial(const unsigned int value) + { + _iteration_best_found_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::initial_temperature_trial(const double value) + { + _initial_temperature_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::temperature_best_found_trial(const double value) + { + _temperature_best_found_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::time_spent_trial(const float value) + { + _time_spent_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::trial_best_found(const unsigned int value) + { + _trial_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::iteration_best_found(const unsigned int value) + { + _iteration_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::global_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_global_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::global_best_cost(const double value) + { + _sc.set_contents_state_variable("_global_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::time_best_found(const float value) + { + _time_best_found.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::temperature(const double value) + { + _sc.set_contents_state_variable("_temperature",(char *)&value,1,sizeof(double)); + } + + void Solver::display_state(const int value) + { + _sc.set_contents_state_variable("_display_state",(char *)&value,1,sizeof(int)); + } + + const Statistics& Solver::statistics() const + { + return _stat; + } + + const UserStatistics& Solver::userstatistics() const + { + return _userstat; + } + + const SetUpParams& Solver::setup() const + { + return params; + } + + const Problem& Solver::pbm() const + { + return problem; + } + + void Solver::KeepHistory(const Solution& sol, const double curfit,const float time_spent_in_trial,const float total_time_spent) + { + bool betterG=false; + bool betterT=false; + + switch (_direction) + { + case minimize: betterG = (curfit < global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit < current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + case maximize: betterG = (curfit > global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit > current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + } + + if (betterT) + { + current_best_solution(sol); + current_best_cost(curfit); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(current_iteration()); + temperature_best_found_trial(temperature()); + if (betterG) + { + trial_best_found(current_trial()); + iteration_best_found(current_iteration()); + global_best_solution(sol); + global_best_cost(curfit); + time_best_found(time_spent_in_trial); + } + } + } + + double Solver::UpdateT(double temp, int K) + { + return temp * params.temperature_decay(); // initial + + /* + if(K == 1) return temp/log(2); + else return temp * log(K) / log(K+1); + */ + /* + if(K == 1) return temp/2; + else return (temp * K) / (K + 1); + */ + + /* if(K == 1) return temp / exp(2); + else return (temp * exp(K)) / exp(K+1); + */ + + } + + StateCenter* Solver::GetState() + { + return &_sc; + } + + void Solver::RefreshState() + { + current_solution(current); + current_cost(curfit); + current_time_spent(total_time_spent); + time_spent_trial(time_spent_in_trial); + temperature(currentTemperature); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::UpdateFromState() + { + current = current_solution(); + curfit = current_cost(); + total_time_spent=current_time_spent(); + time_spent_in_trial=time_spent_trial(); + currentTemperature = temperature(); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::show_state() const + { + cout << endl << "Current trial: " << current_trial(); + cout << endl << "Current iteration: " << current_iteration(); + cout << endl << "Current Temperature: " << temperature (); + cout << endl << "Current cost: " << current_cost(); + cout << endl << "Best cost in trial: " << current_best_cost(); + cout << endl << "Time of best solution found in trial: " << time_best_found_trial(); + cout << endl << "Iteration of best solution found in trial: " << iteration_best_found_trial(); + cout << endl << "Initial temperature in trial: " << initial_temperature_trial(); + cout << endl << "Temperature of best solution found in trial: " << temperature_best_found_trial(); + cout << endl << "Time spent in trial: " << time_spent_trial(); + cout << endl << "Global best cost: " << global_best_cost(); + cout << endl << "Trial of best global solution found: " << trial_best_found(); + cout << endl << "Iteration of best global solution found: " << iteration_best_found(); + cout << endl << "Time of global best solution found: " << time_best_found(); + // cout << endl << "Current solution: " << current_solution(); + // cout << endl << "Best solution of trial: " << current_best_solution(); + // cout << endl << "Global solution: " << global_best_solution() << endl; + cout << endl << endl << "Current time spent (so far): " << current_time_spent() << endl; + } + + Solver::~Solver() + { + _sc.removeAll(); + delete move; + } + + bool Solver::AcceptQ (double tent, double cur, double temperature) + { + if (_direction==minimize) + + return (tent < cur) || + ((rand01()*(1+exp((tent-cur)/temperature)))<2.0); + + else + + return (tent > cur) || + ((rand01()*(1+exp((cur-tent)/temperature)))<2.0); + } + + double Solver::Set_Initial_Temperature(const Problem& pbm) + { + const double beta = 1.05; + const double test = 10; + const double acrat = .8; + const double T = 1.0; + + Solution current (pbm); + Solution newsol (pbm); + double ac; + double fit; + double temperature = T; + + do + { + temperature *= beta; + ac = 0; + current.initialize(); + fit = current.fitness(); + for (int i=0; i<test; i++) + { + newsol = current; + move->Apply(newsol); + if (AcceptQ(newsol.fitness(),fit,temperature)) + ac += 1.0/test; + } + } while (ac < acrat); + + initial_temperature_trial(temperature); + return temperature; + + } + + void Solver::SetMove (Move* mov) + { + delete move; + move = mov; + } + + // Solver sequencial ----------------------------------------------------- + + Solver_Seq::Solver_Seq (const Problem& pbm, const SetUpParams& setup) + : Solver(pbm,setup) + { + random_seed(time(0)); + _end_trial=true; + } + + Solver_Seq::~Solver_Seq () + {} + + void Solver_Seq::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Seq::StartUp(const Solution& sol, const double initialTemperature) + { + start_trial=_used_time(); + start_global=total_time_spent; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current = sol; + curfit = current.fitness(); + current_best_cost((-1) * problem.direction() * infinity()); + currentTemperature = initialTemperature; + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + void Solver_Seq::DoStep() + { + current_iteration(current_iteration()+1); + + tentative = current; + move->Apply(tentative); + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + + void Solver_Seq::run (unsigned long int max_evaluations) + { + StartUp(); + + while (current_iteration()<max_evaluations && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + // Solver LAN ----------------------------------------------------------- + + Solver_Lan::Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); + } + + Solver_Lan::~Solver_Lan () + { + NetStream::finalize(); + } + + int Solver_Lan::pid() const + { + return mypid; + } + + NetStream& Solver_Lan::netstream() + { + return _netstream; + } + + void Solver_Lan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Lan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + void update(Direction direction, Solution &solution_received,double cost_received, Solution &solution_to_send, double &best_cost) + { + switch (direction) + { + case minimize: if (cost_received < best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + case maximize: if (cost_received > best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + } + } + + int Solver_Lan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Lan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Lan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Lan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Lan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Lan::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + void Solver_Lan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } + + // Solver WAN ------------------------------------------------------------ + + Solver_Wan::Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); + } + + Solver_Wan::~Solver_Wan () + { + NetStream::finalize(); + } + + int Solver_Wan::pid() const + { + return mypid; + } + + NetStream& Solver_Wan::netstream() + { + return _netstream; + } + + void Solver_Wan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Wan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + int Solver_Wan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Wan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Wan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Wan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Wan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Wan::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + void Solver_Wan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } +}; + diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/SA.pro.cc1 b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/SA.pro.cc1 new file mode 100644 index 0000000000000000000000000000000000000000..3d95a77e472c61314ac087f8a415735030e5fa6e --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/SA.pro.cc1 @@ -0,0 +1,1837 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** Provided classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** *** +************************************************/ + +#include <iostream.h> +#include <math.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "Mallba/time.hh" +#include "ContigBuilder.h" + +skeleton SA +{ + +// SetUpParams ----------------------------------------------------------- + + SetUpParams::SetUpParams (): + _independent_runs(0), + _max_evaluations(0), + _MarkovChain_length(0), + _temperature_decay(0), + _refresh_global_state(0), + _synchronized(0), + _display_state(0), + _cooperation(0) + {} + + istream& operator>> (istream& is, SetUpParams& setup) + { + char buffer[MAX_BUFFER]; // current line in the setup file + char command[50]; + int op; + double dop; + short int nb_param=0; + short int nb_section=0; + short int nb_LAN_param=0; + + while (is.getline(buffer,MAX_BUFFER,'\n')) + { + sscanf(buffer," %s ",command); + + if (!(strcmp(command,"General"))) nb_section=0; + if (!(strcmp(command,"LAN-configuration"))) nb_section=1; + + if (nb_param==3 && nb_section==0) + { + dop=-1; + sscanf(buffer," %lf ",&dop); + if (dop<0) continue; + } + else + { + op=-1; + sscanf(buffer," %d ",&op); + if (op<0) continue; + } + + switch (nb_section) + { + case 0: switch (nb_param) + { + case 0: setup.independent_runs(op); break; + case 1: setup.max_evaluations(op); break; + case 2: setup.MarkovChain_length(op); break; + case 3: setup.temperature_decay(dop); break; + case 4: setup.display_state(op); break; + } + nb_param++; + break; + case 1: if (nb_LAN_param>=3) break; + if (nb_LAN_param==0) setup.refresh_global_state(op); + if (nb_LAN_param==1) setup.synchronized(op); + if (nb_LAN_param==2) setup.cooperation(op); + nb_LAN_param++; + break; + } // end switch + } // end while + return is; + } + + ostream& operator<< (ostream& os, const SetUpParams& setup) + { + os << "CONFIGURATION -------------------------------------------" << endl << endl; + os << "\t" << "Independent runs : " << setup.independent_runs() << endl + << "\t" << "Evaluation steps: " << setup.max_evaluations() << endl + << "\t" << "Markov-Chain Length: " << setup.MarkovChain_length() << endl + << "\t" << "Temperature Decay: " << setup.temperature_decay() << endl; + + if (setup.display_state()) + os << "\t" << "Display state" << endl; + else + os << "\t" << "Not display state" << endl; + os << endl << "\t" << "LAN configuration:" << endl + << "\t" << "----------------------" << endl << endl + << "\t" << "Refresh global state in number of generations: " << setup.refresh_global_state() << endl; + + if (setup.synchronized()) + os << "\t" << "Running in synchronous mode" << endl; + else + os << "\t" << "Running in asynchronous mode" << endl; + + if (!setup.cooperation()) + os << "\t" << "Running without cooperation" << endl << endl; + else + os << "\t" << "Running with cooperation in " << setup.cooperation() << " iterations. " << endl << endl; + + os << endl << endl << "END CONFIGURATION -------------------------------------------" << endl << endl; + return os; + } + + const unsigned int SetUpParams::independent_runs() const + { + return _independent_runs; + } + + const unsigned long SetUpParams::max_evaluations() const + { + return _max_evaluations; + } + + const unsigned int SetUpParams::MarkovChain_length() const + { + return _MarkovChain_length; + } + + const double SetUpParams::temperature_decay() const + { + return _temperature_decay; + } + + const bool SetUpParams::display_state() const + { + return _display_state; + } + + const unsigned long SetUpParams::refresh_global_state() const + { + return _refresh_global_state; + } + + const bool SetUpParams::synchronized() const + { + return _synchronized; + } + + const unsigned int SetUpParams::cooperation() const + { + return _cooperation; + } + + void SetUpParams::independent_runs(const unsigned int val) + { + _independent_runs = val; + } + + void SetUpParams::max_evaluations(const unsigned long val) + { + _max_evaluations= val; + } + void SetUpParams::MarkovChain_length(const unsigned int val) + { + _MarkovChain_length= val; + } + void SetUpParams::temperature_decay(const double val) + { + _temperature_decay= val; + } + + void SetUpParams::display_state(const bool val) + { + _display_state=val; + } + + void SetUpParams::refresh_global_state(const unsigned long val) + { + _refresh_global_state=val; + } + + void SetUpParams::synchronized(const bool val) + { + _synchronized=val; + } + + void SetUpParams::cooperation(const unsigned int val) + { + _cooperation=val; + } + + SetUpParams::~SetUpParams() + {} + +// Statistics ------------------------------------------------------ + + Statistics::Statistics() + {} + + ostream& operator<< (ostream& os, const Statistics& stats) + { + int j; + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF CURRENT TRIAL " << endl; + os << "------------------------------------------------------------------" << endl; + for (int i=0;i< stats.stats_data.size();i++) + { + os << endl + << " Evaluations: " << stats.stats_data[i].nb_evaluations + << " Best: " << stats.stats_data[i].best_cost + << " Current: " << stats.stats_data[i].current_cost; + } + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + Statistics& Statistics::operator= (const Statistics& stats) + { + stats_data = stats.stats_data; + return *this; + } + + void Statistics::update(const Solver& solver) + { + /* struct stat *new_stat; + if ((new_stat=(struct stat *)malloc(sizeof(struct stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluations= solver.current_iteration(); + new_stat->best_cost = solver.current_best_cost(); + new_stat->current_cost = solver.current_cost(); + stats_data.append(*new_stat); */ + } + + Statistics::~Statistics() + { + stats_data.remove(); + } + + void Statistics::clear() + { + stats_data.remove(); + } + +// Solver (superclass)--------------------------------------------------- + + Solver::Solver (const Problem& pbm, const SetUpParams& setup) + : problem(pbm), + params(setup), + _stat(), + _userstat(), + _sc(), + _direction(pbm.direction()), + current(pbm), + tentative(pbm), + currentTemperature(0.0), + time_spent_in_trial(0.0), + total_time_spent(0.0), + start_trial(0.0), + start_global(0.0), + _current_trial("_current_trial",_sc), + _current_iteration("_current_iteration",_sc), + _current_best_solution("_current_best_solution",_sc), + _current_best_cost("_current_best_cost",_sc), + _current_solution("_current_solution",_sc), + _current_cost("_current_cost",_sc), + _current_time_spent("_current_time_spent",_sc), + _initial_temperature_trial("_initial_temperature_trial",_sc), + _time_best_found_trial("_time_best_found_trial",_sc), + _iteration_best_found_trial("_iteration_best_found_trial",_sc), + _temperature_best_found_trial("_temperature_best_found_trial",_sc), + _time_spent_trial("_time_spent_trial",_sc), + _trial_best_found("_trial_best_found",_sc), + _iteration_best_found("_iteration_best_found;",_sc), + _global_best_solution("_global_best_solution",_sc), + _global_best_cost("_global_best_cost",_sc), + _time_best_found("_time_best_found",_sc), + _temperature("_temperature",_sc), + _display_state("_display_state",_sc) + { + current_trial(0); + current_iteration(0); + current_best_solution(current), + current_best_cost((-1) * pbm.direction() * infinity()); + current_solution(current); + current_cost((-1) * pbm.direction() * infinity()); + current_time_spent(total_time_spent); + initial_temperature_trial(0); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(0); + temperature_best_found_trial(0.0); + time_spent_trial(time_spent_in_trial); + trial_best_found(0); + iteration_best_found(0); + global_best_solution(current); + global_best_cost((-1) * pbm.direction() * infinity()); + time_best_found(total_time_spent); + temperature(currentTemperature); + display_state(setup.display_state()); + + move = new DefaultMove; + } + + int Solver::pid() const + { + return 0; + } + + bool Solver::end_trial() const + { + return _end_trial; + } + + unsigned int Solver::current_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_trial",(char *)&value, nitems, length); + return value; + } + + unsigned long Solver::current_iteration() const + { + unsigned long value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_iteration",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_best_solution() const + { + Solution sol(problem); + unsigned long nitems,length; + char data_stored[_current_best_solution.get_nitems() + _current_best_solution.get_length()]; + _sc.get_contents_state_variable("_current_best_solution", data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::current_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_best_cost",(char *)&value, nitems, length); + return value; + } + + double Solver::current_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_cost",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_solution() const + { + Solution sol(problem); + char data_stored[_current_solution.get_nitems() + _current_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_solution",data_stored, nitems, length); + sol.to_Solution((char *)data_stored); + return sol; + } + + float Solver::current_time_spent() const + { + float value=0.0; + unsigned long nitems,length; + _current_time_spent.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::initial_temperature_trial() const + { + double value=0.0; + unsigned long nitems,length; + _initial_temperature_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature_best_found_trial() const + { + double value=0.0; + unsigned long nitems,length; + _temperature_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_spent_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_spent_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::trial_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _trial_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::global_best_solution() const + { + Solution sol(problem); + char data_stored[_global_best_solution.get_nitems() + _global_best_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_solution",data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::global_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_cost",(char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_temperature",(char *)&value, nitems, length); + return value; + } + + int Solver::display_state() const + { + int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_display_state",(char *)&value, nitems, length); + return value; + } + + void Solver::current_trial(const unsigned int value) + { + _sc.set_contents_state_variable("_current_trial",(char *)&value,1,sizeof(int)); + } + + void Solver::current_iteration(const unsigned long value) + { + _sc.set_contents_state_variable("_current_iteration",(char *)&value,1,sizeof(long)); + } + + void Solver::current_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_best_cost(const double value) + { + _sc.set_contents_state_variable("_current_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_cost(const double value) + { + _sc.set_contents_state_variable("_current_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_time_spent(const float value) + { + _current_time_spent.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::time_best_found_trial(const float value) + { + _time_best_found_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::iteration_best_found_trial(const unsigned int value) + { + _iteration_best_found_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::initial_temperature_trial(const double value) + { + _initial_temperature_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::temperature_best_found_trial(const double value) + { + _temperature_best_found_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::time_spent_trial(const float value) + { + _time_spent_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::trial_best_found(const unsigned int value) + { + _trial_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::iteration_best_found(const unsigned int value) + { + _iteration_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::global_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_global_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::global_best_cost(const double value) + { + _sc.set_contents_state_variable("_global_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::time_best_found(const float value) + { + _time_best_found.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::temperature(const double value) + { + _sc.set_contents_state_variable("_temperature",(char *)&value,1,sizeof(double)); + } + + void Solver::display_state(const int value) + { + _sc.set_contents_state_variable("_display_state",(char *)&value,1,sizeof(int)); + } + + const Statistics& Solver::statistics() const + { + return _stat; + } + + const UserStatistics& Solver::userstatistics() const + { + return _userstat; + } + + const SetUpParams& Solver::setup() const + { + return params; + } + + const Problem& Solver::pbm() const + { + return problem; + } + + void Solver::KeepHistory(const Solution& sol, const double curfit,const float time_spent_in_trial,const float total_time_spent) + { + bool betterG=false; + bool betterT=false; + + switch (_direction) + { + case minimize: betterG = (curfit < global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit < current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + case maximize: betterG = (curfit > global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit > current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + } + + if (betterT) + { + current_best_solution(sol); + current_best_cost(curfit); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(current_iteration()); + temperature_best_found_trial(temperature()); + if (betterG) + { + trial_best_found(current_trial()); + iteration_best_found(current_iteration()); + global_best_solution(sol); + global_best_cost(curfit); + time_best_found(time_spent_in_trial); + } + } + } + + double Solver::UpdateT(double temp, int K) + { + return temp * params.temperature_decay(); // initial + + /* + if(K == 1) return temp/log(2); + else return temp * log(K) / log(K+1); + */ + /* + if(K == 1) return temp/2; + else return (temp * K) / (K + 1); + */ + +/* if(K == 1) return temp / exp(2); + else return (temp * exp(K)) / exp(K+1);*/ + + } + + StateCenter* Solver::GetState() + { + return &_sc; + } + + void Solver::RefreshState() + { + current_solution(current); + current_cost(curfit); + current_time_spent(total_time_spent); + time_spent_trial(time_spent_in_trial); + temperature(currentTemperature); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::UpdateFromState() + { + current = current_solution(); + curfit = current_cost(); + total_time_spent=current_time_spent(); + time_spent_in_trial=time_spent_trial(); + currentTemperature = temperature(); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::show_state() const + { + cout << endl << "Current trial: " << current_trial(); + cout << endl << "Current iteration: " << current_iteration(); + cout << endl << "Current Temperature: " << temperature (); + cout << endl << "Current cost: " << current_cost(); + cout << endl << "Best cost in trial: " << current_best_cost(); + cout << endl << "Time of best solution found in trial: " << time_best_found_trial(); + cout << endl << "Iteration of best solution found in trial: " << iteration_best_found_trial(); + cout << endl << "Initial temperature in trial: " << initial_temperature_trial(); + cout << endl << "Temperature of best solution found in trial: " << temperature_best_found_trial(); + cout << endl << "Time spent in trial: " << time_spent_trial(); + cout << endl << "Global best cost: " << global_best_cost(); + cout << endl << "Trial of best global solution found: " << trial_best_found(); + cout << endl << "Iteration of best global solution found: " << iteration_best_found(); + cout << endl << "Time of global best solution found: " << time_best_found(); + // cout << endl << "Current solution: " << current_solution(); + // cout << endl << "Best solution of trial: " << current_best_solution(); + // cout << endl << "Global solution: " << global_best_solution() << endl; + cout << endl << endl << "Current time spent (so far): " << current_time_spent() << endl; + } + + Solver::~Solver() + { + _sc.removeAll(); + delete move; + } + + bool Solver::AcceptQ (double tent, double cur, double temperature) + { + if (_direction==minimize) + + return (tent < cur) || + ((rand01()*(1+exp((tent-cur)/temperature)))<2.0); + + else + + return (tent > cur) || + ((rand01()*(1+exp((cur-tent)/temperature)))<2.0); + } + + double Solver::Set_Initial_Temperature(const Problem& pbm) + { + const double beta = 1.05; + const double test = 10; + const double acrat = .8; + const double T = 1.0; + + Solution current (pbm); + Solution newsol (pbm); + double ac; + double fit; + double temperature = T; + + do + { + temperature *= beta; + ac = 0; + current.initialize(); + fit = current.fitness(); + for (int i=0; i<test; i++) + { + newsol = current; + move->Apply(newsol); + if (AcceptQ(newsol.fitness(),fit,temperature)) + ac += 1.0/test; + } + } while (ac < acrat); + + initial_temperature_trial(temperature); + return temperature; + + } + + void Solver::SetMove (Move* mov) + { + delete move; + move = mov; + } + + // Solver sequencial ----------------------------------------------------- + + Solver_Seq::Solver_Seq (const Problem& pbm, const SetUpParams& setup) + : Solver(pbm,setup) + { + random_seed(time(0)); + _end_trial=true; + } + + Solver_Seq::~Solver_Seq () + {} + + void Solver_Seq::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Seq::StartUp(const Solution& sol, const double initialTemperature) + { + start_trial=_used_time(); + start_global=total_time_spent; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current = sol; + curfit = current.fitness(); + current_best_cost((-1) * problem.direction() * infinity()); + currentTemperature = initialTemperature; + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + void Solver_Seq::DoStep() + { + current_iteration(current_iteration()+1); + + tentative = current; + move->Apply(tentative); + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + +cerr << current_best_cost() << endl; + + if (display_state()) + show_state(); + } + + + void Solver_Seq::run (unsigned long int max_evaluations) + { + StartUp(); + + while (current_iteration()<max_evaluations && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run () + { + while (current_trial() < params.independent_runs()) + { + run(params.max_evaluations()); +// cerr << "Entrado" << endl; +// Solution s(current_best_solution()); +// cerr << s; +// ContigBuilder * builder = new ContigBuilder(s.fragments(), problem.detector->getScoreTable(),&problem); +// builder->buildContigs(); +// builder->mergeContigs(); +// // builder->buildConsensus(); +// delete builder; + + } + } + + // Solver LAN ----------------------------------------------------------- + + Solver_Lan::Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { +cout << "ConstructorA " << endl; + NetStream::init(argc,argv); +cout << "ConstructorB " << endl; + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); +cout << "Constructor " << endl; + } + + Solver_Lan::~Solver_Lan () + { + NetStream::finalize(); + } + + int Solver_Lan::pid() const + { + return mypid; + } + + NetStream& Solver_Lan::netstream() + { + return _netstream; + } + + void Solver_Lan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Lan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + void update(Direction direction, Solution &solution_received,double cost_received, Solution &solution_to_send, double &best_cost) + { + switch (direction) + { + case minimize: if (cost_received < best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + case maximize: if (cost_received > best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + } + } + + int Solver_Lan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Lan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Lan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Lan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Lan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Lan::run () + { + while (current_trial() < params.independent_runs()) + { + run(params.max_evaluations()); + if(mypid == 0) + { +// cerr << "Entrado" << endl; +// Solution s(current_solution()); +// cerr << s; +// ContigBuilder * builder = new ContigBuilder(s.fragments(), problem.detector->getScoreTable(),&problem); +// builder->buildContigs(); +// builder->mergeContigs(); +// // builder->buildConsensus(); +// delete builder; + } + } + } + + void Solver_Lan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } + + // Solver WAN ------------------------------------------------------------ + + Solver_Wan::Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); + } + + Solver_Wan::~Solver_Wan () + { + NetStream::finalize(); + } + + int Solver_Wan::pid() const + { + return mypid; + } + + NetStream& Solver_Wan::netstream() + { + return _netstream; + } + + void Solver_Wan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Wan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + int Solver_Wan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Wan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Wan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Wan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Wan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Wan::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + void Solver_Wan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } +}; + diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/SA.req.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/SA.req.cc new file mode 100644 index 0000000000000000000000000000000000000000..153f37cf575f7b928df2b483af2710d9c5751bc7 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/SA.req.cc @@ -0,0 +1,437 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** User-required classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** Tab size = 4 *** +*** *** +*** *** +************************************************/ + +#include <iostream.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "StopCondition.hh" +#include <math.h> +#include "Util.h" +#include "AdjKeys.h" + +skeleton SA { + + // Problem --------------------------------------------------------------- + + Problem::Problem ():numOfFragments(0),avgLength(0.0),cutoff(0), + fragmentLength(NULL),fragments(NULL),rcFragments(NULL), + description(NULL) + { + } + + ostream& operator<< (ostream& os, const Problem& pbm) + { + return os; + } + + istream& operator>> (istream& is, Problem& pbm) + { + char buffer[MAX_BUFFER]; + int i; + + + is.getline(buffer,MAX_BUFFER,'\n'); + sscanf(buffer,"%d",&pbm.cutoff); + + is.getline(buffer,MAX_BUFFER,'\n'); +//cout << buffer; + ifstream f((string(getenv("HOME")) + buffer).c_str()); + + int seqCount = -1; + pbm.fragments = new vector<string>(); + pbm.description = new vector<string>(); + + /* read fragments from input file and store its description in descr[] + and its sequence in sequence[] */ + + char oneLine[2000]; + string sequence; + string upperSeq; + while(f.getline(oneLine, 2000)) + { +//cout << oneLine; + string temp = string(oneLine); + int rightArrow = temp.find_first_of(">"); + if(rightArrow != -1) //rightArrow is found + { + seqCount++; + if(seqCount != 0) + pbm.fragments->push_back(sequence); + int space = temp.find(" ", rightArrow); + pbm.description->push_back(temp.substr(rightArrow+1, space)); + sequence = ""; + } + else //line doesn't start with rightArrow + { + upperSeq = ""; + for(int i = 0; i < temp.length(); i++) + upperSeq += toupper(temp.at(i)); + + sequence.append(upperSeq); + } + } + pbm.fragments->push_back(sequence); + f.close(); + + pbm.numOfFragments = pbm.fragments->size(); + pbm.fragmentLength = new int[pbm.numOfFragments]; + + pbm.rcFragments = new vector<string>(); + + for(int j = 0; j < pbm.numOfFragments; j++) + { + pbm.rcFragments->push_back(Util::rcSequence(pbm.fragments->at(j))); +//cout << pbm.description->at(j) << " " << pbm.fragments->at(j) << " " << pbm.rcFragments->at(j) << endl; + } + + int sumLength = 0; + for(int i = 0; i < pbm.numOfFragments; i++) + { + pbm.fragmentLength[i] = pbm.fragments->at(i).length(); + sumLength += pbm.fragmentLength[i]; + } + pbm.avgLength = (double)sumLength / (double)pbm.numOfFragments; + + pbm.detector = new OverlapDetector(pbm.numOfFragments); +// pbm.detector->buildScoresTable(pbm.fragments, pbm.rcFragments); + pbm.detector->readScoreTable(); +// pbm.detector->printScoreTable(); + + return is; + } + + bool Problem::operator== (const Problem& pbm) const + { + // Falta terminar + return true; + } + + bool Problem::operator!= (const Problem& pbm) const + { + return !(*this == pbm); + } + + Direction Problem::direction() const + { + return maximize; // F1 +// return minimize; // F2 + } + + Problem::~Problem() + { + delete detector; + delete fragments; + delete rcFragments; + delete description; + delete [] fragmentLength; + } + + // Solution -------------------------------------------------------------- + + Solution::Solution (const Problem& pbm):_pbm(pbm),fragOrder(new int[pbm.numOfFragments]) + {} + + const Problem& Solution::pbm() const + { + return _pbm; + } + + Solution::Solution(const Solution& sol):_pbm(sol.pbm()) + { + if(fragOrder != NULL) delete [] fragOrder; + + fragOrder = new int [_pbm.numOfFragments]; + + for(int i = 0; i < _pbm.numOfFragments; i++) + fragOrder[i] = sol.fragOrder[i]; + } + + istream& operator>> (istream& is, Solution& sol) + { + for (int i=0;i<sol.pbm().numOfFragments;i++) + is >> sol.fragOrder[i]; + return is; + } + + ostream& operator<< (ostream& os, const Solution& sol) + { + for (int i=0;i<sol.pbm().numOfFragments;i++) + os << " " << sol.fragOrder[i]; + return os; + } + + NetStream& operator << (NetStream& ns, const Solution& sol) + { + for (int i=0;i<sol.pbm().numOfFragments;i++) + ns << sol.fragOrder[i]; + return ns; + } + + NetStream& operator >> (NetStream& ns, Solution& sol) + { + for (int i=0;i<sol.pbm().numOfFragments;i++) + ns >> sol.fragOrder[i]; + return ns; + } + + Solution& Solution::operator= (const Solution &sol) + { + if(fragOrder != NULL) delete [] fragOrder; + + fragOrder = new int [_pbm.numOfFragments]; + + for(int i = 0; i < _pbm.numOfFragments; i++) + fragOrder[i] = sol.fragOrder[i]; + + return *this; + } + + bool Solution::operator== (const Solution& sol) const + { + if (sol.pbm() != _pbm) return false; + for(int i = 0; i < _pbm.numOfFragments; i++) + if(fragOrder[i] != sol.fragOrder[i]) return false; + return true; + } + + bool Solution::operator!= (const Solution& sol) const + { + return !(*this == sol); + } + + void Solution::initialize() + { + int * randNum = new int[_pbm.numOfFragments]; + + for(int k = 0; k < _pbm.numOfFragments; k++) + { + int num = rand_int(0, _pbm.numOfFragments * 2); + randNum[k] = num; + fragOrder[k] = k; + } + + // sort value and store index as fragment order + for(int i = 0; i < _pbm.numOfFragments-1; i++) + { + for(int j = i+1; j < _pbm.numOfFragments; j++) + { + if( randNum[i] > randNum[j]) + { + int temp = randNum[i]; + randNum[i] = randNum[j]; + randNum[j] = temp; + + temp = fragOrder[i]; + fragOrder[i] = fragOrder[j]; + fragOrder[j] = temp; + } + } + } + delete [] randNum; + } + + double Solution::fitness () + { + int ** score = _pbm.detector->getScoreTable(); + // F1 maximization + int fit = 0; + + for(int k = 0; k < _pbm.numOfFragments-1; k++) + { + int i = fragOrder[k]; + int j = fragOrder[k+1]; + + fit += abs(score[i][j]); + } + return (double) fit; + // F2 minimization +/* int fit = 0; + int nof = _pbm.numOfFragments; + + for(int i = 0; i < nof; i++) + { + int m = fragOrder[i]; + for(int j = 0; j < nof; j++) + { + if(i != j) + { + int n = fragOrder[j]; + if((nof<m) || (nof<n) || (m<0) || (n<0)) + { + cout << "Error en indices" << endl; + return infinity(); + } + fit += abs(i-j) * abs(score[m][n]); + } + } + } + return (double)fit; +*/ } + + char *Solution::to_String() const + { + return (char *)fragOrder; + } + + void Solution::to_Solution(char *_string_) + { + int *ptr=(int *)_string_; + + for (int i=0;i<_pbm.numOfFragments;i++) + { + fragOrder[i]=*ptr; + ptr++; + } + } + + unsigned int Solution::size() const + { + return (_pbm.numOfFragments * sizeof(int)); + } + + + int& Solution::fragment(const int index) + { + return fragOrder[index]; + } + + + int* Solution::fragments() + { + return fragOrder; + } + + Solution::~Solution() + { + delete [] fragOrder; + } + + // UserStatistics ------------------------------------------------------- + + UserStatistics::UserStatistics () + {} + + ostream& operator<< (ostream& os, const UserStatistics& userstat) + { + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF TRIALS " << endl; + os << "------------------------------------------------------------------" << endl; + + for (int i=0;i< userstat.result_trials.size();i++) + { + os << endl + << "\t" << userstat.result_trials[i].trial + << "\t" << userstat.result_trials[i].best_cost_trial + << "\t\t" << userstat.result_trials[i].nb_evaluation_best_found_trial + << "\t\t" << userstat.result_trials[i].initial_temperature + << "\t\t" << userstat.result_trials[i].temperature_best_found_trial + << "\t\t" << userstat.result_trials[i].time_best_found_trial + << "\t\t" << userstat.result_trials[i].time_spent_trial; + } + + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + + UserStatistics& UserStatistics::operator= (const UserStatistics& userstats) + { + result_trials=userstats.result_trials; + return (*this); + } + + + void UserStatistics::update(const Solver& solver) + { + if ((solver.pid()!=0) || (solver.end_trial()!=true) + || ((solver.current_iteration()!=solver.setup().max_evaluations()) + && !TerminateQ(solver.pbm(),solver,solver.setup()))) + return; + + struct user_stat *new_stat; + if ((new_stat=(struct user_stat *)malloc(sizeof(struct user_stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluation_best_found_trial= solver.iteration_best_found_trial(); + new_stat->initial_temperature=solver.initial_temperature_trial(); + new_stat->temperature_best_found_trial=solver.temperature_best_found_trial(); + new_stat->best_cost_trial = solver.current_best_cost(); + new_stat->time_best_found_trial= solver.time_best_found_trial(); + new_stat->time_spent_trial = solver.time_spent_trial(); + result_trials.append(*new_stat); + } + + void UserStatistics::clear() + { + result_trials.remove(); + } + + UserStatistics::~UserStatistics() + { + result_trials.remove(); + } + +// DefaultMove ------------------------------------------------------- + + + DefaultMove::DefaultMove() + {} + + DefaultMove::~DefaultMove() + {} + + void DefaultMove::Apply (Solution& sol) const + { + int indsize = sol.pbm().numOfFragments; + int r1 = rand_int(0, indsize-1); + int r2 = rand_int(0, indsize-1); + + while(r2 == r1) + { + if(r1 == indsize-1) r2 = rand_int(0, indsize-2); + else r2 = rand_int(r1, indsize-1); + } + + /* // swap + int temp = sol.fragment(r1); + sol.fragment(r1) = sol.fragment(r2); + sol.fragment(r2) = temp; +*/ + // 2-opt + if(r2 < r1) + { + int temp = r1; + r1 = r2; + r2 = temp; + } + while(r2 > r1) + { + int temp = sol.fragment(r1); + sol.fragment(r1) = sol.fragment(r2); + sol.fragment(r2) = temp; + ++r1; + --r2; + } + } + + //------------------------------------------------------------------------ + // Specific methods ------------------------------------------------------ + //------------------------------------------------------------------------ + + bool TerminateQ (const Problem& pbm, const Solver& solver, + const SetUpParams& setup) + { + + StopCondition_3 stop; + return stop.EvaluateCondition(pbm,solver,setup); + } +} + + diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/StopCondition.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/StopCondition.cc new file mode 100644 index 0000000000000000000000000000000000000000..2033972200be773a0ab34fc208d4cb4b54dcbe52 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/StopCondition.cc @@ -0,0 +1,52 @@ +#include "StopCondition.hh" +skeleton SA +{ + +// StopCondition ------------------------------------------------------------------------------------- + + StopCondition::StopCondition() + {} + + StopCondition::~StopCondition() + {} + +// StopCondition_1 ------------------------------------------------------------------------------------- + + StopCondition_1::StopCondition_1():StopCondition() + {} + + bool StopCondition_1::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return false; + } + + StopCondition_1::~StopCondition_1() + {} + +// StopCondition_2 ------------------------------------------------------------------------------------- + + StopCondition_2::StopCondition_2():StopCondition() + {} + + bool StopCondition_2::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return (solver.global_best_cost()>8.5); + } + + StopCondition_2::~StopCondition_2() + {} + +// StopCondition_3 ------------------------------------------------------------------------------------- + + StopCondition_3::StopCondition_3():StopCondition() + {} + + bool StopCondition_3::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return (false); + } + + StopCondition_3::~StopCondition_3() + {} + +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/StopCondition.hh b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/StopCondition.hh new file mode 100644 index 0000000000000000000000000000000000000000..04ef770d9cac5bb9ef69aae7d085e3ae2166e187 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/StopCondition.hh @@ -0,0 +1,41 @@ +#ifndef stop_condition +#define stop_condition + +#include "SA.hh" +skeleton SA +{ + + provides class StopCondition + { + public: + StopCondition(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup)=0; + ~StopCondition(); + }; + + requires class StopCondition_1 : public StopCondition + { + public: + StopCondition_1(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_1(); + }; + + requires class StopCondition_2 : public StopCondition + { + public: + StopCondition_2(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_2(); + }; + + requires class StopCondition_3 : public StopCondition + { + public: + StopCondition_3(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_3(); + }; +} + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/Util.h b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/Util.h new file mode 100644 index 0000000000000000000000000000000000000000..fcea0d2d0d04098a16abf56b5b97da6c779cb053 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/Util.h @@ -0,0 +1,71 @@ +/************************************************************** + * File: Util.h + * Author: Lishan Li + * Date: May, 2003 + * + * Description: This Util class consists of utility functions + * used by other classes + **************************************************************/ + +#ifndef UTIL_H +#define UTIL_H + +#include <stdlib.h> +#include <vector> + +using namespace std; + +class Util +{ +public: + /* returns a randomly generated floating point number ranged [min, max] */ +// static double randDouble(double min, double max) +// { +// return (1.0*rand()*(max-min)/RAND_MAX + min); +// } + + /* returns a randomly generated interge number ranged [min, max] */ +// static int randInt(int min, int max) +// { +// return (int)randDouble(min, max); +// } + + /* returns a string that is the reverse of a given DNA sequence */ + static string revSequence(const string &s) + { + string revSeq = s; + int j = 0; + for(int i = s.length()-1; i >= 0; i--) + revSeq[j++] = s.at(i); + + return revSeq; + } + + /* returns a string that is the complement of a given DNA sequence */ + static string complSequence(const string &s) + { + string compSeq = s; + int j = 0; + for(unsigned int i = 0; i < s.length(); i++) + { + if(s.at(i) == 'A') + compSeq[j++] = 'T'; + else if(s.at(i) == 'T') + compSeq[j++] = 'A'; + else if(s.at(i) == 'C') + compSeq[j++] = 'G'; + else if(s.at(i) == 'G') + compSeq[j++] = 'C'; + else + compSeq[j++] = s.at(i); + } + return compSeq; + } + + /* returns a string that is the reverse complement of a given DNA sequence */ + static string rcSequence(const string &s) + { + return complSequence(revSequence(s)); + } +}; +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/list.h b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/list.h new file mode 100644 index 0000000000000000000000000000000000000000..46eff2e9f78b877a8488dbe648d45cc3ef473b16 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/list.h @@ -0,0 +1,300 @@ +/*************************************************************** + * File: list.h + * Author: Lishan Li + * Date: May, 2003 + * + * Description: This List class is a template class. It builds a + * single linked list of any type of objects. + ***************************************************************/ + +#ifndef LIST_H +#define LIST_H + +#include <assert.h> +#include <stdlib.h> +#include <iostream> +using namespace std; + +template <class T> +struct ListNode +{ + T data; // T could be any type of object + ListNode<T> *next; +}; + +template <class T> +class List1 +{ +public: + ListNode<T>* header; // header is a dummy node + ListNode<T>* current; + int len; // length of the linked list + + List1(); // constructor + ~List1(); // destructor + + List1(const List1<T> & source); // copy constructor + List1<T> & operator=(const List1<T> & source); + void append(const T); // append data at the end of list + void insert(const T); // insert data in order + void insertPtr(const T); // insert pointer type of object in order + void insertFront(const T); // insert data at the beginning of the list + void remove(const T); // delete data from list + void next(); + void prev(); + void reset(); + void clear(); + int length() const { return len; } + bool isEmpty() const; // check whether list is empty + bool isFull() const; // check whether memory is allocated + T value() const; // return content of the data + void printList(); + void printListPtr(); + ListNode<T>* findPrevious(const T); + ListNode<T>* search(const T); +}; + +template <class T> +List1<T>::List1() +{ + header = new ListNode<T>; + header->next = NULL; + current = header; + len = 0; +} + +template <class T> +List1<T>::List1(const List1<T> & source) +{ + header = NULL; + *this = source; +} + +template <class T> +List1<T> & List1<T>::operator=(const List1<T> & source) +{ + if(this != &source) + { + ListNode<T> * current = source.header; + while(current != NULL) + { + insert(current->data); + current = current->pnext; + } + } + return *this; +} + +template <class T> +void List1<T>::clear() +{ + ListNode<T> *tmp; + ListNode<T> *previous = header; + ListNode<T> *traverse = header->next; + + while(traverse != NULL) // release memory from list + { + tmp = traverse; + previous->next = traverse->next; + traverse = traverse->next; + delete tmp; + } + current = header; + len = 0; +} + +template <class T> +List1<T>::~List1() +{ + clear(); + delete header; +} + + +template <class T> +void List1<T>::insert(const T item) +{ + assert(!isFull()); + ListNode<T> * newNode = new ListNode<T>; + newNode->data = item; + newNode->next = NULL; + if(len == 0) // no need to traverse + { + newNode->next = current->next; + current->next = newNode; + } + else // need to traverse + { + ListNode<T> * temp = header; + while((temp->next != NULL) && (item < temp->next->data)) + temp = temp->next; + newNode->next = temp->next; + temp->next = newNode; + } + len++; +} + +template <class T> +void List1<T>::insertPtr(const T item) +{ + assert(!isFull()); + ListNode<T> * newNode = new ListNode<T>; + newNode->data = item; + newNode->next = NULL; + if(len == 0) // no need to traverse + { + newNode->next = current->next; + current->next = newNode; + } + else // need to traverse + { + ListNode<T> * temp = header; + while((temp->next != NULL) && (*item < *(temp->next->data))) // pointer need dereference + temp = temp->next; + newNode->next = temp->next; + temp->next = newNode; + } + len++; +} + +template <class T> +void List1<T>::insertFront(const T item) +{ + ListNode<T> * newNode = new ListNode<T>; + newNode->data = item; + newNode->next = header->next; + header->next = newNode; + len++; +} + +template <class T> +void List1<T>::append(const T item) +{ + assert(!isFull()); + ListNode<T> * newNode = new ListNode<T>; + newNode->data = item; + newNode->next = NULL; + ListNode<T> *traverse = header; + while(traverse->next != NULL) + traverse = traverse->next; + traverse->next = newNode; + len++; +} + +template <class T> +ListNode<T>* List1<T>::findPrevious(const T target) +{ + ListNode<T> *temp; + + for(temp = header; temp->next != NULL; temp = temp->next) + if(*(temp->next->data) == *target) + return temp; + + return NULL; +} + +template <class T> +void List1<T>::remove(const T target) +{ + if(len != 0) + { + ListNode<T> *p = findPrevious(target); + if(p->next != NULL) + { + ListNode<T> *oldNode = p->next; + p->next = p->next->next; + delete oldNode; + len--; + } + } +} + +template <class T> +void List1<T>::next() +{ + current = current->next; +} + +template <class T> +void List1<T>::prev() +{ + if(len > 1) + { + ListNode<T>* tmp = header; + while(tmp->next != current) + tmp = tmp->nect; + + current = tmp; + } +} + +template <class T> +void List1<T>::reset() +{ + current = header; +} + +template <class T> +bool List1<T>::isEmpty() const +{ + return (len == 0); +} + +template <class T> +bool List1<T>::isFull() const +{ + ListNode<T> *tmp = new ListNode<T>; + if(tmp == NULL) + return true; + else + { + delete tmp; + return false; + } +} + +template <class T> +T List1<T>::value() const +{ + return current->next->data; +} + +template <class T> +ListNode<T>* List1<T>::search(const T target) +{ + ListNode<T> *temp; + + for(temp = header->next; temp != NULL; temp = temp->next) + if((*target) == *(temp->data)) + return temp; + + return NULL; +} + +template <class T> +void List1<T>::printList() +{ + cout << endl; + for(int i = 0; i < len; i++) + { + cout << value(); + next(); + } + reset(); +} + +template <class T> +void List1<T>::printListPtr() +{ + cout << endl; + for(int i = 0; i < len; i++) + { + cout << *(value()); // pointer need dereference + next(); + } + reset(); +} + +#endif + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/pgfileLan b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/pgfileLan new file mode 100644 index 0000000000000000000000000000000000000000..d8a00110375f2cad056cb82ee4d938042e208f9e --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/pgfileLan @@ -0,0 +1,3 @@ +localhost 0 ~/Mallba/rep/SA/dnafa/MainLan +localhost 1 ~/Mallba/rep/SA/dnafa/MainLan +localhost 1 ~/Mallba/rep/SA/dnafa/MainLan diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/scp.h b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/scp.h new file mode 100644 index 0000000000000000000000000000000000000000..86960d68b9807b5477c99e38ffbb907aaacb00da --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/scp.h @@ -0,0 +1,53 @@ +/******************************************************************* + * File: scp.h + * Author: Lishan Li + * Date: May, 2003 + * + * Description: This SubConsensusPair class is used to create + * SubConsensusPair objects for ConsensusBuilder class + *******************************************************************/ + +#ifndef SCP_H +#define SCP_H + +#include <iostream> + +using namespace std; + +class SubConsensusPair +{ +public: + int cid1; // first consensus's ID + int cid2; // second consensus's ID + int score; // overlap score between two consensuses + + SubConsensusPair() { } // default constructor + SubConsensusPair(int id1, int id2, int s) // user defined constructor + { + cid1 = id1; + cid2 = id2; + score = s; + } + virtual ~SubConsensusPair() { } // destructor + + bool operator<(const SubConsensusPair& source) const + { + if(score < source.score) + return true; + else + return false; + } + /* overload operator<< for printing the contents of a SubConsensusPair object */ + friend ostream& operator<<(ostream& os, const SubConsensusPair &info) + { + os << "(" << info.cid1 << ", " << info.cid2 << ", " << info.score << ")" << endl; + return os; + } +}; + + /* overload operator<< for printing the contents of a SubConsensusPair object */ + //ostream& operator<<(ostream& os, const SubConsensusPair& info) + +#endif + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/sga.cpp b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/sga.cpp new file mode 100644 index 0000000000000000000000000000000000000000..29d740b668052d9a94319ae6a4f3854f98a7dc87 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/sga.cpp @@ -0,0 +1,256 @@ +/*********************************************************************** + * File: sga.cpp + * Author: Lishan Li + * Date: May, 2003 + * + * Description: It provides implementation of all the functions declared + * in the header file sga.h. + ***********************************************************************/ + +#include "sga.h" + +/********************************************* + * Purpose: allocate memory and initialization + *********************************************/ + +SGA::SGA(const string &is, const string &it) +{ + g = -2; // gap penalty = -2 + s = is; + t = it; + m = s.length(); + n = t.length(); +// /**/ cout << "\t size " << m+1 << " x " << n+1 << endl; + bestScore = 0; +} + +/************************* + * Purpose: release memory + *************************/ + +SGA::~SGA() +{ +} + + +/******************************************************* + * Purpose: Build a score matrix to store the scores of + * pairwise semiglobal alignment + *******************************************************/ + +void SGA::CalculateBest(int i, int j, int score) +{ +//cout << "(" << i<<","<< j<<","<<score<<")"<<endl; + if(j == n) + { + if((score == n) && (score > bestScore)) // ------- + { // --- + bestScore = score; + overlapType = 1; + } + else if((score == i) && (score > bestScore)) // ------- + { // ------- + bestScore = score; + overlapType = 2; + } + } + + if(i == m) + { + if((score == m) && (score > bestScore)) // --- + { // --------- + bestScore = score; + overlapType = 3; + } + else if((score == j) && (score > bestScore)) // ------- + { // ------- + bestScore = score; + overlapType = 4; + } + } +} + +void SGA::buildMatrix() +{ + // Primero la mitad superior + int i,j,k; + int score; + bestScore = 0; + overlapType = 3; + for(k = 1; k <= m; k++) + { + score = 0; + i = k; + j = 1; + while((j <=n) && (i <=m)) + { + if(p(i,j) == 1) + score = score + 1; + else + score = 0; + j++; + i++; + } + i--;j--; + CalculateBest(i,j,score); + } + + for(k = 2; k <= n; k++) + { + score = 0; + j = k; + i = 1; + while(j <=n && i <=m) + { + if(p(i,j) == 1) + score = score + 1; + else + score = 0; + j++; + i++; + } + i--;j--; + CalculateBest(i,j,score); + } +} + +/*************************** + * match score = 1 + * mismatch score = -1 + ***************************/ + +int SGA::p(int i, int j) +{ + if (s[i-1] == t[j-1]) // match + return 1; + else + return -1; +} + +/**************************************************** + * Purpose: find the maximum number of x, y, and z + ****************************************************/ + +int SGA::max(int x, int y, int z) +{ + int temp = x; + if (x < y) + temp = y; + if (temp < z) + temp = z; + return temp; +} + +/******************************************************************** + * Purpose: find the best score for the pairwise semiglobal alignment + ********************************************************************/ + +void SGA::findBestScore() +{ +} + + +/********************************************************************** + * Purpose: Align the two sequence starting from the the row and column + * with the best score + **********************************************************************/ + +void SGA::align() +{ + int i; + int start; +//cout << s << endl << t << endl << bestScore << " " << overlapType << endl; +//exit(-1); + string preGaps = ""; + string postGaps = ""; + if((start = s.find(t)) != string::npos) // t is substring of s + { + align_s = s; + for(i = 0; i < start; i++) + preGaps += "-"; + align_t = preGaps + t; + + for(i = start+bestScore; i < m; i++) + postGaps += "-"; + align_t += postGaps; + } + else if((start = t.find(s)) != string::npos) // s is substring of t + { + align_t = t; + for(i = 0; i < start; i++) + preGaps += "-"; + align_s = preGaps + s; + + for(i = start+bestScore; i < n; i++) + postGaps += "-"; + align_s += postGaps; + } + else if(overlapType == 4) + { + int preNumGaps = m - bestScore; + for(int i = 0; i < preNumGaps; i++) + preGaps += "-"; + align_t = preGaps + t; + + int postNumGaps = align_t.length() - m; + for(int j = 0; j < postNumGaps; j++) + postGaps += "-"; + align_s = s + postGaps; + } + else + { + int preNumGaps = n - bestScore; + for(int i = 0; i < preNumGaps; i++) + preGaps += "-"; + align_s = preGaps + s; + + int postNumGaps = align_s.length() - n; + for(int j = 0; j < postNumGaps; j++) + postGaps += "-"; + align_t = t + postGaps; + } +} + +/************************************************************ + * Purpose: Print the score matrix for the pairwise alignment + ************************************************************/ + +void SGA::printMatrix() +{ +/* for (int i = 0; i <= m; i++) + { + cout << endl; + for (int j = 0; j <= n; j++) + { + printf("%3d", score[i][j]); + } + } + cout << endl << endl; + cout << "The best score is: " << bestScore << endl << endl;*/ +} + +/*************************************** + * Purpose: Print the pairwise alignment + ***************************************/ + +void SGA::printAlign() +{ + cout << align_s << endl; + cout << align_t << endl << endl; +} + +/******************************* + * Purpose: Print Info for debug + *******************************/ +void SGA::printInfo() +{ + cout << "m = " << m << " n = " << n << " g = " << g + << " bestRow = " << bestRow << " bestCol = " << bestCol << " bestscore = " << bestScore + << endl; + cout << "s = " << align_s << " t = " << align_t << endl; + +// printMatrix(); +} + +/************************************ End of File **************************************/ + diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/sga.h b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/sga.h new file mode 100644 index 0000000000000000000000000000000000000000..1cf336dada75a9e2adb8ca309763b379943cac87 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/dnafa/sga.h @@ -0,0 +1,52 @@ +/*************************************************************** + * File: sga.h + * Author: Lishan Li + * Date: May, 2003 + * + * Description: This SGA class is used to do pairwise alignment + * between two fragments + ***************************************************************/ + +#ifndef SGA_H +#define SGA_H + +#include <iostream> +#include <string> +using namespace std; + +class SGA +{ +public: + string align_s; // to store sequence s after alignment + string align_t; // to store sequence t after alignment + + SGA() {} // default constructor + SGA(const string &is, const string &it); // user defined constructor + ~SGA(); // destructor + void buildMatrix(); + int p(int i, int j); + void align(); + void findBestScore(); + void printMatrix(); + void printAlign(); + void printInfo(); + int getBestRow() { return bestRow; } + int getBestCol() { return bestCol; } + int getBestScore() { return bestScore; } +private: + int max(int x, int y, int z); + void CalculateBest(int i, int j, int score); + string s, t; + int g; // gap + int m; // length of s + int n; // length of t + int bestRow; // the row containning best score + int bestCol; // the column containing best score + int bestScore; // the best score of the semiglobal alignment +// int ** score; // to store the scores for pairwise alignment + int overlapType; +}; + +#endif + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/Config.cfg b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/Config.cfg new file mode 100644 index 0000000000000000000000000000000000000000..2d6daf719378e680570b455a37d82b7ec818007f --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/Config.cfg @@ -0,0 +1,3 @@ +SA.cfg +../../../ProblemInstances/MAXSAT-instances/sat1.txt +res/sat1.sa.lan.txt diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/MainLan.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/MainLan.cc new file mode 100644 index 0000000000000000000000000000000000000000..8949422e10f93211d953aba1308c203d13f30f0a --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/MainLan.cc @@ -0,0 +1,53 @@ +#include "SA.hh" +#include <iostream.h> +#include <fstream.h> + +int main (int argc, char** argv) +{ + using skeleton SA; + char path[MAX_BUFFER]; + int len; + int longitud; + + system("clear"); + + get_path(argv[0],path); + len = strlen(path); + longitud = MAX_BUFFER - len; + + strcat(path,"Config.cfg"); + ifstream f(path); + if(!f) show_message(10); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f1(path); + if(!f1) show_message(11); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f2(path); + if(!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + SetUpParams cfg; + f1 >> cfg; + + + Solver_Lan solver(pbm,cfg,argc,argv); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solucion: " << solver.global_best_solution() << " Fitness: " << solver.global_best_solution().fitness(); + + f.getline(&(path[len]),longitud,'\n'); + ofstream fexit(path); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + cout << endl << endl << " :( ---------------------- THE END --------------- :) " << endl; + } + return(0); +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/MainSeq.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/MainSeq.cc new file mode 100644 index 0000000000000000000000000000000000000000..41d8a720793c0d10b14e1d5dfa05b7f11e9c4dda --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/MainSeq.cc @@ -0,0 +1,42 @@ +#include "SA.hh" +#include <iostream.h> +#include <fstream.h> + +int main (int argc, char** argv) +{ + using skeleton SA; + + system("clear"); + + if(argc < 4) + show_message(1); + + ifstream f1(argv[1]); + if (!f1) show_message(11); + + ifstream f2(argv[2]); + if (!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + SetUpParams cfg; + f1 >> cfg; + + Solver_Seq solver(pbm,cfg); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << solver.global_best_solution() + << " Fitness: " << solver.global_best_solution().fitness() << endl; + cout << "\n\n :( ---------------------- THE END --------------- :) "; + + ofstream fexit(argv[3]); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + } + return(0); +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/Makefile b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..0ffc8d9c151fb9b922fcccfa68aa615941ac220e --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/Makefile @@ -0,0 +1,22 @@ +include ../../../environment + +all: MainSeq MainLan + +clean: + rm -f MainLan MainSeq MainWan *.o *% *~ + +MainLan: SA.req.o SA.pro.o StopCondition.o MainLan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainWan: SA.req.o SA.pro.o StopCondition.o MainWan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainSeq: SA.req.o SA.pro.o StopCondition.o MainSeq.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +LAN: + $(RUN) -v -p4pg pgfileLan MainLan +WAN: + $(RUN) -v -p4pg pgfileWan MainWan +SEQ: + ./MainSeq SA.cfg ../../../ProblemInstances/MAXSAT-instances/sat1.txt res/sat1.sa.seq.txt diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/SA.cfg b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/SA.cfg new file mode 100644 index 0000000000000000000000000000000000000000..0aef72f34001678c87b53ac173ca9eb0050bd7f5 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/SA.cfg @@ -0,0 +1,9 @@ +10 // number of independent runs +500 // number of evaluations +10 // Markov-Chain Length +.99 // temperature Decay +1 // display state ? +LAN-configuration +10 // the global state is updated in this number of evaluations +0 // 0: asynchronized mode // 1: synchronized mode +10 // interval of iterations to cooperate ( if 0 no cooperation) diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/SA.hh b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/SA.hh new file mode 100644 index 0000000000000000000000000000000000000000..26c7864e2a9fcae1ba394ae2e930018f4605df0a --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/SA.hh @@ -0,0 +1,493 @@ +#ifndef INC_SA +#define INC_SA + +#include "Mallba/mallba.hh" +#include "Mallba/States.hh" +#include "Mallba/Rarray.h" +#include "Mallba/time.hh" +#include "Mallba/netstream.hh" +#include <math.h> +#include <string.h> + +skeleton SA +{ + + provides class SetUpParams; + provides class Statistics; + provides class Move; + provides class StopCondition; + provides class Solver; + provides class Solver_Seq; + provides class Solver_Lan; + provides class Solver_Wan; + + requires class Problem; + requires class Solution; + requires class StopCondition_1; + requires class StopCondition_2; + requires class StopCondition_3; + requires class DefaultMove; + requires class UserStatistics; + requires bool TerminateQ (const Problem& pbm, const Solver& solver, const SetUpParams& setup); + +// Problem ---------------------------------------------------------------------------- + + requires class Problem + { + public: + Problem(); + ~Problem(); + + friend ostream& operator<< (ostream& os, const Problem& pbm); + friend istream& operator>> (istream& is, Problem& pbm); + + Problem& operator= (const Problem& pbm); + bool operator== (const Problem& pbm) const; + bool operator!= (const Problem& pbm) const; + + Direction direction () const; + double infinity() const; + + int numvar() const; + int numclause() const; + int lenclause() const; + int *clause(const int i) const; + + + private: + + int _numvar; + int _numclause; + int _lenclause; + int ** _clauses; + }; + +//Solution ---------------------------------------------------------------------------- + + requires class Solution + { + public: + Solution (const Problem& pbm); + Solution (const Solution& sol); + ~Solution(); + + friend ostream& operator<< (ostream& os, const Solution& sol); + friend istream& operator>> (istream& is, Solution& sol); + friend NetStream& operator << (NetStream& ns, const Solution& sol); + friend NetStream& operator >> (NetStream& ns, Solution& sol); + + const Problem& pbm() const; + + Solution& operator= (const Solution& sol); + bool operator== (const Solution& sol) const; + bool operator!= (const Solution& sol) const; + + char *to_String() const; + void to_Solution(char *_cadena_); + + void initialize(); + double fitness (); + unsigned int size() const; + + int& var(const int index); + Rarray<int>& array_var(); + + private: + Rarray<int> _var; + const Problem& _pbm; + }; + +// UserStatistics ---------------------------------------------------------------------------- + + requires class UserStatistics + { + private: + struct user_stat + { + unsigned int trial; + double initial_temperature; + double temperature_best_found_trial; + unsigned long nb_evaluation_best_found_trial; + double best_cost_trial; + float time_best_found_trial; + float time_spent_trial; + }; + + Rlist<struct user_stat> result_trials; + + public: + UserStatistics (); + ~UserStatistics(); + + friend ostream& operator<< (ostream& os, const UserStatistics& usertats); + + UserStatistics& operator= (const UserStatistics& userstats); + void update(const Solver& solver); + void clear(); + }; + +// Move ---------------------------------------------------------------------------------- + + provides class Move + { + public: + Move() {} + virtual ~Move() {} + + virtual void Apply(Solution& sol) const = 0; + }; + +// DefaultMove ---------------------------------------------------------------------------------- + + requires class DefaultMove: public Move + { + public: + DefaultMove(); + ~DefaultMove(); + + void Apply(Solution& sol) const; + }; + +// SetUpParams ------------------------------------------------------------------------------- + + provides class SetUpParams + { + private: + unsigned int _independent_runs; + unsigned long _max_evaluations; + unsigned int _MarkovChain_length; + double _temperature_decay; + bool _display_state; + + // for LAN execution configuration + unsigned long _refresh_global_state; + bool _synchronized; + unsigned int _cooperation; + + public: + SetUpParams (); + + friend ostream& operator<< (ostream& os, const SetUpParams& setup); + friend istream& operator>> (istream& is, SetUpParams& setup); + + const unsigned int independent_runs() const; + const unsigned long max_evaluations() const; + const unsigned int MarkovChain_length() const; + const double temperature_decay() const; + const bool display_state() const; + const unsigned long refresh_global_state() const; + const bool synchronized() const; + const unsigned int cooperation() const; + + void independent_runs(const unsigned int val); + void max_evaluations(const unsigned long val); + void MarkovChain_length(const unsigned int val); + void temperature_decay(const double val); + void display_state(const bool val); + void refresh_global_state(const unsigned long val); + void synchronized(const bool val); + void cooperation(const unsigned int val); + + ~SetUpParams(); + }; + +// Statistics --------------------------------------------------------------------------------- + + provides class Statistics + { + private: + struct stat + { + unsigned int trial; + unsigned long nb_evaluations; + double best_cost; + double current_cost; + }; + + Rlist<struct stat> stats_data; + + public: + Statistics(); + + friend ostream& operator<< (ostream& os, const Statistics& stats); + + Statistics& operator= (const Statistics& stats); + void update(const Solver& solver); + void clear(); + + ~Statistics(); + }; + +// Solver --------------------------------------------------------------------------------- + + provides class Solver + { + protected: + const Problem& problem; + const SetUpParams& params; + UserStatistics _userstat; + Statistics _stat; + Move* move; + Solution current; + double curfit; + Solution tentative; + double currentTemperature; + unsigned int k; // to control temperature update. + StateCenter _sc; + + float total_time_spent; + float time_spent_in_trial; + float start_trial; + float start_global; + + bool _end_trial; + + State_Vble _current_trial; + State_Vble _current_iteration; + State_Vble _current_best_solution; + State_Vble _current_best_cost; + State_Vble _current_solution; + State_Vble _current_cost; + + State_Vble _current_time_spent; + State_Vble _initial_temperature_trial; + State_Vble _time_best_found_trial; + State_Vble _iteration_best_found_trial; + State_Vble _temperature_best_found_trial; + State_Vble _time_spent_trial; + + State_Vble _trial_best_found; + State_Vble _iteration_best_found; + State_Vble _global_best_solution; + State_Vble _global_best_cost; + State_Vble _time_best_found; + + State_Vble _temperature; + State_Vble _display_state; + + const Direction _direction; + + bool AcceptQ(double tent, double cur, double temperature); + double Set_Initial_Temperature(const Problem& pbm); + void KeepHistory(const Solution& sol, const double curfit,const float time_spent_trial,const float total_time_spent); + + double UpdateT(double temp, int K); + + public: + // Constructor - Destructor ------------------------- + + Solver (const Problem& pbm, const SetUpParams& setup); + virtual ~Solver (); + virtual int pid() const; + bool end_trial() const; + + // Execution methods -------------------------------- + + // Full execution + virtual void run () =0; + virtual void run (unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol, unsigned long int nb_evaluations) =0; + + virtual void run (const double initialTemperature) =0; + virtual void run (const Solution& sol,const double initialTemperature) =0; + virtual void run (const double initialTemperature, unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations) =0; + + // Partial execution + virtual void StartUp () =0; + virtual void StartUp (const Solution& sol) =0; + virtual void StartUp (const double initialTemperature) =0; + virtual void StartUp (const Solution& sol, const double initialTemperature) =0; + virtual void DoStep () =0; + + // Statistics handling ------------------------------ + + const Statistics& statistics() const; + const UserStatistics& userstatistics () const; + const SetUpParams& setup() const; + const Problem& pbm() const; + + // State handling ----------------------------------- + + void RefreshState(); + void UpdateFromState(); + StateCenter* GetState(); + + unsigned int current_trial() const; + unsigned long current_iteration() const; + Solution current_best_solution() const; + Solution current_solution() const; + double current_best_cost() const; + double current_cost() const; + float current_time_spent() const; + float time_best_found_trial() const; + double initial_temperature_trial() const; + unsigned int iteration_best_found_trial() const; + double temperature_best_found_trial() const; + float time_spent_trial() const; + unsigned int trial_best_found() const; + unsigned int iteration_best_found() const; + Solution global_best_solution() const; + double global_best_cost() const; + float time_best_found() const; + double temperature() const; + int display_state() const; + + void current_trial(const unsigned int value); + void current_iteration(const unsigned long value); + void current_best_solution(const Solution& sol); + void current_best_cost(const double value); + void current_solution(const Solution& sol); + void current_cost(const double value); + void current_time_spent(const float value); + void time_best_found_trial(const float value); + void initial_temperature_trial(const double temperature); + void iteration_best_found_trial(const unsigned int value); + void temperature_best_found_trial(const double value); + void time_spent_trial(const float value); + void trial_best_found(const unsigned int value); + void iteration_best_found(const unsigned int value); + void global_best_solution(const Solution& sol); + void global_best_cost(const double value); + void time_best_found(const float value); + void temperature(const double value); + void display_state(const int value); + void show_state() const; + + // State handling ----------------------------------- + void SetMove(Move* mov); + }; + + provides class Solver_Seq: public Solver + { + public: + // Constructor - Destructor ------------------------- + + Solver_Seq ( const Problem& pbm, const SetUpParams& setup); + virtual ~Solver_Seq (); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + }; + + provides class Solver_Lan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + public: + Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Lan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + + provides class Solver_Wan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + public: + Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Wan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + +}; + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/SA.pro.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/SA.pro.cc new file mode 100644 index 0000000000000000000000000000000000000000..43dcaf9ebda2aa5738f2982cb5f6441259ce44f5 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/SA.pro.cc @@ -0,0 +1,1807 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** Provided classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** *** +************************************************/ + +#include <iostream.h> +#include <math.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "Mallba/time.hh" + +skeleton SA +{ + +// SetUpParams ----------------------------------------------------------- + + SetUpParams::SetUpParams (): + _independent_runs(0), + _max_evaluations(0), + _MarkovChain_length(0), + _temperature_decay(0), + _refresh_global_state(0), + _synchronized(0), + _display_state(0), + _cooperation(0) + {} + + istream& operator>> (istream& is, SetUpParams& setup) + { + char buffer[MAX_BUFFER]; // current line in the setup file + char command[50]; + int op; + double dop; + short int nb_param=0; + short int nb_section=0; + short int nb_LAN_param=0; + + while (is.getline(buffer,MAX_BUFFER,'\n')) + { + sscanf(buffer," %s ",command); + + if (!(strcmp(command,"General"))) nb_section=0; + if (!(strcmp(command,"LAN-configuration"))) nb_section=1; + + if (nb_param==3 && nb_section==0) + { + dop=-1; + sscanf(buffer," %lf ",&dop); + if (dop<0) continue; + } + else + { + op=-1; + sscanf(buffer," %ld%*s ",&op); + if (op<0) continue; + } + + switch (nb_section) + { + case 0: switch (nb_param) + { + case 0: setup.independent_runs(op); break; + case 1: setup.max_evaluations(op); break; + case 2: setup.MarkovChain_length(op); break; + case 3: setup.temperature_decay(dop); break; + case 4: setup.display_state(op); break; + } + nb_param++; + break; + case 1: if (nb_LAN_param>=3) break; + if (nb_LAN_param==0) setup.refresh_global_state(op); + if (nb_LAN_param==1) setup.synchronized(op); + if (nb_LAN_param==2) setup.cooperation(op); + nb_LAN_param++; + break; + } // end switch + } // end while + return is; + } + + ostream& operator<< (ostream& os, const SetUpParams& setup) + { + os << "CONFIGURATION -------------------------------------------" << endl << endl; + os << "\t" << "Independent runs : " << setup.independent_runs() << endl + << "\t" << "Evaluation steps: " << setup.max_evaluations() << endl + << "\t" << "Markov-Chain Length: " << setup.MarkovChain_length() << endl + << "\t" << "Temperature Decay: " << setup.temperature_decay() << endl; + + if (setup.display_state()) + os << "\t" << "Display state" << endl; + else + os << "\t" << "Not display state" << endl; + os << endl << "\t" << "LAN configuration:" << endl + << "\t" << "----------------------" << endl << endl + << "\t" << "Refresh global state in number of generations: " << setup.refresh_global_state() << endl; + + if (setup.synchronized()) + os << "\t" << "Running in synchronous mode" << endl; + else + os << "\t" << "Running in asynchronous mode" << endl; + + if (!setup.cooperation()) + os << "\t" << "Running without cooperation" << endl << endl; + else + os << "\t" << "Running with cooperation in " << setup.cooperation() << " iterations. " << endl << endl; + + os << endl << endl << "END CONFIGURATION -------------------------------------------" << endl << endl; + return os; + } + + const unsigned int SetUpParams::independent_runs() const + { + return _independent_runs; + } + + const unsigned long SetUpParams::max_evaluations() const + { + return _max_evaluations; + } + + const unsigned int SetUpParams::MarkovChain_length() const + { + return _MarkovChain_length; + } + + const double SetUpParams::temperature_decay() const + { + return _temperature_decay; + } + + const bool SetUpParams::display_state() const + { + return _display_state; + } + + const unsigned long SetUpParams::refresh_global_state() const + { + return _refresh_global_state; + } + + const bool SetUpParams::synchronized() const + { + return _synchronized; + } + + const unsigned int SetUpParams::cooperation() const + { + return _cooperation; + } + + void SetUpParams::independent_runs(const unsigned int val) + { + _independent_runs = val; + } + + void SetUpParams::max_evaluations(const unsigned long val) + { + _max_evaluations= val; + } + void SetUpParams::MarkovChain_length(const unsigned int val) + { + _MarkovChain_length= val; + } + void SetUpParams::temperature_decay(const double val) + { + _temperature_decay= val; + } + + void SetUpParams::display_state(const bool val) + { + _display_state=val; + } + + void SetUpParams::refresh_global_state(const unsigned long val) + { + _refresh_global_state=val; + } + + void SetUpParams::synchronized(const bool val) + { + _synchronized=val; + } + + void SetUpParams::cooperation(const unsigned int val) + { + _cooperation=val; + } + + SetUpParams::~SetUpParams() + {} + +// Statistics ------------------------------------------------------ + + Statistics::Statistics() + {} + + ostream& operator<< (ostream& os, const Statistics& stats) + { + int j; + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF CURRENT TRIAL " << endl; + os << "------------------------------------------------------------------" << endl; + for (int i=0;i< stats.stats_data.size();i++) + { + os << endl + << " Evaluations: " << stats.stats_data[i].nb_evaluations + << " Best: " << stats.stats_data[i].best_cost + << " Current: " << stats.stats_data[i].current_cost; + } + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + Statistics& Statistics::operator= (const Statistics& stats) + { + stats_data = stats.stats_data; + return *this; + } + + void Statistics::update(const Solver& solver) + { + /* struct stat *new_stat; + if ((new_stat=(struct stat *)malloc(sizeof(struct stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluations= solver.current_iteration(); + new_stat->best_cost = solver.current_best_cost(); + new_stat->current_cost = solver.current_cost(); + stats_data.append(*new_stat); */ + } + + Statistics::~Statistics() + { + stats_data.remove(); + } + + void Statistics::clear() + { + stats_data.remove(); + } + +// Solver (superclass)--------------------------------------------------- + + Solver::Solver (const Problem& pbm, const SetUpParams& setup) + : problem(pbm), + params(setup), + _stat(), + _userstat(), + _sc(), + _direction(pbm.direction()), + current(pbm), + tentative(pbm), + currentTemperature(0.0), + time_spent_in_trial(0.0), + total_time_spent(0.0), + start_trial(0.0), + start_global(0.0), + _current_trial("_current_trial",_sc), + _current_iteration("_current_iteration",_sc), + _current_best_solution("_current_best_solution",_sc), + _current_best_cost("_current_best_cost",_sc), + _current_solution("_current_solution",_sc), + _current_cost("_current_cost",_sc), + _current_time_spent("_current_time_spent",_sc), + _initial_temperature_trial("_initial_temperature_trial",_sc), + _time_best_found_trial("_time_best_found_trial",_sc), + _iteration_best_found_trial("_iteration_best_found_trial",_sc), + _temperature_best_found_trial("_temperature_best_found_trial",_sc), + _time_spent_trial("_time_spent_trial",_sc), + _trial_best_found("_trial_best_found",_sc), + _iteration_best_found("_iteration_best_found;",_sc), + _global_best_solution("_global_best_solution",_sc), + _global_best_cost("_global_best_cost",_sc), + _time_best_found("_time_best_found",_sc), + _temperature("_temperature",_sc), + _display_state("_display_state",_sc) + { + current_trial(0); + current_iteration(0); + current_best_solution(current), + current_best_cost((-1) * pbm.direction() * infinity()); + current_solution(current); + current_cost((-1) * pbm.direction() * infinity()); + current_time_spent(total_time_spent); + initial_temperature_trial(0); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(0); + temperature_best_found_trial(0.0); + time_spent_trial(time_spent_in_trial); + trial_best_found(0); + iteration_best_found(0); + global_best_solution(current); + global_best_cost((-1) * pbm.direction() * infinity()); + time_best_found(total_time_spent); + temperature(currentTemperature); + display_state(setup.display_state()); + + move = new DefaultMove; + } + + int Solver::pid() const + { + return 0; + } + + bool Solver::end_trial() const + { + return _end_trial; + } + + unsigned int Solver::current_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_trial",(char *)&value, nitems, length); + return value; + } + + unsigned long Solver::current_iteration() const + { + unsigned long value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_iteration",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_best_solution() const + { + Solution sol(problem); + unsigned long nitems,length; + char data_stored[_current_best_solution.get_nitems() + _current_best_solution.get_length()]; + _sc.get_contents_state_variable("_current_best_solution", data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::current_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_best_cost",(char *)&value, nitems, length); + return value; + } + + double Solver::current_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_cost",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_solution() const + { + Solution sol(problem); + char data_stored[_current_solution.get_nitems() + _current_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_solution",data_stored, nitems, length); + sol.to_Solution((char *)data_stored); + return sol; + } + + float Solver::current_time_spent() const + { + float value=0.0; + unsigned long nitems,length; + _current_time_spent.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::initial_temperature_trial() const + { + double value=0.0; + unsigned long nitems,length; + _initial_temperature_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature_best_found_trial() const + { + double value=0.0; + unsigned long nitems,length; + _temperature_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_spent_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_spent_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::trial_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _trial_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::global_best_solution() const + { + Solution sol(problem); + char data_stored[_global_best_solution.get_nitems() + _global_best_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_solution",data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::global_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_cost",(char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_temperature",(char *)&value, nitems, length); + return value; + } + + int Solver::display_state() const + { + int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_display_state",(char *)&value, nitems, length); + return value; + } + + void Solver::current_trial(const unsigned int value) + { + _sc.set_contents_state_variable("_current_trial",(char *)&value,1,sizeof(int)); + } + + void Solver::current_iteration(const unsigned long value) + { + _sc.set_contents_state_variable("_current_iteration",(char *)&value,1,sizeof(long)); + } + + void Solver::current_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_best_cost(const double value) + { + _sc.set_contents_state_variable("_current_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_cost(const double value) + { + _sc.set_contents_state_variable("_current_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_time_spent(const float value) + { + _current_time_spent.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::time_best_found_trial(const float value) + { + _time_best_found_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::iteration_best_found_trial(const unsigned int value) + { + _iteration_best_found_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::initial_temperature_trial(const double value) + { + _initial_temperature_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::temperature_best_found_trial(const double value) + { + _temperature_best_found_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::time_spent_trial(const float value) + { + _time_spent_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::trial_best_found(const unsigned int value) + { + _trial_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::iteration_best_found(const unsigned int value) + { + _iteration_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::global_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_global_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::global_best_cost(const double value) + { + _sc.set_contents_state_variable("_global_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::time_best_found(const float value) + { + _time_best_found.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::temperature(const double value) + { + _sc.set_contents_state_variable("_temperature",(char *)&value,1,sizeof(double)); + } + + void Solver::display_state(const int value) + { + _sc.set_contents_state_variable("_display_state",(char *)&value,1,sizeof(int)); + } + + const Statistics& Solver::statistics() const + { + return _stat; + } + + const UserStatistics& Solver::userstatistics() const + { + return _userstat; + } + + const SetUpParams& Solver::setup() const + { + return params; + } + + const Problem& Solver::pbm() const + { + return problem; + } + + void Solver::KeepHistory(const Solution& sol, const double curfit,const float time_spent_in_trial,const float total_time_spent) + { + bool betterG=false; + bool betterT=false; + + switch (_direction) + { + case minimize: betterG = (curfit < global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit < current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + case maximize: betterG = (curfit > global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit > current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + } + + if (betterT) + { + current_best_solution(sol); + current_best_cost(curfit); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(current_iteration()); + temperature_best_found_trial(temperature()); + if (betterG) + { + trial_best_found(current_trial()); + iteration_best_found(current_iteration()); + global_best_solution(sol); + global_best_cost(curfit); + time_best_found(time_spent_in_trial); + } + } + } + + double Solver::UpdateT(double temp, int K) + { + //return temp * params.temperature_decay(); // initial + + /* + if(K == 1) return temp/log(2); + else return temp * log(K) / log(K+1); + */ + /* + if(K == 1) return temp/2; + else return (temp * K) / (K + 1); + */ + + if(K == 1) return temp / exp(2); + else return (temp * exp(K)) / exp(K+1); + + } + + StateCenter* Solver::GetState() + { + return &_sc; + } + + void Solver::RefreshState() + { + current_solution(current); + current_cost(curfit); + current_time_spent(total_time_spent); + time_spent_trial(time_spent_in_trial); + temperature(currentTemperature); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::UpdateFromState() + { + current = current_solution(); + curfit = current_cost(); + total_time_spent=current_time_spent(); + time_spent_in_trial=time_spent_trial(); + currentTemperature = temperature(); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::show_state() const + { + cout << endl << "Current trial: " << current_trial(); + cout << endl << "Current iteration: " << current_iteration(); + cout << endl << "Current Temperature: " << temperature (); + cout << endl << "Current cost: " << current_cost(); + cout << endl << "Best cost in trial: " << current_best_cost(); + cout << endl << "Time of best solution found in trial: " << time_best_found_trial(); + cout << endl << "Iteration of best solution found in trial: " << iteration_best_found_trial(); + cout << endl << "Initial temperature in trial: " << initial_temperature_trial(); + cout << endl << "Temperature of best solution found in trial: " << temperature_best_found_trial(); + cout << endl << "Time spent in trial: " << time_spent_trial(); + cout << endl << "Global best cost: " << global_best_cost(); + cout << endl << "Trial of best global solution found: " << trial_best_found(); + cout << endl << "Iteration of best global solution found: " << iteration_best_found(); + cout << endl << "Time of global best solution found: " << time_best_found(); + // cout << endl << "Current solution: " << current_solution(); + // cout << endl << "Best solution of trial: " << current_best_solution(); + // cout << endl << "Global solution: " << global_best_solution() << endl; + cout << endl << endl << "Current time spent (so far): " << current_time_spent() << endl; + } + + Solver::~Solver() + { + _sc.removeAll(); + delete move; + } + + bool Solver::AcceptQ (double tent, double cur, double temperature) + { + if (_direction==minimize) + + return (tent < cur) || + ((rand01()*(1+exp((tent-cur)/temperature)))<2.0); + + else + + return (tent > cur) || + ((rand01()*(1+exp((cur-tent)/temperature)))<2.0); + } + + double Solver::Set_Initial_Temperature(const Problem& pbm) + { + const double beta = 1.05; + const double test = 10; + const double acrat = .8; + const double T = 1.0; + + Solution current (pbm); + Solution newsol (pbm); + double ac; + double fit; + double temperature = T; + + do + { + temperature *= beta; + ac = 0; + current.initialize(); + fit = current.fitness(); + for (int i=0; i<test; i++) + { + newsol = current; + move->Apply(newsol); + if (AcceptQ(newsol.fitness(),fit,temperature)) + ac += 1.0/test; + } + } while (ac < acrat); + + initial_temperature_trial(temperature); + return temperature; + + } + + void Solver::SetMove (Move* mov) + { + delete move; + move = mov; + } + + // Solver sequencial ----------------------------------------------------- + + Solver_Seq::Solver_Seq (const Problem& pbm, const SetUpParams& setup) + : Solver(pbm,setup) + { + random_seed(time(0)); + _end_trial=true; + } + + Solver_Seq::~Solver_Seq () + {} + + void Solver_Seq::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Seq::StartUp(const Solution& sol, const double initialTemperature) + { + start_trial=_used_time(); + start_global=total_time_spent; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current = sol; + curfit = current.fitness(); + current_best_cost((-1) * problem.direction() * infinity()); + currentTemperature = initialTemperature; + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + void Solver_Seq::DoStep() + { + current_iteration(current_iteration()+1); + + tentative = current; + move->Apply(tentative); + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + + void Solver_Seq::run (unsigned long int max_evaluations) + { + StartUp(); + + while (current_iteration()<max_evaluations && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + // Solver LAN ----------------------------------------------------------- + + Solver_Lan::Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); + } + + Solver_Lan::~Solver_Lan () + { + NetStream::finalize(); + } + + int Solver_Lan::pid() const + { + return mypid; + } + + NetStream& Solver_Lan::netstream() + { + return _netstream; + } + + void Solver_Lan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Lan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + void update(Direction direction, Solution &solution_received,double cost_received, Solution &solution_to_send, double &best_cost) + { + switch (direction) + { + case minimize: if (cost_received < best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + case maximize: if (cost_received > best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + } + } + + int Solver_Lan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Lan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Lan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Lan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Lan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Lan::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + void Solver_Lan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } + + // Solver WAN ------------------------------------------------------------ + + Solver_Wan::Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); + } + + Solver_Wan::~Solver_Wan () + { + NetStream::finalize(); + } + + int Solver_Wan::pid() const + { + return mypid; + } + + NetStream& Solver_Wan::netstream() + { + return _netstream; + } + + void Solver_Wan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Wan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + int Solver_Wan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Wan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Wan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Wan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Wan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Wan::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + void Solver_Wan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } +}; + diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/SA.req.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/SA.req.cc new file mode 100644 index 0000000000000000000000000000000000000000..f3554e78d1d41df92f0395d8eb58136986f5bde4 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/SA.req.cc @@ -0,0 +1,364 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** User-required classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** Tab size = 4 *** +*** *** +*** *** +************************************************/ + +#include <iostream.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "StopCondition.hh" + +skeleton SA { + + // Problem --------------------------------------------------------------- + + Problem::Problem ():_numvar(0),_numclause(0),_clauses(NULL),_lenclause(0) + {} + + ostream& operator<< (ostream& os, const Problem& pbm) + { + os << endl << endl << "Number of variables " << pbm._numvar + << endl << endl << "Number of clauses " << pbm._numclause + << endl << endl << "Length of clauses " << pbm._lenclause + << endl << endl + << " Clauses: " << endl; + + for (int i=0;i<pbm._numclause;i++) + { + os << "\t clause " << i << "\t "; + for(int j = 0; j < pbm._lenclause; j++) + os << pbm._clauses[i][j] << " "; + os << endl; + } + return os; + } + + istream& operator>> (istream& is, Problem& pbm) + { + int l; + int n; + is >> pbm._numvar >> pbm._numclause >> pbm._lenclause; + + n = pbm._lenclause; + // read clauses + pbm._clauses = new int*[pbm._numclause]; + + for (int i = 0; i < pbm._numclause; i++) + { + pbm._clauses[i] = new int[n]; + for(int j = 0; j < n;j++) + { + is >> l; + pbm._clauses[i][j] = l; + } + is >> l; + } + + return is; + } + + Problem& Problem::operator= (const Problem& pbm) + { + int n; + _numvar=pbm.numvar(); + for(int i = 0; i < _numclause;i++) + delete [] _clauses[i]; + delete [] _clauses; + + _numclause = pbm.numclause(); + n = _lenclause = pbm.lenclause(); + + _clauses = new int *[_numclause]; + + for(int i = 0; i < pbm._numclause;i++) + { + _clauses[i] = new int [n]; + for(int j = 0; j < n ; j++) + _clauses[i][j] = pbm._clauses[i][j]; + } + return *this; + } + + bool Problem::operator== (const Problem& pbm) const + { + if (_numvar!=pbm.numvar()) return false; + for (int i = 0; i < _numclause; i++) + for(int j = 0; j < _lenclause;j++) + if ( _clauses[i][j] != pbm._clauses[i][j]) + return false; + return true; + } + + bool Problem::operator!= (const Problem& pbm) const + { + return !(*this == pbm); + } + + Direction Problem::direction() const + { + return maximize; + //return minimize; + } + + double Problem::infinity() const + { + double one=1.0; + double zero=0.0; + return 0.0 - one/zero; + } + + int Problem::numvar() const + { + return _numvar; + } + + int Problem::numclause() const + { + return _numclause; + } + + int Problem::lenclause() const + { + return _lenclause; + } + + int *Problem::clause(const int i) const + { + return _clauses[i]; + } + + Problem::~Problem() + { + for(int i = 0;i < _numclause;i++) + delete [] _clauses[i]; + + delete [] _clauses; + } + + // Solution -------------------------------------------------------------- + + Solution::Solution (const Problem& pbm):_pbm(pbm),_var(pbm.numvar()) + {} + + const Problem& Solution::pbm() const + { + return _pbm; + } + + Solution::Solution(const Solution& sol):_pbm(sol.pbm()) + { + *this=sol; + } + + istream& operator>> (istream& is, Solution& sol) + { + for (int i=0;i<sol.pbm().numvar();i++) + is >> sol._var[i]; + return is; + } + + ostream& operator<< (ostream& os, const Solution& sol) + { + for (int i=0;i<sol.pbm().numvar();i++) + os << " " << sol._var[i]; + return os; + } + + NetStream& operator << (NetStream& ns, const Solution& sol) + { + for (int i=0;i<sol._var.size();i++) + ns << sol._var[i]; + return ns; + } + + NetStream& operator >> (NetStream& ns, Solution& sol) + { + for (int i=0;i<sol._var.size();i++) + ns >> sol._var[i]; + return ns; + } + + Solution& Solution::operator= (const Solution &sol) + { + _var = sol._var; + return *this; + } + + bool Solution::operator== (const Solution& sol) const + { + if (sol.pbm() != _pbm) return false; + return true; + } + + bool Solution::operator!= (const Solution& sol) const + { + return !(*this == sol); + } + + void Solution::initialize() + { + for (int i=0;i<_pbm.numvar();i++) + _var[i]=rand_int(0,1); + } + + double Solution::fitness () + { + double fitness = 0.0; + int acum = 0; + + for(int i = 0; i < _pbm.numclause(); i++) + { + int *rl = _pbm.clause(i); + acum = 0; + for(int j = 0; (j < _pbm.lenclause()) && (acum != 1);j++) + { + if( ((rl[j] < 0) && (_var[(int)abs(rl[j])-1] == 0)) + || ((rl[j] > 0) && (_var[rl[j]-1] == 1)) ) + acum = 1; + } + fitness += acum; + } + return fitness; + } + + char *Solution::to_String() const + { + return (char *)_var.get_first(); + } + + void Solution::to_Solution(char *_string_) + { + int *ptr=(int *)_string_; + for (int i=0;i<_pbm.numvar();i++) + { + _var[i]=*ptr; + ptr++; + } + } + + unsigned int Solution::size() const + { + return (_pbm.numvar() * sizeof(int)); + } + + + int& Solution::var(const int index) + { + return _var[index]; + } + + + Rarray<int>& Solution::array_var() + { + return _var; + } + + Solution::~Solution() + {} + +// UserStatistics ------------------------------------------------------- + + UserStatistics::UserStatistics () + {} + + ostream& operator<< (ostream& os, const UserStatistics& userstat) + { + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF TRIALS " << endl; + os << "------------------------------------------------------------------" << endl; + + for (int i=0;i< userstat.result_trials.size();i++) + { + os << endl + << "\t" << userstat.result_trials[i].trial + << "\t" << userstat.result_trials[i].best_cost_trial + << "\t\t" << userstat.result_trials[i].nb_evaluation_best_found_trial + << "\t\t" << userstat.result_trials[i].initial_temperature + << "\t\t" << userstat.result_trials[i].temperature_best_found_trial + << "\t\t" << userstat.result_trials[i].time_best_found_trial + << "\t\t" << userstat.result_trials[i].time_spent_trial; + } + + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + + UserStatistics& UserStatistics::operator= (const UserStatistics& userstats) + { + result_trials=userstats.result_trials; + return (*this); + } + + + void UserStatistics::update(const Solver& solver) + { + if ((solver.pid()!=0) || (solver.end_trial()!=true) + || ((solver.current_iteration()!=solver.setup().max_evaluations()) + && !TerminateQ(solver.pbm(),solver,solver.setup()))) + return; + struct user_stat *new_stat; + if ((new_stat=(struct user_stat *)malloc(sizeof(struct user_stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluation_best_found_trial= solver.iteration_best_found_trial(); + new_stat->initial_temperature=solver.initial_temperature_trial(); + new_stat->temperature_best_found_trial=solver.temperature_best_found_trial(); + new_stat->best_cost_trial = solver.current_best_cost(); + new_stat->time_best_found_trial= solver.time_best_found_trial(); + new_stat->time_spent_trial = solver.time_spent_trial(); + result_trials.append(*new_stat); + } + + void UserStatistics::clear() + { + result_trials.remove(); + } + + UserStatistics::~UserStatistics() + { + result_trials.remove(); + } + +// DefaultMove ------------------------------------------------------- + + + DefaultMove::DefaultMove() + {} + + DefaultMove::~DefaultMove() + {} + + void DefaultMove::Apply (Solution& sol) const + { + const float probability = 0.03; + + for (int i=0;i<sol.pbm().numvar();i++) + { + if (rand01()<=probability) + { + if (sol.var(i)==1) sol.var(i)=0; + else sol.var(i)=1; + } + } + } + + //------------------------------------------------------------------------ + // Specific methods ------------------------------------------------------ + //------------------------------------------------------------------------ + + bool TerminateQ (const Problem& pbm, const Solver& solver, + const SetUpParams& setup) + { + + StopCondition_3 stop; + return stop.EvaluateCondition(pbm,solver,setup); + } +} + + diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/StopCondition.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/StopCondition.cc new file mode 100644 index 0000000000000000000000000000000000000000..dcd0513b3aa3efbd58c9aac87a7ae91e94585170 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/StopCondition.cc @@ -0,0 +1,52 @@ +#include "StopCondition.hh" +skeleton SA +{ + +// StopCondition ------------------------------------------------------------------------------------- + + StopCondition::StopCondition() + {} + + StopCondition::~StopCondition() + {} + +// StopCondition_1 ------------------------------------------------------------------------------------- + + StopCondition_1::StopCondition_1():StopCondition() + {} + + bool StopCondition_1::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return false; + } + + StopCondition_1::~StopCondition_1() + {} + +// StopCondition_2 ------------------------------------------------------------------------------------- + + StopCondition_2::StopCondition_2():StopCondition() + {} + + bool StopCondition_2::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return (solver.global_best_cost()>8.5); + } + + StopCondition_2::~StopCondition_2() + {} + +// StopCondition_3 ------------------------------------------------------------------------------------- + + StopCondition_3::StopCondition_3():StopCondition() + {} + + bool StopCondition_3::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return ((int)solver.current_best_cost() == pbm.numclause()); + } + + StopCondition_3::~StopCondition_3() + {} + +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/StopCondition.hh b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/StopCondition.hh new file mode 100644 index 0000000000000000000000000000000000000000..04ef770d9cac5bb9ef69aae7d085e3ae2166e187 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/StopCondition.hh @@ -0,0 +1,41 @@ +#ifndef stop_condition +#define stop_condition + +#include "SA.hh" +skeleton SA +{ + + provides class StopCondition + { + public: + StopCondition(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup)=0; + ~StopCondition(); + }; + + requires class StopCondition_1 : public StopCondition + { + public: + StopCondition_1(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_1(); + }; + + requires class StopCondition_2 : public StopCondition + { + public: + StopCondition_2(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_2(); + }; + + requires class StopCondition_3 : public StopCondition + { + public: + StopCondition_3(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_3(); + }; +} + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/pgfileLan b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/pgfileLan new file mode 100644 index 0000000000000000000000000000000000000000..a681b216557346c572dd8531406475a201cd01b1 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/maxsat/pgfileLan @@ -0,0 +1,5 @@ +localhost 0 ~/Mallba/rep/SA/maxsat/MainLan +localhost 1 ~/Mallba/rep/SA/maxsat/MainLan +localhost 1 ~/Mallba/rep/SA/maxsat/MainLan +localhost 1 ~/Mallba/rep/SA/maxsat/MainLan +localhost 1 ~/Mallba/rep/SA/maxsat/MainLan diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/Config.cfg b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/Config.cfg new file mode 100644 index 0000000000000000000000000000000000000000..87d424d262edb6ee4764dadc24bd085dfe030248 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/Config.cfg @@ -0,0 +1,3 @@ +SA.cfg +../../../ProblemInstances/ONEMAX-instances/onemax10.txt +res/om10.sa.lan.txt diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/MainLan.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/MainLan.cc new file mode 100644 index 0000000000000000000000000000000000000000..8949422e10f93211d953aba1308c203d13f30f0a --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/MainLan.cc @@ -0,0 +1,53 @@ +#include "SA.hh" +#include <iostream.h> +#include <fstream.h> + +int main (int argc, char** argv) +{ + using skeleton SA; + char path[MAX_BUFFER]; + int len; + int longitud; + + system("clear"); + + get_path(argv[0],path); + len = strlen(path); + longitud = MAX_BUFFER - len; + + strcat(path,"Config.cfg"); + ifstream f(path); + if(!f) show_message(10); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f1(path); + if(!f1) show_message(11); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f2(path); + if(!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + SetUpParams cfg; + f1 >> cfg; + + + Solver_Lan solver(pbm,cfg,argc,argv); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solucion: " << solver.global_best_solution() << " Fitness: " << solver.global_best_solution().fitness(); + + f.getline(&(path[len]),longitud,'\n'); + ofstream fexit(path); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + cout << endl << endl << " :( ---------------------- THE END --------------- :) " << endl; + } + return(0); +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/MainSeq.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/MainSeq.cc new file mode 100644 index 0000000000000000000000000000000000000000..41d8a720793c0d10b14e1d5dfa05b7f11e9c4dda --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/MainSeq.cc @@ -0,0 +1,42 @@ +#include "SA.hh" +#include <iostream.h> +#include <fstream.h> + +int main (int argc, char** argv) +{ + using skeleton SA; + + system("clear"); + + if(argc < 4) + show_message(1); + + ifstream f1(argv[1]); + if (!f1) show_message(11); + + ifstream f2(argv[2]); + if (!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + SetUpParams cfg; + f1 >> cfg; + + Solver_Seq solver(pbm,cfg); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << solver.global_best_solution() + << " Fitness: " << solver.global_best_solution().fitness() << endl; + cout << "\n\n :( ---------------------- THE END --------------- :) "; + + ofstream fexit(argv[3]); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + } + return(0); +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/Makefile b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..82415bbd05b58056dc192ea02ba203de90048153 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/Makefile @@ -0,0 +1,22 @@ +include ../../../environment + +all: MainSeq MainLan + +clean: + rm -f MainLan MainSeq MainWan *.o *% *~ + +MainLan: SA.req.o SA.pro.o StopCondition.o MainLan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainWan: SA.req.o SA.pro.o StopCondition.o MainWan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainSeq: SA.req.o SA.pro.o StopCondition.o MainSeq.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +LAN: + $(RUN) -v -p4pg pgfileLan MainLan +WAN: + $(RUN) -v -p4pg pgfileWan MainWan +SEQ: + ./MainSeq SA.cfg ../../../ProblemInstances/ONEMAX-instances/onemax10.txt res/om10.sa.seq.txt diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/SA.cfg b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/SA.cfg new file mode 100644 index 0000000000000000000000000000000000000000..b6c93992066b9367d040e96d81efd590532238a3 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/SA.cfg @@ -0,0 +1,9 @@ +10 // number of independent runs +500 // number of evaluations +5 // Markov-Chain Length +.99 // temperature Decay +1 // display state ? +LAN-configuration +10 // the global state is updated in this number of evaluations +0 // 0: asynchronized mode // 1: synchronized mode +10 // interval of iterations to cooperate ( if 0 no cooperation) diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/SA.hh b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/SA.hh new file mode 100644 index 0000000000000000000000000000000000000000..6238f6de1290020e2dc587e829e825e0e7edb4ae --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/SA.hh @@ -0,0 +1,488 @@ +#ifndef INC_SA +#define INC_SA + +#include "Mallba/mallba.hh" +#include "Mallba/States.hh" +#include "Mallba/Rarray.h" +#include "Mallba/time.hh" +#include "Mallba/netstream.hh" +#include <math.h> +#include <string.h> + +skeleton SA +{ + + provides class SetUpParams; + provides class Statistics; + provides class Move; + provides class StopCondition; + provides class Solver; + provides class Solver_Seq; + provides class Solver_Lan; + provides class Solver_Wan; + + requires class Problem; + requires class Solution; + requires class StopCondition_1; + requires class StopCondition_2; + requires class StopCondition_3; + requires class DefaultMove; + requires class UserStatistics; + requires bool TerminateQ (const Problem& pbm, const Solver& solver, const SetUpParams& setup); + +// Problem ---------------------------------------------------------------------------- + + requires class Problem + { + public: + Problem (); + ~Problem (); + + friend ostream& operator<< (ostream& os, const Problem& pbm); + friend istream& operator>> (istream& is, Problem& pbm); + + Problem& operator= (const Problem& pbm); + bool operator== (const Problem& pbm) const; + bool operator!= (const Problem& pbm) const; + + Direction direction () const; + + int dimension() const; + double infinity() const; + + private: + + int _dimension; + }; + +//Solution ---------------------------------------------------------------------------- + + requires class Solution + { + public: + Solution (const Problem& pbm); + Solution (const Solution& sol); + ~Solution(); + + friend ostream& operator<< (ostream& os, const Solution& sol); + friend istream& operator>> (istream& is, Solution& sol); + friend NetStream& operator << (NetStream& ns, const Solution& sol); + friend NetStream& operator >> (NetStream& ns, Solution& sol); + + const Problem& pbm() const; + + Solution& operator= (const Solution& sol); + bool operator== (const Solution& sol) const; + bool operator!= (const Solution& sol) const; + + char *to_String() const; + void to_Solution(char *_vertex_); + unsigned int size() const; + + void initialize(); + double fitness () const; + + int& var(const int index); + Rarray<int>& array_var(); + + private: + Rarray<int> _var; + const Problem& _pbm; + }; + +// UserStatistics ---------------------------------------------------------------------------- + + requires class UserStatistics + { + private: + struct user_stat + { + unsigned int trial; + double initial_temperature; + double temperature_best_found_trial; + unsigned long nb_evaluation_best_found_trial; + double best_cost_trial; + float time_best_found_trial; + float time_spent_trial; + }; + + Rlist<struct user_stat> result_trials; + + public: + UserStatistics (); + ~UserStatistics(); + + friend ostream& operator<< (ostream& os, const UserStatistics& usertats); + + UserStatistics& operator= (const UserStatistics& userstats); + void update(const Solver& solver); + void clear(); + }; + +// Move ---------------------------------------------------------------------------------- + + provides class Move + { + public: + Move() {} + virtual ~Move() {} + + virtual void Apply(Solution& sol) const = 0; + }; + +// DefaultMove ---------------------------------------------------------------------------------- + + requires class DefaultMove: public Move + { + public: + DefaultMove(); + ~DefaultMove(); + + void Apply(Solution& sol) const; + }; + +// SetUpParams ------------------------------------------------------------------------------- + + provides class SetUpParams + { + private: + unsigned int _independent_runs; + unsigned long _max_evaluations; + unsigned int _MarkovChain_length; + double _temperature_decay; + bool _display_state; + + // for LAN execution configuration + unsigned long _refresh_global_state; + bool _synchronized; + unsigned int _cooperation; + + public: + SetUpParams (); + + friend ostream& operator<< (ostream& os, const SetUpParams& setup); + friend istream& operator>> (istream& is, SetUpParams& setup); + + const unsigned int independent_runs() const; + const unsigned long max_evaluations() const; + const unsigned int MarkovChain_length() const; + const double temperature_decay() const; + const bool display_state() const; + const unsigned long refresh_global_state() const; + const bool synchronized() const; + const unsigned int cooperation() const; + + void independent_runs(const unsigned int val); + void max_evaluations(const unsigned long val); + void MarkovChain_length(const unsigned int val); + void temperature_decay(const double val); + void display_state(const bool val); + void refresh_global_state(const unsigned long val); + void synchronized(const bool val); + void cooperation(const unsigned int val); + + ~SetUpParams(); + }; + +// Statistics --------------------------------------------------------------------------------- + + provides class Statistics + { + private: + struct stat + { + unsigned int trial; + unsigned long nb_evaluations; + double best_cost; + double current_cost; + }; + + Rlist<struct stat> stats_data; + + public: + Statistics(); + + friend ostream& operator<< (ostream& os, const Statistics& stats); + + Statistics& operator= (const Statistics& stats); + void update(const Solver& solver); + void clear(); + + ~Statistics(); + }; + +// Solver --------------------------------------------------------------------------------- + + provides class Solver + { + protected: + const Problem& problem; + const SetUpParams& params; + UserStatistics _userstat; + Statistics _stat; + Move* move; + Solution current; + double curfit; + Solution tentative; + double currentTemperature; + unsigned int k; // to control temperature update. + StateCenter _sc; + + float total_time_spent; + float time_spent_in_trial; + float start_trial; + float start_global; + + bool _end_trial; + + State_Vble _current_trial; + State_Vble _current_iteration; + State_Vble _current_best_solution; + State_Vble _current_best_cost; + State_Vble _current_solution; + State_Vble _current_cost; + + State_Vble _current_time_spent; + State_Vble _initial_temperature_trial; + State_Vble _time_best_found_trial; + State_Vble _iteration_best_found_trial; + State_Vble _temperature_best_found_trial; + State_Vble _time_spent_trial; + + State_Vble _trial_best_found; + State_Vble _iteration_best_found; + State_Vble _global_best_solution; + State_Vble _global_best_cost; + State_Vble _time_best_found; + + State_Vble _temperature; + State_Vble _display_state; + + const Direction _direction; + + bool AcceptQ(double tent, double cur, double temperature); + double Set_Initial_Temperature(const Problem& pbm); + void KeepHistory(const Solution& sol, const double curfit,const float time_spent_trial,const float total_time_spent); + + double UpdateT(double temp, int K); + + public: + // Constructor - Destructor ------------------------- + + Solver (const Problem& pbm, const SetUpParams& setup); + virtual ~Solver (); + virtual int pid() const; + bool end_trial() const; + + // Execution methods -------------------------------- + + // Full execution + virtual void run () =0; + virtual void run (unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol, unsigned long int nb_evaluations) =0; + + virtual void run (const double initialTemperature) =0; + virtual void run (const Solution& sol,const double initialTemperature) =0; + virtual void run (const double initialTemperature, unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations) =0; + + // Partial execution + virtual void StartUp () =0; + virtual void StartUp (const Solution& sol) =0; + virtual void StartUp (const double initialTemperature) =0; + virtual void StartUp (const Solution& sol, const double initialTemperature) =0; + virtual void DoStep () =0; + + // Statistics handling ------------------------------ + + const Statistics& statistics() const; + const UserStatistics& userstatistics () const; + const SetUpParams& setup() const; + const Problem& pbm() const; + + // State handling ----------------------------------- + + void RefreshState(); + void UpdateFromState(); + StateCenter* GetState(); + + unsigned int current_trial() const; + unsigned long current_iteration() const; + Solution current_best_solution() const; + Solution current_solution() const; + double current_best_cost() const; + double current_cost() const; + float current_time_spent() const; + float time_best_found_trial() const; + double initial_temperature_trial() const; + unsigned int iteration_best_found_trial() const; + double temperature_best_found_trial() const; + float time_spent_trial() const; + unsigned int trial_best_found() const; + unsigned int iteration_best_found() const; + Solution global_best_solution() const; + double global_best_cost() const; + float time_best_found() const; + double temperature() const; + int display_state() const; + + void current_trial(const unsigned int value); + void current_iteration(const unsigned long value); + void current_best_solution(const Solution& sol); + void current_best_cost(const double value); + void current_solution(const Solution& sol); + void current_cost(const double value); + void current_time_spent(const float value); + void time_best_found_trial(const float value); + void initial_temperature_trial(const double temperature); + void iteration_best_found_trial(const unsigned int value); + void temperature_best_found_trial(const double value); + void time_spent_trial(const float value); + void trial_best_found(const unsigned int value); + void iteration_best_found(const unsigned int value); + void global_best_solution(const Solution& sol); + void global_best_cost(const double value); + void time_best_found(const float value); + void temperature(const double value); + void display_state(const int value); + void show_state() const; + + // State handling ----------------------------------- + void SetMove(Move* mov); + }; + + provides class Solver_Seq: public Solver + { + public: + // Constructor - Destructor ------------------------- + + Solver_Seq ( const Problem& pbm, const SetUpParams& setup); + virtual ~Solver_Seq (); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + }; + + provides class Solver_Lan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + + public: + Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Lan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + + provides class Solver_Wan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + + public: + Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Wan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + +}; + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/SA.pro.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/SA.pro.cc new file mode 100644 index 0000000000000000000000000000000000000000..43dcaf9ebda2aa5738f2982cb5f6441259ce44f5 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/SA.pro.cc @@ -0,0 +1,1807 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** Provided classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** *** +************************************************/ + +#include <iostream.h> +#include <math.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "Mallba/time.hh" + +skeleton SA +{ + +// SetUpParams ----------------------------------------------------------- + + SetUpParams::SetUpParams (): + _independent_runs(0), + _max_evaluations(0), + _MarkovChain_length(0), + _temperature_decay(0), + _refresh_global_state(0), + _synchronized(0), + _display_state(0), + _cooperation(0) + {} + + istream& operator>> (istream& is, SetUpParams& setup) + { + char buffer[MAX_BUFFER]; // current line in the setup file + char command[50]; + int op; + double dop; + short int nb_param=0; + short int nb_section=0; + short int nb_LAN_param=0; + + while (is.getline(buffer,MAX_BUFFER,'\n')) + { + sscanf(buffer," %s ",command); + + if (!(strcmp(command,"General"))) nb_section=0; + if (!(strcmp(command,"LAN-configuration"))) nb_section=1; + + if (nb_param==3 && nb_section==0) + { + dop=-1; + sscanf(buffer," %lf ",&dop); + if (dop<0) continue; + } + else + { + op=-1; + sscanf(buffer," %ld%*s ",&op); + if (op<0) continue; + } + + switch (nb_section) + { + case 0: switch (nb_param) + { + case 0: setup.independent_runs(op); break; + case 1: setup.max_evaluations(op); break; + case 2: setup.MarkovChain_length(op); break; + case 3: setup.temperature_decay(dop); break; + case 4: setup.display_state(op); break; + } + nb_param++; + break; + case 1: if (nb_LAN_param>=3) break; + if (nb_LAN_param==0) setup.refresh_global_state(op); + if (nb_LAN_param==1) setup.synchronized(op); + if (nb_LAN_param==2) setup.cooperation(op); + nb_LAN_param++; + break; + } // end switch + } // end while + return is; + } + + ostream& operator<< (ostream& os, const SetUpParams& setup) + { + os << "CONFIGURATION -------------------------------------------" << endl << endl; + os << "\t" << "Independent runs : " << setup.independent_runs() << endl + << "\t" << "Evaluation steps: " << setup.max_evaluations() << endl + << "\t" << "Markov-Chain Length: " << setup.MarkovChain_length() << endl + << "\t" << "Temperature Decay: " << setup.temperature_decay() << endl; + + if (setup.display_state()) + os << "\t" << "Display state" << endl; + else + os << "\t" << "Not display state" << endl; + os << endl << "\t" << "LAN configuration:" << endl + << "\t" << "----------------------" << endl << endl + << "\t" << "Refresh global state in number of generations: " << setup.refresh_global_state() << endl; + + if (setup.synchronized()) + os << "\t" << "Running in synchronous mode" << endl; + else + os << "\t" << "Running in asynchronous mode" << endl; + + if (!setup.cooperation()) + os << "\t" << "Running without cooperation" << endl << endl; + else + os << "\t" << "Running with cooperation in " << setup.cooperation() << " iterations. " << endl << endl; + + os << endl << endl << "END CONFIGURATION -------------------------------------------" << endl << endl; + return os; + } + + const unsigned int SetUpParams::independent_runs() const + { + return _independent_runs; + } + + const unsigned long SetUpParams::max_evaluations() const + { + return _max_evaluations; + } + + const unsigned int SetUpParams::MarkovChain_length() const + { + return _MarkovChain_length; + } + + const double SetUpParams::temperature_decay() const + { + return _temperature_decay; + } + + const bool SetUpParams::display_state() const + { + return _display_state; + } + + const unsigned long SetUpParams::refresh_global_state() const + { + return _refresh_global_state; + } + + const bool SetUpParams::synchronized() const + { + return _synchronized; + } + + const unsigned int SetUpParams::cooperation() const + { + return _cooperation; + } + + void SetUpParams::independent_runs(const unsigned int val) + { + _independent_runs = val; + } + + void SetUpParams::max_evaluations(const unsigned long val) + { + _max_evaluations= val; + } + void SetUpParams::MarkovChain_length(const unsigned int val) + { + _MarkovChain_length= val; + } + void SetUpParams::temperature_decay(const double val) + { + _temperature_decay= val; + } + + void SetUpParams::display_state(const bool val) + { + _display_state=val; + } + + void SetUpParams::refresh_global_state(const unsigned long val) + { + _refresh_global_state=val; + } + + void SetUpParams::synchronized(const bool val) + { + _synchronized=val; + } + + void SetUpParams::cooperation(const unsigned int val) + { + _cooperation=val; + } + + SetUpParams::~SetUpParams() + {} + +// Statistics ------------------------------------------------------ + + Statistics::Statistics() + {} + + ostream& operator<< (ostream& os, const Statistics& stats) + { + int j; + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF CURRENT TRIAL " << endl; + os << "------------------------------------------------------------------" << endl; + for (int i=0;i< stats.stats_data.size();i++) + { + os << endl + << " Evaluations: " << stats.stats_data[i].nb_evaluations + << " Best: " << stats.stats_data[i].best_cost + << " Current: " << stats.stats_data[i].current_cost; + } + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + Statistics& Statistics::operator= (const Statistics& stats) + { + stats_data = stats.stats_data; + return *this; + } + + void Statistics::update(const Solver& solver) + { + /* struct stat *new_stat; + if ((new_stat=(struct stat *)malloc(sizeof(struct stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluations= solver.current_iteration(); + new_stat->best_cost = solver.current_best_cost(); + new_stat->current_cost = solver.current_cost(); + stats_data.append(*new_stat); */ + } + + Statistics::~Statistics() + { + stats_data.remove(); + } + + void Statistics::clear() + { + stats_data.remove(); + } + +// Solver (superclass)--------------------------------------------------- + + Solver::Solver (const Problem& pbm, const SetUpParams& setup) + : problem(pbm), + params(setup), + _stat(), + _userstat(), + _sc(), + _direction(pbm.direction()), + current(pbm), + tentative(pbm), + currentTemperature(0.0), + time_spent_in_trial(0.0), + total_time_spent(0.0), + start_trial(0.0), + start_global(0.0), + _current_trial("_current_trial",_sc), + _current_iteration("_current_iteration",_sc), + _current_best_solution("_current_best_solution",_sc), + _current_best_cost("_current_best_cost",_sc), + _current_solution("_current_solution",_sc), + _current_cost("_current_cost",_sc), + _current_time_spent("_current_time_spent",_sc), + _initial_temperature_trial("_initial_temperature_trial",_sc), + _time_best_found_trial("_time_best_found_trial",_sc), + _iteration_best_found_trial("_iteration_best_found_trial",_sc), + _temperature_best_found_trial("_temperature_best_found_trial",_sc), + _time_spent_trial("_time_spent_trial",_sc), + _trial_best_found("_trial_best_found",_sc), + _iteration_best_found("_iteration_best_found;",_sc), + _global_best_solution("_global_best_solution",_sc), + _global_best_cost("_global_best_cost",_sc), + _time_best_found("_time_best_found",_sc), + _temperature("_temperature",_sc), + _display_state("_display_state",_sc) + { + current_trial(0); + current_iteration(0); + current_best_solution(current), + current_best_cost((-1) * pbm.direction() * infinity()); + current_solution(current); + current_cost((-1) * pbm.direction() * infinity()); + current_time_spent(total_time_spent); + initial_temperature_trial(0); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(0); + temperature_best_found_trial(0.0); + time_spent_trial(time_spent_in_trial); + trial_best_found(0); + iteration_best_found(0); + global_best_solution(current); + global_best_cost((-1) * pbm.direction() * infinity()); + time_best_found(total_time_spent); + temperature(currentTemperature); + display_state(setup.display_state()); + + move = new DefaultMove; + } + + int Solver::pid() const + { + return 0; + } + + bool Solver::end_trial() const + { + return _end_trial; + } + + unsigned int Solver::current_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_trial",(char *)&value, nitems, length); + return value; + } + + unsigned long Solver::current_iteration() const + { + unsigned long value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_iteration",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_best_solution() const + { + Solution sol(problem); + unsigned long nitems,length; + char data_stored[_current_best_solution.get_nitems() + _current_best_solution.get_length()]; + _sc.get_contents_state_variable("_current_best_solution", data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::current_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_best_cost",(char *)&value, nitems, length); + return value; + } + + double Solver::current_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_cost",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_solution() const + { + Solution sol(problem); + char data_stored[_current_solution.get_nitems() + _current_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_solution",data_stored, nitems, length); + sol.to_Solution((char *)data_stored); + return sol; + } + + float Solver::current_time_spent() const + { + float value=0.0; + unsigned long nitems,length; + _current_time_spent.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::initial_temperature_trial() const + { + double value=0.0; + unsigned long nitems,length; + _initial_temperature_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature_best_found_trial() const + { + double value=0.0; + unsigned long nitems,length; + _temperature_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_spent_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_spent_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::trial_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _trial_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::global_best_solution() const + { + Solution sol(problem); + char data_stored[_global_best_solution.get_nitems() + _global_best_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_solution",data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::global_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_cost",(char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_temperature",(char *)&value, nitems, length); + return value; + } + + int Solver::display_state() const + { + int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_display_state",(char *)&value, nitems, length); + return value; + } + + void Solver::current_trial(const unsigned int value) + { + _sc.set_contents_state_variable("_current_trial",(char *)&value,1,sizeof(int)); + } + + void Solver::current_iteration(const unsigned long value) + { + _sc.set_contents_state_variable("_current_iteration",(char *)&value,1,sizeof(long)); + } + + void Solver::current_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_best_cost(const double value) + { + _sc.set_contents_state_variable("_current_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_cost(const double value) + { + _sc.set_contents_state_variable("_current_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_time_spent(const float value) + { + _current_time_spent.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::time_best_found_trial(const float value) + { + _time_best_found_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::iteration_best_found_trial(const unsigned int value) + { + _iteration_best_found_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::initial_temperature_trial(const double value) + { + _initial_temperature_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::temperature_best_found_trial(const double value) + { + _temperature_best_found_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::time_spent_trial(const float value) + { + _time_spent_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::trial_best_found(const unsigned int value) + { + _trial_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::iteration_best_found(const unsigned int value) + { + _iteration_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::global_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_global_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::global_best_cost(const double value) + { + _sc.set_contents_state_variable("_global_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::time_best_found(const float value) + { + _time_best_found.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::temperature(const double value) + { + _sc.set_contents_state_variable("_temperature",(char *)&value,1,sizeof(double)); + } + + void Solver::display_state(const int value) + { + _sc.set_contents_state_variable("_display_state",(char *)&value,1,sizeof(int)); + } + + const Statistics& Solver::statistics() const + { + return _stat; + } + + const UserStatistics& Solver::userstatistics() const + { + return _userstat; + } + + const SetUpParams& Solver::setup() const + { + return params; + } + + const Problem& Solver::pbm() const + { + return problem; + } + + void Solver::KeepHistory(const Solution& sol, const double curfit,const float time_spent_in_trial,const float total_time_spent) + { + bool betterG=false; + bool betterT=false; + + switch (_direction) + { + case minimize: betterG = (curfit < global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit < current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + case maximize: betterG = (curfit > global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit > current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + } + + if (betterT) + { + current_best_solution(sol); + current_best_cost(curfit); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(current_iteration()); + temperature_best_found_trial(temperature()); + if (betterG) + { + trial_best_found(current_trial()); + iteration_best_found(current_iteration()); + global_best_solution(sol); + global_best_cost(curfit); + time_best_found(time_spent_in_trial); + } + } + } + + double Solver::UpdateT(double temp, int K) + { + //return temp * params.temperature_decay(); // initial + + /* + if(K == 1) return temp/log(2); + else return temp * log(K) / log(K+1); + */ + /* + if(K == 1) return temp/2; + else return (temp * K) / (K + 1); + */ + + if(K == 1) return temp / exp(2); + else return (temp * exp(K)) / exp(K+1); + + } + + StateCenter* Solver::GetState() + { + return &_sc; + } + + void Solver::RefreshState() + { + current_solution(current); + current_cost(curfit); + current_time_spent(total_time_spent); + time_spent_trial(time_spent_in_trial); + temperature(currentTemperature); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::UpdateFromState() + { + current = current_solution(); + curfit = current_cost(); + total_time_spent=current_time_spent(); + time_spent_in_trial=time_spent_trial(); + currentTemperature = temperature(); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::show_state() const + { + cout << endl << "Current trial: " << current_trial(); + cout << endl << "Current iteration: " << current_iteration(); + cout << endl << "Current Temperature: " << temperature (); + cout << endl << "Current cost: " << current_cost(); + cout << endl << "Best cost in trial: " << current_best_cost(); + cout << endl << "Time of best solution found in trial: " << time_best_found_trial(); + cout << endl << "Iteration of best solution found in trial: " << iteration_best_found_trial(); + cout << endl << "Initial temperature in trial: " << initial_temperature_trial(); + cout << endl << "Temperature of best solution found in trial: " << temperature_best_found_trial(); + cout << endl << "Time spent in trial: " << time_spent_trial(); + cout << endl << "Global best cost: " << global_best_cost(); + cout << endl << "Trial of best global solution found: " << trial_best_found(); + cout << endl << "Iteration of best global solution found: " << iteration_best_found(); + cout << endl << "Time of global best solution found: " << time_best_found(); + // cout << endl << "Current solution: " << current_solution(); + // cout << endl << "Best solution of trial: " << current_best_solution(); + // cout << endl << "Global solution: " << global_best_solution() << endl; + cout << endl << endl << "Current time spent (so far): " << current_time_spent() << endl; + } + + Solver::~Solver() + { + _sc.removeAll(); + delete move; + } + + bool Solver::AcceptQ (double tent, double cur, double temperature) + { + if (_direction==minimize) + + return (tent < cur) || + ((rand01()*(1+exp((tent-cur)/temperature)))<2.0); + + else + + return (tent > cur) || + ((rand01()*(1+exp((cur-tent)/temperature)))<2.0); + } + + double Solver::Set_Initial_Temperature(const Problem& pbm) + { + const double beta = 1.05; + const double test = 10; + const double acrat = .8; + const double T = 1.0; + + Solution current (pbm); + Solution newsol (pbm); + double ac; + double fit; + double temperature = T; + + do + { + temperature *= beta; + ac = 0; + current.initialize(); + fit = current.fitness(); + for (int i=0; i<test; i++) + { + newsol = current; + move->Apply(newsol); + if (AcceptQ(newsol.fitness(),fit,temperature)) + ac += 1.0/test; + } + } while (ac < acrat); + + initial_temperature_trial(temperature); + return temperature; + + } + + void Solver::SetMove (Move* mov) + { + delete move; + move = mov; + } + + // Solver sequencial ----------------------------------------------------- + + Solver_Seq::Solver_Seq (const Problem& pbm, const SetUpParams& setup) + : Solver(pbm,setup) + { + random_seed(time(0)); + _end_trial=true; + } + + Solver_Seq::~Solver_Seq () + {} + + void Solver_Seq::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Seq::StartUp(const Solution& sol, const double initialTemperature) + { + start_trial=_used_time(); + start_global=total_time_spent; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current = sol; + curfit = current.fitness(); + current_best_cost((-1) * problem.direction() * infinity()); + currentTemperature = initialTemperature; + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + void Solver_Seq::DoStep() + { + current_iteration(current_iteration()+1); + + tentative = current; + move->Apply(tentative); + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + + void Solver_Seq::run (unsigned long int max_evaluations) + { + StartUp(); + + while (current_iteration()<max_evaluations && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + // Solver LAN ----------------------------------------------------------- + + Solver_Lan::Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); + } + + Solver_Lan::~Solver_Lan () + { + NetStream::finalize(); + } + + int Solver_Lan::pid() const + { + return mypid; + } + + NetStream& Solver_Lan::netstream() + { + return _netstream; + } + + void Solver_Lan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Lan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + void update(Direction direction, Solution &solution_received,double cost_received, Solution &solution_to_send, double &best_cost) + { + switch (direction) + { + case minimize: if (cost_received < best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + case maximize: if (cost_received > best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + } + } + + int Solver_Lan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Lan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Lan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Lan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Lan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Lan::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + void Solver_Lan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } + + // Solver WAN ------------------------------------------------------------ + + Solver_Wan::Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); + } + + Solver_Wan::~Solver_Wan () + { + NetStream::finalize(); + } + + int Solver_Wan::pid() const + { + return mypid; + } + + NetStream& Solver_Wan::netstream() + { + return _netstream; + } + + void Solver_Wan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Wan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + int Solver_Wan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Wan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Wan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Wan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Wan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Wan::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + void Solver_Wan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } +}; + diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/SA.req.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/SA.req.cc new file mode 100644 index 0000000000000000000000000000000000000000..a327cb306d729022f5bb8908ec9d8932cb288f90 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/SA.req.cc @@ -0,0 +1,286 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** User-required classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** Tab size = 4 *** +*** *** +*** *** +************************************************/ + +#include <iostream.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "StopCondition.hh" + +skeleton SA { + + // Problem --------------------------------------------------------------- + + Problem::Problem ():_dimension(0) + {} + + ostream& operator<< (ostream& os, const Problem& pbm) + { + os << endl << endl << "Number of Variables " << pbm._dimension + << endl; + return os; + } + + istream& operator>> (istream& is, Problem& pbm) + { + char buffer[MAX_BUFFER]; + int i; + + is.getline(buffer,MAX_BUFFER,'\n'); + sscanf(buffer,"%d",&pbm._dimension); + + return is; + } + + bool Problem::operator== (const Problem& pbm) const + { + if (_dimension!=pbm.dimension()) return false; + return true; + } + + bool Problem::operator!= (const Problem& pbm) const + { + return !(*this == pbm); + } + + Direction Problem::direction() const + { + return maximize; + //return minimize; + } + + int Problem::dimension() const + { + return _dimension; + } + + double Problem::infinity() const + { + double one=1.0; + double zero=0.0; + return 0.0 - one/zero; + } + + Problem::~Problem() + { + } + + // Solution -------------------------------------------------------------- + + Solution::Solution (const Problem& pbm):_pbm(pbm),_var(pbm.dimension()) + {} + + const Problem& Solution::pbm() const + { + return _pbm; + } + + Solution::Solution(const Solution& sol):_pbm(sol.pbm()) + { + *this=sol; + } + + istream& operator>> (istream& is, Solution& sol) + { + for (int i=0;i<sol.pbm().dimension();i++) + is >> sol._var[i]; + return is; + } + + ostream& operator<< (ostream& os, const Solution& sol) + { + for (int i=0;i<sol.pbm().dimension();i++) + os << " " << sol._var[i]; + return os; + } + + NetStream& operator << (NetStream& ns, const Solution& sol) + { + for (int i=0;i<sol._var.size();i++) + ns << sol._var[i]; + return ns; + } + + NetStream& operator >> (NetStream& ns, Solution& sol) + { + for (int i=0;i<sol._var.size();i++) + ns >> sol._var[i]; + return ns; + } + + Solution& Solution::operator= (const Solution &sol) + { + _var=sol._var; + return *this; + } + + bool Solution::operator== (const Solution& sol) const + { + if (sol.pbm() != _pbm) return false; + return true; + } + + bool Solution::operator!= (const Solution& sol) const + { + return !(*this == sol); + } + + void Solution::initialize() + { + for (int i=0;i<_pbm.dimension();i++) + _var[i]=rand_int(0,1); + } + + double Solution::fitness () const + { + double fitness = 0.0; + + for (int i=0;i<_var.size();i++) + fitness += _var[i]; + + return fitness; + } + + char *Solution::to_String() const + { + return (char *)_var.get_first(); + } + + void Solution::to_Solution(char *_string_) + { + int *ptr=(int *)_string_; + for (int i=0;i<_pbm.dimension();i++) + { + _var[i]=*ptr; + ptr++; + } + } + + unsigned int Solution::size() const + { + return (_pbm.dimension() * sizeof(int)); + } + + + int& Solution::var(const int index) + { + return _var[index]; + } + + + Rarray<int>& Solution::array_var() + { + return _var; + } + + Solution::~Solution() + {} + +// UserStatistics ------------------------------------------------------- + + UserStatistics::UserStatistics () + {} + + ostream& operator<< (ostream& os, const UserStatistics& userstat) + { + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF TRIALS " << endl; + os << "------------------------------------------------------------------" << endl; + + for (int i=0;i< userstat.result_trials.size();i++) + { + os << endl + << "\t" << userstat.result_trials[i].trial + << "\t" << userstat.result_trials[i].best_cost_trial + << "\t\t" << userstat.result_trials[i].nb_evaluation_best_found_trial + << "\t\t" << userstat.result_trials[i].initial_temperature + << "\t\t" << userstat.result_trials[i].temperature_best_found_trial + << "\t\t" << userstat.result_trials[i].time_best_found_trial + << "\t\t" << userstat.result_trials[i].time_spent_trial; + } + + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + + UserStatistics& UserStatistics::operator= (const UserStatistics& userstats) + { + result_trials=userstats.result_trials; + return (*this); + } + + + void UserStatistics::update(const Solver& solver) + { + if ((solver.pid()!=0) || (solver.end_trial()!=true) + || ((solver.current_iteration()!=solver.setup().max_evaluations()) + && !TerminateQ(solver.pbm(),solver,solver.setup()))) + return; + + struct user_stat *new_stat; + if ((new_stat=(struct user_stat *)malloc(sizeof(struct user_stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluation_best_found_trial= solver.iteration_best_found_trial(); + new_stat->initial_temperature=solver.initial_temperature_trial(); + new_stat->temperature_best_found_trial=solver.temperature_best_found_trial(); + new_stat->best_cost_trial = solver.current_best_cost(); + new_stat->time_best_found_trial= solver.time_best_found_trial(); + new_stat->time_spent_trial = solver.time_spent_trial(); + result_trials.append(*new_stat); + } + + void UserStatistics::clear() + { + result_trials.remove(); + } + + UserStatistics::~UserStatistics() + { + result_trials.remove(); + } + +// DefaultMove ------------------------------------------------------- + + + DefaultMove::DefaultMove() + {} + + DefaultMove::~DefaultMove() + {} + + void DefaultMove::Apply (Solution& sol) const + { + const float probability = 0.03; + + for (int i=0;i<sol.pbm().dimension();i++) + { + if (rand01()<=probability) + { + if (sol.var(i)==1) sol.var(i)=0; + else sol.var(i)=1; + } + } + } + + //------------------------------------------------------------------------ + // Specific methods ------------------------------------------------------ + //------------------------------------------------------------------------ + + bool TerminateQ (const Problem& pbm, const Solver& solver, + const SetUpParams& setup) + { + + StopCondition_3 stop; + return stop.EvaluateCondition(pbm,solver,setup); + } +} + + diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/StopCondition.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/StopCondition.cc new file mode 100644 index 0000000000000000000000000000000000000000..f9cfd89b1a6f5292633566664a6caa78815ea279 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/StopCondition.cc @@ -0,0 +1,52 @@ +#include "StopCondition.hh" +skeleton SA +{ + +// StopCondition ------------------------------------------------------------------------------------- + + StopCondition::StopCondition() + {} + + StopCondition::~StopCondition() + {} + +// StopCondition_1 ------------------------------------------------------------------------------------- + + StopCondition_1::StopCondition_1():StopCondition() + {} + + bool StopCondition_1::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return false; + } + + StopCondition_1::~StopCondition_1() + {} + +// StopCondition_2 ------------------------------------------------------------------------------------- + + StopCondition_2::StopCondition_2():StopCondition() + {} + + bool StopCondition_2::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return (solver.global_best_cost()>8.5); + } + + StopCondition_2::~StopCondition_2() + {} + +// StopCondition_3 ------------------------------------------------------------------------------------- + + StopCondition_3::StopCondition_3():StopCondition() + {} + + bool StopCondition_3::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return ((int)solver.current_best_cost() == pbm.dimension()); + } + + StopCondition_3::~StopCondition_3() + {} + +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/StopCondition.hh b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/StopCondition.hh new file mode 100644 index 0000000000000000000000000000000000000000..04ef770d9cac5bb9ef69aae7d085e3ae2166e187 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/StopCondition.hh @@ -0,0 +1,41 @@ +#ifndef stop_condition +#define stop_condition + +#include "SA.hh" +skeleton SA +{ + + provides class StopCondition + { + public: + StopCondition(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup)=0; + ~StopCondition(); + }; + + requires class StopCondition_1 : public StopCondition + { + public: + StopCondition_1(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_1(); + }; + + requires class StopCondition_2 : public StopCondition + { + public: + StopCondition_2(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_2(); + }; + + requires class StopCondition_3 : public StopCondition + { + public: + StopCondition_3(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_3(); + }; +} + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/pgfileLan b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/pgfileLan new file mode 100644 index 0000000000000000000000000000000000000000..fa76afbfbf07aa7bda8b6c94d3c79b850b22342e --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/onemax/pgfileLan @@ -0,0 +1,5 @@ +localhost 0 ~/Mallba/rep/SA/onemax/MainLan +localhost 1 ~/Mallba/rep/SA/onemax/MainLan +localhost 1 ~/Mallba/rep/SA/onemax/MainLan +localhost 1 ~/Mallba/rep/SA/onemax/MainLan +localhost 1 ~/Mallba/rep/SA/onemax/MainLan diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/pgfileLan b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/pgfileLan new file mode 100644 index 0000000000000000000000000000000000000000..2c73753f745ee91a25a367aeaaeae00da9237c76 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/pgfileLan @@ -0,0 +1 @@ +machine_name number_of_process executable_path login diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/pgfileWan b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/pgfileWan new file mode 100644 index 0000000000000000000000000000000000000000..2c73753f745ee91a25a367aeaaeae00da9237c76 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/pgfileWan @@ -0,0 +1 @@ +machine_name number_of_process executable_path login diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/Config.cfg b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/Config.cfg new file mode 100644 index 0000000000000000000000000000000000000000..c8bac1a1bf02c9abdb8c509e47f01d8f5848f1e0 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/Config.cfg @@ -0,0 +1,3 @@ +SA.cfg +../../../ProblemInstances/RND-instances/rnd149.txt +res/rnd149.sa.lan.txt diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/MainLan.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/MainLan.cc new file mode 100644 index 0000000000000000000000000000000000000000..8949422e10f93211d953aba1308c203d13f30f0a --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/MainLan.cc @@ -0,0 +1,53 @@ +#include "SA.hh" +#include <iostream.h> +#include <fstream.h> + +int main (int argc, char** argv) +{ + using skeleton SA; + char path[MAX_BUFFER]; + int len; + int longitud; + + system("clear"); + + get_path(argv[0],path); + len = strlen(path); + longitud = MAX_BUFFER - len; + + strcat(path,"Config.cfg"); + ifstream f(path); + if(!f) show_message(10); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f1(path); + if(!f1) show_message(11); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f2(path); + if(!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + SetUpParams cfg; + f1 >> cfg; + + + Solver_Lan solver(pbm,cfg,argc,argv); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solucion: " << solver.global_best_solution() << " Fitness: " << solver.global_best_solution().fitness(); + + f.getline(&(path[len]),longitud,'\n'); + ofstream fexit(path); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + cout << endl << endl << " :( ---------------------- THE END --------------- :) " << endl; + } + return(0); +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/MainSeq.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/MainSeq.cc new file mode 100644 index 0000000000000000000000000000000000000000..41d8a720793c0d10b14e1d5dfa05b7f11e9c4dda --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/MainSeq.cc @@ -0,0 +1,42 @@ +#include "SA.hh" +#include <iostream.h> +#include <fstream.h> + +int main (int argc, char** argv) +{ + using skeleton SA; + + system("clear"); + + if(argc < 4) + show_message(1); + + ifstream f1(argv[1]); + if (!f1) show_message(11); + + ifstream f2(argv[2]); + if (!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + SetUpParams cfg; + f1 >> cfg; + + Solver_Seq solver(pbm,cfg); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << solver.global_best_solution() + << " Fitness: " << solver.global_best_solution().fitness() << endl; + cout << "\n\n :( ---------------------- THE END --------------- :) "; + + ofstream fexit(argv[3]); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + } + return(0); +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/Makefile b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..b15a6cd5f40fff6ee58229521da579010270af89 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/Makefile @@ -0,0 +1,22 @@ +include ../../../environment + +all: MainSeq MainLan + +clean: + rm -f MainLan MainSeq MainWan *.o *% *~ + +MainLan: SA.req.o SA.pro.o StopCondition.o MainLan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainWan: SA.req.o SA.pro.o StopCondition.o MainWan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainSeq: SA.req.o SA.pro.o StopCondition.o MainSeq.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +LAN: + $(RUN) -v -p4pg pgfileLan MainLan +WAN: + $(RUN) -v -p4pg pgfileWan MainWan +SEQ: + ./MainSeq SA.cfg ../../../ProblemInstances/RND-instances/rnd149.txt res/rnd149.sa.seq.txt diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/SA.cfg b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/SA.cfg new file mode 100644 index 0000000000000000000000000000000000000000..1dbac85cb0d3cf28e87175c640e6f9d53e5988f5 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/SA.cfg @@ -0,0 +1,9 @@ +10 // number of independent runs +5000 // number of evaluations +50 // Markov-Chain Length +.99 // temperature Decay +1 // display state ? +LAN-configuration +10 // the global state is updated in this number of evaluations +0 // 0: asynchronized mode // 1: synchronized mode +10 // interval of iterations to cooperate ( if 0 no cooperation) diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/SA.hh b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/SA.hh new file mode 100644 index 0000000000000000000000000000000000000000..6238f6de1290020e2dc587e829e825e0e7edb4ae --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/SA.hh @@ -0,0 +1,488 @@ +#ifndef INC_SA +#define INC_SA + +#include "Mallba/mallba.hh" +#include "Mallba/States.hh" +#include "Mallba/Rarray.h" +#include "Mallba/time.hh" +#include "Mallba/netstream.hh" +#include <math.h> +#include <string.h> + +skeleton SA +{ + + provides class SetUpParams; + provides class Statistics; + provides class Move; + provides class StopCondition; + provides class Solver; + provides class Solver_Seq; + provides class Solver_Lan; + provides class Solver_Wan; + + requires class Problem; + requires class Solution; + requires class StopCondition_1; + requires class StopCondition_2; + requires class StopCondition_3; + requires class DefaultMove; + requires class UserStatistics; + requires bool TerminateQ (const Problem& pbm, const Solver& solver, const SetUpParams& setup); + +// Problem ---------------------------------------------------------------------------- + + requires class Problem + { + public: + Problem (); + ~Problem (); + + friend ostream& operator<< (ostream& os, const Problem& pbm); + friend istream& operator>> (istream& is, Problem& pbm); + + Problem& operator= (const Problem& pbm); + bool operator== (const Problem& pbm) const; + bool operator!= (const Problem& pbm) const; + + Direction direction () const; + + int dimension() const; + double infinity() const; + + private: + + int _dimension; + }; + +//Solution ---------------------------------------------------------------------------- + + requires class Solution + { + public: + Solution (const Problem& pbm); + Solution (const Solution& sol); + ~Solution(); + + friend ostream& operator<< (ostream& os, const Solution& sol); + friend istream& operator>> (istream& is, Solution& sol); + friend NetStream& operator << (NetStream& ns, const Solution& sol); + friend NetStream& operator >> (NetStream& ns, Solution& sol); + + const Problem& pbm() const; + + Solution& operator= (const Solution& sol); + bool operator== (const Solution& sol) const; + bool operator!= (const Solution& sol) const; + + char *to_String() const; + void to_Solution(char *_vertex_); + unsigned int size() const; + + void initialize(); + double fitness () const; + + int& var(const int index); + Rarray<int>& array_var(); + + private: + Rarray<int> _var; + const Problem& _pbm; + }; + +// UserStatistics ---------------------------------------------------------------------------- + + requires class UserStatistics + { + private: + struct user_stat + { + unsigned int trial; + double initial_temperature; + double temperature_best_found_trial; + unsigned long nb_evaluation_best_found_trial; + double best_cost_trial; + float time_best_found_trial; + float time_spent_trial; + }; + + Rlist<struct user_stat> result_trials; + + public: + UserStatistics (); + ~UserStatistics(); + + friend ostream& operator<< (ostream& os, const UserStatistics& usertats); + + UserStatistics& operator= (const UserStatistics& userstats); + void update(const Solver& solver); + void clear(); + }; + +// Move ---------------------------------------------------------------------------------- + + provides class Move + { + public: + Move() {} + virtual ~Move() {} + + virtual void Apply(Solution& sol) const = 0; + }; + +// DefaultMove ---------------------------------------------------------------------------------- + + requires class DefaultMove: public Move + { + public: + DefaultMove(); + ~DefaultMove(); + + void Apply(Solution& sol) const; + }; + +// SetUpParams ------------------------------------------------------------------------------- + + provides class SetUpParams + { + private: + unsigned int _independent_runs; + unsigned long _max_evaluations; + unsigned int _MarkovChain_length; + double _temperature_decay; + bool _display_state; + + // for LAN execution configuration + unsigned long _refresh_global_state; + bool _synchronized; + unsigned int _cooperation; + + public: + SetUpParams (); + + friend ostream& operator<< (ostream& os, const SetUpParams& setup); + friend istream& operator>> (istream& is, SetUpParams& setup); + + const unsigned int independent_runs() const; + const unsigned long max_evaluations() const; + const unsigned int MarkovChain_length() const; + const double temperature_decay() const; + const bool display_state() const; + const unsigned long refresh_global_state() const; + const bool synchronized() const; + const unsigned int cooperation() const; + + void independent_runs(const unsigned int val); + void max_evaluations(const unsigned long val); + void MarkovChain_length(const unsigned int val); + void temperature_decay(const double val); + void display_state(const bool val); + void refresh_global_state(const unsigned long val); + void synchronized(const bool val); + void cooperation(const unsigned int val); + + ~SetUpParams(); + }; + +// Statistics --------------------------------------------------------------------------------- + + provides class Statistics + { + private: + struct stat + { + unsigned int trial; + unsigned long nb_evaluations; + double best_cost; + double current_cost; + }; + + Rlist<struct stat> stats_data; + + public: + Statistics(); + + friend ostream& operator<< (ostream& os, const Statistics& stats); + + Statistics& operator= (const Statistics& stats); + void update(const Solver& solver); + void clear(); + + ~Statistics(); + }; + +// Solver --------------------------------------------------------------------------------- + + provides class Solver + { + protected: + const Problem& problem; + const SetUpParams& params; + UserStatistics _userstat; + Statistics _stat; + Move* move; + Solution current; + double curfit; + Solution tentative; + double currentTemperature; + unsigned int k; // to control temperature update. + StateCenter _sc; + + float total_time_spent; + float time_spent_in_trial; + float start_trial; + float start_global; + + bool _end_trial; + + State_Vble _current_trial; + State_Vble _current_iteration; + State_Vble _current_best_solution; + State_Vble _current_best_cost; + State_Vble _current_solution; + State_Vble _current_cost; + + State_Vble _current_time_spent; + State_Vble _initial_temperature_trial; + State_Vble _time_best_found_trial; + State_Vble _iteration_best_found_trial; + State_Vble _temperature_best_found_trial; + State_Vble _time_spent_trial; + + State_Vble _trial_best_found; + State_Vble _iteration_best_found; + State_Vble _global_best_solution; + State_Vble _global_best_cost; + State_Vble _time_best_found; + + State_Vble _temperature; + State_Vble _display_state; + + const Direction _direction; + + bool AcceptQ(double tent, double cur, double temperature); + double Set_Initial_Temperature(const Problem& pbm); + void KeepHistory(const Solution& sol, const double curfit,const float time_spent_trial,const float total_time_spent); + + double UpdateT(double temp, int K); + + public: + // Constructor - Destructor ------------------------- + + Solver (const Problem& pbm, const SetUpParams& setup); + virtual ~Solver (); + virtual int pid() const; + bool end_trial() const; + + // Execution methods -------------------------------- + + // Full execution + virtual void run () =0; + virtual void run (unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol, unsigned long int nb_evaluations) =0; + + virtual void run (const double initialTemperature) =0; + virtual void run (const Solution& sol,const double initialTemperature) =0; + virtual void run (const double initialTemperature, unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations) =0; + + // Partial execution + virtual void StartUp () =0; + virtual void StartUp (const Solution& sol) =0; + virtual void StartUp (const double initialTemperature) =0; + virtual void StartUp (const Solution& sol, const double initialTemperature) =0; + virtual void DoStep () =0; + + // Statistics handling ------------------------------ + + const Statistics& statistics() const; + const UserStatistics& userstatistics () const; + const SetUpParams& setup() const; + const Problem& pbm() const; + + // State handling ----------------------------------- + + void RefreshState(); + void UpdateFromState(); + StateCenter* GetState(); + + unsigned int current_trial() const; + unsigned long current_iteration() const; + Solution current_best_solution() const; + Solution current_solution() const; + double current_best_cost() const; + double current_cost() const; + float current_time_spent() const; + float time_best_found_trial() const; + double initial_temperature_trial() const; + unsigned int iteration_best_found_trial() const; + double temperature_best_found_trial() const; + float time_spent_trial() const; + unsigned int trial_best_found() const; + unsigned int iteration_best_found() const; + Solution global_best_solution() const; + double global_best_cost() const; + float time_best_found() const; + double temperature() const; + int display_state() const; + + void current_trial(const unsigned int value); + void current_iteration(const unsigned long value); + void current_best_solution(const Solution& sol); + void current_best_cost(const double value); + void current_solution(const Solution& sol); + void current_cost(const double value); + void current_time_spent(const float value); + void time_best_found_trial(const float value); + void initial_temperature_trial(const double temperature); + void iteration_best_found_trial(const unsigned int value); + void temperature_best_found_trial(const double value); + void time_spent_trial(const float value); + void trial_best_found(const unsigned int value); + void iteration_best_found(const unsigned int value); + void global_best_solution(const Solution& sol); + void global_best_cost(const double value); + void time_best_found(const float value); + void temperature(const double value); + void display_state(const int value); + void show_state() const; + + // State handling ----------------------------------- + void SetMove(Move* mov); + }; + + provides class Solver_Seq: public Solver + { + public: + // Constructor - Destructor ------------------------- + + Solver_Seq ( const Problem& pbm, const SetUpParams& setup); + virtual ~Solver_Seq (); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + }; + + provides class Solver_Lan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + + public: + Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Lan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + + provides class Solver_Wan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + + public: + Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Wan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + +}; + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/SA.pro.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/SA.pro.cc new file mode 100644 index 0000000000000000000000000000000000000000..43dcaf9ebda2aa5738f2982cb5f6441259ce44f5 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/SA.pro.cc @@ -0,0 +1,1807 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** Provided classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** *** +************************************************/ + +#include <iostream.h> +#include <math.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "Mallba/time.hh" + +skeleton SA +{ + +// SetUpParams ----------------------------------------------------------- + + SetUpParams::SetUpParams (): + _independent_runs(0), + _max_evaluations(0), + _MarkovChain_length(0), + _temperature_decay(0), + _refresh_global_state(0), + _synchronized(0), + _display_state(0), + _cooperation(0) + {} + + istream& operator>> (istream& is, SetUpParams& setup) + { + char buffer[MAX_BUFFER]; // current line in the setup file + char command[50]; + int op; + double dop; + short int nb_param=0; + short int nb_section=0; + short int nb_LAN_param=0; + + while (is.getline(buffer,MAX_BUFFER,'\n')) + { + sscanf(buffer," %s ",command); + + if (!(strcmp(command,"General"))) nb_section=0; + if (!(strcmp(command,"LAN-configuration"))) nb_section=1; + + if (nb_param==3 && nb_section==0) + { + dop=-1; + sscanf(buffer," %lf ",&dop); + if (dop<0) continue; + } + else + { + op=-1; + sscanf(buffer," %ld%*s ",&op); + if (op<0) continue; + } + + switch (nb_section) + { + case 0: switch (nb_param) + { + case 0: setup.independent_runs(op); break; + case 1: setup.max_evaluations(op); break; + case 2: setup.MarkovChain_length(op); break; + case 3: setup.temperature_decay(dop); break; + case 4: setup.display_state(op); break; + } + nb_param++; + break; + case 1: if (nb_LAN_param>=3) break; + if (nb_LAN_param==0) setup.refresh_global_state(op); + if (nb_LAN_param==1) setup.synchronized(op); + if (nb_LAN_param==2) setup.cooperation(op); + nb_LAN_param++; + break; + } // end switch + } // end while + return is; + } + + ostream& operator<< (ostream& os, const SetUpParams& setup) + { + os << "CONFIGURATION -------------------------------------------" << endl << endl; + os << "\t" << "Independent runs : " << setup.independent_runs() << endl + << "\t" << "Evaluation steps: " << setup.max_evaluations() << endl + << "\t" << "Markov-Chain Length: " << setup.MarkovChain_length() << endl + << "\t" << "Temperature Decay: " << setup.temperature_decay() << endl; + + if (setup.display_state()) + os << "\t" << "Display state" << endl; + else + os << "\t" << "Not display state" << endl; + os << endl << "\t" << "LAN configuration:" << endl + << "\t" << "----------------------" << endl << endl + << "\t" << "Refresh global state in number of generations: " << setup.refresh_global_state() << endl; + + if (setup.synchronized()) + os << "\t" << "Running in synchronous mode" << endl; + else + os << "\t" << "Running in asynchronous mode" << endl; + + if (!setup.cooperation()) + os << "\t" << "Running without cooperation" << endl << endl; + else + os << "\t" << "Running with cooperation in " << setup.cooperation() << " iterations. " << endl << endl; + + os << endl << endl << "END CONFIGURATION -------------------------------------------" << endl << endl; + return os; + } + + const unsigned int SetUpParams::independent_runs() const + { + return _independent_runs; + } + + const unsigned long SetUpParams::max_evaluations() const + { + return _max_evaluations; + } + + const unsigned int SetUpParams::MarkovChain_length() const + { + return _MarkovChain_length; + } + + const double SetUpParams::temperature_decay() const + { + return _temperature_decay; + } + + const bool SetUpParams::display_state() const + { + return _display_state; + } + + const unsigned long SetUpParams::refresh_global_state() const + { + return _refresh_global_state; + } + + const bool SetUpParams::synchronized() const + { + return _synchronized; + } + + const unsigned int SetUpParams::cooperation() const + { + return _cooperation; + } + + void SetUpParams::independent_runs(const unsigned int val) + { + _independent_runs = val; + } + + void SetUpParams::max_evaluations(const unsigned long val) + { + _max_evaluations= val; + } + void SetUpParams::MarkovChain_length(const unsigned int val) + { + _MarkovChain_length= val; + } + void SetUpParams::temperature_decay(const double val) + { + _temperature_decay= val; + } + + void SetUpParams::display_state(const bool val) + { + _display_state=val; + } + + void SetUpParams::refresh_global_state(const unsigned long val) + { + _refresh_global_state=val; + } + + void SetUpParams::synchronized(const bool val) + { + _synchronized=val; + } + + void SetUpParams::cooperation(const unsigned int val) + { + _cooperation=val; + } + + SetUpParams::~SetUpParams() + {} + +// Statistics ------------------------------------------------------ + + Statistics::Statistics() + {} + + ostream& operator<< (ostream& os, const Statistics& stats) + { + int j; + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF CURRENT TRIAL " << endl; + os << "------------------------------------------------------------------" << endl; + for (int i=0;i< stats.stats_data.size();i++) + { + os << endl + << " Evaluations: " << stats.stats_data[i].nb_evaluations + << " Best: " << stats.stats_data[i].best_cost + << " Current: " << stats.stats_data[i].current_cost; + } + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + Statistics& Statistics::operator= (const Statistics& stats) + { + stats_data = stats.stats_data; + return *this; + } + + void Statistics::update(const Solver& solver) + { + /* struct stat *new_stat; + if ((new_stat=(struct stat *)malloc(sizeof(struct stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluations= solver.current_iteration(); + new_stat->best_cost = solver.current_best_cost(); + new_stat->current_cost = solver.current_cost(); + stats_data.append(*new_stat); */ + } + + Statistics::~Statistics() + { + stats_data.remove(); + } + + void Statistics::clear() + { + stats_data.remove(); + } + +// Solver (superclass)--------------------------------------------------- + + Solver::Solver (const Problem& pbm, const SetUpParams& setup) + : problem(pbm), + params(setup), + _stat(), + _userstat(), + _sc(), + _direction(pbm.direction()), + current(pbm), + tentative(pbm), + currentTemperature(0.0), + time_spent_in_trial(0.0), + total_time_spent(0.0), + start_trial(0.0), + start_global(0.0), + _current_trial("_current_trial",_sc), + _current_iteration("_current_iteration",_sc), + _current_best_solution("_current_best_solution",_sc), + _current_best_cost("_current_best_cost",_sc), + _current_solution("_current_solution",_sc), + _current_cost("_current_cost",_sc), + _current_time_spent("_current_time_spent",_sc), + _initial_temperature_trial("_initial_temperature_trial",_sc), + _time_best_found_trial("_time_best_found_trial",_sc), + _iteration_best_found_trial("_iteration_best_found_trial",_sc), + _temperature_best_found_trial("_temperature_best_found_trial",_sc), + _time_spent_trial("_time_spent_trial",_sc), + _trial_best_found("_trial_best_found",_sc), + _iteration_best_found("_iteration_best_found;",_sc), + _global_best_solution("_global_best_solution",_sc), + _global_best_cost("_global_best_cost",_sc), + _time_best_found("_time_best_found",_sc), + _temperature("_temperature",_sc), + _display_state("_display_state",_sc) + { + current_trial(0); + current_iteration(0); + current_best_solution(current), + current_best_cost((-1) * pbm.direction() * infinity()); + current_solution(current); + current_cost((-1) * pbm.direction() * infinity()); + current_time_spent(total_time_spent); + initial_temperature_trial(0); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(0); + temperature_best_found_trial(0.0); + time_spent_trial(time_spent_in_trial); + trial_best_found(0); + iteration_best_found(0); + global_best_solution(current); + global_best_cost((-1) * pbm.direction() * infinity()); + time_best_found(total_time_spent); + temperature(currentTemperature); + display_state(setup.display_state()); + + move = new DefaultMove; + } + + int Solver::pid() const + { + return 0; + } + + bool Solver::end_trial() const + { + return _end_trial; + } + + unsigned int Solver::current_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_trial",(char *)&value, nitems, length); + return value; + } + + unsigned long Solver::current_iteration() const + { + unsigned long value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_iteration",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_best_solution() const + { + Solution sol(problem); + unsigned long nitems,length; + char data_stored[_current_best_solution.get_nitems() + _current_best_solution.get_length()]; + _sc.get_contents_state_variable("_current_best_solution", data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::current_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_best_cost",(char *)&value, nitems, length); + return value; + } + + double Solver::current_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_cost",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_solution() const + { + Solution sol(problem); + char data_stored[_current_solution.get_nitems() + _current_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_solution",data_stored, nitems, length); + sol.to_Solution((char *)data_stored); + return sol; + } + + float Solver::current_time_spent() const + { + float value=0.0; + unsigned long nitems,length; + _current_time_spent.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::initial_temperature_trial() const + { + double value=0.0; + unsigned long nitems,length; + _initial_temperature_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature_best_found_trial() const + { + double value=0.0; + unsigned long nitems,length; + _temperature_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_spent_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_spent_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::trial_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _trial_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::global_best_solution() const + { + Solution sol(problem); + char data_stored[_global_best_solution.get_nitems() + _global_best_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_solution",data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::global_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_cost",(char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_temperature",(char *)&value, nitems, length); + return value; + } + + int Solver::display_state() const + { + int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_display_state",(char *)&value, nitems, length); + return value; + } + + void Solver::current_trial(const unsigned int value) + { + _sc.set_contents_state_variable("_current_trial",(char *)&value,1,sizeof(int)); + } + + void Solver::current_iteration(const unsigned long value) + { + _sc.set_contents_state_variable("_current_iteration",(char *)&value,1,sizeof(long)); + } + + void Solver::current_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_best_cost(const double value) + { + _sc.set_contents_state_variable("_current_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_cost(const double value) + { + _sc.set_contents_state_variable("_current_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_time_spent(const float value) + { + _current_time_spent.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::time_best_found_trial(const float value) + { + _time_best_found_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::iteration_best_found_trial(const unsigned int value) + { + _iteration_best_found_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::initial_temperature_trial(const double value) + { + _initial_temperature_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::temperature_best_found_trial(const double value) + { + _temperature_best_found_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::time_spent_trial(const float value) + { + _time_spent_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::trial_best_found(const unsigned int value) + { + _trial_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::iteration_best_found(const unsigned int value) + { + _iteration_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::global_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_global_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::global_best_cost(const double value) + { + _sc.set_contents_state_variable("_global_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::time_best_found(const float value) + { + _time_best_found.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::temperature(const double value) + { + _sc.set_contents_state_variable("_temperature",(char *)&value,1,sizeof(double)); + } + + void Solver::display_state(const int value) + { + _sc.set_contents_state_variable("_display_state",(char *)&value,1,sizeof(int)); + } + + const Statistics& Solver::statistics() const + { + return _stat; + } + + const UserStatistics& Solver::userstatistics() const + { + return _userstat; + } + + const SetUpParams& Solver::setup() const + { + return params; + } + + const Problem& Solver::pbm() const + { + return problem; + } + + void Solver::KeepHistory(const Solution& sol, const double curfit,const float time_spent_in_trial,const float total_time_spent) + { + bool betterG=false; + bool betterT=false; + + switch (_direction) + { + case minimize: betterG = (curfit < global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit < current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + case maximize: betterG = (curfit > global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit > current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + } + + if (betterT) + { + current_best_solution(sol); + current_best_cost(curfit); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(current_iteration()); + temperature_best_found_trial(temperature()); + if (betterG) + { + trial_best_found(current_trial()); + iteration_best_found(current_iteration()); + global_best_solution(sol); + global_best_cost(curfit); + time_best_found(time_spent_in_trial); + } + } + } + + double Solver::UpdateT(double temp, int K) + { + //return temp * params.temperature_decay(); // initial + + /* + if(K == 1) return temp/log(2); + else return temp * log(K) / log(K+1); + */ + /* + if(K == 1) return temp/2; + else return (temp * K) / (K + 1); + */ + + if(K == 1) return temp / exp(2); + else return (temp * exp(K)) / exp(K+1); + + } + + StateCenter* Solver::GetState() + { + return &_sc; + } + + void Solver::RefreshState() + { + current_solution(current); + current_cost(curfit); + current_time_spent(total_time_spent); + time_spent_trial(time_spent_in_trial); + temperature(currentTemperature); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::UpdateFromState() + { + current = current_solution(); + curfit = current_cost(); + total_time_spent=current_time_spent(); + time_spent_in_trial=time_spent_trial(); + currentTemperature = temperature(); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::show_state() const + { + cout << endl << "Current trial: " << current_trial(); + cout << endl << "Current iteration: " << current_iteration(); + cout << endl << "Current Temperature: " << temperature (); + cout << endl << "Current cost: " << current_cost(); + cout << endl << "Best cost in trial: " << current_best_cost(); + cout << endl << "Time of best solution found in trial: " << time_best_found_trial(); + cout << endl << "Iteration of best solution found in trial: " << iteration_best_found_trial(); + cout << endl << "Initial temperature in trial: " << initial_temperature_trial(); + cout << endl << "Temperature of best solution found in trial: " << temperature_best_found_trial(); + cout << endl << "Time spent in trial: " << time_spent_trial(); + cout << endl << "Global best cost: " << global_best_cost(); + cout << endl << "Trial of best global solution found: " << trial_best_found(); + cout << endl << "Iteration of best global solution found: " << iteration_best_found(); + cout << endl << "Time of global best solution found: " << time_best_found(); + // cout << endl << "Current solution: " << current_solution(); + // cout << endl << "Best solution of trial: " << current_best_solution(); + // cout << endl << "Global solution: " << global_best_solution() << endl; + cout << endl << endl << "Current time spent (so far): " << current_time_spent() << endl; + } + + Solver::~Solver() + { + _sc.removeAll(); + delete move; + } + + bool Solver::AcceptQ (double tent, double cur, double temperature) + { + if (_direction==minimize) + + return (tent < cur) || + ((rand01()*(1+exp((tent-cur)/temperature)))<2.0); + + else + + return (tent > cur) || + ((rand01()*(1+exp((cur-tent)/temperature)))<2.0); + } + + double Solver::Set_Initial_Temperature(const Problem& pbm) + { + const double beta = 1.05; + const double test = 10; + const double acrat = .8; + const double T = 1.0; + + Solution current (pbm); + Solution newsol (pbm); + double ac; + double fit; + double temperature = T; + + do + { + temperature *= beta; + ac = 0; + current.initialize(); + fit = current.fitness(); + for (int i=0; i<test; i++) + { + newsol = current; + move->Apply(newsol); + if (AcceptQ(newsol.fitness(),fit,temperature)) + ac += 1.0/test; + } + } while (ac < acrat); + + initial_temperature_trial(temperature); + return temperature; + + } + + void Solver::SetMove (Move* mov) + { + delete move; + move = mov; + } + + // Solver sequencial ----------------------------------------------------- + + Solver_Seq::Solver_Seq (const Problem& pbm, const SetUpParams& setup) + : Solver(pbm,setup) + { + random_seed(time(0)); + _end_trial=true; + } + + Solver_Seq::~Solver_Seq () + {} + + void Solver_Seq::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Seq::StartUp(const Solution& sol, const double initialTemperature) + { + start_trial=_used_time(); + start_global=total_time_spent; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current = sol; + curfit = current.fitness(); + current_best_cost((-1) * problem.direction() * infinity()); + currentTemperature = initialTemperature; + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + void Solver_Seq::DoStep() + { + current_iteration(current_iteration()+1); + + tentative = current; + move->Apply(tentative); + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + + void Solver_Seq::run (unsigned long int max_evaluations) + { + StartUp(); + + while (current_iteration()<max_evaluations && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + // Solver LAN ----------------------------------------------------------- + + Solver_Lan::Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); + } + + Solver_Lan::~Solver_Lan () + { + NetStream::finalize(); + } + + int Solver_Lan::pid() const + { + return mypid; + } + + NetStream& Solver_Lan::netstream() + { + return _netstream; + } + + void Solver_Lan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Lan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + void update(Direction direction, Solution &solution_received,double cost_received, Solution &solution_to_send, double &best_cost) + { + switch (direction) + { + case minimize: if (cost_received < best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + case maximize: if (cost_received > best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + } + } + + int Solver_Lan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Lan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Lan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Lan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Lan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Lan::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + void Solver_Lan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } + + // Solver WAN ------------------------------------------------------------ + + Solver_Wan::Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); + } + + Solver_Wan::~Solver_Wan () + { + NetStream::finalize(); + } + + int Solver_Wan::pid() const + { + return mypid; + } + + NetStream& Solver_Wan::netstream() + { + return _netstream; + } + + void Solver_Wan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Wan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + int Solver_Wan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Wan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Wan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Wan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Wan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Wan::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + void Solver_Wan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } +}; + diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/SA.req.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/SA.req.cc new file mode 100644 index 0000000000000000000000000000000000000000..1702a43465ebe97fa3160f868220d72a0b5d96c8 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/SA.req.cc @@ -0,0 +1,385 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** User-required classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** Tab size = 4 *** +*** *** +*** *** +************************************************/ + +#include <iostream.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "StopCondition.hh" + +//Parámetros para RND ------------------------------------------------------------- + +#define GRID_SIZE_X 287 //Artificial grid horizontal size. +#define GRID_SIZE_Y 287 //Artificial grid vertical size. +#define GRID_SIZE 82369 //Total grid size. +#define TRANS_NUMB 59 //Number of transmiters used. +#define TRANS_TOTAL 349 //Number of total transmiters. + //49 transmiters distributed regulary... + //... the rest is distributed randomly. + +#define RANGE 20 //Transmiter cover range (square area) + +//------------------------------------------------------------------------------------------------------- +#define TARGET_FITNESS 204.08 //Fitness to be achieved in current trial +//------------------------------------------------------------------------------------------------------- + + +#define MAX_FIT 204.08 //Fitness for optimum solution. +#define AVG_B -4.878 //Coef. for linear penalty of fitness value ... +#define AVG_A 4.878 // ... depending on avg. and dev. overlapping. +#define DEV_B 0.0 +#define DEV_A 2.404 + +//--------------------------------------------------------------------------------- + +skeleton SA { + + + + + //Array ------------------------------------------------------------------ + + static short int trans_location[TRANS_TOTAL*2]= + {20,20, 61,20, 102,20, 143,20, 184,20, 225,20, 266,20, + 20,61, 61,61, 102,61, 143,61, 184,61, 225,61, 266,61, + 20,102, 61,102, 102,102, 143,102, 184,102, 225,102, 266,102, + 20,143, 61,143, 102,143, 143,143, 184,143, 225,143, 266,143, + 20,184, 61,184, 102,184, 143,184, 184,184, 225,184, 266,184, + 20,225, 61,225, 102,225, 143,225, 184,225, 225,225, 266,225, + 20,266, 61,266, 102,266, 143,266, 184,266, 225,266, 266,266, + + 169,180, 180,161, 160,233, 57,156, 158,145, 138,151, 160,32, + 165,36, 228,111, 251,181, 110,130, 286,19, 96,183, 91,133, + 88,74, 93,56, 35,273, 152,198, 142,181, 37,117, 271,193, + 49,109, 104,119, 110,54, 58,160, 135,204, 220,172, 4,141, + 160,244, 210,14, 36,37, 98,3, 134,226, 197,109, 101,17, + 112,230, 169,126, 215,44, 206,27, 18,90, 14,272, 40,134, + 160,150, 58,216, 170,37, 252,185, 246,142, 154,247, 180,128, + 188,55, 207,201, 134,15, 31,111, 166,34, 206,116, 223,261, + 94,48, 227,179, 24,250, 46,26, 159,245, 279,56, 235,43, + 195,166, 165,241, 203,9, 190,73, 20,91, 25,200, 211,255, + 260,199, 262,66, 283,120, 16,76, 38,112, 201,172, 144,1, + 273,282, 230,285, 222,240, 70,132, 240,40, 202,147, 35,175, + 24,41, 4,120, 88,114, 23,104, 274,142, 83,230, 281,265, + 248,58, 140,42, 136,185, 17,2, 9,42, 156,115, 216,32, + 242,104, 221,224, +241,113,224,229,261,56,96,220,79,158,137,180,104,147,273,262,182,205,40,174, +4,69,39,230,44,115,37,31,286,62,147,240,175,84,182,150,141,279,83,221, +151,220,114,255,81,101,231,263,20,272,150,24,55,190,255,100,18,5,131,18, +68,278,258,244,76,154,107,218,147,191,152,11,125,267,267,206,81,211,183,101, +197,47,126,252,237,94,65,256,100,197,274,168,188,246,126,265,114,233,196,261, +138,61,272,264,42,252,183,123,177,80,225,88,128,64,53,79,159,119,48,260, +29,36,142,218,282,268,196,109,215,105,84,66,167,70,43,210,36,227,47,213, +21,272,15,149,50,68,228,210,188,277,183,218,26,38,149,22,20,58,132,235, +164,216,14,45,286,58,255,36,286,15,249,20,1,264,170,51,46,112,262,235, +103,158,166,129,197,28,152,217,87,284,165,251,214,180,10,214,239,265,250,238, +281,213,259,282,191,142,47,238,255,22,186,71,180,65,201,90,94,66,21,181, +64,186,146,278,80,156,206,32,135,170,271,129,96,243,124,0,98,171,239,67, +193,138,138,87,204,52,178,11,118,199,193,183,99,52,174,179,209,94,212,58, +264,196,187,73,152,25,74,251,196,26,31,103,165,170,191,82,222,82,94,54, +282,1,237,95,54,125,275,263,219,200,34,196,110,222,270,262,247,58,227,157, +85,259,261,250,142,165,46,78,248,141,133,243,142,83,51,196,208,39,173,141, +240,207,51,63,143,34,39,103,93,267,260,178,240,234,142,96,113,189,174,74, +43,20,30,185,104,82,95,26,122,268,167,76,189,218,139,45,253,179,148,59, +160,122,238,113,70,93,209,183,282,97,257,39,117,1,224,222,84,32,248,206, +14,128,283,203,60,136,248,26,28,109,86,188,232,37,14,15,131,224,198,127}; + //Transmiters location array + + static short int grid[GRID_SIZE]; + + // Problem --------------------------------------------------------------- + + Problem::Problem ():_dimension(0) + {} + + ostream& operator<< (ostream& os, const Problem& pbm) + { + os << endl << endl << "Number of Variables " << pbm._dimension + << endl; + return os; + } + + istream& operator>> (istream& is, Problem& pbm) + { + char buffer[MAX_BUFFER]; + int i; + + is.getline(buffer,MAX_BUFFER,'\n'); + sscanf(buffer,"%d",&pbm._dimension); + + return is; + } + + Problem& Problem::operator= (const Problem& pbm) + { + return *this; + } + + bool Problem::operator== (const Problem& pbm) const + { + if (_dimension!=pbm.dimension()) return false; + return true; + } + + bool Problem::operator!= (const Problem& pbm) const + { + return !(*this == pbm); + } + + Direction Problem::direction() const + { + return maximize; + //return minimize; + } + + int Problem::dimension() const + { + return _dimension; + } + + Problem::~Problem() + {} + + // Solution -------------------------------------------------------------- + + Solution::Solution (const Problem& pbm):_pbm(pbm),_var(pbm.dimension()) + {} + + const Problem& Solution::pbm() const + { + return _pbm; + } + + Solution::Solution(const Solution& sol):_pbm(sol.pbm()) + { + *this=sol; + } + + istream& operator>> (istream& is, Solution& sol) + { + for (int i=0;i<sol.pbm().dimension();i++) + is >> sol._var[i]; + return is; + } + + ostream& operator<< (ostream& os, const Solution& sol) + { + for (int i=0;i<sol.pbm().dimension();i++) + os << " " << sol._var[i]; + return os; + } + + NetStream& operator << (NetStream& ns, const Solution& sol) + { + for (int i=0;i<sol._var.size();i++) + ns << sol._var[i]; + return ns; + } + + NetStream& operator >> (NetStream& ns, Solution& sol) + { + for (int i=0;i<sol._var.size();i++) + ns >> sol._var[i]; + return ns; + } + + Solution& Solution::operator= (const Solution &sol) + { + _var=sol._var; + return *this; + } + + bool Solution::operator== (const Solution& sol) const + { + if (sol.pbm() != _pbm) return false; + return true; + } + + bool Solution::operator!= (const Solution& sol) const + { + return !(*this == sol); + } + + void Solution::initialize() + { + for (int i=0;i<_pbm.dimension();i++) + _var[i]=rand_int(0,1); + } + + double Solution::fitness () const + { + register int x,y,x1,y1,k; + double covered_points=0.0, cover_rate=0.0, fitness=0.0,alfa=2.0; + int used_trans; + + for (k=0;k<GRID_SIZE;k++) // Initializing the grid + grid[k]=0; + + + used_trans=0; // Updating covered points in the grid according ... + for (k=0;k<_var.size();k++) // with transmiter locations and calculating ... + { // covered points. + if (_var[k]!=0.0) + { + used_trans++; + x=trans_location[k*2]; + y=trans_location[k*2+1]; + for (x1=x-RANGE;x1<=x+RANGE;x1++) + for (y1=y-RANGE;y1<=y+RANGE;y1++) + if ((x1>=0)&(y1>=0)&(x1<GRID_SIZE_X)&(y1<GRID_SIZE_Y)) + { + grid[x1*GRID_SIZE_X+y1]++; + if (grid[x1*GRID_SIZE_X+y1]==1) covered_points++; + } + } + } + + cover_rate =(double) (100.0 * covered_points) / (GRID_SIZE); + fitness = (cover_rate * cover_rate )/used_trans; + + return fitness; + } + + char *Solution::to_String() const + { + return (char *)_var.get_first(); + } + + void Solution::to_Solution(char *_string_) + { + int *ptr=(int *)_string_; + for (int i=0;i<_pbm.dimension();i++) + { + _var[i]=*ptr; + ptr++; + } + } + + unsigned int Solution::size() const + { + return (_pbm.dimension() * sizeof(int)); + } + + + int& Solution::var(const int index) + { + return _var[index]; + } + + + Rarray<int>& Solution::array_var() + { + return _var; + } + + Solution::~Solution() + {} + +// UserStatistics ------------------------------------------------------- + + UserStatistics::UserStatistics () + {} + + ostream& operator<< (ostream& os, const UserStatistics& userstat) + { + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF TRIALS " << endl; + os << "------------------------------------------------------------------" << endl; + + for (int i=0;i< userstat.result_trials.size();i++) + { + os << endl + << "\t" << userstat.result_trials[i].trial + << "\t" << userstat.result_trials[i].best_cost_trial + << "\t\t" << userstat.result_trials[i].nb_evaluation_best_found_trial + << "\t\t" << userstat.result_trials[i].initial_temperature + << "\t\t" << userstat.result_trials[i].temperature_best_found_trial + << "\t\t" << userstat.result_trials[i].time_best_found_trial + << "\t\t" << userstat.result_trials[i].time_spent_trial; + } + + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + + UserStatistics& UserStatistics::operator= (const UserStatistics& userstats) + { + result_trials=userstats.result_trials; + return (*this); + } + + + void UserStatistics::update(const Solver& solver) + { + if ((solver.pid()!=0) || (solver.end_trial()!=true) + || ((solver.current_iteration()!=solver.setup().max_evaluations()) + && !TerminateQ(solver.pbm(),solver,solver.setup()))) + return; + + struct user_stat *new_stat; + if ((new_stat=(struct user_stat *)malloc(sizeof(struct user_stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluation_best_found_trial= solver.iteration_best_found_trial(); + new_stat->initial_temperature=solver.initial_temperature_trial(); + new_stat->temperature_best_found_trial=solver.temperature_best_found_trial(); + new_stat->best_cost_trial = solver.current_best_cost(); + new_stat->time_best_found_trial= solver.time_best_found_trial(); + new_stat->time_spent_trial = solver.time_spent_trial(); + result_trials.append(*new_stat); + } + + void UserStatistics::clear() + { + result_trials.remove(); + } + + UserStatistics::~UserStatistics() + { + result_trials.remove(); + } + +// DefaultMove ------------------------------------------------------- + + + DefaultMove::DefaultMove() + {} + + DefaultMove::~DefaultMove() + {} + + void DefaultMove::Apply (Solution& sol) const + { + const float probability = 0.03; + + for (int i=0;i<sol.pbm().dimension();i++) + { + if (rand01()<=probability) + { + if (sol.var(i)==1) sol.var(i)=0; + else sol.var(i)=1; + } + } + } + + //------------------------------------------------------------------------ + // Specific methods ------------------------------------------------------ + //------------------------------------------------------------------------ + + bool TerminateQ (const Problem& pbm, const Solver& solver, + const SetUpParams& setup) + { + + StopCondition_3 stop; + return stop.EvaluateCondition(pbm,solver,setup); + } +} + + diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/StopCondition.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/StopCondition.cc new file mode 100644 index 0000000000000000000000000000000000000000..f9cfd89b1a6f5292633566664a6caa78815ea279 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/StopCondition.cc @@ -0,0 +1,52 @@ +#include "StopCondition.hh" +skeleton SA +{ + +// StopCondition ------------------------------------------------------------------------------------- + + StopCondition::StopCondition() + {} + + StopCondition::~StopCondition() + {} + +// StopCondition_1 ------------------------------------------------------------------------------------- + + StopCondition_1::StopCondition_1():StopCondition() + {} + + bool StopCondition_1::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return false; + } + + StopCondition_1::~StopCondition_1() + {} + +// StopCondition_2 ------------------------------------------------------------------------------------- + + StopCondition_2::StopCondition_2():StopCondition() + {} + + bool StopCondition_2::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return (solver.global_best_cost()>8.5); + } + + StopCondition_2::~StopCondition_2() + {} + +// StopCondition_3 ------------------------------------------------------------------------------------- + + StopCondition_3::StopCondition_3():StopCondition() + {} + + bool StopCondition_3::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return ((int)solver.current_best_cost() == pbm.dimension()); + } + + StopCondition_3::~StopCondition_3() + {} + +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/StopCondition.hh b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/StopCondition.hh new file mode 100644 index 0000000000000000000000000000000000000000..04ef770d9cac5bb9ef69aae7d085e3ae2166e187 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/StopCondition.hh @@ -0,0 +1,41 @@ +#ifndef stop_condition +#define stop_condition + +#include "SA.hh" +skeleton SA +{ + + provides class StopCondition + { + public: + StopCondition(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup)=0; + ~StopCondition(); + }; + + requires class StopCondition_1 : public StopCondition + { + public: + StopCondition_1(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_1(); + }; + + requires class StopCondition_2 : public StopCondition + { + public: + StopCondition_2(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_2(); + }; + + requires class StopCondition_3 : public StopCondition + { + public: + StopCondition_3(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_3(); + }; +} + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/pgfileLan b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/pgfileLan new file mode 100644 index 0000000000000000000000000000000000000000..d85e66e2fa7c529318184a2a5c96bfaeae7541d7 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/rnd/pgfileLan @@ -0,0 +1,5 @@ +localhost 0 ~/Mallba/rep/SA/rnd/MainLan +localhost 1 ~/Mallba/rep/SA/rnd/MainLan +localhost 1 ~/Mallba/rep/SA/rnd/MainLan +localhost 1 ~/Mallba/rep/SA/rnd/MainLan +localhost 1 ~/Mallba/rep/SA/rnd/MainLan diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/Config.cfg b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/Config.cfg new file mode 100644 index 0000000000000000000000000000000000000000..510e26da3a108155d6e73d191716818c909969eb --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/Config.cfg @@ -0,0 +1,3 @@ +SA.cfg +../../../ProblemInstances/VRP-instances/vrpnc1.txt +res/vrp1.sa.lan.txt diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/MainLan.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/MainLan.cc new file mode 100644 index 0000000000000000000000000000000000000000..8949422e10f93211d953aba1308c203d13f30f0a --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/MainLan.cc @@ -0,0 +1,53 @@ +#include "SA.hh" +#include <iostream.h> +#include <fstream.h> + +int main (int argc, char** argv) +{ + using skeleton SA; + char path[MAX_BUFFER]; + int len; + int longitud; + + system("clear"); + + get_path(argv[0],path); + len = strlen(path); + longitud = MAX_BUFFER - len; + + strcat(path,"Config.cfg"); + ifstream f(path); + if(!f) show_message(10); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f1(path); + if(!f1) show_message(11); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f2(path); + if(!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + SetUpParams cfg; + f1 >> cfg; + + + Solver_Lan solver(pbm,cfg,argc,argv); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solucion: " << solver.global_best_solution() << " Fitness: " << solver.global_best_solution().fitness(); + + f.getline(&(path[len]),longitud,'\n'); + ofstream fexit(path); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + cout << endl << endl << " :( ---------------------- THE END --------------- :) " << endl; + } + return(0); +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/MainSeq.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/MainSeq.cc new file mode 100644 index 0000000000000000000000000000000000000000..41d8a720793c0d10b14e1d5dfa05b7f11e9c4dda --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/MainSeq.cc @@ -0,0 +1,42 @@ +#include "SA.hh" +#include <iostream.h> +#include <fstream.h> + +int main (int argc, char** argv) +{ + using skeleton SA; + + system("clear"); + + if(argc < 4) + show_message(1); + + ifstream f1(argv[1]); + if (!f1) show_message(11); + + ifstream f2(argv[2]); + if (!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + SetUpParams cfg; + f1 >> cfg; + + Solver_Seq solver(pbm,cfg); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << solver.global_best_solution() + << " Fitness: " << solver.global_best_solution().fitness() << endl; + cout << "\n\n :( ---------------------- THE END --------------- :) "; + + ofstream fexit(argv[3]); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + } + return(0); +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/Makefile b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..cb3ba14e21ee15fc02d05ce6aebc08d3d68d7c50 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/Makefile @@ -0,0 +1,22 @@ +include ../../../environment + +all: MainSeq MainLan + +clean: + rm -f MainLan MainSeq MainWan *.o *% *~ + +MainLan: SA.req.o SA.pro.o StopCondition.o MainLan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainWan: SA.req.o SA.pro.o StopCondition.o MainWan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainSeq: SA.req.o SA.pro.o StopCondition.o MainSeq.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +LAN: + $(RUN) -v -p4pg pgfileLan MainLan +WAN: + $(RUN) -v -p4pg pgfileWan MainWan +SEQ: + ./MainSeq SA.cfg ../../../ProblemInstances/VRP-instances/vrpnc1.txt res/vrp1.sa.seq.txt diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/SA.cfg b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/SA.cfg new file mode 100644 index 0000000000000000000000000000000000000000..eed67390e35f1f52eb2aa2b46bb6394ac80ed143 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/SA.cfg @@ -0,0 +1,9 @@ +10 // number of independent runs +1000 // number of evaluations +10 // Markov-Chain Length +.99 // temperature Decay +1 // display state ? +LAN-configuration +1001 // the global state is updated in this number of evaluations +0 // 0: asynchronized mode // 1: synchronized mode +10 // interval of iterations to cooperate ( if 0 no cooperation) diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/SA.hh b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/SA.hh new file mode 100644 index 0000000000000000000000000000000000000000..845bb53b54a0727cf7524ab217729f766a8fe577 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/SA.hh @@ -0,0 +1,499 @@ +#ifndef INC_SA +#define INC_SA + +#include "Mallba/mallba.hh" +#include "Mallba/States.hh" +#include "Mallba/Rarray.h" +#include "Mallba/time.hh" +#include "Mallba/netstream.hh" +#include <math.h> +#include <string.h> + +skeleton SA +{ + + provides class SetUpParams; + provides class Statistics; + provides class Move; + provides class StopCondition; + provides class Solver; + provides class Solver_Seq; + provides class Solver_Lan; + provides class Solver_Wan; + + requires class Problem; + requires class Solution; + requires class StopCondition_1; + requires class StopCondition_2; + requires class StopCondition_3; + requires class DefaultMove; + requires class UserStatistics; + requires bool TerminateQ (const Problem& pbm, const Solver& solver, const SetUpParams& setup); + +// Problem ---------------------------------------------------------------------------- + + requires class Problem + { + public: + Problem (); + ~Problem (); + + friend ostream& operator<< (ostream& os, const Problem& pbm); + friend istream& operator>> (istream& is, Problem& pbm); + + Problem& operator= (const Problem& pbm); + bool operator== (const Problem& pbm) const; + bool operator!= (const Problem& pbm) const; + + Direction direction () const; + + int nCustomers() const; + int capacity() const; + double maxRouteTime() const; + double bestCost() const; + double distance(const int i, const int j) const; + int demand(const int i) const; + int service_time() const; + + private: + void genDistances(int *x,int *y); + + int _nCustomers; + int _capacity; + double **_distance; + int _service_time; + double _maxRouteTime; + double _bestCost; + int *_demand; + }; + +//Solution ---------------------------------------------------------------------------- + + requires class Solution + { + public: + Solution (const Problem& pbm); + Solution (const Solution& sol); + ~Solution(); + + friend ostream& operator<< (ostream& os, const Solution& sol); + friend istream& operator>> (istream& is, Solution& sol); + friend NetStream& operator << (NetStream& ns, const Solution& sol); + friend NetStream& operator >> (NetStream& ns, Solution& sol); + + const Problem& pbm() const; + + Solution& operator= (const Solution& sol); + bool operator== (const Solution& sol) const; + bool operator!= (const Solution& sol) const; + + char *to_String() const; + void to_Solution(char *_vertex_); + unsigned int size() const; + + void initialize(); + double fitness () const; + + int & pos(const int index); + Rarray<int> & routes(); + void print(); + + private: + Rarray<int> _routes; + const Problem& _pbm; + }; + +// UserStatistics ---------------------------------------------------------------------------- + + requires class UserStatistics + { + private: + struct user_stat + { + unsigned int trial; + double initial_temperature; + double temperature_best_found_trial; + unsigned long nb_evaluation_best_found_trial; + double best_cost_trial; + float time_best_found_trial; + float time_spent_trial; + }; + + Rlist<struct user_stat> result_trials; + + public: + UserStatistics (); + ~UserStatistics(); + + friend ostream& operator<< (ostream& os, const UserStatistics& usertats); + + UserStatistics& operator= (const UserStatistics& userstats); + void update(const Solver& solver); + void clear(); + }; + +// Move ---------------------------------------------------------------------------------- + + provides class Move + { + public: + Move() {} + virtual ~Move() {} + + virtual void Apply(Solution& sol) const = 0; + }; + +// DefaultMove ---------------------------------------------------------------------------------- + + requires class DefaultMove: public Move + { + public: + DefaultMove(); + ~DefaultMove(); + + void Apply(Solution& sol) const; + }; + +// SetUpParams ------------------------------------------------------------------------------- + + provides class SetUpParams + { + private: + unsigned int _independent_runs; + unsigned long _max_evaluations; + unsigned int _MarkovChain_length; + double _temperature_decay; + bool _display_state; + + // for LAN execution configuration + unsigned long _refresh_global_state; + bool _synchronized; + unsigned int _cooperation; + + public: + SetUpParams (); + + friend ostream& operator<< (ostream& os, const SetUpParams& setup); + friend istream& operator>> (istream& is, SetUpParams& setup); + + const unsigned int independent_runs() const; + const unsigned long max_evaluations() const; + const unsigned int MarkovChain_length() const; + const double temperature_decay() const; + const bool display_state() const; + const unsigned long refresh_global_state() const; + const bool synchronized() const; + const unsigned int cooperation() const; + + void independent_runs(const unsigned int val); + void max_evaluations(const unsigned long val); + void MarkovChain_length(const unsigned int val); + void temperature_decay(const double val); + void display_state(const bool val); + void refresh_global_state(const unsigned long val); + void synchronized(const bool val); + void cooperation(const unsigned int val); + + ~SetUpParams(); + }; + +// Statistics --------------------------------------------------------------------------------- + + provides class Statistics + { + private: + struct stat + { + unsigned int trial; + unsigned long nb_evaluations; + double best_cost; + double current_cost; + }; + + Rlist<struct stat> stats_data; + + public: + Statistics(); + + friend ostream& operator<< (ostream& os, const Statistics& stats); + + Statistics& operator= (const Statistics& stats); + void update(const Solver& solver); + void clear(); + + ~Statistics(); + }; + +// Solver --------------------------------------------------------------------------------- + + provides class Solver + { + protected: + const Problem& problem; + const SetUpParams& params; + UserStatistics _userstat; + Statistics _stat; + Move* move; + Solution current; + double curfit; + Solution tentative; + double currentTemperature; + unsigned int k; // to control temperature update. + StateCenter _sc; + + float total_time_spent; + float time_spent_in_trial; + float start_trial; + float start_global; + + bool _end_trial; + + State_Vble _current_trial; + State_Vble _current_iteration; + State_Vble _current_best_solution; + State_Vble _current_best_cost; + State_Vble _current_solution; + State_Vble _current_cost; + + State_Vble _current_time_spent; + State_Vble _initial_temperature_trial; + State_Vble _time_best_found_trial; + State_Vble _iteration_best_found_trial; + State_Vble _temperature_best_found_trial; + State_Vble _time_spent_trial; + + State_Vble _trial_best_found; + State_Vble _iteration_best_found; + State_Vble _global_best_solution; + State_Vble _global_best_cost; + State_Vble _time_best_found; + + State_Vble _temperature; + State_Vble _display_state; + + const Direction _direction; + + bool AcceptQ(double tent, double cur, double temperature); + double Set_Initial_Temperature(const Problem& pbm); + void KeepHistory(const Solution& sol, const double curfit,const float time_spent_trial,const float total_time_spent); + + double UpdateT(double temp, int K); + + public: + // Constructor - Destructor ------------------------- + + Solver (const Problem& pbm, const SetUpParams& setup); + virtual ~Solver (); + virtual int pid() const; + bool end_trial() const; + + // Execution methods -------------------------------- + + // Full execution + virtual void run () =0; + virtual void run (unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol, unsigned long int nb_evaluations) =0; + + virtual void run (const double initialTemperature) =0; + virtual void run (const Solution& sol,const double initialTemperature) =0; + virtual void run (const double initialTemperature, unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations) =0; + + // Partial execution + virtual void StartUp () =0; + virtual void StartUp (const Solution& sol) =0; + virtual void StartUp (const double initialTemperature) =0; + virtual void StartUp (const Solution& sol, const double initialTemperature) =0; + virtual void DoStep () =0; + + // Statistics handling ------------------------------ + + const Statistics& statistics() const; + const UserStatistics& userstatistics () const; + const SetUpParams& setup() const; + const Problem& pbm() const; + + // State handling ----------------------------------- + + void RefreshState(); + void UpdateFromState(); + StateCenter* GetState(); + + unsigned int current_trial() const; + unsigned long current_iteration() const; + Solution current_best_solution() const; + Solution current_solution() const; + double current_best_cost() const; + double current_cost() const; + float current_time_spent() const; + float time_best_found_trial() const; + double initial_temperature_trial() const; + unsigned int iteration_best_found_trial() const; + double temperature_best_found_trial() const; + float time_spent_trial() const; + unsigned int trial_best_found() const; + unsigned int iteration_best_found() const; + Solution global_best_solution() const; + double global_best_cost() const; + float time_best_found() const; + double temperature() const; + int display_state() const; + + void current_trial(const unsigned int value); + void current_iteration(const unsigned long value); + void current_best_solution(const Solution& sol); + void current_best_cost(const double value); + void current_solution(const Solution& sol); + void current_cost(const double value); + void current_time_spent(const float value); + void time_best_found_trial(const float value); + void initial_temperature_trial(const double temperature); + void iteration_best_found_trial(const unsigned int value); + void temperature_best_found_trial(const double value); + void time_spent_trial(const float value); + void trial_best_found(const unsigned int value); + void iteration_best_found(const unsigned int value); + void global_best_solution(const Solution& sol); + void global_best_cost(const double value); + void time_best_found(const float value); + void temperature(const double value); + void display_state(const int value); + void show_state() const; + + // State handling ----------------------------------- + void SetMove(Move* mov); + }; + + provides class Solver_Seq: public Solver + { + public: + // Constructor - Destructor ------------------------- + + Solver_Seq ( const Problem& pbm, const SetUpParams& setup); + virtual ~Solver_Seq (); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + }; + + provides class Solver_Lan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + public: + Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Lan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + + provides class Solver_Wan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + public: + Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Wan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + +}; + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/SA.pro.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/SA.pro.cc new file mode 100644 index 0000000000000000000000000000000000000000..43dcaf9ebda2aa5738f2982cb5f6441259ce44f5 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/SA.pro.cc @@ -0,0 +1,1807 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** Provided classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** *** +************************************************/ + +#include <iostream.h> +#include <math.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "Mallba/time.hh" + +skeleton SA +{ + +// SetUpParams ----------------------------------------------------------- + + SetUpParams::SetUpParams (): + _independent_runs(0), + _max_evaluations(0), + _MarkovChain_length(0), + _temperature_decay(0), + _refresh_global_state(0), + _synchronized(0), + _display_state(0), + _cooperation(0) + {} + + istream& operator>> (istream& is, SetUpParams& setup) + { + char buffer[MAX_BUFFER]; // current line in the setup file + char command[50]; + int op; + double dop; + short int nb_param=0; + short int nb_section=0; + short int nb_LAN_param=0; + + while (is.getline(buffer,MAX_BUFFER,'\n')) + { + sscanf(buffer," %s ",command); + + if (!(strcmp(command,"General"))) nb_section=0; + if (!(strcmp(command,"LAN-configuration"))) nb_section=1; + + if (nb_param==3 && nb_section==0) + { + dop=-1; + sscanf(buffer," %lf ",&dop); + if (dop<0) continue; + } + else + { + op=-1; + sscanf(buffer," %ld%*s ",&op); + if (op<0) continue; + } + + switch (nb_section) + { + case 0: switch (nb_param) + { + case 0: setup.independent_runs(op); break; + case 1: setup.max_evaluations(op); break; + case 2: setup.MarkovChain_length(op); break; + case 3: setup.temperature_decay(dop); break; + case 4: setup.display_state(op); break; + } + nb_param++; + break; + case 1: if (nb_LAN_param>=3) break; + if (nb_LAN_param==0) setup.refresh_global_state(op); + if (nb_LAN_param==1) setup.synchronized(op); + if (nb_LAN_param==2) setup.cooperation(op); + nb_LAN_param++; + break; + } // end switch + } // end while + return is; + } + + ostream& operator<< (ostream& os, const SetUpParams& setup) + { + os << "CONFIGURATION -------------------------------------------" << endl << endl; + os << "\t" << "Independent runs : " << setup.independent_runs() << endl + << "\t" << "Evaluation steps: " << setup.max_evaluations() << endl + << "\t" << "Markov-Chain Length: " << setup.MarkovChain_length() << endl + << "\t" << "Temperature Decay: " << setup.temperature_decay() << endl; + + if (setup.display_state()) + os << "\t" << "Display state" << endl; + else + os << "\t" << "Not display state" << endl; + os << endl << "\t" << "LAN configuration:" << endl + << "\t" << "----------------------" << endl << endl + << "\t" << "Refresh global state in number of generations: " << setup.refresh_global_state() << endl; + + if (setup.synchronized()) + os << "\t" << "Running in synchronous mode" << endl; + else + os << "\t" << "Running in asynchronous mode" << endl; + + if (!setup.cooperation()) + os << "\t" << "Running without cooperation" << endl << endl; + else + os << "\t" << "Running with cooperation in " << setup.cooperation() << " iterations. " << endl << endl; + + os << endl << endl << "END CONFIGURATION -------------------------------------------" << endl << endl; + return os; + } + + const unsigned int SetUpParams::independent_runs() const + { + return _independent_runs; + } + + const unsigned long SetUpParams::max_evaluations() const + { + return _max_evaluations; + } + + const unsigned int SetUpParams::MarkovChain_length() const + { + return _MarkovChain_length; + } + + const double SetUpParams::temperature_decay() const + { + return _temperature_decay; + } + + const bool SetUpParams::display_state() const + { + return _display_state; + } + + const unsigned long SetUpParams::refresh_global_state() const + { + return _refresh_global_state; + } + + const bool SetUpParams::synchronized() const + { + return _synchronized; + } + + const unsigned int SetUpParams::cooperation() const + { + return _cooperation; + } + + void SetUpParams::independent_runs(const unsigned int val) + { + _independent_runs = val; + } + + void SetUpParams::max_evaluations(const unsigned long val) + { + _max_evaluations= val; + } + void SetUpParams::MarkovChain_length(const unsigned int val) + { + _MarkovChain_length= val; + } + void SetUpParams::temperature_decay(const double val) + { + _temperature_decay= val; + } + + void SetUpParams::display_state(const bool val) + { + _display_state=val; + } + + void SetUpParams::refresh_global_state(const unsigned long val) + { + _refresh_global_state=val; + } + + void SetUpParams::synchronized(const bool val) + { + _synchronized=val; + } + + void SetUpParams::cooperation(const unsigned int val) + { + _cooperation=val; + } + + SetUpParams::~SetUpParams() + {} + +// Statistics ------------------------------------------------------ + + Statistics::Statistics() + {} + + ostream& operator<< (ostream& os, const Statistics& stats) + { + int j; + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF CURRENT TRIAL " << endl; + os << "------------------------------------------------------------------" << endl; + for (int i=0;i< stats.stats_data.size();i++) + { + os << endl + << " Evaluations: " << stats.stats_data[i].nb_evaluations + << " Best: " << stats.stats_data[i].best_cost + << " Current: " << stats.stats_data[i].current_cost; + } + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + Statistics& Statistics::operator= (const Statistics& stats) + { + stats_data = stats.stats_data; + return *this; + } + + void Statistics::update(const Solver& solver) + { + /* struct stat *new_stat; + if ((new_stat=(struct stat *)malloc(sizeof(struct stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluations= solver.current_iteration(); + new_stat->best_cost = solver.current_best_cost(); + new_stat->current_cost = solver.current_cost(); + stats_data.append(*new_stat); */ + } + + Statistics::~Statistics() + { + stats_data.remove(); + } + + void Statistics::clear() + { + stats_data.remove(); + } + +// Solver (superclass)--------------------------------------------------- + + Solver::Solver (const Problem& pbm, const SetUpParams& setup) + : problem(pbm), + params(setup), + _stat(), + _userstat(), + _sc(), + _direction(pbm.direction()), + current(pbm), + tentative(pbm), + currentTemperature(0.0), + time_spent_in_trial(0.0), + total_time_spent(0.0), + start_trial(0.0), + start_global(0.0), + _current_trial("_current_trial",_sc), + _current_iteration("_current_iteration",_sc), + _current_best_solution("_current_best_solution",_sc), + _current_best_cost("_current_best_cost",_sc), + _current_solution("_current_solution",_sc), + _current_cost("_current_cost",_sc), + _current_time_spent("_current_time_spent",_sc), + _initial_temperature_trial("_initial_temperature_trial",_sc), + _time_best_found_trial("_time_best_found_trial",_sc), + _iteration_best_found_trial("_iteration_best_found_trial",_sc), + _temperature_best_found_trial("_temperature_best_found_trial",_sc), + _time_spent_trial("_time_spent_trial",_sc), + _trial_best_found("_trial_best_found",_sc), + _iteration_best_found("_iteration_best_found;",_sc), + _global_best_solution("_global_best_solution",_sc), + _global_best_cost("_global_best_cost",_sc), + _time_best_found("_time_best_found",_sc), + _temperature("_temperature",_sc), + _display_state("_display_state",_sc) + { + current_trial(0); + current_iteration(0); + current_best_solution(current), + current_best_cost((-1) * pbm.direction() * infinity()); + current_solution(current); + current_cost((-1) * pbm.direction() * infinity()); + current_time_spent(total_time_spent); + initial_temperature_trial(0); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(0); + temperature_best_found_trial(0.0); + time_spent_trial(time_spent_in_trial); + trial_best_found(0); + iteration_best_found(0); + global_best_solution(current); + global_best_cost((-1) * pbm.direction() * infinity()); + time_best_found(total_time_spent); + temperature(currentTemperature); + display_state(setup.display_state()); + + move = new DefaultMove; + } + + int Solver::pid() const + { + return 0; + } + + bool Solver::end_trial() const + { + return _end_trial; + } + + unsigned int Solver::current_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_trial",(char *)&value, nitems, length); + return value; + } + + unsigned long Solver::current_iteration() const + { + unsigned long value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_iteration",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_best_solution() const + { + Solution sol(problem); + unsigned long nitems,length; + char data_stored[_current_best_solution.get_nitems() + _current_best_solution.get_length()]; + _sc.get_contents_state_variable("_current_best_solution", data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::current_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_best_cost",(char *)&value, nitems, length); + return value; + } + + double Solver::current_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_cost",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_solution() const + { + Solution sol(problem); + char data_stored[_current_solution.get_nitems() + _current_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_solution",data_stored, nitems, length); + sol.to_Solution((char *)data_stored); + return sol; + } + + float Solver::current_time_spent() const + { + float value=0.0; + unsigned long nitems,length; + _current_time_spent.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::initial_temperature_trial() const + { + double value=0.0; + unsigned long nitems,length; + _initial_temperature_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature_best_found_trial() const + { + double value=0.0; + unsigned long nitems,length; + _temperature_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_spent_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_spent_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::trial_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _trial_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::global_best_solution() const + { + Solution sol(problem); + char data_stored[_global_best_solution.get_nitems() + _global_best_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_solution",data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::global_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_cost",(char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_temperature",(char *)&value, nitems, length); + return value; + } + + int Solver::display_state() const + { + int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_display_state",(char *)&value, nitems, length); + return value; + } + + void Solver::current_trial(const unsigned int value) + { + _sc.set_contents_state_variable("_current_trial",(char *)&value,1,sizeof(int)); + } + + void Solver::current_iteration(const unsigned long value) + { + _sc.set_contents_state_variable("_current_iteration",(char *)&value,1,sizeof(long)); + } + + void Solver::current_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_best_cost(const double value) + { + _sc.set_contents_state_variable("_current_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_cost(const double value) + { + _sc.set_contents_state_variable("_current_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_time_spent(const float value) + { + _current_time_spent.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::time_best_found_trial(const float value) + { + _time_best_found_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::iteration_best_found_trial(const unsigned int value) + { + _iteration_best_found_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::initial_temperature_trial(const double value) + { + _initial_temperature_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::temperature_best_found_trial(const double value) + { + _temperature_best_found_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::time_spent_trial(const float value) + { + _time_spent_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::trial_best_found(const unsigned int value) + { + _trial_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::iteration_best_found(const unsigned int value) + { + _iteration_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::global_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_global_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::global_best_cost(const double value) + { + _sc.set_contents_state_variable("_global_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::time_best_found(const float value) + { + _time_best_found.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::temperature(const double value) + { + _sc.set_contents_state_variable("_temperature",(char *)&value,1,sizeof(double)); + } + + void Solver::display_state(const int value) + { + _sc.set_contents_state_variable("_display_state",(char *)&value,1,sizeof(int)); + } + + const Statistics& Solver::statistics() const + { + return _stat; + } + + const UserStatistics& Solver::userstatistics() const + { + return _userstat; + } + + const SetUpParams& Solver::setup() const + { + return params; + } + + const Problem& Solver::pbm() const + { + return problem; + } + + void Solver::KeepHistory(const Solution& sol, const double curfit,const float time_spent_in_trial,const float total_time_spent) + { + bool betterG=false; + bool betterT=false; + + switch (_direction) + { + case minimize: betterG = (curfit < global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit < current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + case maximize: betterG = (curfit > global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit > current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + } + + if (betterT) + { + current_best_solution(sol); + current_best_cost(curfit); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(current_iteration()); + temperature_best_found_trial(temperature()); + if (betterG) + { + trial_best_found(current_trial()); + iteration_best_found(current_iteration()); + global_best_solution(sol); + global_best_cost(curfit); + time_best_found(time_spent_in_trial); + } + } + } + + double Solver::UpdateT(double temp, int K) + { + //return temp * params.temperature_decay(); // initial + + /* + if(K == 1) return temp/log(2); + else return temp * log(K) / log(K+1); + */ + /* + if(K == 1) return temp/2; + else return (temp * K) / (K + 1); + */ + + if(K == 1) return temp / exp(2); + else return (temp * exp(K)) / exp(K+1); + + } + + StateCenter* Solver::GetState() + { + return &_sc; + } + + void Solver::RefreshState() + { + current_solution(current); + current_cost(curfit); + current_time_spent(total_time_spent); + time_spent_trial(time_spent_in_trial); + temperature(currentTemperature); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::UpdateFromState() + { + current = current_solution(); + curfit = current_cost(); + total_time_spent=current_time_spent(); + time_spent_in_trial=time_spent_trial(); + currentTemperature = temperature(); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::show_state() const + { + cout << endl << "Current trial: " << current_trial(); + cout << endl << "Current iteration: " << current_iteration(); + cout << endl << "Current Temperature: " << temperature (); + cout << endl << "Current cost: " << current_cost(); + cout << endl << "Best cost in trial: " << current_best_cost(); + cout << endl << "Time of best solution found in trial: " << time_best_found_trial(); + cout << endl << "Iteration of best solution found in trial: " << iteration_best_found_trial(); + cout << endl << "Initial temperature in trial: " << initial_temperature_trial(); + cout << endl << "Temperature of best solution found in trial: " << temperature_best_found_trial(); + cout << endl << "Time spent in trial: " << time_spent_trial(); + cout << endl << "Global best cost: " << global_best_cost(); + cout << endl << "Trial of best global solution found: " << trial_best_found(); + cout << endl << "Iteration of best global solution found: " << iteration_best_found(); + cout << endl << "Time of global best solution found: " << time_best_found(); + // cout << endl << "Current solution: " << current_solution(); + // cout << endl << "Best solution of trial: " << current_best_solution(); + // cout << endl << "Global solution: " << global_best_solution() << endl; + cout << endl << endl << "Current time spent (so far): " << current_time_spent() << endl; + } + + Solver::~Solver() + { + _sc.removeAll(); + delete move; + } + + bool Solver::AcceptQ (double tent, double cur, double temperature) + { + if (_direction==minimize) + + return (tent < cur) || + ((rand01()*(1+exp((tent-cur)/temperature)))<2.0); + + else + + return (tent > cur) || + ((rand01()*(1+exp((cur-tent)/temperature)))<2.0); + } + + double Solver::Set_Initial_Temperature(const Problem& pbm) + { + const double beta = 1.05; + const double test = 10; + const double acrat = .8; + const double T = 1.0; + + Solution current (pbm); + Solution newsol (pbm); + double ac; + double fit; + double temperature = T; + + do + { + temperature *= beta; + ac = 0; + current.initialize(); + fit = current.fitness(); + for (int i=0; i<test; i++) + { + newsol = current; + move->Apply(newsol); + if (AcceptQ(newsol.fitness(),fit,temperature)) + ac += 1.0/test; + } + } while (ac < acrat); + + initial_temperature_trial(temperature); + return temperature; + + } + + void Solver::SetMove (Move* mov) + { + delete move; + move = mov; + } + + // Solver sequencial ----------------------------------------------------- + + Solver_Seq::Solver_Seq (const Problem& pbm, const SetUpParams& setup) + : Solver(pbm,setup) + { + random_seed(time(0)); + _end_trial=true; + } + + Solver_Seq::~Solver_Seq () + {} + + void Solver_Seq::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Seq::StartUp(const Solution& sol, const double initialTemperature) + { + start_trial=_used_time(); + start_global=total_time_spent; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current = sol; + curfit = current.fitness(); + current_best_cost((-1) * problem.direction() * infinity()); + currentTemperature = initialTemperature; + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + void Solver_Seq::DoStep() + { + current_iteration(current_iteration()+1); + + tentative = current; + move->Apply(tentative); + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + + void Solver_Seq::run (unsigned long int max_evaluations) + { + StartUp(); + + while (current_iteration()<max_evaluations && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + // Solver LAN ----------------------------------------------------------- + + Solver_Lan::Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); + } + + Solver_Lan::~Solver_Lan () + { + NetStream::finalize(); + } + + int Solver_Lan::pid() const + { + return mypid; + } + + NetStream& Solver_Lan::netstream() + { + return _netstream; + } + + void Solver_Lan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Lan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + void update(Direction direction, Solution &solution_received,double cost_received, Solution &solution_to_send, double &best_cost) + { + switch (direction) + { + case minimize: if (cost_received < best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + case maximize: if (cost_received > best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + } + } + + int Solver_Lan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Lan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Lan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Lan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Lan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Lan::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + void Solver_Lan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } + + // Solver WAN ------------------------------------------------------------ + + Solver_Wan::Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); + } + + Solver_Wan::~Solver_Wan () + { + NetStream::finalize(); + } + + int Solver_Wan::pid() const + { + return mypid; + } + + NetStream& Solver_Wan::netstream() + { + return _netstream; + } + + void Solver_Wan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Wan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + int Solver_Wan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Wan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Wan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Wan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Wan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Wan::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + void Solver_Wan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } +}; + diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/SA.req.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/SA.req.cc new file mode 100644 index 0000000000000000000000000000000000000000..c14f23a5386c9beadab6a7a497ef34ae141e2929 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/SA.req.cc @@ -0,0 +1,527 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** User-required classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** *** +*** *** +************************************************/ + +#include <iostream.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "StopCondition.hh" + +skeleton SA { + + +// Problem --------------------------------------------------------------- + Problem::Problem ():_nCustomers(0),_capacity(0),_distance(NULL), + _demand(NULL),_service_time(0),_maxRouteTime(0.0) + {} + + ostream& operator<< (ostream& os, const Problem& pbm) + { + os << endl << endl << " Vehicle capacity: " << pbm._capacity + << endl << " Number of Customers: " << pbm._nCustomers << endl + << " Service time: " << pbm._service_time << endl + << " Max Time for any route: " << pbm._maxRouteTime << endl + << " Distances: " << endl; + + for(int i = 0; i < (pbm._nCustomers + 1) ; i++) + { + for(int j = 0; j < pbm._nCustomers; j++) + os << " " << pbm.distance(i,j); + os << endl; + } + + os << endl << " Demand for each customer: " << endl; + + for(int i = 0; i < (pbm._nCustomers + 1) ; i++) + { + os << " " << i << "\t" << pbm._demand[i] << endl; + } + + return os; + } + + istream& operator>> (istream& is, Problem& pbm) + { + char buffer[MAX_BUFFER]; + int *x; + int *y; + + is.getline(buffer,MAX_BUFFER,'\n'); + sscanf(buffer," %d %d %lf %d %lf",&pbm._nCustomers,&pbm._capacity,&pbm._maxRouteTime,&pbm._service_time,&pbm._bestCost); + + if( ((pbm._distance = new double *[pbm._nCustomers + 1]) == NULL) + || ((pbm._demand = new int[pbm._nCustomers + 1]) == NULL) + || ((x = new int[pbm._nCustomers + 1]) == NULL) + || ((y = new int[pbm._nCustomers + 1]) == NULL)) + show_message(7); + + // Read depot coordenates + if( ((pbm._distance[0] = new double[pbm._nCustomers+1]) == NULL)) + show_message(7); + + is.getline(buffer,MAX_BUFFER,'\n'); + sscanf(buffer," %d %d",&(x[0]),&(y[0])); + pbm._demand[0] = 0; + + // Read customers coordenates + for(int i = 1; i < (pbm._nCustomers + 1); i++) + { + if( ((pbm._distance[i] = new double[pbm._nCustomers+1]) == NULL)) + show_message(7); + + is.getline(buffer,MAX_BUFFER,'\n'); + sscanf(buffer," %d %d %d", &(x[i]),&(y[i]),&(pbm._demand[i])); + } + + pbm.genDistances(x,y); + + delete [] x; + delete [] y; + + return is; + } + + void Problem::genDistances(int *x,int *y) + { + for(int i = 0; i < (_nCustomers + 1); i++) + for(int j = 0; j < (_nCustomers +1) ; j++) + _distance[i][j] = sqrt( pow( (double) (x[j] - x[i]),2 ) + + pow( (double) (y[j] - y[i]),2 ) ) + _service_time ; + } + + Problem& Problem::operator= (const Problem& pbm) + { + if(_distance != NULL) + { + for(int i= 0;i < (_nCustomers+1); i++) + if(_distance[i] != NULL) delete [] _distance[i]; + delete [] _distance; + } + + if(_demand != NULL) delete [] _demand; + + if( ((_distance = new double*[pbm._nCustomers]) == NULL) + || ((_demand = new int[pbm._nCustomers + 1]) == NULL)) + show_message(7); + + _nCustomers = pbm.nCustomers(); + _capacity = pbm.capacity(); + _service_time = pbm.service_time(); + _maxRouteTime = pbm.maxRouteTime(); + + for(int i = 0; i < (_nCustomers+1); i++) + { + _demand[i] = pbm.demand(i); + + if( ((_distance[i] = new double[_nCustomers+1]) == NULL)) + show_message(7); + + for(int j = 0; j < (_nCustomers+1); i++) + { + _distance[i][j] = pbm.distance(i,j); + } + } + + return *this; + } + + bool Problem::operator== (const Problem& pbm) const + { + if( (_maxRouteTime != pbm.maxRouteTime()) || (_nCustomers != pbm.nCustomers()) + || (_capacity != pbm.capacity()) || (_service_time != pbm.service_time())) + return false; + + for(int i = 0; i < (_nCustomers+1); i++) + { + if(_demand[i] != pbm.demand(i)) + return false; + + for(int j = 0; j < (_nCustomers+1); i++) + { + if(distance(i,j) != pbm.distance(i,j)) return false; + } + } + + return true; + } + + bool Problem::operator!= (const Problem& pbm) const + { + return !(*this == pbm); + } + + Direction Problem::direction() const + { + //return maximize; + return minimize; + } + + double Problem::maxRouteTime() const + { + return _maxRouteTime; + } + + double Problem::bestCost() const + { + return _bestCost; + } + + int Problem::nCustomers() const + { + return _nCustomers; + } + + int Problem::capacity() const + { + return _capacity; + } + + double Problem::distance(const int i, const int j) const + { + return _distance[i][j]; + } + + int Problem::demand(const int i) const + { + return _demand[i]; + } + + int Problem::service_time() const + { + return _service_time; + } + + Problem::~Problem() + { + if(_distance != NULL) + { + for(int i= 0;i < (_nCustomers+1); i++) + if(_distance[i] != NULL) delete [] _distance[i]; + delete [] _distance; + } + + if(_demand != NULL) delete [] _demand; + + } + +// Solution -------------------------------------------------------------- + Solution::Solution (const Problem& pbm):_pbm(pbm),_routes(pbm.nCustomers()) + {} + + const Problem& Solution::pbm() const + { + return _pbm; + } + + Solution::Solution(const Solution& sol):_pbm(sol.pbm()) + { + *this=sol; + } + + istream& operator>> (istream& is, Solution& sol) + { + for (int i=0;i<sol.pbm().nCustomers(); i++) + { + is >> sol._routes[i]; + } + return is; + } + + ostream& operator<< (ostream& os, const Solution& sol) + { + for (int i=0;i<sol.pbm().nCustomers(); i++) + { + os << (sol._routes[i]<10?" ":"") << sol._routes[i] << " "; + } + + return os; + } + + void Solution::print() + { + int ultimo = 0; + double dist = 0.0; + int cap = _pbm.capacity(); + + register int c_actual; + register int i = 0; + + int nRoute = 1; + + cout << " Ruta " << nRoute << " = 0 "; + while(i < _pbm.nCustomers()) + { + c_actual = _routes[i]; + + if( ((dist + _pbm.distance(ultimo,c_actual) + _pbm.distance(c_actual,0)) > _pbm.maxRouteTime()) + || (( cap - _pbm.demand(c_actual)) < 0) + // add in version 1.0.1 + || ((_pbm.distance(ultimo,0) + _pbm.distance(0,c_actual)) < _pbm.distance(ultimo,c_actual)) + ) + { + nRoute++; + cout << "0 -> dist = " << (dist + _pbm.distance(ultimo,0)) << " capacidad sobra = " << cap + << endl << "Ruta " << nRoute << " = 0 "; + ultimo = 0; + dist = 0.0; + cap = _pbm.capacity(); + } + else + { + dist += _pbm.distance(ultimo,c_actual); + cap -= _pbm.demand(c_actual); + ultimo = c_actual; + cout << ultimo << " "; + i++; + } + } + + cout << "0 -> dist = " << (dist + _pbm.distance(ultimo,0)) << " capacidad sobra = " << cap + << endl; + } + + NetStream& operator << (NetStream& ns, const Solution& sol) + { + for (int i=0;i<sol.pbm().nCustomers();i++) + ns << sol._routes[i]; + return ns; + } + + NetStream& operator >> (NetStream& ns, Solution& sol) + { + for (int i=0;i<sol.pbm().nCustomers();i++) + ns >> sol._routes[i]; + return ns; + } + + Solution& Solution::operator= (const Solution &sol) + { + _routes = sol._routes; + return *this; + } + + bool Solution::operator== (const Solution& sol) const + { + if (sol.pbm() != _pbm) return false; + return true; + } + + bool Solution::operator!= (const Solution& sol) const + { + return !(*this == sol); + } + + void Solution::initialize() + { + int aux,ind1,ind2; + + int max = _pbm.nCustomers(); + + for(int i = 0; i < max; i++) + _routes[i] = i+1; + + cout << endl; + + for(int i=0;i< (max*5) ; i++) + { + ind1 = rand_int(0,max-1); + ind2 = rand_int(0,max-1); + + aux = _routes[ind1]; + _routes[ind1] = _routes[ind2]; + _routes[ind2] = aux; + } + } + + double Solution::fitness () const + { + double fitness = 0.0; + int ultimo = 0; + double dist = 0.0; + int cap = _pbm.capacity(); + + register int c_actual; + register int i = 0; + + while(i < _pbm.nCustomers()) + { + c_actual = _routes[i]; + + if( ((dist + _pbm.distance(ultimo,c_actual) + _pbm.distance(c_actual,0)) > _pbm.maxRouteTime()) + || (( cap - _pbm.demand(c_actual)) < 0) + // Add on version 1.0.1 + // New constrains: cost( Route + actual) < cost( new Route(actual)) + || ((_pbm.distance(ultimo,0) + _pbm.distance(0,c_actual)) < _pbm.distance(ultimo,c_actual)) + ) + { + fitness += dist + _pbm.distance(ultimo,0); + ultimo = 0; + dist = 0.0; + cap = _pbm.capacity(); + } + else + { + dist += _pbm.distance(ultimo,c_actual); + cap -= _pbm.demand(c_actual); + ultimo = c_actual; + i++; + } + } + + fitness += dist + _pbm.distance(ultimo,0); + + return fitness; + } + + char *Solution::to_String() const + { + return (char *)_routes.get_first(); + } + + void Solution::to_Solution(char *_routes_) + { + int *ptr=(int *)_routes_; + + for (int i=0;i<_pbm.nCustomers();i++) + { + _routes[i]=*ptr; + ptr++; + } + } + + unsigned int Solution::size() const + { + return ( _pbm.nCustomers() * sizeof(int)); + } + + int & Solution::pos(const int index) + { + return _routes[index]; + } + + + Rarray<int>& Solution::routes() + { + return _routes; + } + + Solution::~Solution() + {} + +// UserStatistics ------------------------------------------------------- + + UserStatistics::UserStatistics () + {} + + ostream& operator<< (ostream& os, const UserStatistics& userstat) + { + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF TRIALS " << endl; + os << "------------------------------------------------------------------" << endl; + + for (int i=0;i< userstat.result_trials.size();i++) + { + os << endl + << "\t" << userstat.result_trials[i].trial + << "\t" << userstat.result_trials[i].best_cost_trial + << "\t\t" << userstat.result_trials[i].nb_evaluation_best_found_trial + << "\t\t" << userstat.result_trials[i].initial_temperature + << "\t\t" << userstat.result_trials[i].temperature_best_found_trial + << "\t\t" << userstat.result_trials[i].time_best_found_trial + << "\t\t" << userstat.result_trials[i].time_spent_trial; + } + + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + + UserStatistics& UserStatistics::operator= (const UserStatistics& userstats) + { + result_trials=userstats.result_trials; + return (*this); + } + + + void UserStatistics::update(const Solver& solver) + { + if ((solver.pid()!=0) || (solver.end_trial()!=true) + || ((solver.current_iteration()!=solver.setup().max_evaluations()) + && !TerminateQ(solver.pbm(),solver,solver.setup()))) + return; + struct user_stat *new_stat; + if ((new_stat=(struct user_stat *)malloc(sizeof(struct user_stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluation_best_found_trial= solver.iteration_best_found_trial(); + new_stat->initial_temperature=solver.initial_temperature_trial(); + new_stat->temperature_best_found_trial=solver.temperature_best_found_trial(); + new_stat->best_cost_trial = solver.current_best_cost(); + new_stat->time_best_found_trial= solver.time_best_found_trial(); + new_stat->time_spent_trial = solver.time_spent_trial(); + result_trials.append(*new_stat); + } + + void UserStatistics::clear() + { + result_trials.remove(); + } + + UserStatistics::~UserStatistics() + { + result_trials.remove(); + } + +// DefaultMove ------------------------------------------------------- + + + DefaultMove::DefaultMove() + {} + + DefaultMove::~DefaultMove() + {} + + void DefaultMove::Apply (Solution& sol) const + { + Solution aux(sol); + const int max = sol.pbm().nCustomers(); + float fit = sol.fitness(); + float fit_a; + Direction d = sol.pbm().direction(); + + for(int i = 0; i < max; i++) + for(int j = i+1; j < max; j++) + { + aux.routes().invert(i,j); + fit_a = aux.fitness(); + if( ((d == minimize) && (fit_a < fit)) + || ((d == minimize) && (fit_a > fit) && (rand01() < 0.3)) + || ((d == maximize) && (fit_a > fit)) + || ((d == maximize) && (fit_a < fit) && (rand01() < 0.3))) + { + fit = fit_a; + sol = aux; + } + else aux = sol; + } + } + + //------------------------------------------------------------------------ + // Specific methods ------------------------------------------------------ + //------------------------------------------------------------------------ + + bool TerminateQ (const Problem& pbm, const Solver& solver, + const SetUpParams& setup) + { + + StopCondition_3 stop; + return stop.EvaluateCondition(pbm,solver,setup); + } +} + + diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/StopCondition.cc b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/StopCondition.cc new file mode 100644 index 0000000000000000000000000000000000000000..e5a2279a6bb41b1041feb49142a46d1c0c72a52e --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/StopCondition.cc @@ -0,0 +1,52 @@ +#include "StopCondition.hh" +skeleton SA +{ + +// StopCondition ------------------------------------------------------------------------------------- + + StopCondition::StopCondition() + {} + + StopCondition::~StopCondition() + {} + +// StopCondition_1 ------------------------------------------------------------------------------------- + + StopCondition_1::StopCondition_1():StopCondition() + {} + + bool StopCondition_1::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return false; + } + + StopCondition_1::~StopCondition_1() + {} + +// StopCondition_2 ------------------------------------------------------------------------------------- + + StopCondition_2::StopCondition_2():StopCondition() + {} + + bool StopCondition_2::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return (solver.global_best_cost()>8.5); + } + + StopCondition_2::~StopCondition_2() + {} + +// StopCondition_3 ------------------------------------------------------------------------------------- + + StopCondition_3::StopCondition_3():StopCondition() + {} + + bool StopCondition_3::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return ((double)solver.current_best_cost()==pbm.bestCost()); + } + + StopCondition_3::~StopCondition_3() + {} + +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/StopCondition.hh b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/StopCondition.hh new file mode 100644 index 0000000000000000000000000000000000000000..04ef770d9cac5bb9ef69aae7d085e3ae2166e187 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/StopCondition.hh @@ -0,0 +1,41 @@ +#ifndef stop_condition +#define stop_condition + +#include "SA.hh" +skeleton SA +{ + + provides class StopCondition + { + public: + StopCondition(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup)=0; + ~StopCondition(); + }; + + requires class StopCondition_1 : public StopCondition + { + public: + StopCondition_1(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_1(); + }; + + requires class StopCondition_2 : public StopCondition + { + public: + StopCondition_2(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_2(); + }; + + requires class StopCondition_3 : public StopCondition + { + public: + StopCondition_3(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_3(); + }; +} + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/pgfileLan b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/pgfileLan new file mode 100644 index 0000000000000000000000000000000000000000..1c419a1ec3c19506364c4b8024570096296426c8 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/rep/SA/vrp/pgfileLan @@ -0,0 +1,5 @@ +localhost 0 ~/Mallba/rep/SA/vrp/MainLan +localhost 1 ~/Mallba/rep/SA/vrp/MainLan +localhost 1 ~/Mallba/rep/SA/vrp/MainLan +localhost 1 ~/Mallba/rep/SA/vrp/MainLan +localhost 1 ~/Mallba/rep/SA/vrp/MainLan diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/src/Makefile b/ProyectoFinal/AlgoritmoGenetico/malva/src/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..b6d64fba4ba48d6a207029d215eedf5df8a69730 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/src/Makefile @@ -0,0 +1,14 @@ +include ../environment + +OBJS = States.o netstream.o + +all: $(OBJS) + +States.o: States.cc States.hh + $(CXX) $(CPPFLAGS) States.cc -c + +netstream.o: netstream.cc netstream.hh + $(CXX) $(CPPFLAGS) netstream.cc -c + +clean: + rm -f *.o *~ *% diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/src/Matrix.hh b/ProyectoFinal/AlgoritmoGenetico/malva/src/Matrix.hh new file mode 100644 index 0000000000000000000000000000000000000000..cc30ae7e23189594a197d99982205dac483fd37b --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/src/Matrix.hh @@ -0,0 +1,337 @@ +/***************************************************************************** +*** *** +*** Este fichero decribe el template Matrix, para el manejo de matrices. *** +*** Tambien permite el manejo de vectores, los que trata como matrices cuya*** +*** primera dimension es 1. *** +*** *** +*****************************************************************************/ +#ifndef _MATRIX +#define _MATRIX + +#include "Messages.h" +#include <assert.h> + +template <class T> class Matrix +{ + private: + T *_matrix; + T nulo,neutro,inverso; + int _dimX,_dimY; + + public: + Matrix() + { + _dimX = _dimY = 0; + _matrix = NULL; + } + + Matrix(const int x,const int y,const T nulo = 0.0,const T neutro = 1.0,const T inverso = -1.0) + { + assert(x >= 1); + assert(y >= 1); + + int k = 0; + + _dimX = x; + _dimY = y; + + this->nulo = nulo; + this->neutro = neutro; + this->inverso = inverso; + + _matrix = new T [_dimX*_dimY]; + if(!_matrix) show_message(7); + + for(int i = 0; i < x; i++) + { + for(int j = 0; j < y ; j++) + { + _matrix[k] = (i!=j?nulo:neutro); + k++; + } + + } + } + + Matrix(const int y,const T nulo = 0.0,const T neutro = 1.0,const T inverso = -1.0) + { + assert(y >= 1); + + _dimX = 1; + _dimY = y; + + this->nulo = nulo; + this->neutro = neutro; + this->inverso = inverso; + + _matrix = new T [_dimY]; + if(!_matrix) show_message(7); + + _matrix[0] = neutro; + for(int j = 1; j < y ; j++) + _matrix[j] = nulo; + } + + Matrix(const Matrix<T> &m) + { + + _dimX = m.dimX(); + _dimY = m.dimY(); + + nulo = m.nulo; + neutro = m.neutro; + inverso = m.inverso; + + _matrix = new T [_dimX*_dimY]; + if(!_matrix) show_message(7); + + for(int i = 0; i < (_dimX*_dimY); i++) + { + _matrix[i] = m[i]; + } + } + + + ~Matrix() + { + remove(); + } + + T &operator()(const int x,const int y) const + { + if((x >= _dimX) || (y >= _dimY)) + show_message(14); + + return (T&)(*(_matrix + (x*_dimX) + y)); + } + + T &operator[](const int y) const + { + if(y >= (_dimX*_dimY)) + show_message(14); + + return (T&)(*(_matrix + y)); + } + + T &operator()(const int y) const + { + if(y >= (_dimX*_dimY)) + show_message(14); + + return (T&)(*(_matrix + y)); + } + + Matrix<T> &operator=(const Matrix<T> &m) + { + remove(); + + _dimX = m.dimX(); + _dimY = m.dimY(); + + _matrix = new T [_dimX*_dimY]; + if(!_matrix) show_message(7); + + for(int i = 0; i < (_dimX*_dimY); i++) + { + _matrix[i] = m[i]; + } + + return (*this); + } + + bool operator==(const Matrix<T> &m) const + { + if((_dimX != m.dimX()) || (_dimY != m.dimY())) + return false; + + for(int i = 0; i < (_dimX*_dimY); i++) + if(_matrix[i] != m[i]) return false; + + return true; + } + + bool operator!=(const Matrix<T> &m) const + { + return !((*this) == m); + } + + Matrix<T> operator*(const Matrix<T> &m) + { + int x = (m.dimX()!=_dimY?0:_dimX); + int y = (x!=0?m.dimY():0); + T acum = nulo; + + Matrix<T> res(x,y); + + for(int i = 0; i < _dimX; i++) + for(int j = 0; j < m.dimY(); j++) + { + acum = nulo; + for( int k = 0; k < _dimY; k++) + acum += (*this)(i,k)* m(k,j); + res(i,j) = acum; + } + + return Matrix<T>(res); + + } + + Matrix<T> &operator*=(const Matrix<T> &m) + { + int x = (m.dimX()!=_dimY?0:_dimX); + int y = (x!=0?0:m.dimY()); + T acum = nulo; + + Matrix<T> res(x,y); + + for(int i = 0; i < _dimX; i++) + for(int j = 0; j < m.dimY(); j++) + { + acum = nulo; + for( int k = 0; k < _dimY; k++) + acum += (*this)(i,k)*m(k,j); + res(i,j) = acum; + } + + (*this) = res; + + return (*this); + + } + + Matrix<T> operator*(const T &elem) + { + Matrix<T> res(_dimX,_dimY); + + for(int i = 0; i < (_dimX*_dimY); i++) + res[i] = _matrix[i] * elem; + + return Matrix(res); + } + + Matrix<T> &operator*=(const T &elem) + { + for(int i = 0; i < (_dimX*_dimY); i++) + _matrix[i] *= elem; + + return (*this); + } + + Matrix<T> operator+(const Matrix<T> &m) + { + int x = (m.dimX()!=_dimX?0:_dimX); + int y = (m.dimY()!=_dimY?0:_dimY); + + Matrix<T> res(x,y); + + for(int i = 0; i < (x*y); i++) + res[i] = _matrix[i] + m[i]; + + return Matrix<T>(res); + } + + Matrix<T> &operator+=(const Matrix<T> &m) + { + int x = (m.dimX()!=_dimX?0:_dimX); + int y = (m.dimY()!=_dimY?0:_dimY); + + for(int i = 0; i < (x*y); i++) + _matrix[i] += m[i]; + + return (*this); + } + + Matrix<T> operator-(const Matrix<T> &m) + { + Matrix<T> res(); + + res = m * inverso; + return (*this) + res; + } + + + Matrix<T> &operator-=(const Matrix<T> &m) + { + Matrix<T> res(); + + res = m * inverso; + (*this) += res; + + return (*this); + } + + Matrix<T> Traspuesta() + { + Matrix<T> res(_dimY,_dimX); + + for(int i = 0; i < _dimX; i++) + for(int j = 0; j < _dimY; j++) + res(j,i) = (*this)(i,j); + + return Matrix<T>(res); + } + + Matrix<T> &nula() + { + for(int i = 0; i < (_dimX*dimY); i++) + _matrix[i] = nulo; + + return (*this); + } + + Matrix<T> &identity() + { + register int k = 0; + + for(int i = 0; i < _dimX; i++) + for(int j = 0; j < _dimY; j++) + { + _matrix[k] = (i!=j?nulo:neutro); + k++; + } + + return (*this); + } + + unsigned int size() const + { + return (sizeof(T)*_dimX*_dimY); + } + + char *to_string() const + { + return (char *) _matrix; + } + + Matrix<T> &to_Matrix(char *_cadena) + { + T *ptr = (T *)_cadena; + + for(int i = 0; i < (_dimX*_dimY) ; i++) + { + _matrix[i] = *ptr; + ptr++; + } + + return (*this); + } + + + int dimX() const + { + return _dimX; + } + + int dimY() const + { + return _dimY; + } + + void remove() + { + if(_matrix != NULL) + delete [] _matrix; + } +}; + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/src/Messages.h b/ProyectoFinal/AlgoritmoGenetico/malva/src/Messages.h new file mode 100644 index 0000000000000000000000000000000000000000..e46b1d823977e76b1c942dda51104206102cc62f --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/src/Messages.h @@ -0,0 +1,112 @@ +/*****************************************************************************/ +/*** ***/ +/*** Modificado por G.J.L.P. ***/ +/*** Añadidos nuevos mensajes que indican falta de algún ***/ +/*** Fichero de Configuración (No específico para ningún ***/ +/*** problema) o nuevos errores. ***/ +/*** ***/ +/*****************************************************************************/ + +#ifndef RLFAP_MESSAGES +#define RLFAP_MESSAGES + +#ifndef MAX_BUFFER +#define MAX_BUFFER 200 +#endif + +#include <iostream> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +using namespace std; + +inline void show_message(int value) +{ + switch (value) + { + case 1: cout << endl << "Error: number of arguments in the execution call is incorrect !!" + << endl; break; + case 2: cout << endl << "Error: It's imposible find Configuration file !!" << endl; + break; + /* Específicos de RLFAP */ + case 3: cout << endl << "Error: It is imposible find the Celar problem definition file (cst.txt) !!" + << endl; break; + case 4: cout << endl << "Error: It is imposible find the Celar domains file (dom.txt) !!" + << endl; break; + case 5: cout << endl << "Error: It is imposible find the Celar links file (var.txt) !!" + << endl; break; + case 6: cout << endl << "Error: It is imposible find the Celar constraints file (ctr.txt) !!" + << endl; break; + /* Fallos de Memoria */ + case 7: cout << endl << "Error: No avalible memory for \"malloc\" operation !!" << endl; + break; + case 8: cout << endl << "Error: in \"free\" operation !!" << endl; + break; + /* Específicos del MaxCut */ + case 9: cout << endl << "Error: It is imposible find the Maxcut file (Maxcut.txt) !!" + << endl; break; + /* Genéricos de Falta de ficheros de configuracion adicionales al mensaje 2 */ + case 10: cout << endl << "Error: It's imposible find Configuration file (Config.cfg) !!" + << endl; break; + case 11: cout << endl << "Error: It's imposible find Skeleton Configuration File (Ske.cfg) !!" + << endl; break; + case 12: cout << endl << "Error: It's imposible find Instance Problem File !!" << endl; + break; + case 13: cout << endl << "Error: It's imposible find Resultate File !!" << endl; + break; + case 14: cout << endl << "Error: Index out of Range !!" << endl; + break; + default: cout << endl << "Unkown Error !!" << endl; + } + + cout << endl << " " << endl; + exit(-1); +} + +inline void continue_question() +{ + fflush(stdout); + cout << endl << "Press any key to continue..." << endl; + fflush(stdin); + getc(stdin); +} + +inline void get_path(const char *source,char *target) +{ + int last = 0; + + for(int i = 0; i < strlen(source); i++) + { + target[i] = source[i]; + if(target[i] == '/') + last = i; + } + target[last+1] = '\0'; +} + +inline unsigned count_lines(char *file_name) // returns the number of lines of a file +{ + char line[MAX_BUFFER]; + FILE *file; + int count=0; + + if ((file=fopen(file_name,"r"))==NULL) + { + fflush(stdout); + printf("File not found !"); + } + + while (!feof(file)) + { + if (fgets(line,MAX_BUFFER,file)) count++; + else + { + fclose(file); + break; + } + } + return count; +} + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/src/Rarray.h b/ProyectoFinal/AlgoritmoGenetico/malva/src/Rarray.h new file mode 100644 index 0000000000000000000000000000000000000000..5d1a1c24919e00e84e1c1bf889021e2c04054dba --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/src/Rarray.h @@ -0,0 +1,145 @@ +/****************************************************************************** +*** *** +*** Template para el manejo dinámico de arrays *** +*** Añadido métodos para invertir todo o parte del array. *** +*** *** +******************************************************************************/ + +#ifndef ARRAY_INC +#define ARRAY_INC 1 +#include <iostream> +#include <assert.h> + +using namespace std; + +template<class E1> class Rarray +{ + private: + E1 *first; + int count; + + public: + Rarray() + { + first = NULL; + count = 0; + } + + ~Rarray() + { + remove(); + } + + E1* get_first() const + { + return first; + } + + void message_a(int cod) const + { + switch (cod) + { + case 1: cout << endl << "The size of array must be upper that 0 !!!" ; + } + } + + Rarray(const int size_a) + { + if (size_a<0) message_a(1); + first = new E1[size_a]; + count=size_a; + } + + void remove() + { + if (count!=0) + delete [] first; + } + + int size() const + { + return count; + } + + E1& operator[](int pos) const + { + return (E1&)(*(first + pos)); + } + + friend ostream& operator<< (ostream& os,const Rarray<E1>& a) + { + for (int i=0;i<a.size();i++) + os << endl << a[i]; + return os; + } + + Rarray<E1>& operator=(const Rarray<E1>& source) + { + remove(); + count = source.size(); + first = new E1[count]; + + for (int i=0;i<count;i++) + (*this)[i] = source[i]; + + return (*this); + } + + + Rarray<E1>& invert() + { + return invert(0,count-1); + } + + Rarray<E1>& invert(const int pos1, const int pos2) + { + int max,min,half,i,j; + E1 aux; + + if(pos1 > pos2) + { + max = pos1; + min = pos2; + } + else + { + max = pos2; + min = pos1; + } + + assert((min > 0) || (min < count-1)); + half = ((max-min)/2) + 1; + + for(i = min,j=max; i< half; i++,j--) + { + aux = first[min]; + first[min] = first[max]; + first[max] = aux; + } + + return (*this); + } + + Rarray<E1>& sort(int (*comp)(const E1 &,const E1 &)) + { + E1 aux; + int j; + + for (int i=1; i < count ; i++) + { + aux = first[i]; + j = i - 1; + while ( (comp(aux,first[j])) && (j >= 0) ) + { + first[j+1]= first[j]; + j--; + } + first[j+1] = aux; + } + + return (*this); + } + +}; // end of class + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/src/Rlist.h b/ProyectoFinal/AlgoritmoGenetico/malva/src/Rlist.h new file mode 100644 index 0000000000000000000000000000000000000000..f561d0bcd49bbffc7fe449f74252df988343f2ff --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/src/Rlist.h @@ -0,0 +1,415 @@ +/****************************************************************************** +*** *** +*** Este template sirve para el manejo de listas din�micas *** +*** *** +******************************************************************************/ + +#ifndef LIST_INC +#define LIST_INC 1 +#include <iostream> +#include <stdlib.h> +#include <Messages.h> + +using namespace std; + +template<class E> class Rlist_item +{ + public: + E *useful_data; // pointer to the structure stored in the list + Rlist_item<E> *next; + Rlist_item<E> *previous; + + Rlist_item(E& new_data) + { + useful_data=&new_data; + next=NULL; + previous=NULL; + } + + Rlist_item(E *new_data) + { + useful_data=new_data; + next=NULL; + previous=NULL; + } + + ~Rlist_item() + { + } + + Rlist_item<E>& next_item() + { + return *(next); + } + + Rlist_item<E>& previous_item() + { + return *(previous); + } + + bool is_last() + { + return (next==NULL); + } + + bool is_first() + { + return (previous==NULL); + } + + E& data() + { + return *(useful_data); + } +}; + +template<class E> class Rlist +{ + private: + Rlist_item<E> *first; // first item in the list + Rlist_item<E> *last; // last item un the list + int count; // number of items in the list + + public: + // constructor + Rlist() + { + first=NULL; + last=NULL; + count=0; + } + + // destructor + ~Rlist() + { + remove(); + } + + // Return the size of the list + int size() const + { return count; } + + // Go back to the initial state of the list + void reset() + { + first=NULL; + last=NULL; + count=0; + } + + // Add a item at the final of the list + Rlist<E>& append(E& new_item) + { + Rlist_item<E> *new_Rlist_item=new Rlist_item<E>(new_item); + if (first==NULL) + { + first=new_Rlist_item; + new_Rlist_item->next=NULL; + new_Rlist_item->previous=NULL; + } + else + { + last->next=new_Rlist_item; + new_Rlist_item->previous=last; + } + last=new_Rlist_item; + count++; + return *this; + } + + Rlist<E>& append(E *new_item) + { + append(*new_item); + return (*this); + } + + // Add a item in a position ( pos ) of the list + Rlist<E>& add_pos(E& new_item, const int pos) + { + if (pos==size()-1) + return append(new_item); + + if (pos==-1) + return add(new_item,NULL); + else + return add(new_item,get_at(pos).useful_data); + } + + // Add a item in the list in the position next to "previous item" + Rlist<E>& add(E& new_item,E *previous_item) + { + if (first==NULL) + return append(new_item); + + Rlist_item<E> *new_Rlist_item=new Rlist_item<E>(new_item); + + if (previous_item==NULL) // Add the item like the first of the list + { + new_Rlist_item->next=first; + new_Rlist_item->previous=NULL; + first->previous=new_Rlist_item; + first=new_Rlist_item; + } + else + { + int previous_position=get_position(*previous_item); + if (previous_position==-1) return(*this); + Rlist_item<E> *previous_Rlist_item = &( get_at(previous_position)); + new_Rlist_item->next=previous_Rlist_item->next; + new_Rlist_item->previous=previous_Rlist_item; + if (previous_Rlist_item->next!=NULL) + (previous_Rlist_item->next)->previous=new_Rlist_item; + else last=new_Rlist_item; + previous_Rlist_item->next=new_Rlist_item; + } + count++; + return *this; + } + + // Return a pointer to the first item of the list + Rlist_item<E> *get_first() const + { return first; } + + // Assign a item like the first item in the list + void set_first(Rlist_item<E> *new_first) + { first=new_first; } + + // Return a pointer to the last item of the list + Rlist_item<E> *get_last() const + { return last; } + + // Assign a item like the last item in the list + void set_last(Rlist_item<E> *new_last) + { last=new_last; } + + // Return the item at position "pos" + E& operator[](int pos) const + { + return *(get_at(pos).useful_data); + } + + // Return the Rlist_item at position "pos" + Rlist_item<E>& get_at(int pos) const + { + Rlist_item<E> *present=first; + for (int k=0;k<size();k++) + if (k==pos) return *present; + else present=present->next; + } + + // Return the item position in the list + int get_position(const E& item) const // probado + { + Rlist_item<E> *present=first; + int i=0; + + while(present!=NULL) + { + if (present->useful_data==&item) return i; + i++; + present=present->next; + } + return -1; // the object has not been found + } + + // Delete a item of the list + Rlist<E>& delete_item(E& item) + { + int position = get_position(item); + + if (position==-1) return *this; + Rlist_item<E> *present=&(get_at(position)); + + if (&item==first->useful_data) // is the first + { + if (&item==last->useful_data) + { + delete(first->useful_data); + delete(first); + first=NULL; + last=NULL; + count=0; + } + else + { + first=first->next; + first->previous=NULL; + delete(present->useful_data); + delete(present); + count--; + } + } + else + { + if (&item==last->useful_data) + { + last=present->previous; + last->next=NULL; + delete(present->useful_data); + delete(present); + count--; + } + else + { + (present->next)->previous=present->previous; + (present->previous)->next=present->next; + delete(present->useful_data); + delete(present); + count--; + } + } + return *this; + } + + // Delete a item of the list without free the useful_data + Rlist<E>& delete_item_1(E& item) + { + int position = get_position(item); + + if (position==-1) return *this; + Rlist_item<E> *present=&(get_at(position)); + + if (&item==first->useful_data) // is the first + { + if (&item==last->useful_data) + { + delete(first); + first=NULL; + last=NULL; + count=0; + } + else + { + first=first->next; + first->previous=NULL; + delete(present); + count--; + } + } + else + { + if (&item==last->useful_data) + { + last=present->previous; + last->next=NULL; + delete(present); + count--; + } + else + { + (present->next)->previous=present->previous; + (present->previous)->next=present->next; + delete(present); + count--; + } + } + return *this; + } + + // Delete item at position "pos" + Rlist<E>& delete_item_by_position(const int pos) + { return delete_item(*(get_at(pos).useful_data)); } + + // Delete the last item in the list + Rlist<E>& delete_last() + { return delete_item(*(last->useful_data)); } + + // delete all items in the list + Rlist<E>& remove() + { + Rlist_item<E> *next,*present=first; + while (present!=NULL) + { + next=present->next; + delete(present->useful_data); + delete(present); + present=next; + } + first=NULL; + last=NULL; + count=0; + return *this; + } + + // Join a new list to this list + Rlist<E>& join(Rlist<E>& new_list) + { + if (new_list.size()==0) + return *this; + + if (first==NULL) + { + first=new_list.get_first(); + last=new_list.get_last(); + } + else + { + last->next=new_list.get_first(); + (new_list.get_first())->previous=last; + last = new_list.get_last(); + } + count += new_list.size(); + new_list.reset(); + return *this; + } + + // Show items of the list + friend ostream& operator<<(ostream& os, const Rlist<E>& list) + { + Rlist_item<E> *present=list.get_first(); + if (list.get_first()==NULL) os << endl << "THE LIST IS EMPTY !!"; + while (present!=NULL) + { + os << endl << (*(present->useful_data)); + // Falta el operador para stat. + // (habra que ver) + present=present->next; + } + return os; + } + + // Copy the list passed + Rlist<E>& operator=(const Rlist<E>& source) + { + E *new_item; + remove(); + if (source.first==NULL && source.last==NULL) + { + first=NULL; + last=NULL; + count=0; + } + else + { + for (int i=0;i<source.size();i++) + { + if ((new_item=(E *)malloc(sizeof(E)))==NULL) + show_message(7); + (*new_item)=*(source.get_at(i).useful_data); + append(*new_item); + } + } + return *this; + } + + // Invert the order of items in the list + Rlist<E>& invert() + { + Rlist_item<E> *present,*interchange; + + present=first; + + for (int i=0;i<size();i++) + { + interchange=present->next; + present->next=present->previous; + present->previous=interchange; + present=interchange; + } + interchange=first; + first=last; + last=interchange; + return (*this); + } +}; // end of class +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/src/States.cc b/ProyectoFinal/AlgoritmoGenetico/malva/src/States.cc new file mode 100644 index 0000000000000000000000000000000000000000..f36d1979373c40068088fb6951f13a126bc033fe --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/src/States.cc @@ -0,0 +1,228 @@ +/****************************************************************************** + Modified by Carlos Cotta Porras + April 2001 + + Modified by G.J.L.P +******************************************************************************/ + + +#include <string.h> +#include "States.hh" + +// Methods of class State_Vble + + // constructors + State_Vble ::State_Vble () + { + name=NULL; + nitems=0; + length=0; + content=NULL; + } + + State_Vble ::State_Vble (const char *st_name) + { + name=strdup(st_name); + nitems=0; + length=0; + content=NULL; + } + + State_Vble::State_Vble (const char *st_name,StateCenter& sc) + { + name=strdup(st_name); + nitems=0; + length=0; + content=NULL; + sc.add(*this); + } + + State_Vble ::State_Vble (const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length) + { + name=strdup(st_name); + nitems=0; + length=0; + content=NULL; + set_contents(new_contents,new_nitems,new_length); + } + + State_Vble ::State_Vble (const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length,StateCenter& sc) + { + name=strdup(st_name); + nitems=0; + length=0; + content=NULL; + set_contents(new_contents,new_nitems,new_length); + sc.add(*this); + } + + + // Set the name of a state vble. + void State_Vble ::set_name (const char* st_name) // Set the name of a state vble. + { + if (name!=NULL) + free(name); + name=strdup(st_name); + } + + // Get the name of a state vble. + char* State_Vble ::get_name () const // Get the name of a state vble. + { + return name; + } + + // Number of basic items + unsigned long State_Vble ::get_nitems() const // Number of basic items + { + return nitems; + } + + // Get the total number of bytes + unsigned long State_Vble ::get_length () const // Get the total number of bytes + { + return length; + } + + // Fill up a state vble. + void State_Vble ::set_contents (const char *new_contents, unsigned long new_nitems, unsigned long new_length) + { + if (content!=NULL) + free(content); + content=(char *)malloc(new_nitems * new_length); + memcpy(content,new_contents,(new_nitems*new_length)); + nitems=new_nitems; + length=new_length; + } + + // Obtain the contents of a state vble. + void *State_Vble ::get_contents (char *read_contents, unsigned long& read_nitems, unsigned long& read_length) const + { + memcpy(read_contents,content,nitems * length); + read_nitems=nitems; + read_length=length; + return NULL; + } + + ostream& operator<< (ostream& os,const State_Vble& st) + { + os << endl << st.name + << endl << st.nitems + << endl << st.length + << endl << st.content; + + return os; + } + + State_Vble ::~State_Vble () + { + free(content); + free(name); + } + +// Methods of class StateCenter + + StateCenter::StateCenter():state_variables() + {} + + // searchs a state variable + State_Vble *StateCenter::find(const char *st_name) const + { + Rlist_item<State_Vble> *current_state=state_variables.get_first(); + + for (int i=0;i<state_variables.size();i++) + { + if (!(strcmp(current_state->data().get_name(),st_name))) + return &(current_state->data()); + current_state=¤t_state->next_item(); + } + return NULL; + } + + // Add one state variable + void StateCenter::add(State_Vble& st) + { + State_Vble *found_state=find(st.get_name()); + if (found_state==NULL) + state_variables.append(st); + else + cout << endl << "You are trying to introduce a state variable that is yet used in the skeleton !!" << st.get_name(); + } + + void StateCenter::add(State_Vble *st) + { + State_Vble *found_state=find(st->get_name()); + if (found_state==NULL) + state_variables.append(*st); + else + cout << endl << "You are trying to introduce a state variable that is yet used in the skeleton !!" << st->get_name(); + } + + // Remove one state variable + void StateCenter::remove(const char* st_name) + { + State_Vble *found_state=find(st_name); + if (found_state!=NULL) + state_variables.delete_item_1(*found_state); + } + + // Update the contents of one vble. + void StateCenter::update(const char* st_name, const State_Vble& st) const // Update the contents of one vble. + { + State_Vble *found_state=find(st_name); + if (found_state!=NULL) + { + char *a=(char *)malloc(found_state->get_nitems() * found_state->get_length()); + unsigned long nitems,length; + st.get_contents(a,nitems,length); + found_state->set_contents(a,nitems,length); + free(a); + } + } + + // Get a vble. with a given name + State_Vble& StateCenter::get(const char* st_name) const // Get a vble. with a given name + { + State_Vble *found_state=find(st_name); + return *found_state; + } + + // Allows an easy iterated extraction + State_Vble* StateCenter::get_next(const State_Vble& st) const + { + State_Vble *found_state=find(st.get_name()); + if (found_state==NULL) return NULL; + if ( state_variables.get_at(state_variables.get_position(*found_state)).is_last()) return NULL; + else return &(state_variables.get_at(state_variables.get_position(*found_state)).next_item().data()); + } + + // returns the number of state variables + unsigned int StateCenter::size() const + { + return state_variables.size(); + } + + // Obtain the contents of a state vble. of name st_name + void StateCenter::get_contents_state_variable(const char *st_name,char *read_contents, unsigned long& read_nitems, unsigned long& read_length) const + { + get(st_name).get_contents(read_contents,read_nitems,read_length); + } + + // Fill up a state vble.of name st_name + void StateCenter::set_contents_state_variable(const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length) const + { + get(st_name).set_contents(new_contents,new_nitems,new_length); + } + + void StateCenter::removeAll() + { + while(state_variables.get_first()) + { + Rlist_item<State_Vble>* v = state_variables.get_first(); + remove(v->useful_data->get_name()); + } + } + + StateCenter::~StateCenter() + { + removeAll(); + } diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/src/States.hh b/ProyectoFinal/AlgoritmoGenetico/malva/src/States.hh new file mode 100644 index 0000000000000000000000000000000000000000..e3a215f5066608ec161882d5ae0c1273944ceaa1 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/src/States.hh @@ -0,0 +1,64 @@ +/******************************************************************************************************** +*** *** +*** Class StateCenter: Pool of state variables for skeletons *** +*** *** +*** Class State_Vble: State Variable of a skeleton *** +*** *** +*********************************************************************************************************/ + +#ifndef STATE_CENTER +#define STATE_CENTER 1 + +#include "Rlist.h" +#include <iostream> + +class StateCenter; + +class State_Vble +{ + private: + char *name; + unsigned long nitems; + unsigned long length; + char *content; + + public: + // constructors + State_Vble (); + State_Vble (const char *st_name); + State_Vble (const char *st_name,StateCenter& sc); + State_Vble (const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length); + State_Vble (const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length,StateCenter& sc); + + void set_name (const char* st_name); // Set the name of a state vble. + char* get_name () const; // Get the name of a state vble. + unsigned long get_nitems() const; + unsigned long get_length () const; // Get the total number of bytes + void set_contents (const char *new_contents, unsigned long new_nitems, unsigned long new_length); // Fill up a state vble. + void *get_contents (char *read_contents, unsigned long& read_nitems, unsigned long& read_length) const; // Obtain the contents of a state vble. + friend ostream& operator<< (ostream& os,const State_Vble& st); + ~State_Vble (); +}; + +class StateCenter +{ + private: + Rlist<State_Vble> state_variables; + + public: + StateCenter(); + State_Vble *find(const char *st_name) const; // search a state variable + void add(State_Vble& st); // Add one state variable + void add(State_Vble *st); // Add one state variable + void remove(const char* st_name); // Remove one state variable + void removeAll(); // Removes all variables + void update(const char* st_name, const State_Vble& st) const; // Update the contents of one vble. + State_Vble& get(const char* st_name) const; // Get a vble. with a given name + State_Vble* get_next(const State_Vble& st) const; // Allows an easy iterated extraction + unsigned int size() const; // returns the number of state variables + void get_contents_state_variable(const char *st_name,char *read_contents, unsigned long& read_nitems, unsigned long& read_length) const; // Obtain the contents of a state vble. of name st_name + void set_contents_state_variable(const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length) const; // Fill up a state vble.of name st_name + ~StateCenter(); +}; + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/src/States.o b/ProyectoFinal/AlgoritmoGenetico/malva/src/States.o new file mode 100644 index 0000000000000000000000000000000000000000..f5e95c8928fb22e26363c12820d0e56fd98709d2 Binary files /dev/null and b/ProyectoFinal/AlgoritmoGenetico/malva/src/States.o differ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/src/mallba.hh b/ProyectoFinal/AlgoritmoGenetico/malva/src/mallba.hh new file mode 100644 index 0000000000000000000000000000000000000000..e4a35c07363b0c19d91cf9d5f03f352d0550fd83 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/src/mallba.hh @@ -0,0 +1,26 @@ +/***************************************************************************** +*** *** +*** Este fichero hace algunas declaraciones y declara algunos tipos comu- *** +*** nes a todos los algoritmos implementados. *** +*** *** +*****************************************************************************/ + +#ifndef INC_mallba_hh +#define INC_mallba_hh + +#define skeleton namespace +#define requires +#define provides +#define hybridizes(x) +#define inherits typedef +#define as + +enum Direction { minimize=-1,maximize=1}; + +extern const double plus_infinity; +extern const double minus_infinity; + +#define false 0 +#define true 1 + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/src/netstream.cc b/ProyectoFinal/AlgoritmoGenetico/malva/src/netstream.cc new file mode 100644 index 0000000000000000000000000000000000000000..932e89e56ab5eff64306137bd0ae97b1380a05e2 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/src/netstream.cc @@ -0,0 +1,380 @@ +/*************************************************************************** + *** netstream.cc *** + *** v1.6 - July 2001 *** + ** *** + *** v1.5 - March 2001 *** + *** v1.0 - November 2000 *** + *** *** + *** v1.5 extends v1.0: *** + *** .- Changes metods init() and finalize() to be static *** + *** .- Incorporates process group management *** + *** .- Do not consider LEDA anymore *** + *** .- Contains a method "int my_pid()" for easy invokations *** + *** .- Adds "unsigned" and "long double" input/output *** + *** *** + *** v1.6 extends v1.5: *** + ** .- Internal in/out buffers for packed separated *** + *** *** + *** Communication services for LAN/WAN use following the message *** + *** passing paradigm. *** + *** STREAM C++ VERSION *** + *** MPI implementation *** + *** Developed by Erique Alba *** + ***************************************************************************/ +#include "netstream.hh" +// Default constructor +NetStream::NetStream() +{ + this->reset(); // Reset to default values member variables + packin_buffer = new char[MAX_PACK_BUFFER_SIZE]; + packout_buffer = new char[MAX_PACK_BUFFER_SIZE]; +} +// Init the underlying communication library (MPI) +NetStream::NetStream (int argc, char ** argv) +{ + init(argc,argv); + this->reset(); + packin_buffer = new char[MAX_PACK_BUFFER_SIZE]; + packout_buffer = new char[MAX_PACK_BUFFER_SIZE]; +} +// Default destructor +NetStream::~NetStream() +{ + delete [] packin_buffer; delete [] packout_buffer; + this->reset(); +} +// Give default values to member variables +void NetStream::reset(void) +{ + default_target = default_source = 0; + pack_in_progress = false; + packin_index = packout_index = 0; + pending_input_packet = false; + pack_in = pack_out = false; + broadcast = false; + my_communicator = MPI_COMM_WORLD; +} +// Init the communication system. Invoke it only ONCE +void NetStream::init(int argc, char** argv) +{ + static bool system_up = false; // Is MPI already running? + if (!system_up) + { MPI_Init(&argc,&argv); + system_up = true; + } +} +// Shutdown the communication system. Invoke it ONCE +void NetStream::finalize(void) +{ + MPI_Finalize(); // Unconditional Finalization +} +// BASIC INPUT/OUTPUT SERVICES +// =================================================================================== + +NetStream& NetStream::operator>> (bool& d) +{ rcv(&d,1,NET_BOOL,default_source); return(*this); } + +NetStream& NetStream::operator<< (bool d) +{ send(&d,1,NET_BOOL,default_target); return(*this); } +NetStream& NetStream::operator>> (char& d) +{ rcv(&d,1,NET_CHAR,default_source); return(*this); } +NetStream& NetStream::operator<< (char d) +{ send(&d,1,NET_CHAR,default_target); return(*this); } +NetStream& NetStream::operator>> (short& d) +{ rcv(&d,1,NET_SHORT,default_source); return(*this); } +NetStream& NetStream::operator<< (short d) +{ send(&d,1,NET_SHORT,default_target); return(*this); } +NetStream& NetStream::operator>> (int& d) +{ rcv(&d,1,NET_INT,default_source); return(*this); } +NetStream& NetStream::operator<< (int d) +{ send(&d,1,NET_INT,default_target); return(*this); } +NetStream& NetStream::operator>> (long& d) +{ rcv(&d,1,NET_LONG,default_source); return(*this); } +NetStream& NetStream::operator<< (long d) +{ send(&d,1,NET_LONG,default_target); return(*this); } +NetStream& NetStream::operator>> (float& d) +{ rcv(&d,1,NET_FLOAT,default_source); return(*this); } +NetStream& NetStream::operator<< (float d) +{ send(&d,1,NET_FLOAT,default_target); return(*this); } +NetStream& NetStream::operator>> (double& d) +{ rcv(&d,1,NET_DOUBLE,default_source); return(*this); } +NetStream& NetStream::operator<< (double d) +{ send(&d,1,NET_DOUBLE,default_target); return(*this); } +NetStream& NetStream::operator>> (char* d) +{ rcv(d,MAX_MSG_LENGTH,NET_CHAR,default_source); return(*this); } +NetStream& NetStream::operator<< (char* d) +{ send(d,strlen(d)+1,NET_CHAR,default_target); return(*this); } +NetStream& NetStream::operator>> (void* d) +{ rcv(d,MAX_MSG_LENGTH,NET_CHAR,default_source); return(*this); } +NetStream& NetStream::operator<< (void* d) +{ send(d,strlen((char*)d)+1,NET_CHAR,default_target); return(*this); } +// Extended data types from version 1.5 on +NetStream& NetStream::operator>> (unsigned char& d) +{ rcv(&d,MAX_MSG_LENGTH,NET_UNSIGNED_CHAR,default_source);return(*this); } + +NetStream& NetStream::operator<< (unsigned char d) +{ send(&d,1,NET_UNSIGNED_CHAR,default_target); return(*this); } +NetStream& NetStream::operator>> (unsigned short int& d) +{ rcv(&d,MAX_MSG_LENGTH,NET_UNSIGNED_SHORT,default_source);return(*this); } +NetStream& NetStream::operator<< (unsigned short int d) +{ send(&d,1,NET_UNSIGNED_SHORT,default_target); return(*this); } +NetStream& NetStream::operator>> (unsigned int& d) +{ rcv(&d,MAX_MSG_LENGTH,NET_UNSIGNED,default_source); return(*this); } + +NetStream& NetStream::operator<< (unsigned int d) +{ send(&d,1,NET_UNSIGNED,default_target); return(*this); } +NetStream& NetStream::operator>> (unsigned long int& d) +{ rcv(&d,MAX_MSG_LENGTH,NET_UNSIGNED_LONG,default_source);return(*this); } + +NetStream& NetStream::operator<< (unsigned long int d) +{ send(&d,1,NET_UNSIGNED_LONG,default_target); return(*this); } +NetStream& NetStream::operator>> (long double& d) +{ rcv(&d,MAX_MSG_LENGTH,NET_LONG_DOUBLE,default_source); return(*this); } + +NetStream& NetStream::operator<< (long double d) +{ send(&d,1,NET_LONG_DOUBLE,default_target); return(*this); } +// SET-GET TARGET AND SOURCE PROCESSES +NetStream& __set_target(NetStream& n, const int p) { return n._set_target(p); } +NetStream& NetStream::_set_target(const int p) +{ assert(p>=0); default_target = p; return (*this); } +NetStream& __get_target(NetStream& n, int* p) { return n._get_target(p); } +NetStream& NetStream::_get_target(int* p) +{ *p = default_target; return (*this); } +NetStream& __set_source(NetStream& n, const int p) { return n._set_source(p); } +NetStream& NetStream::_set_source(const int p) +{ /*assert(p>=0);*/ default_source = p; return (*this); } +NetStream& __get_source(NetStream& n, int* p) { return n._get_source(p); } +NetStream& NetStream::_get_source(int* p) +{ *p = default_source; return (*this); } +// Get the number of processes involved in the communications +int NetStream::pnumber(void) +{ int numprocs, rvalue; + rvalue = MPI_Comm_size(my_communicator,&numprocs); + assert(rvalue==MPI_SUCCESS); + return numprocs; +} +// MANIPULATORS: SYNCHRONIZATION AND PACKING SERVICES +// =================================================================================== +// Get the process ID [0, 1, 2, ...] fro the calling process +NetStream& __my_pid(NetStream& n, int* pid) +{ + return n._my_pid(pid); +} +NetStream& NetStream::_my_pid(int* pid) +{ + MPI_Comm_rank(my_communicator,pid); + return (*this); +} +// EASY access to rank - Returns the process ID of the calling process +int NetStream::my_pid(void) +{ int pid; + this->_my_pid(&pid); + return pid; +} +// Sit and wait until all processes are in the same barrier +// Can be used as a MANIPULATOR +NetStream& barrier(NetStream& n) +{ + return n._barrier(); +} +NetStream& NetStream::_barrier(void) +{ int status; + status = MPI_Barrier(my_communicator); + assert(status==MPI_SUCCESS); + return (*this); +} +// Wait for an incoming message in any input stream +NetStream& NetStream::_wait(const int stream_type) // class +{ + int rvalue; + MPI_Status status; + assert(stream_type==regular||stream_type==packed||stream_type==any); + if( ((stream_type==packed) || (stream_type==any) )&& (pending_input_packet) ) + //if( (stream_type==packed) && (pending_input_packet) ) + return (*this); // wait befor packet_begin when already received + rvalue = MPI_Probe(default_source,stream_type,my_communicator,&status); + assert(rvalue==MPI_SUCCESS); + return (*this); +} + +NetStream& NetStream::_wait2(const int stream_type, int& tipo) // class +{ + int rvalue; + MPI_Status status; + assert(stream_type==regular||stream_type==packed||stream_type==any); + if( ((stream_type==packed) || (stream_type==any) )&& (pending_input_packet) ) + //if( (stream_type==packed) && (pending_input_packet) ) + return (*this); // wait befor packet_begin when already received + rvalue = MPI_Probe(default_source,stream_type,my_communicator,&status); + assert(rvalue==MPI_SUCCESS); + if (status.MPI_SOURCE == 0){ + tipo = 1; + } + return (*this); +} +NetStream& __wait(NetStream& n, const int stream_type) // helper +{ + return n._wait(stream_type); +} +// Marks the beginning of a packed information +NetStream& pack_begin(NetStream& n) +{ + return n._pack_begin(); +} +NetStream& NetStream::_pack_begin(void) +{ + int rvalue=MPI_SUCCESS; + MPI_Status status; + if(!pack_in_progress) + { pack_in_progress = true; + packin_index = packout_index = 0; + pack_in = false; + pack_out = false; + if (!pending_input_packet) + { _probe(packed,pending_input_packet); + if(pending_input_packet) + rvalue = MPI_Recv(packin_buffer, MAX_PACK_BUFFER_SIZE, NET_PACKED, + default_source, PACKED_STREAM_TAG, my_communicator, &status); + } + } + return (*this); +} +// Marks the end of a packed and flush it to the net +NetStream& pack_end(NetStream& n) +{ + return n._pack_end(); +} +NetStream& NetStream::_pack_end(void) +{ + int rvalue, mypid; + if (pack_in_progress) + { + if(pack_out) + { if(broadcast) // Packet broadcast + { broadcast = false; + _my_pid(&mypid); + rvalue = MPI_Bcast(packout_buffer,packout_index,NET_PACKED, + mypid,my_communicator); + assert(rvalue==MPI_SUCCESS); + } + else + { rvalue = MPI_Send(packout_buffer, packout_index, NET_PACKED, + default_target,PACKED_STREAM_TAG,my_communicator); + assert(rvalue==MPI_SUCCESS); + } + } + pack_in_progress = false; + pack_in = pack_out = false; + packin_index = packout_index = 0 ; + } + return (*this); +} +// Check whether there are awaiting data +NetStream& probe(NetStream& n, const int stream_type, int& pending) +{ + return n._probe(stream_type, pending); +} +NetStream& NetStream::_probe(const int stream_type, int& pending) +{ + MPI_Status status; + int rvalue; + assert(stream_type==regular||stream_type==packed||stream_type==any); + rvalue = MPI_Iprobe(default_source,stream_type,my_communicator,&pending,&status); + assert(rvalue==MPI_SUCCESS); + return (*this); +} +// Broadcast a message to all the processes +NetStream& broadcast(NetStream& n) +{ + return n._broadcast(); +} +NetStream& NetStream::_broadcast(void) +{ + broadcast = true; + return (*this); +} +// PRIVATE SERVICES +// =================================================================================== +// Usually, the length is the number of bytes for every net type +// When packing we must use in the pack calls the numer of items (length divided by type size) +// Any char is encoded with a leading field of length +void NetStream::send(void* d, const int len, const NET_TYPE type, const int target) +{ + int rvalue = MPI_SUCCESS, length = len; + // PACKING SERVICE + if(pack_in_progress) + { + pack_out = true; + assert(pack_out!=pack_in); // Error condition + if(type==NET_CHAR) + send(&length,sizeof(NET_INT),NET_INT,target); // Recursive call to store string length + else + length = 1; + rvalue = MPI_Pack(d,length,type,packout_buffer,MAX_PACK_BUFFER_SIZE,&packout_index,my_communicator); + assert(rvalue==MPI_SUCCESS); + return; + } + if(broadcast) // Regular broadcast, packed broadcast managed in _pack_end() + { int mypid; + + broadcast = false; + _my_pid(&mypid); + rvalue = MPI_Bcast(d,len,type,mypid,my_communicator); + assert(rvalue==MPI_SUCCESS); + return; + } + rvalue = MPI_Send(d,len,type,target,REGULAR_STREAM_TAG,my_communicator); + assert(rvalue==MPI_SUCCESS); +} +void NetStream::rcv (void* d, const int len, const NET_TYPE type, const int source) +{ MPI_Status status; + int rvalue = MPI_SUCCESS, length=len; + if(pack_in_progress) + { +// if(!pack_in && !pending_input_packet) +// rvalue = MPI_Recv(packin_buffer, MAX_PACK_BUFFER_SIZE, NET_PACKED, +// default_source, PACKED_STREAM_TAG, my_communicator, &status); + pack_in = true; + pending_input_packet = false; + assert(pack_out!=pack_in); + if(type==NET_CHAR) + rcv(&length,sizeof(NET_INT),NET_INT,source); // Gets the string length + else + length = 1; + rvalue = MPI_Unpack(packin_buffer, MAX_PACK_BUFFER_SIZE, &packin_index, d, + length, type, my_communicator); + assert(rvalue==MPI_SUCCESS); + return; + } + + rvalue=MPI_Recv(d,len,type,source,REGULAR_STREAM_TAG,my_communicator,&status); + assert(status.MPI_ERROR==MPI_SUCCESS); + assert(rvalue==MPI_SUCCESS); +} +/////////////////////////////////////// GROUP MANAGEMENT //////////////////////////////// +// Set the netstream to a new communicator +void NetStream::set_communicator(NET_Comm comm) +{ + my_communicator = comm; +} +// Get the present communicator in this netstream +NET_Comm NetStream::get_communicator(void) +{ + return my_communicator; +} +// Create a new group inside the present communicator +NET_Comm NetStream::create_group(NET_Comm comm, int color, int key) +{ int rvalue; + NET_Comm newcomm; + rvalue=MPI_Comm_split(comm,color,key,&newcomm); + assert(rvalue==MPI_SUCCESS); + return newcomm; +} +// Create a bridge between local and remote MATCHING call +NET_Comm NetStream::create_inter_group(NET_Comm lcomm, int lrank, NET_Comm bcomm, int rrank, int strtype) +{ int rvalue; + NET_Comm newcomm; + rvalue=MPI_Intercomm_create(lcomm,lrank,bcomm,rrank,strtype,&newcomm); + assert(rvalue==MPI_SUCCESS); + return newcomm; +} diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/src/netstream.hh b/ProyectoFinal/AlgoritmoGenetico/malva/src/netstream.hh new file mode 100644 index 0000000000000000000000000000000000000000..5c24a3dc072e2d1dbed9ebecef2b7d6190e51683 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/src/netstream.hh @@ -0,0 +1,161 @@ +/*************************************************************************** + *** netstream.cc *** + *** v1.6 - July 2001 *** + ** *** + *** v1.5 - March 2001 *** + *** v1.0 - November 2000 *** + *** *** + *** v1.5 extends v1.0: *** + *** .- Changes metods init() and finalize() to be static *** + *** .- Incorporates process group management *** + *** .- Do not consider LEDA anymore *** + *** .- Contains a method "int my_pid()" for easy invokations *** + *** .- Adds "unsigned" and "long double" input/output *** + *** *** + *** v1.6 extends v1.5: *** + ** .- Internal in/out buffers for packed separated *** + *** *** + *** Communication services for LAN/WAN use following the message *** + *** passing paradigm. *** + *** STREAM C++ VERSION *** + *** MPI implementation *** + *** Developed by Erique Alba *** + ***************************************************************************/ +#ifndef INC_netstream +#define INC_netstream +#include "mpi.h" +#include <assert.h> +#include <string.h> +// Class NetStream allows to define and use network streams trhough LAN and WAN +#define REGULAR_STREAM_TAG 0 // Used for tagging MPI regular messages +#define PACKED_STREAM_TAG 1 // Used for tagging MPI packet messages +#define NET_TYPE MPI_Datatype // Network allowable data types +#define NET_BOOL MPI_CHAR // Bools like chars +#define NET_CHAR MPI_CHAR +#define NET_SHORT MPI_SHORT +#define NET_INT MPI_INT +#define NET_LONG MPI_LONG +#define NET_UNSIGNED_CHAR MPI_UNSIGNED_CHAR +#define NET_UNSIGNED_SHORT MPI_UNSIGNED_SHORT +#define NET_UNSIGNED MPI_UNSIGNED +#define NET_UNSIGNED_LONG MPI_UNSIGNED_LONG +#define NET_FLOAT MPI_FLOAT +#define NET_DOUBLE MPI_DOUBLE +#define NET_LONG_DOUBLE MPI_LONG_DOUBLE +#define NET_BYTE MPI_BYTE +#define NET_PACKED MPI_PACKED +#define NET_Comm MPI_Comm +#define MAX_MSG_LENGTH 204800 // Max length of a message +#define MAX_PACK_BUFFER_SIZE 204800 // Max length of a packed message +// Help structure for manipulators having one int& argument +class NetStream; +struct smanip1c // "const int" +{ NetStream& (*f)(NetStream&, const int); // The ONE argument function + int i; // The argument + smanip1c( NetStream&(*ff)(NetStream&,const int), int ii) : f(ff), i(ii) {} // Constuctor +}; +struct smanip1 // "int*" note: references do not work! "int&" +{ NetStream& (*f)(NetStream&, int*); // The ONE argument function + int* i; // The argument + smanip1( NetStream&(*ff)(NetStream&, int*), int* ii) : f(ff), i(ii) {} // Constuctor +}; +// Tags for the available streams +const int any = MPI_ANY_TAG; // Tag value valid for any stream +const int regular = REGULAR_STREAM_TAG; // Tag value for regular stream of data +const int packed = PACKED_STREAM_TAG; // Tag value for packed stream of data +// Tags for sources +const int any_source = MPI_ANY_SOURCE; // Tag value valid for any source +class NetStream +{ + public: + NetStream (); // Default constructor + // Constructor with source integer left unchanged + NetStream (int, char **); // Init the communications + ~NetStream (); // Default destructor + static void init(int,char**); // Init the communication system. Invoke it only ONCE + static void finalize(void); // Shutdown the communication system. Invoke it ONCE + // GROUP management + void set_communicator(NET_Comm comm); // Set the netstream to a new communicator + NET_Comm get_communicator(void); // Get the present communicator in this netstream + static NET_Comm create_group(NET_Comm comm, int color, int key); // Create a new group inside the present communicator + // Create a bridge between local and remote MATCHING call + static NET_Comm create_inter_group(NET_Comm lcomm, int lrank, NET_Comm bcomm, int rrank, int strtrype); + +// BASIC INPUT SERVICES <comments> BASIC OUTPUT SERVICES +// ============================================================================================================ + NetStream& operator>> (bool& d); NetStream& operator<< (bool d); + NetStream& operator>> (char& d); NetStream& operator<< (char d); + NetStream& operator>> (short& d); NetStream& operator<< (short d); + NetStream& operator>> (int& d); NetStream& operator<< (int d); + NetStream& operator>> (long& d); NetStream& operator<< (long d); + NetStream& operator>> (float& d); NetStream& operator<< (float d); + NetStream& operator>> (double& d); NetStream& operator<< (double d); + NetStream& operator>> (char* d); /*NULL terminated*/ NetStream& operator<< (char* d); + NetStream& operator>> (void* d); /*NULL terminated*/ NetStream& operator<< (void* d); + // Extended data types from version 1.5 on + NetStream& operator>> (unsigned char& d); NetStream& operator<< (unsigned char d); + NetStream& operator>> (unsigned short int& d); NetStream& operator<< (unsigned short int d); + NetStream& operator>> (unsigned int& d); NetStream& operator<< (unsigned int d); + NetStream& operator>> (unsigned long int& d); NetStream& operator<< (unsigned long int d); + NetStream& operator>> (long double& d); NetStream& operator<< (long double d); + int pnumber(void); // Returns the number of processes + bool broadcast; // Determines whether the next sent message is for broadcasting + // Input MANIPULATORS for modifying the behavior of the channel on the fly + // NO ARGUMENTS + NetStream& operator<< (NetStream& (*f)(NetStream& n)) { return f(*this); } // NO arguments + NetStream& _barrier(void); // Sit and wait until all processes are in barrier + NetStream& _pack_begin(void); // Marks the beginning of a packed information + NetStream& _pack_end(void); // Marks the end of a packed and flush it to the net + NetStream& _probe(const int stream_type, int& pending); // Check whether there are awaiting data + NetStream& _broadcast(void); // Broadcast a message to all the processes + // ONE ARGUMENT + // "const int" + NetStream& operator<< (smanip1c m) { return m.f((*this),m.i); }// ONE int& argument constant + // "int*" + NetStream& operator<< (smanip1 m) { return m.f((*this),m.i); }// ONE int& argument + // BASIC CLASS METHODS FOR MANIPULATORS + NetStream& _my_pid(int* pid); // Returns the process ID of the calling process + NetStream& _wait(const int stream_type); // Wait for an incoming message in the specified stream + NetStream& _wait2(const int stream_type, int& tipo); + NetStream& _set_target(const int p); // Stablish "p" as the default receiver + NetStream& _get_target(int* p); // Get into "p" the default receiver + NetStream& _set_source(const int p); // Stablish "p" as the default transmitter + NetStream& _get_source(int* p); // Get into "p" the default transmitter + // AUXILIAR PUBLIC METHODS FOR ALLOWING EASY MANAGEMENTS OF NETSTREAMS + int my_pid(void); // Returns the process ID of the calling process + private: + int default_target, default_source; // Default process IDs to send-recv data to-from + bool pack_in_progress; // Defines whether a packet is being defined with "pack_begin-pack_end" + int packin_index; // Index to be used for extracting from a IN packed message - v1.6 + int packout_index; // Index to be used for adding to an OUT packed message - v1.6 + int pending_input_packet;//Is there a pending packet already read into the IN buffer? - v1.6 + char* packin_buffer; // Buffer to temporary storage of the IN packed being defined - v1.6 + char* packout_buffer; // Buffer to temporary storage of the OUT packed being defined - v1.6 + bool pack_in, pack_out; // Define whether input-output packed message is being used + void reset(void); // Reset member variables of this class + NET_Comm my_communicator; // Communicator of this netstream + void send(void* d, const int len, const NET_TYPE type, const int target); + void rcv (void* d, const int len, const NET_TYPE type, const int source); +}; // class NetStream + // MANIPULATORS (must be static or non-member methods in C++ -mpiCC only allows non-member!-) + // NO ARGUMENTS + NetStream& barrier(NetStream& n); // Sit and wait until all processes are in barrier + NetStream& broadcast(NetStream& n); // Broadcast a message to all the processes + NetStream& pack_begin(NetStream& n); // Marks the beginning of a packed information + NetStream& pack_end(NetStream& n); // Marks the end of a packed and flush it to the net + // ONE ARGUMENT + NetStream& __my_pid(NetStream& n, int* pid); // Returns the process ID of the calling process + inline smanip1 my_pid(int* pid){ return smanip1(__my_pid,pid); } // manipulator + NetStream& __wait(NetStream& n, const int stream_type);// Wait for an incoming message - helper + inline smanip1c wait(const int stream_type){ return smanip1c(__wait,stream_type); } // manipulator + NetStream& __set_target(NetStream& n, const int p); // Stablish "p" as the default receiver + inline smanip1c set_target(const int p){ return smanip1c(__set_target,p); } // manipulator + NetStream& __get_target(NetStream& n, int* p); // Get into "p" the default receiver + inline smanip1 get_target(int* p){ return smanip1(__get_target,p); } // manipulator + NetStream& __set_source(NetStream& n, const int p); // Stablish "p" as the default transmitter + inline smanip1c set_source(const int p){ return smanip1c(__set_source,p); } // manipulator + NetStream& __get_source(NetStream& n, int* p); // Get into "p" the default transmitter + inline smanip1 get_source(int* p){ return smanip1(__get_source,p); } // manipulator + // TWO ARGUMENTS - not used yet + NetStream& probe(NetStream& n, const int stream_type, int& pending); // Check whether there are awaiting data +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/src/netstream.o b/ProyectoFinal/AlgoritmoGenetico/malva/src/netstream.o new file mode 100644 index 0000000000000000000000000000000000000000..fb40ece360fb739d83d40beffbf1b01c031a15aa Binary files /dev/null and b/ProyectoFinal/AlgoritmoGenetico/malva/src/netstream.o differ diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/src/random.hh b/ProyectoFinal/AlgoritmoGenetico/malva/src/random.hh new file mode 100644 index 0000000000000000000000000000000000000000..ae6bde6ae8230c733aeb341be926e21fc5648d94 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/src/random.hh @@ -0,0 +1,50 @@ +/****************************************************************************** +*** *** +*** Este fichero contiene funciones (en general inlines) para generar núme- *** +*** ros aleatorios y otras funciones relacionadas con ello *** +*** *** +*******************************************************************************/ + +#ifndef INC_random_hh +#define INC_random_hh + +#include <stdlib.h> + + +inline double undefined () +{ + double zero = 0; + return zero/zero; +} + +// Returns a valeu greater than any other +inline double infinity () +{ + double one=1.0; + double zero=0.0; + return one/zero; +} + +// Returns a random number in [0,1]. +inline double rand01 () +{ + return drand48(); +} + +// Returns a random number +inline int rand_int (float min,float max) +{ + int value=rand(); + int range= (int)(max - min); + int order = value % (range+1); + return ((int)min + order); +} + +// selects a seed +inline void random_seed(long int seed) +{ + srand48(seed); + srand(seed); +} + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/src/time.hh b/ProyectoFinal/AlgoritmoGenetico/malva/src/time.hh new file mode 100644 index 0000000000000000000000000000000000000000..088f4d5ea51f4a597ec1f0609ae5e175eae0a055 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/src/time.hh @@ -0,0 +1,43 @@ +/****************************************************************************** +*** *** +*** Este fichero incluye algunas funciones útiles para la medicion de tiem- *** +*** pos. *** +*** *** +******************************************************************************/ + +#ifndef INC_time_hh +#define INC_time_hh + +#define MAXTIME 4294 + +#include <time.h> +#include <sys/time.h> +#include <unistd.h> + +// return time in microseconds +inline float _used_time() +{ + struct timeval tv ; + static long tiempo = -1; + float u_clock; + + gettimeofday(&tv,NULL); + + if(tiempo < 0) tiempo = tv.tv_sec; + + u_clock = ((float)(tv.tv_sec - tiempo)*1000000.0) + ((float)tv.tv_usec); + return u_clock; + +} + + +inline float _used_time(float time) +{ + float dif=_used_time() - time; + if (dif<0) dif = 0; + return dif; +} + + + +#endif diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/stat/file_stat_aco b/ProyectoFinal/AlgoritmoGenetico/malva/stat/file_stat_aco new file mode 100644 index 0000000000000000000000000000000000000000..8426ce41ac5119b9755a1efa3fb86f0dbffa2076 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/stat/file_stat_aco @@ -0,0 +1,12 @@ +#!/bin/bash + +lines=`cat $1 | wc -l` +head_op=$(($lines - 1)) +tail_op=$(($head_op - 5)) + +head -n $head_op $1 | tail -n $tail_op | gawk '{print $2}' > $1.best_fit +head -n $head_op $1 | tail -n $tail_op | gawk '{print $3}' > $1.worse_fit +head -n $head_op $1 | tail -n $tail_op | gawk '{print $5}' > $1.iter +head -n $head_op $1 | tail -n $tail_op | gawk '{print $6}' > $1.time +head -n $head_op $1 | tail -n $tail_op | gawk '{print $7}' > $1.total_time +echo $tail_op > $1.num_exec diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/stat/file_stat_pop b/ProyectoFinal/AlgoritmoGenetico/malva/stat/file_stat_pop new file mode 100644 index 0000000000000000000000000000000000000000..8512575c9d1b84198ff3c895d26986950acf5591 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/stat/file_stat_pop @@ -0,0 +1,13 @@ +#!/bin/bash + +lines=`cat $1 | wc -l` +head_op=$(($lines - 1)) +tail_op=$(($head_op - 5)) + +head -n $head_op $1 | tail -n $tail_op | gawk '{print $2}' > $1.best_fit +head -n $head_op $1 | tail -n $tail_op | gawk '{print $3}' > $1.worse_fit +head -n $head_op $1 | tail -n $tail_op | gawk '{print $3}' > $1.eval +head -n $head_op $1 | tail -n $tail_op | gawk '{print $5}' > $1.iter +head -n $head_op $1 | tail -n $tail_op | gawk '{print $6}' > $1.time +head -n $head_op $1 | tail -n $tail_op | gawk '{print $7}' > $1.total_time +echo $tail_op > $1.num_exec diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/stat/file_stat_pso b/ProyectoFinal/AlgoritmoGenetico/malva/stat/file_stat_pso new file mode 100644 index 0000000000000000000000000000000000000000..672f85797195fd2fa2ec8a64a4c869d40afba124 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/stat/file_stat_pso @@ -0,0 +1,12 @@ +#!/bin/bash + +lines=`cat $1 | wc -l` +head_op=$(($lines - 1)) +tail_op=$(($head_op - 5)) + +head -n $head_op $1 | tail -n $tail_op | gawk '{print $2}' > $1.best_fit +head -n $head_op $1 | tail -n $tail_op | gawk '{print $3}' > $1.worse_fit +head -n $head_op $1 | tail -n $tail_op | gawk '{print $4}' > $1.iter +head -n $head_op $1 | tail -n $tail_op | gawk '{print $5}' > $1.time +head -n $head_op $1 | tail -n $tail_op | gawk '{print $6}' > $1.total_time +echo $tail_op > $1.num_exec diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/stat/file_stat_sa b/ProyectoFinal/AlgoritmoGenetico/malva/stat/file_stat_sa new file mode 100644 index 0000000000000000000000000000000000000000..d006462e8b7445d4c971805fd6706bd104ef12d6 --- /dev/null +++ b/ProyectoFinal/AlgoritmoGenetico/malva/stat/file_stat_sa @@ -0,0 +1,13 @@ +#!/bin/bash + +lines=`cat $1 | wc -l` +head_op=$(($lines - 1)) +tail_op=$(($head_op - 5)) + +head -n $head_op $1 | tail -n $tail_op | gawk '{print $2}' > $1.best_fit +head -n $head_op $1 | tail -n $tail_op | gawk '{print $3}' > $1.eval +head -n $head_op $1 | tail -n $tail_op | gawk '{print $4}' > $1.init_temp +head -n $head_op $1 | tail -n $tail_op | gawk '{print $5}' > $1.best_temp +head -n $head_op $1 | tail -n $tail_op | gawk '{print $6}' > $1.time +head -n $head_op $1 | tail -n $tail_op | gawk '{print $7}' > $1.total_time +echo $tail_op > $1.num_exec diff --git a/ProyectoFinal/AlgoritmoGenetico/malva/uml-comun.gif b/ProyectoFinal/AlgoritmoGenetico/malva/uml-comun.gif new file mode 100644 index 0000000000000000000000000000000000000000..e86a0eb3c9795f45438a28d1e81e8e0b6ec2b90b Binary files /dev/null and b/ProyectoFinal/AlgoritmoGenetico/malva/uml-comun.gif differ diff --git a/ProyectoFinal/CHC/malva/.Rhistory b/ProyectoFinal/CHC/malva/.Rhistory new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ProyectoFinal/CHC/malva/.cproject b/ProyectoFinal/CHC/malva/.cproject new file mode 100644 index 0000000000000000000000000000000000000000..4d31d90c5d30341f047854770a3b9d88675e97c9 --- /dev/null +++ b/ProyectoFinal/CHC/malva/.cproject @@ -0,0 +1,134 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<?fileVersion 4.0.0?> + +<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage"> + <storageModule moduleId="org.eclipse.cdt.core.settings"> + <cconfiguration id="cdt.managedbuild.toolchain.gnu.base.1028103499"> + <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.1028103499" moduleId="org.eclipse.cdt.core.settings" name="Default"> + <externalSettings/> + <extensions> + <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/> + <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + </extensions> + </storageModule> + <storageModule moduleId="cdtBuildSystem" version="4.0.0"> + <configuration artifactName="${ProjName}" buildProperties="" description="" id="cdt.managedbuild.toolchain.gnu.base.1028103499" name="Default" parent="org.eclipse.cdt.build.core.emptycfg"> + <folderInfo id="cdt.managedbuild.toolchain.gnu.base.1028103499.1127827476" name="/" resourcePath=""> + <toolChain id="cdt.managedbuild.toolchain.gnu.base.765753298" name="cdt.managedbuild.toolchain.gnu.base" superClass="cdt.managedbuild.toolchain.gnu.base"> + <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.1817766457" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/> + <builder id="cdt.managedbuild.target.gnu.builder.base.1493464269" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.base"/> + <tool id="cdt.managedbuild.tool.gnu.archiver.base.1457471918" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.1006777203" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base"> + <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.224865571" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/> + </tool> + <tool id="cdt.managedbuild.tool.gnu.c.compiler.base.2140176745" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base"> + <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.587099952" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> + </tool> + <tool id="cdt.managedbuild.tool.gnu.c.linker.base.1988570852" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/> + <tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.1956065400" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base"> + <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.507618374" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input"> + <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> + <additionalInput kind="additionalinput" paths="$(LIBS)"/> + </inputType> + </tool> + <tool id="cdt.managedbuild.tool.gnu.assembler.base.535458070" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base"> + <inputType id="cdt.managedbuild.tool.gnu.assembler.input.584095528" superClass="cdt.managedbuild.tool.gnu.assembler.input"/> + </tool> + </toolChain> + </folderInfo> + </configuration> + </storageModule> + <storageModule moduleId="scannerConfiguration"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + <profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="makefileGenerator"> + <runAction arguments="-E -P -v -dD" command="" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + <profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC"> + <buildOutputProvider> + <openAction enabled="true" filePath=""/> + <parser enabled="true"/> + </buildOutputProvider> + <scannerInfoProvider id="specsFile"> + <runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/> + <parser enabled="true"/> + </scannerInfoProvider> + </profile> + </storageModule> + <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> + </cconfiguration> + </storageModule> + <storageModule moduleId="cdtBuildSystem" version="4.0.0"> + <project id="malva.null.2024921052" name="malva"/> + </storageModule> +</cproject> diff --git a/ProyectoFinal/CHC/malva/.gitignore b/ProyectoFinal/CHC/malva/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..42fcba11cdc125b4add7382cc45c372d7f5839b3 --- /dev/null +++ b/ProyectoFinal/CHC/malva/.gitignore @@ -0,0 +1,6 @@ +.cproject/ +.project/ +.svn/ +.idea/ +.DS_Store + diff --git a/ProyectoFinal/CHC/malva/.project b/ProyectoFinal/CHC/malva/.project new file mode 100644 index 0000000000000000000000000000000000000000..1bb914cafb7eb471ef782c892e428d4d182ddae0 --- /dev/null +++ b/ProyectoFinal/CHC/malva/.project @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>Malva</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name> + <triggers>clean,full,incremental,</triggers> + <arguments> + <dictionary> + <key>?name?</key> + <value></value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.append_environment</key> + <value>true</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.autoBuildTarget</key> + <value>all</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.buildArguments</key> + <value></value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.buildCommand</key> + <value>make</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.cleanBuildTarget</key> + <value>clean</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.contents</key> + <value>org.eclipse.cdt.make.core.activeConfigSettings</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.enableAutoBuild</key> + <value>false</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.enableCleanBuild</key> + <value>true</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.enableFullBuild</key> + <value>true</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.fullBuildTarget</key> + <value>all</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.stopOnError</key> + <value>true</value> + </dictionary> + <dictionary> + <key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key> + <value>true</value> + </dictionary> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name> + <triggers>full,incremental,</triggers> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.cdt.core.cnature</nature> + <nature>org.eclipse.cdt.core.ccnature</nature> + <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature> + <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature> + </natures> +</projectDescription> diff --git a/ProyectoFinal/CHC/malva/Makefile b/ProyectoFinal/CHC/malva/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..a662e76dd1a29fb21d5ef629333e0e5bd4e4c2cf --- /dev/null +++ b/ProyectoFinal/CHC/malva/Makefile @@ -0,0 +1,24 @@ +default: + @echo "Make what? (all, libs, skeletons, clean)" + +all: + (cd inc ; rm -f Mallba) + (cd inc ; ./inc.env) + (cd src ; make all) + (cd lib ; make all) + (cd rep ; make all) + +libs: + (cd inc ; rm -f Mallba) + (cd inc ; ./inc.env) + (cd src ; make all) + (cd lib ; make all) + +skeletons: + (cd rep ; make all) + +clean: + (cd inc ; rm -f Mallba) + (cd src ; make clean) + (cd lib ; make clean) + (cd rep ; make clean) diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/ATSP-instances/br17.atsp b/ProyectoFinal/CHC/malva/ProblemInstances/ATSP-instances/br17.atsp new file mode 100644 index 0000000000000000000000000000000000000000..37313b1fe39b7e174543156a59dabac8cb897506 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/ATSP-instances/br17.atsp @@ -0,0 +1,42 @@ +NAME: br17 +TYPE: ATSP +COMMENT: 17 city problem (Repetto) +DIMENSION: 17 +EDGE_WEIGHT_TYPE: EXPLICIT +EDGE_WEIGHT_FORMAT: FULL_MATRIX +EDGE_WEIGHT_SECTION + 9999 3 5 48 48 8 8 5 5 3 3 0 3 5 8 8 + 5 + 3 9999 3 48 48 8 8 5 5 0 0 3 0 3 8 8 + 5 + 5 3 9999 72 72 48 48 24 24 3 3 5 3 0 48 48 + 24 + 48 48 74 9999 0 6 6 12 12 48 48 48 48 74 6 6 + 12 + 48 48 74 0 9999 6 6 12 12 48 48 48 48 74 6 6 + 12 + 8 8 50 6 6 9999 0 8 8 8 8 8 8 50 0 0 + 8 + 8 8 50 6 6 0 9999 8 8 8 8 8 8 50 0 0 + 8 + 5 5 26 12 12 8 8 9999 0 5 5 5 5 26 8 8 + 0 + 5 5 26 12 12 8 8 0 9999 5 5 5 5 26 8 8 + 0 + 3 0 3 48 48 8 8 5 5 9999 0 3 0 3 8 8 + 5 + 3 0 3 48 48 8 8 5 5 0 9999 3 0 3 8 8 + 5 + 0 3 5 48 48 8 8 5 5 3 3 9999 3 5 8 8 + 5 + 3 0 3 48 48 8 8 5 5 0 0 3 9999 3 8 8 + 5 + 5 3 0 72 72 48 48 24 24 3 3 5 3 9999 48 48 + 24 + 8 8 50 6 6 0 0 8 8 8 8 8 8 50 9999 0 + 8 + 8 8 50 6 6 0 0 8 8 8 8 8 8 50 0 9999 + 8 + 5 5 26 12 12 8 8 0 0 5 5 5 5 26 8 8 + 9999 +EOF diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/ATSP-instances/ft53.atsp b/ProyectoFinal/CHC/malva/ProblemInstances/ATSP-instances/ft53.atsp new file mode 100644 index 0000000000000000000000000000000000000000..3f81c5bc3c7f5029423cd185473ac26a641fb5d0 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/ATSP-instances/ft53.atsp @@ -0,0 +1,220 @@ +NAME: ft53 +TYPE: ATSP +COMMENT: Asymmetric TSP (Fischetti) +DIMENSION: 53 +EDGE_WEIGHT_TYPE: EXPLICIT +EDGE_WEIGHT_FORMAT: FULL_MATRIX +EDGE_WEIGHT_SECTION + 9999999 223 210 125 245 363 322 388 290 341 267 281 258 247 302 + 325 311 276 392 475 417 324 372 437 610 310 362 333 498 459 + 467 352 199 336 305 172 143 273 292 364 262 296 435 423 433 + 354 509 472 238 185 357 420 344 + 58 9999999 179 100 287 155 116 170 74 137 239 260 234 221 282 + 294 286 251 434 512 409 367 406 410 598 354 353 371 451 490 + 510 389 244 313 291 210 185 318 329 402 297 81 241 215 292 + 308 301 262 207 159 300 214 314 + 60 109 9999999 80 295 246 209 270 174 225 227 179 221 212 262 + 131 117 79 382 431 263 309 321 235 452 355 338 324 497 449 + 360 243 251 140 272 223 189 259 337 388 308 174 340 309 382 + 396 393 355 198 141 201 302 190 + 58 115 98 9999999 285 255 215 279 178 232 154 176 157 136 194 + 219 207 170 429 516 326 366 411 323 517 344 270 368 541 498 + 446 323 244 225 203 214 183 314 278 403 301 183 352 311 391 + 341 410 367 130 76 247 312 236 + 93 58 63 90 9999999 194 160 210 117 174 238 235 231 224 280 + 175 171 133 281 267 221 248 139 286 415 82 136 135 309 264 + 341 293 231 189 75 253 219 306 360 351 340 123 277 248 288 + 323 305 256 155 155 152 248 146 + 531 593 584 499 765 9999999 344 405 309 360 631 654 632 622 679 + 697 685 647 909 992 807 847 887 809 999 789 750 848 763 716 + 763 643 724 539 682 687 664 788 762 881 781 669 832 796 824 + 825 885 838 90 140 164 70 296 + 417 484 469 384 651 55 9999999 257 190 180 519 547 524 506 563 + 586 573 533 803 875 693 733 777 692 888 607 577 662 585 539 + 575 454 611 361 561 581 543 682 645 769 666 546 577 565 493 + 662 653 700 123 177 201 112 343 + 466 521 506 427 693 86 111 9999999 236 275 566 585 505 546 552 + 621 618 574 804 863 594 495 733 735 790 695 673 660 675 627 + 674 556 654 453 615 614 587 685 634 715 707 591 673 659 589 + 690 749 771 154 209 228 147 371 + 243 309 285 205 468 92 54 111 9999999 69 342 366 345 326 385 + 406 391 350 619 705 510 552 599 511 707 501 451 558 472 425 + 471 346 432 253 394 393 373 500 468 588 491 369 532 501 535 + 534 591 549 160 210 233 147 376 + 262 321 302 222 491 81 68 99 32 9999999 359 386 357 340 400 + 424 409 371 639 714 536 569 611 528 728 448 415 504 424 376 + 412 296 450 196 407 419 386 521 488 605 503 389 554 521 554 + 550 614 568 151 204 228 137 359 + 361 416 404 317 435 522 512 544 471 449 9999999 194 179 327 228 + 441 438 392 480 560 357 401 554 557 549 502 453 418 596 544 + 655 532 383 455 396 352 319 359 313 475 437 352 453 467 453 + 373 527 531 78 135 308 392 291 + 182 241 229 134 411 376 341 402 302 314 114 9999999 195 184 246 + 304 288 258 499 583 376 420 494 411 568 395 315 433 612 564 + 511 413 364 311 250 333 305 375 322 493 425 306 469 435 466 + 385 531 481 180 202 333 425 319 + 271 305 315 224 271 354 341 374 301 283 110 105 9999999 164 60 + 276 263 233 313 400 186 241 395 389 387 336 283 255 424 378 + 486 361 220 290 224 179 154 197 138 308 273 182 290 308 285 + 203 363 362 179 231 311 399 293 + 216 277 259 176 281 209 199 227 155 140 35 54 24 9999999 77 + 132 125 79 331 411 204 253 329 246 400 225 147 265 443 397 + 346 239 229 140 80 193 163 211 157 322 288 200 296 320 295 + 215 374 380 94 148 163 255 151 + 275 338 327 242 344 300 293 331 256 241 122 119 99 111 9999999 + 230 220 181 400 479 144 197 371 340 337 327 242 204 384 334 + 446 347 295 238 176 265 235 275 223 262 352 140 303 270 346 + 286 363 315 189 242 261 352 252 + 369 329 451 411 404 405 367 422 324 378 345 393 514 539 561 + 9999999 329 297 264 313 405 312 528 446 596 407 358 316 380 448 + 557 432 286 353 460 163 226 141 278 276 244 379 425 443 412 + 335 494 538 86 146 89 188 75 + 246 305 286 204 416 353 317 374 276 331 181 75 266 252 307 + 24 9999999 310 275 324 158 207 225 136 356 337 270 221 398 348 + 471 348 204 368 315 177 238 151 288 279 260 143 307 267 356 + 351 362 316 99 160 103 199 94 + 278 343 325 243 450 390 353 417 315 367 215 115 301 293 349 + 65 48 9999999 308 365 195 243 261 175 388 381 292 260 430 392 + 292 170 237 79 358 217 274 193 327 318 294 184 346 312 394 + 384 405 355 138 192 141 228 127 + 118 85 249 161 356 148 113 176 78 128 250 149 299 284 345 + 70 86 44 9999999 90 226 277 293 204 425 180 241 241 162 363 + 330 210 271 109 355 227 245 198 337 344 306 146 307 275 359 + 379 368 327 146 202 154 216 140 + 134 93 266 176 364 172 137 191 90 153 255 155 317 301 363 + 93 81 62 31 9999999 227 276 291 207 418 102 160 162 82 291 + 341 227 279 118 370 242 261 216 351 351 322 169 325 294 374 + 392 390 338 157 203 151 225 142 + 306 367 350 263 371 212 171 229 139 186 238 142 322 312 365 + 412 417 378 356 371 9999999 64 239 275 207 196 121 84 252 204 + 558 432 285 370 375 226 223 227 248 138 265 351 377 413 389 + 304 409 368 285 285 330 268 310 + 376 460 449 354 466 305 266 323 227 282 336 230 416 408 462 + 448 448 424 389 372 115 9999999 250 262 307 291 225 171 350 306 + 600 483 332 468 472 322 322 327 342 231 361 429 383 426 401 + 407 415 372 356 306 421 370 410 + 136 225 336 245 369 292 264 314 221 277 328 231 387 368 428 + 221 210 191 160 145 101 122 9999999 251 300 235 212 168 211 299 + 472 353 318 248 239 296 266 314 333 230 351 199 149 187 173 + 203 182 141 121 72 239 339 236 + 223 307 374 280 399 233 198 252 158 213 256 160 343 332 388 + 303 298 273 247 226 36 87 96 9999999 233 217 147 100 270 227 + 350 236 84 331 328 242 246 253 264 165 288 280 238 269 255 + 291 268 217 207 156 332 293 320 + 183 267 381 290 407 296 267 319 223 276 329 226 411 402 460 + 256 251 230 200 185 103 92 61 81 9999999 270 219 173 254 297 + 420 302 153 288 278 316 303 319 339 226 352 241 195 232 208 + 245 226 181 171 117 289 363 272 + 598 658 641 559 823 621 644 551 718 780 695 718 695 682 739 + 689 678 707 946 998 734 782 890 806 924 9999999 71 72 244 195 + 729 609 789 715 750 756 721 819 819 857 838 727 689 726 716 + 744 718 675 315 368 321 407 309 + 536 605 586 502 765 567 585 494 669 719 635 657 639 627 680 + 630 622 652 887 942 766 819 831 748 960 105 9999999 158 334 284 + 811 700 726 709 690 692 660 762 768 882 780 666 779 803 799 + 827 813 768 399 460 404 499 396 + 581 646 628 543 812 611 638 542 710 767 687 701 682 673 724 + 675 664 698 925 982 675 727 871 789 866 135 61 9999999 184 141 + 669 547 771 651 722 737 713 809 808 801 833 682 637 677 650 + 688 665 620 257 312 259 348 246 + 620 677 670 581 853 647 655 579 624 677 717 620 716 702 761 + 718 701 734 835 853 498 547 725 763 696 36 99 98 9999999 218 + 500 375 773 479 775 618 711 711 734 621 714 751 713 752 733 + 768 743 701 86 138 91 182 80 + 586 647 632 545 821 614 634 547 663 716 692 668 681 674 735 + 681 672 698 880 896 547 598 773 791 741 85 67 138 63 9999999 + 546 429 780 522 736 662 714 763 778 669 757 715 762 800 781 + 815 796 752 132 184 135 224 119 + 500 712 702 613 737 847 812 871 776 829 756 770 747 737 792 + 812 803 764 879 958 908 814 861 925 1103 797 782 822 987 943 + 9999999 653 691 559 793 659 628 764 774 849 753 784 927 911 917 + 838 998 963 724 677 843 911 833 + 619 720 707 621 850 685 705 614 723 772 764 725 756 746 807 + 758 739 766 883 862 596 502 740 747 791 220 134 281 447 407 + 136 9999999 485 118 815 775 752 815 830 717 853 673 700 620 795 + 721 778 815 520 573 528 621 514 + 768 870 853 766 1000 831 853 762 872 923 905 870 910 892 956 + 904 893 916 1032 1015 742 648 884 901 936 369 279 431 598 551 + 285 166 9999999 262 964 931 898 966 983 866 1000 819 854 775 946 + 870 926 964 669 725 676 766 664 + 722 816 801 722 951 786 805 710 820 873 860 820 859 848 901 + 858 847 875 978 959 702 600 837 852 894 322 232 376 554 510 + 235 119 381 9999999 915 879 852 912 931 825 950 773 797 722 902 + 821 871 923 625 678 621 712 611 + 730 693 861 768 883 538 493 738 678 664 619 759 779 894 825 + 678 689 652 619 706 838 784 898 818 1026 520 435 582 752 705 + 274 316 169 394 9999999 642 698 617 755 754 722 756 896 889 889 + 815 974 932 95 144 99 188 84 + 341 300 311 337 257 375 338 399 305 361 254 374 427 467 474 + 297 306 267 237 315 264 163 384 416 462 291 215 178 349 302 + 461 345 194 332 324 9999999 135 116 137 210 109 238 275 296 272 + 199 358 396 124 73 243 335 231 + 371 325 341 374 292 403 360 425 331 382 139 312 308 451 352 + 323 335 303 266 345 297 195 413 442 485 315 246 204 373 333 + 341 222 81 329 351 48 9999999 142 158 231 133 260 307 322 301 + 226 386 423 152 102 271 366 264 + 247 200 330 286 276 274 236 300 203 257 218 273 383 410 434 + 192 207 168 139 218 282 179 395 324 472 303 231 185 280 321 + 428 309 157 230 334 40 93 9999999 154 158 120 254 293 311 291 + 216 367 408 148 98 269 337 261 + 225 179 195 223 140 320 280 337 249 301 147 321 321 346 367 + 250 264 221 188 268 301 214 265 382 499 203 265 214 337 345 + 361 241 88 277 202 61 23 67 9999999 207 147 117 157 174 152 + 76 238 271 168 116 279 371 268 + 331 288 305 330 253 178 139 379 292 304 221 360 395 459 433 + 289 301 261 227 311 304 206 374 415 491 311 255 215 370 335 + 433 315 166 317 315 96 98 110 125 9999999 144 225 267 285 265 + 188 341 383 215 162 329 241 317 + 250 214 223 255 174 287 245 305 209 262 165 283 335 373 385 + 211 218 177 152 226 170 79 297 331 365 204 132 85 260 207 + 373 256 109 243 234 54 47 26 48 118 9999999 143 188 205 181 + 108 260 306 167 116 279 341 271 + 529 587 576 488 738 428 456 355 574 613 548 618 623 605 669 + 593 602 569 537 613 494 548 561 477 693 403 454 461 380 590 + 556 594 445 628 289 509 566 476 613 616 586 9999999 172 144 227 + 241 232 189 257 204 370 466 358 + 412 441 461 373 592 269 287 194 421 448 495 512 509 497 556 + 437 447 406 373 454 427 480 490 410 628 339 400 398 322 530 + 496 532 381 464 229 360 418 335 464 470 436 61 9999999 107 158 + 135 84 131 212 168 309 323 297 + 393 453 440 353 622 347 370 272 497 527 498 519 495 478 544 + 516 527 488 452 537 459 515 520 442 659 426 478 475 399 606 + 528 560 413 547 261 433 497 410 551 553 515 67 94 9999999 190 + 115 163 211 128 74 245 338 239 + 464 520 508 421 648 353 370 275 401 464 505 407 558 546 605 + 520 533 489 457 478 282 334 346 262 483 425 398 353 401 479 + 343 387 234 464 86 447 497 415 518 408 528 65 98 76 9999999 + 181 170 221 161 147 167 260 152 + 296 360 344 258 527 348 375 276 427 477 394 415 398 385 440 + 462 449 406 459 534 360 410 430 338 552 422 475 426 398 551 + 426 463 315 465 162 442 423 422 526 491 523 50 94 112 94 + 9999999 173 213 226 178 240 330 232 + 339 403 387 301 524 359 387 286 443 495 435 462 436 426 479 + 443 453 409 377 457 354 412 422 331 554 387 443 420 364 546 + 423 456 310 473 160 283 338 264 394 397 369 31 110 29 88 + 58 9999999 184 144 97 240 329 221 + 364 426 411 320 564 276 299 211 425 461 379 445 465 453 511 + 448 460 423 386 469 314 364 378 295 510 220 278 282 203 410 + 383 414 272 478 113 327 383 306 434 443 406 76 26 67 47 + 86 61 9999999 177 134 193 294 184 + 1551 1527 1596 1509 1784 1572 1562 1504 1522 1513 1653 1593 1650 1634 1695 + 1512 1530 1489 1455 1532 1512 1560 1549 1582 1505 1050 1026 1104 1028 978 + 1419 1297 1562 1197 1678 1635 1678 1643 1747 1637 1717 1578 1617 1634 1614 + 1534 1693 1672 9999999 73 233 330 224 + 1599 1569 1649 1566 1834 1527 1515 1543 1478 1463 1706 1641 1621 1687 1673 + 1571 1578 1543 1504 1585 1548 1530 1496 1520 1458 1102 1078 1154 1079 1027 + 1360 1248 1506 1144 1628 1682 1727 1689 1754 1666 1775 1517 1568 1582 1557 + 1486 1638 1621 60 9999999 188 274 169 + 1504 1464 1629 1541 1713 1598 1564 1542 1528 1543 1552 1549 1454 1603 1497 + 1550 1557 1526 1490 1566 1539 1566 1579 1609 1534 1080 1062 1144 1060 1010 + 1192 1071 1343 977 1621 1627 1593 1632 1577 1663 1715 1514 1553 1578 1548 + 1477 1627 1670 44 100 9999999 272 159 + 1505 1534 1545 1464 1705 1550 1572 1487 1533 1523 1607 1601 1548 1586 1590 + 1532 1543 1503 1470 1547 1519 1573 1563 1549 1517 1057 1045 1120 1040 993 + 1280 1168 1432 1060 1366 1462 1581 1563 1584 1648 1551 1255 1302 1319 1298 + 1224 1380 1412 24 79 106 9999999 240 + 1520 1472 1612 1526 1722 1589 1574 1517 1528 1520 1559 1558 1466 1616 1513 + 1530 1536 1501 1466 1544 1517 1573 1562 1593 1518 1056 1044 1116 1036 992 + 1206 1088 1352 986 1469 1571 1607 1642 1595 1643 1658 1362 1411 1429 1401 + 1325 1479 1516 21 80 29 118 9999999 +EOF diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/ATSP-instances/ft70.atsp b/ProyectoFinal/CHC/malva/ProblemInstances/ATSP-instances/ft70.atsp new file mode 100644 index 0000000000000000000000000000000000000000..75cacb6f328537a583263bfb878737db59505a68 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/ATSP-instances/ft70.atsp @@ -0,0 +1,358 @@ +NAME: ft70 +TYPE: ATSP +COMMENT: Asymmetric TSP (Fischetti) +DIMENSION: 70 +EDGE_WEIGHT_TYPE: EXPLICIT +EDGE_WEIGHT_FORMAT: FULL_MATRIX +EDGE_WEIGHT_SECTION + 9999999 375 1000 1011 853 950 936 1027 1101 1235 1279 1109 1141 976 1389 + 858 1368 1110 1263 1435 1091 936 1047 962 1079 1083 826 926 1004 1203 + 1037 1105 1229 986 1227 1096 1235 973 753 1165 1518 1064 1285 1149 1312 + 914 1161 1349 1418 1515 1170 966 1112 1049 1064 912 901 1040 1086 1177 + 1118 1239 1103 1203 1094 1237 1143 1195 1293 1229 + 609 9999999 1068 980 1029 976 1068 1144 1100 1342 1262 1097 1304 1217 1494 + 960 1214 1233 1040 1175 1122 1237 1133 1031 1192 1004 1005 1087 1119 1109 + 1019 1087 1248 1257 1196 1061 1284 1142 951 1117 1329 1320 1284 1340 1282 + 934 1207 1200 1559 1717 1190 1168 1213 1144 1196 1317 1112 1048 1259 1008 + 871 1326 1455 977 1139 1335 974 1352 1468 1057 + 669 419 9999999 888 528 955 989 989 794 1185 1055 987 933 1009 1022 + 709 1124 1137 1203 1048 984 845 657 600 880 998 874 739 603 1042 + 939 1024 986 813 1136 872 963 1013 710 801 1189 1126 977 1102 1069 + 683 1102 1253 1316 1373 978 1046 881 998 1001 948 751 982 1092 881 + 829 1335 1082 1071 1053 941 889 1100 1164 970 + 665 645 664 9999999 559 491 528 592 505 769 680 576 793 724 996 + 796 898 755 525 1002 639 629 676 635 694 854 562 543 524 790 + 495 632 968 715 923 665 809 811 496 794 1031 759 714 829 764 + 609 504 1040 903 986 544 703 543 942 814 712 794 546 741 737 + 430 926 1047 660 686 558 632 944 808 890 + 632 606 506 676 9999999 659 742 781 582 926 778 865 868 620 798 + 499 996 787 883 792 858 615 438 483 671 523 527 557 562 661 + 544 609 871 587 837 541 787 571 558 594 1038 910 761 873 765 + 648 651 970 1026 1307 811 669 749 621 548 748 649 697 923 652 + 707 879 968 617 879 706 773 1035 944 863 + 712 373 621 441 416 9999999 441 666 565 524 541 507 803 574 680 + 613 739 875 860 1018 699 697 576 691 801 761 606 511 597 805 + 619 790 808 798 965 654 698 636 676 842 986 886 910 690 897 + 464 556 1062 1178 1097 697 830 869 627 821 661 784 848 868 562 + 623 927 823 544 475 852 674 803 814 786 + 412 702 566 534 473 744 9999999 623 690 765 770 526 699 752 986 + 492 577 596 733 746 598 672 681 715 676 762 608 590 522 782 + 694 769 976 723 700 704 923 692 467 751 964 813 806 818 538 + 485 700 865 996 1234 548 645 766 800 759 606 786 681 651 549 + 482 901 792 702 544 726 456 902 925 827 + 826 666 682 535 668 660 705 9999999 688 861 755 706 766 495 693 + 913 1001 768 727 1046 724 894 748 927 1051 816 863 743 654 822 + 872 952 1094 786 839 968 1126 1039 662 789 1152 1080 798 884 852 + 986 622 1202 1255 1072 813 980 841 984 929 872 868 893 810 876 + 791 1090 1030 708 822 879 577 1058 896 1107 + 874 915 804 786 736 873 725 491 9999999 729 749 578 641 757 747 + 942 943 1023 937 1170 746 1066 943 808 943 893 1064 909 1005 1095 + 803 1046 1041 1079 933 958 1078 1100 820 845 1225 975 971 755 1020 + 956 690 1241 1129 939 820 922 981 1105 961 1136 922 905 956 1001 + 785 1087 1012 905 839 921 753 913 755 981 + 806 919 992 826 940 683 913 470 456 9999999 728 555 653 586 802 + 962 896 1137 811 950 972 1005 797 934 1070 975 857 887 791 1055 + 852 946 1049 983 1037 1094 1111 1122 807 1019 1342 1160 883 814 1119 + 870 932 1124 1364 910 782 1104 1072 1063 938 929 939 926 1084 831 + 864 1151 1137 618 757 828 481 786 740 980 + 773 960 1030 780 702 970 966 697 559 472 9999999 803 609 743 612 + 1100 974 970 970 1162 825 989 910 954 1156 1107 974 1092 1059 908 + 944 1118 1050 1023 1062 975 1172 1154 833 988 1312 1045 1154 592 1182 + 879 815 1097 1368 1193 1001 1106 1003 1026 1130 1007 967 1085 973 922 + 1006 1271 1285 505 737 875 689 1027 842 1123 + 805 663 762 640 787 632 870 475 381 585 501 9999999 628 577 806 + 846 909 1021 880 1087 1009 934 1024 932 905 990 1032 994 847 1121 + 830 911 1138 1018 1134 745 854 851 740 818 965 740 868 514 883 + 968 735 1046 1307 948 694 847 1014 1023 1016 949 1047 882 1138 744 + 844 1307 1154 657 721 856 664 927 730 954 + 910 777 916 662 851 937 745 695 527 528 402 533 9999999 909 669 + 911 1044 1129 938 1099 873 1187 888 956 1193 1126 1172 1026 800 979 + 1119 1041 1235 1154 1195 981 1185 1111 858 1143 1435 1001 1012 833 1205 + 1129 1027 1087 1332 1057 968 1110 849 1089 1207 1026 1111 993 902 1075 + 893 1112 1073 474 624 684 773 1074 750 1060 + 1058 766 1030 850 962 822 865 655 471 625 580 655 608 9999999 703 + 975 1238 1063 991 1213 885 987 1023 942 1137 956 889 923 935 1214 + 1023 1063 1339 983 1046 1040 1025 1180 956 932 1412 906 1006 853 1155 + 871 836 1155 1480 1172 1011 1157 1050 1274 1125 975 950 1092 1001 858 + 795 1295 1039 615 856 948 721 886 799 1149 + 935 773 823 884 766 684 735 663 571 613 479 685 682 643 9999999 + 901 1005 902 877 1117 842 878 963 1038 1156 914 984 1052 999 1176 + 963 1175 1245 942 1114 997 1091 1096 802 990 1247 1022 876 799 949 + 948 890 1137 1274 912 759 898 1094 1040 1175 969 1116 1076 1045 808 + 837 1244 1071 398 656 762 757 998 786 1207 + 647 593 614 715 510 570 622 492 696 670 681 532 710 716 1007 + 9999999 1025 786 989 812 936 662 825 588 842 916 765 563 573 985 + 908 794 825 759 1062 882 1084 794 743 918 1318 931 1050 611 913 + 809 582 742 1357 1068 731 839 816 718 828 975 707 743 830 869 + 897 1194 1054 918 832 723 785 942 910 985 + 675 703 683 693 611 725 910 776 662 870 943 557 856 907 878 + 375 9999999 699 582 560 728 970 601 719 799 831 843 696 625 848 + 718 681 907 695 1005 688 946 811 699 969 1136 716 788 958 656 + 802 709 627 1002 1098 690 559 685 752 689 784 926 790 864 776 + 936 1195 1008 699 845 833 687 940 972 688 + 852 654 736 652 626 608 767 795 635 851 827 876 673 663 692 + 567 555 9999999 760 648 682 734 458 790 645 480 679 676 665 805 + 767 812 845 861 1080 723 838 713 675 777 1154 830 628 974 706 + 608 855 783 976 1245 920 684 781 727 678 600 809 806 817 766 + 871 1144 1058 616 862 762 836 1124 979 729 + 676 602 822 793 723 660 862 636 719 828 885 742 942 880 967 + 492 606 587 9999999 551 710 955 743 877 672 582 785 746 707 821 + 477 502 898 734 958 782 853 577 621 666 1088 883 770 921 868 + 973 877 626 1113 1233 654 709 888 781 941 740 1006 685 675 864 + 902 926 677 808 800 874 931 991 1050 781 + 820 868 737 766 816 800 744 861 631 819 966 775 1015 755 855 + 709 774 617 494 9999999 854 677 563 725 799 482 799 770 742 816 + 506 755 866 710 997 639 856 556 800 771 879 492 692 931 626 + 779 553 526 1047 1112 528 455 754 744 755 483 843 527 636 725 + 836 837 800 932 917 650 831 1038 864 836 + 844 767 714 878 815 561 758 717 752 704 821 642 944 600 808 + 651 662 398 377 793 9999999 780 726 868 582 686 768 937 914 680 + 628 688 762 749 931 745 890 786 747 555 902 872 694 975 763 + 699 816 756 1192 1166 912 868 809 929 994 917 819 654 871 691 + 921 906 796 568 558 711 688 1092 990 912 + 894 676 988 739 891 721 818 957 878 880 788 849 981 721 828 + 806 1065 982 793 913 824 9999999 797 747 545 706 498 582 690 912 + 904 985 972 680 969 620 937 763 775 755 1315 1000 787 988 1119 + 645 770 1092 1354 1337 784 713 829 888 704 664 712 824 932 872 + 707 1022 922 611 867 553 749 1007 773 932 + 721 892 856 716 760 758 739 640 635 787 908 803 876 716 717 + 727 1099 1018 1015 1038 798 492 9999999 574 651 395 666 707 827 927 + 674 995 1005 811 870 544 932 926 914 738 1173 918 984 1028 1123 + 885 685 1145 1252 1354 954 954 765 748 755 742 738 895 836 869 + 975 1179 961 644 737 691 666 1073 743 1067 + 811 753 647 617 776 593 724 835 588 768 645 641 601 745 927 + 434 997 749 658 990 798 550 777 9999999 632 594 483 744 646 644 + 519 609 787 674 909 646 758 609 701 740 1067 657 780 852 788 + 773 612 1035 1194 1225 586 644 514 633 625 505 581 728 848 725 + 917 771 644 536 707 754 640 793 848 876 + 678 604 575 573 490 579 453 828 776 847 727 786 622 630 925 + 672 757 817 646 794 700 630 627 515 9999999 652 611 486 514 598 + 468 775 798 501 727 793 827 811 726 802 1006 692 697 696 943 + 586 675 922 1063 1286 579 707 717 737 682 559 456 710 923 515 + 621 894 792 556 683 409 512 751 647 847 + 731 732 725 489 589 589 680 626 799 712 803 556 656 438 737 + 666 872 817 972 1107 711 656 552 602 514 9999999 765 697 666 670 + 595 745 834 849 855 432 1002 871 869 682 1258 747 712 946 993 + 563 846 1123 1189 1187 835 860 688 846 856 780 678 809 878 712 + 871 1082 1030 756 798 668 589 839 642 790 + 772 738 682 764 816 664 570 905 717 697 860 848 948 547 1005 + 756 991 1006 723 900 799 666 656 646 624 610 9999999 775 651 764 + 687 734 833 626 1018 519 1110 936 871 695 1008 913 950 969 1059 + 776 615 1105 1347 1195 622 733 632 741 717 581 724 762 772 788 + 764 948 879 738 841 774 827 1001 663 938 + 910 887 809 662 731 716 593 859 803 630 677 712 760 547 708 + 628 1054 891 742 867 856 515 331 512 470 531 496 9999999 669 660 + 795 662 777 783 801 656 996 716 750 724 1176 908 752 872 770 + 600 712 882 1081 1311 616 698 615 799 760 764 676 643 640 545 + 858 1006 901 542 685 582 663 1021 936 702 + 908 545 674 582 724 560 725 639 563 628 676 630 602 733 902 + 440 949 750 837 902 801 497 619 561 750 630 492 616 9999999 804 + 476 746 844 730 781 512 864 683 834 623 1008 800 712 703 822 + 452 805 986 977 1197 633 616 575 690 463 555 588 608 675 596 + 978 1029 696 670 782 846 884 838 730 616 + 1085 780 885 770 888 874 926 884 638 611 717 693 577 669 766 + 852 1054 1168 1098 1000 1039 613 663 612 673 748 758 622 712 9999999 + 787 986 879 775 928 787 1129 823 987 775 1338 1010 997 845 862 + 892 916 1174 1191 1161 879 720 973 841 680 698 888 907 801 827 + 998 998 986 519 624 615 780 628 575 596 + 878 696 874 663 770 717 884 655 731 732 732 902 803 960 869 + 500 778 784 861 857 792 885 630 762 761 613 752 690 885 590 + 9999999 838 742 805 716 519 574 406 632 501 925 509 627 924 671 + 716 547 874 1240 1251 516 662 700 809 812 852 788 1006 882 842 + 881 1154 849 557 899 756 683 906 745 646 + 813 784 877 869 876 781 1000 859 706 634 754 805 707 746 843 + 553 822 959 704 833 949 938 822 920 966 816 808 793 784 648 + 370 9999999 670 692 782 511 626 580 693 589 991 506 698 870 649 + 842 557 1083 945 1276 576 587 698 957 904 1055 972 744 529 728 + 644 854 526 676 903 695 669 858 668 701 + 651 673 934 789 845 801 764 715 548 747 612 704 451 772 786 + 642 1139 871 941 960 797 811 566 708 687 632 597 458 945 437 + 530 661 9999999 633 664 617 743 643 636 596 960 572 791 635 543 + 830 621 957 801 1228 802 802 874 825 886 944 873 728 593 677 + 976 922 664 742 608 676 755 600 693 421 + 929 854 813 724 841 643 752 877 605 730 710 834 647 690 1005 + 492 1060 804 895 938 718 972 667 849 704 740 877 645 746 514 + 475 423 475 9999999 589 543 730 578 609 667 978 586 662 795 697 + 778 750 982 886 1100 759 535 802 813 871 921 1022 809 605 602 + 707 873 678 732 903 753 683 683 656 671 + 755 447 1127 804 1000 723 994 736 822 832 875 733 776 786 766 + 778 957 916 992 1118 932 801 826 680 994 749 756 787 999 623 + 636 564 458 684 9999999 824 757 611 868 726 1103 815 615 992 711 + 845 768 1137 853 1159 891 792 862 842 834 895 875 962 788 602 + 850 810 801 778 879 898 664 874 878 686 + 1858 1976 1887 1686 1781 1843 1899 1634 1777 1688 1743 1598 1732 1402 1622 + 1612 2196 2109 2183 2035 1905 2180 1912 1921 1990 2028 2069 1981 1926 1987 + 2098 2050 1948 2016 1931 9999999 1262 1205 1130 1200 1605 1232 1167 1689 1926 + 2031 1923 2276 2160 2197 1858 1820 1924 1965 1932 1846 2129 1716 1877 1731 + 1769 2022 2157 1179 1230 1366 1386 1452 1320 1302 + 1023 1198 1259 1228 1416 1113 1340 1334 1089 1213 1244 1135 1397 914 1167 + 1038 1399 1487 1368 1555 1444 1164 1179 1341 1207 1362 1318 1267 1166 1195 + 1360 1142 1318 1300 1313 642 9999999 570 692 492 845 626 451 1350 1235 + 1232 1202 1404 1647 1647 1182 1040 1242 1281 1253 1205 1376 1280 1191 1120 + 1173 1432 1339 727 734 847 820 822 718 557 + 1203 1180 1235 1260 1198 1296 1196 1297 1266 1350 1316 1346 1498 1353 1361 + 1120 1501 1386 1508 1532 1483 1369 1348 1271 1430 1305 1405 1210 1393 1494 + 1353 1596 1381 1423 1319 742 864 9999999 786 711 1009 841 876 1334 1284 + 1408 1321 1587 1572 1730 1453 1323 1424 1514 1339 1376 1518 1095 1103 1095 + 947 1540 1562 515 819 601 716 649 648 526 + 1137 1280 1415 1140 1466 1182 1287 1125 1146 1204 1134 1012 1215 788 1310 + 1290 1483 1543 1527 1605 1548 1426 1418 1461 1494 1605 1516 1484 1438 1644 + 1347 1455 1452 1311 1481 530 787 731 9999999 558 1148 886 719 1126 1300 + 1458 1332 1705 1571 1622 1521 1289 1388 1339 1421 1326 1425 1185 1349 1149 + 1148 1646 1506 874 974 697 789 812 965 653 + 1044 962 1287 1247 1101 1285 1134 1081 1249 1282 1241 1225 1197 1129 1382 + 1128 1326 1264 1422 1308 1409 1197 1215 1096 1038 1190 1330 1210 1147 1424 + 1229 1126 1325 1315 1466 650 702 332 576 9999999 712 403 448 1354 1125 + 1256 1268 1409 1514 1535 1239 1018 1029 1219 1127 1140 1347 1217 1202 1277 + 944 1469 1354 614 648 572 675 754 838 514 + 1071 1028 1447 1400 1224 1301 1366 1154 1187 1060 1056 1278 1224 1152 1141 + 1110 1471 1481 1432 1546 1213 1158 1123 1050 1148 1047 1159 1127 1214 959 + 1067 1112 925 1170 1050 671 548 682 583 547 9999999 747 650 1060 861 + 708 1233 1670 1196 1380 1110 1214 1230 1144 1313 1159 1207 1138 1069 1158 + 1045 1409 1022 645 951 700 897 718 810 751 + 1050 882 1342 1161 1325 1217 1275 1168 1197 1192 1178 1299 1322 1062 1302 + 1131 1501 1478 1236 1330 1422 1063 1244 931 954 1228 1073 1092 1210 1338 + 1333 1161 1191 1241 1280 811 515 464 601 721 673 9999999 580 1322 1111 + 1156 1295 1583 1473 1836 1096 1289 1372 1242 1128 1113 1277 1091 1258 1215 + 928 1601 1381 553 604 827 763 752 607 602 + 1118 1166 1415 1307 1108 1232 1357 1272 1258 1393 1412 1346 1249 1158 1211 + 1082 1498 1420 1245 1451 1139 1208 1146 1007 965 1377 1144 1251 1092 1159 + 1167 1169 1378 1072 1209 569 648 652 700 699 722 349 9999999 1288 1274 + 1108 1056 1375 1471 1755 1239 1157 1095 1104 1176 1096 1378 1110 1231 1050 + 1253 1566 1279 684 600 690 753 896 824 490 + 1120 1026 1104 1029 1039 1144 875 1148 1176 1140 1117 944 1065 1279 1132 + 1079 1329 1250 1270 1470 1094 1095 973 1079 1243 1148 1235 988 1039 807 + 953 912 1069 1152 879 989 1326 1181 1080 1152 1508 1097 1254 9999999 1029 + 1282 967 1259 1103 762 1172 1106 1289 1155 1229 1137 1257 1157 1211 1087 + 1035 1381 1100 713 582 646 679 705 638 814 + 1369 1236 1472 1205 1340 1223 1195 1303 1266 1524 1284 1353 1294 1243 1534 + 1132 1252 1399 1376 1400 1504 1185 1081 1080 1336 1235 1127 965 1366 1145 + 1379 1342 1244 1257 1159 1023 1543 1256 1457 1439 1619 1341 1464 765 9999999 + 1251 937 1100 770 937 1185 1213 1297 1468 1344 1258 1387 1377 1352 1221 + 1439 1551 1341 783 794 837 971 896 818 1223 + 1562 1364 1372 1207 1311 1293 1237 1450 1295 1368 1284 1359 1349 1471 1459 + 1602 1502 1487 1531 1802 1496 1493 1363 1448 1562 1356 1530 1300 1568 1290 + 1311 1225 1346 1614 1272 1113 1509 1429 1372 1459 1608 1528 1451 821 1126 + 9999999 1261 1616 1183 1039 1341 1539 1586 1500 1561 1585 1420 1221 1005 1231 + 1323 1135 1045 883 937 1058 981 1022 842 1098 + 1663 1689 1725 1516 1698 1648 1597 1522 1702 1575 1471 1725 1775 1839 1556 + 1778 1900 1901 1845 1982 1753 1932 1593 1793 1768 1808 1694 1732 1700 1705 + 1616 1638 1589 1964 1692 1593 1727 1624 1691 1833 1787 1547 1663 935 1285 + 639 9999999 1559 1194 1452 1645 1659 1879 1792 1793 1757 1775 1413 1283 1377 + 1409 1456 1211 1301 1260 1246 1203 1182 1215 1502 + 1207 1142 1416 1333 1350 1096 1469 1331 1341 1332 1410 1418 1320 1257 1638 + 1404 1293 1419 1272 1332 1318 1518 1288 1272 1403 1328 1482 1452 1402 1086 + 1186 1338 1364 978 1246 1238 1384 1239 1298 1172 1521 1398 1248 967 1429 + 1175 1042 9999999 1055 1124 1039 1181 1235 1126 1238 971 1373 1390 1259 1411 + 1277 1448 1192 1210 1120 1181 1138 1335 1176 1215 + 1080 1222 1165 1152 1249 1021 974 1077 1082 1231 1338 1172 1072 1394 1483 + 1154 915 1295 1308 1203 1272 1143 1187 1058 1309 1164 1058 1304 1248 1046 + 1127 1034 1160 1227 1127 931 1474 1106 1127 1234 1597 1225 1238 398 1065 + 906 791 1011 9999999 841 1112 1254 1240 1325 1411 1294 1387 1147 1209 1187 + 1076 1350 1169 829 685 838 634 827 601 1021 + 1220 1228 1212 1160 1249 1025 1072 943 843 1070 913 1120 1022 1014 857 + 1410 1417 1291 1131 1561 1193 1271 1241 1199 1450 1411 1352 1226 1209 986 + 1194 1152 1041 1327 1072 550 1437 1123 1260 1166 1555 1361 1309 571 1249 + 1292 1123 765 791 9999999 1043 1133 1215 1467 1472 1387 1274 1205 1152 1302 + 1155 1467 1234 839 531 806 698 680 720 1023 + 885 859 1096 981 946 697 832 762 749 852 779 875 995 769 838 + 781 697 536 491 743 655 870 615 796 746 719 891 983 881 947 + 847 700 1057 627 1040 606 785 628 672 821 1151 777 781 1053 945 + 939 799 880 1149 1217 9999999 734 612 641 787 762 731 787 939 995 + 830 1077 821 579 903 717 875 1145 870 684 + 1035 921 1037 989 943 922 1038 886 858 1008 1056 852 1085 931 1017 + 725 863 857 642 877 723 996 781 970 926 850 977 935 1041 855 + 973 806 880 731 1173 786 988 844 765 951 1120 936 831 1147 1073 + 709 513 1082 1269 1397 455 9999999 761 682 911 859 822 1071 949 914 + 1180 928 992 866 810 891 685 1151 1144 785 + 769 779 788 757 686 749 800 793 930 793 913 690 965 526 837 + 679 953 882 639 983 847 587 624 657 708 503 807 888 738 929 + 676 888 859 798 818 703 931 594 631 866 1043 984 669 996 976 + 753 578 1144 1078 1291 535 525 9999999 716 586 573 600 810 813 776 + 927 1135 916 831 811 864 958 1063 835 578 + 723 663 638 515 582 691 689 738 744 828 936 626 842 698 1059 + 598 829 756 656 981 636 640 627 606 774 550 601 554 784 745 + 610 873 974 648 893 618 866 585 471 807 1138 803 742 684 1011 + 779 707 938 1154 1056 617 540 506 9999999 686 788 914 877 965 762 + 831 1078 997 752 856 694 717 898 908 690 + 753 653 755 855 820 700 852 884 903 878 562 874 759 772 759 + 960 848 930 839 1024 661 873 664 707 629 764 954 943 691 939 + 839 861 1012 748 907 853 891 792 660 741 1217 1039 912 945 591 + 868 773 1071 994 1228 605 566 381 563 9999999 759 686 482 736 513 + 752 999 810 851 957 967 725 1131 909 685 + 649 622 595 759 775 682 844 678 630 823 826 676 898 573 1009 + 761 669 738 681 888 641 840 580 710 777 511 688 716 808 523 + 433 658 742 641 899 662 727 656 690 648 824 707 642 954 653 + 907 676 818 936 1102 407 390 645 482 560 9999999 865 701 774 776 + 911 746 846 672 626 794 693 805 829 585 + 739 602 661 823 656 690 849 719 676 486 494 695 487 755 758 + 562 719 687 789 756 635 743 648 762 765 562 779 833 788 637 + 490 661 641 395 724 711 673 754 619 568 1014 559 536 802 656 + 647 654 986 867 1145 360 545 561 408 457 417 9999999 669 678 637 + 866 901 713 466 590 890 546 945 772 572 + 807 776 908 1020 667 1005 973 912 861 1184 1074 989 1111 1025 1102 + 833 1235 1076 1128 1235 1068 959 677 682 981 952 977 660 793 882 + 758 867 1157 946 1085 956 1118 984 715 892 1172 1190 1005 713 476 + 873 1042 1351 790 1078 1069 783 978 1030 1009 798 764 9999999 675 992 + 1150 1146 1048 859 997 947 789 978 798 1035 + 1047 1017 869 1092 940 1142 985 1163 1165 1249 1064 1303 1003 857 1263 + 843 1229 1183 1188 1192 1164 917 847 861 898 840 862 801 834 1051 + 1035 961 1283 1104 1152 1047 1259 1083 1020 971 1529 1078 1268 889 760 + 1074 1244 1282 939 1191 1053 1097 1154 1020 1117 1191 897 676 9999999 909 + 1120 1207 1040 937 965 927 965 1041 871 1276 + 1081 904 825 949 716 1083 990 847 762 760 496 877 949 1036 930 + 838 909 1029 844 1127 1095 825 914 1019 977 1011 881 861 880 1128 + 1026 833 977 1025 887 1122 1063 1136 939 918 1408 911 1040 800 621 + 1072 1012 1237 1070 1103 914 934 990 1063 900 1165 1056 496 584 9999999 + 698 963 854 749 800 797 695 1126 906 1063 + 1006 952 726 975 904 1099 970 718 724 717 792 865 1091 947 799 + 1019 986 1153 817 962 1142 821 753 947 1049 854 1037 771 990 849 + 997 762 876 887 706 1021 1048 951 815 1010 1139 945 849 735 540 + 830 1132 1224 873 1185 1030 1111 914 997 1145 1084 1019 657 701 503 + 9999999 778 818 489 568 766 516 1044 925 782 + 1050 835 996 835 678 941 962 816 678 689 674 941 1082 1102 939 + 940 806 980 730 1033 897 948 938 744 874 771 851 887 816 1099 + 854 946 871 890 877 921 763 792 777 763 974 649 786 836 649 + 926 988 1233 1064 1136 964 878 911 720 668 945 1075 536 538 521 + 718 9999999 890 679 736 761 574 1004 940 774 + 962 1085 996 1061 875 1138 910 891 667 805 532 810 936 1081 835 + 872 885 1005 724 1038 1104 932 725 961 1082 869 985 773 796 1099 + 1085 877 1078 1011 778 957 867 762 795 935 1018 826 816 782 577 + 1090 1033 1010 839 1271 1019 1040 1051 968 862 1025 967 433 389 404 + 679 498 9999999 686 850 801 816 1138 902 821 + 1927 1983 1997 1959 2157 2170 2045 2221 2159 2159 2264 2231 2046 1910 2335 + 2056 1966 1987 2199 1989 2150 1950 2147 2255 2087 1995 2160 2226 2154 2039 + 2188 2019 1977 2218 2043 1606 1494 1604 1558 1461 1832 1398 1580 1490 1921 + 1875 1859 1955 1418 1962 1990 2011 2198 2146 2312 2146 2251 2255 2335 2273 + 1991 2373 2181 9999999 486 752 415 1018 923 916 + 2129 2282 2240 2197 2273 2185 2270 2203 2402 2253 2413 2255 2321 2107 2259 + 2100 2034 2205 2269 2219 2272 1814 2239 2166 2161 2217 2002 2092 1996 2253 + 2289 2170 2251 2071 2307 1728 1627 1569 1622 1533 1960 1795 1579 1787 2181 + 2233 1937 1875 1408 1993 2240 2289 2217 2316 2263 2346 2263 2179 2266 2332 + 2320 2588 2275 691 9999999 978 787 1209 881 963 + 1923 1990 2082 1882 1829 2080 1929 1977 2138 2100 2001 1977 2120 1947 2141 + 1944 1927 1964 2176 2114 2267 1893 1869 2108 2138 1996 1960 1994 2081 2130 + 2058 1978 2068 2200 2045 1592 1451 1525 1531 1474 1911 1520 1660 1526 2080 + 1956 1578 1999 1565 1918 2259 2279 2017 2238 2231 2088 2038 2067 1866 2106 + 2195 2452 2069 471 566 9999999 433 645 552 719 + 2271 2110 2196 2019 2099 2085 2033 2056 2015 2050 2189 2107 1949 2157 2134 + 2041 2197 2053 2072 1750 2205 2042 2120 2107 1977 1940 2022 2106 2040 1906 + 1854 2049 1808 2076 2052 1577 1404 1441 1507 1539 1976 1675 1460 1687 2010 + 2212 1746 1956 1659 2021 1959 1995 1995 1916 2095 1960 2185 1916 1993 2040 + 2181 2270 2134 463 443 618 9999999 909 816 871 + 2170 2021 2292 1997 2202 2012 2037 2216 2244 2226 2018 2067 2008 2096 2295 + 2040 2053 2053 2003 2067 1978 2182 2142 2157 2151 2089 2183 1900 2175 1963 + 2121 2044 2065 1883 2122 1473 1527 1532 1468 1613 1794 1644 1634 1441 1840 + 2122 1932 2006 1403 1761 1915 1889 1926 1994 1983 1999 2031 1926 1662 2008 + 2318 2310 2285 386 627 627 759 9999999 712 749 + 2243 2278 2112 2059 2217 2099 2293 2166 2311 2106 2136 2348 1952 1959 2380 + 2041 2253 1954 2053 1801 2215 2009 2104 2283 2228 2008 1935 2167 2264 2064 + 2026 2138 1856 2037 1875 1612 1581 1757 1682 1713 1918 1738 1632 1726 2061 + 2041 1934 2100 1601 2052 2200 2048 2068 1979 2066 1989 2081 1967 1715 2213 + 2352 2395 2113 588 640 641 461 682 9999999 757 + 2058 2030 2049 2062 2021 2048 2033 2126 2328 2299 2170 2276 2164 1985 2236 + 2245 2137 1972 2182 1902 2327 2130 2046 2237 2246 2273 2163 2031 2267 1981 + 2073 2057 1955 2224 2130 1673 1669 1563 1658 1645 1853 1785 1729 1714 1988 + 2230 1766 1910 1507 1817 2175 2111 2024 2289 2177 2214 2080 1984 1770 2042 + 2173 2271 2101 689 522 613 514 589 663 9999999 +EOF diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/ATSP-instances/ftv170.atsp b/ProyectoFinal/CHC/malva/ProblemInstances/ATSP-instances/ftv170.atsp new file mode 100644 index 0000000000000000000000000000000000000000..22a978b5242dc0e3787933e17da2bd2553dc3af7 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/ATSP-instances/ftv170.atsp @@ -0,0 +1,4882 @@ +NAME: ftv170 +TYPE: ATSP +COMMENT: Asymmetric TSP (Fischetti) +DIMENSION: 171 +EDGE_WEIGHT_TYPE: EXPLICIT +EDGE_WEIGHT_FORMAT: FULL_MATRIX +EDGE_WEIGHT_SECTION + 100000000 9 15 19 39 50 + 67 55 75 58 67 85 + 99 100 95 111 125 110 + 103 91 100 109 123 134 + 156 130 143 153 140 126 + 144 132 122 121 111 99 + 112 84 78 88 100 134 + 159 119 125 115 126 137 + 150 51 65 80 91 105 + 148 127 167 180 167 98 + 85 100 188 134 153 132 + 119 117 104 115 140 67 + 47 35 49 68 79 22 + 35 29 22 13 40 82 + 94 133 140 127 141 123 + 130 106 97 85 115 131 + 128 95 114 109 127 143 + 131 143 89 82 74 61 + 67 49 29 21 39 58 + 72 77 90 101 109 127 + 137 136 152 165 111 96 + 85 78 140 131 91 91 + 46 59 69 106 128 138 + 118 132 134 85 86 111 + 122 176 159 128 142 115 + 140 106 91 153 112 127 + 107 114 117 115 123 147 + 158 122 67 109 76 124 + 60 68 45 9 100000000 6 + 26 46 57 74 62 82 + 65 74 76 90 104 102 + 118 132 114 94 82 91 + 100 114 125 147 137 134 + 144 131 117 135 123 113 + 112 102 90 103 75 69 + 79 91 125 150 110 116 + 106 117 128 141 42 56 + 71 82 96 139 118 158 + 171 158 89 76 91 179 + 125 144 123 110 108 95 + 118 131 58 38 26 40 + 59 86 13 26 38 31 + 22 34 91 103 136 143 + 136 150 132 139 115 106 + 94 124 140 137 104 123 + 118 136 152 140 152 98 + 91 83 70 76 58 38 + 30 48 67 81 86 99 + 110 118 136 146 145 161 + 174 120 105 94 87 149 + 140 100 100 55 68 78 + 115 137 147 127 141 141 + 94 93 118 129 185 168 + 135 149 122 147 113 98 + 162 121 118 98 105 108 + 122 130 154 167 131 76 + 118 85 115 51 75 36 + 15 6 100000000 20 40 51 + 68 56 76 59 68 82 + 96 101 96 112 126 111 + 100 88 97 106 120 131 + 153 131 140 150 137 123 + 141 129 119 118 108 96 + 109 81 75 85 97 131 + 156 116 122 112 123 134 + 147 48 62 77 88 102 + 145 124 164 177 164 95 + 82 97 185 131 150 129 + 116 114 101 124 137 64 + 44 32 46 65 80 19 + 32 44 37 28 40 97 + 109 142 149 142 156 138 + 145 121 112 100 130 146 + 143 110 129 124 142 158 + 146 158 104 97 89 76 + 82 64 44 36 54 73 + 87 92 105 116 124 142 + 152 151 167 180 126 111 + 100 93 155 146 106 100 + 61 68 78 121 143 151 + 133 147 135 94 87 112 + 123 191 174 129 143 116 + 141 107 92 168 127 124 + 104 111 114 116 124 148 + 173 137 82 124 91 121 + 57 69 42 75 66 60 + 100000000 20 31 48 36 56 + 39 48 112 126 81 76 + 92 106 91 102 112 118 + 109 123 134 156 111 140 + 153 140 126 144 149 126 + 160 168 156 144 141 135 + 145 157 190 215 176 182 + 172 183 194 207 108 122 + 137 148 162 205 184 224 + 237 224 155 142 157 245 + 190 209 188 175 161 161 + 151 177 124 104 92 76 + 95 60 79 92 104 97 + 88 100 118 130 169 176 + 163 177 159 166 142 133 + 121 151 167 164 131 150 + 145 163 179 167 179 125 + 118 110 97 103 85 65 + 57 75 94 108 113 126 + 137 145 163 173 172 188 + 201 147 132 121 114 160 + 151 127 80 82 48 58 + 142 141 131 148 162 115 + 74 67 92 103 196 179 + 109 123 96 121 87 72 + 189 148 184 164 161 131 + 96 104 128 194 158 103 + 145 112 168 117 49 102 + 55 46 40 53 100000000 11 + 28 16 36 19 28 92 + 106 61 56 72 86 71 + 82 92 98 89 103 114 + 136 91 120 133 120 106 + 124 129 106 140 148 136 + 124 121 115 125 137 170 + 195 156 162 152 163 174 + 187 88 102 117 128 142 + 185 164 204 217 204 135 + 122 137 225 170 189 168 + 155 141 141 131 157 104 + 84 72 56 75 40 59 + 72 84 77 68 80 98 + 110 149 156 143 157 139 + 146 122 113 101 131 147 + 144 111 130 125 143 159 + 147 159 105 98 90 77 + 83 65 45 37 55 74 + 88 93 106 117 125 143 + 153 152 168 181 127 112 + 101 94 140 131 107 60 + 62 28 38 122 121 111 + 128 142 95 54 47 72 + 83 176 159 89 103 76 + 101 67 52 169 128 164 + 144 141 111 76 84 108 + 174 138 83 125 92 148 + 97 29 82 47 56 62 + 42 62 100000000 56 66 86 + 81 90 132 146 111 106 + 122 136 121 132 138 147 + 139 153 164 186 141 170 + 183 170 156 174 179 156 + 168 158 146 159 131 125 + 135 147 181 206 166 172 + 162 173 184 197 98 112 + 127 138 152 195 174 193 + 215 214 145 132 147 223 + 159 178 157 144 130 151 + 120 146 114 94 82 96 + 115 102 69 82 76 69 + 60 87 87 99 138 145 + 132 146 128 135 111 102 + 90 120 136 133 100 119 + 114 132 148 136 148 94 + 87 79 66 72 54 34 + 26 44 63 77 82 95 + 106 114 132 142 141 157 + 170 116 101 90 83 145 + 136 96 49 51 17 27 + 111 133 139 123 137 123 + 43 75 100 111 181 164 + 117 131 104 129 95 80 + 158 117 174 154 161 161 + 126 112 136 163 127 72 + 114 81 137 107 18 92 + 82 73 67 87 72 83 + 100000000 10 30 46 55 119 + 133 55 50 66 80 65 + 76 86 92 83 97 108 + 130 85 114 127 114 100 + 118 123 100 134 155 158 + 118 117 137 147 159 164 + 189 183 184 174 185 196 + 209 115 129 144 155 169 + 212 191 231 244 231 162 + 149 164 252 198 217 196 + 183 181 168 191 204 131 + 111 99 83 102 67 86 + 99 111 104 95 107 164 + 176 209 216 209 223 205 + 212 188 179 167 197 212 + 210 176 195 190 208 224 + 182 194 140 163 156 143 + 149 131 111 103 121 109 + 151 128 141 152 160 178 + 188 187 203 216 162 147 + 136 129 131 122 142 94 + 113 100 72 131 112 102 + 119 133 86 56 38 63 + 74 167 150 80 94 67 + 73 39 24 235 194 176 + 165 135 105 70 56 99 + 209 203 118 190 158 188 + 124 101 109 72 63 57 + 77 62 73 90 100000000 20 + 36 45 109 123 45 40 + 56 70 55 66 76 82 + 73 87 98 120 75 104 + 117 104 90 108 113 90 + 124 145 148 108 107 127 + 137 149 154 179 173 174 + 164 175 186 199 105 119 + 134 145 159 202 181 221 + 234 221 152 139 154 242 + 188 207 186 173 171 158 + 181 194 121 101 89 73 + 92 57 76 89 101 94 + 85 97 154 166 199 206 + 199 213 195 202 178 169 + 157 187 203 200 167 186 + 181 199 215 203 215 161 + 154 146 133 139 121 101 + 93 111 130 144 149 162 + 173 181 199 209 208 224 + 237 183 168 157 150 184 + 175 163 122 118 90 100 + 178 165 155 172 186 139 + 109 91 116 127 220 203 + 133 147 120 96 62 77 + 225 184 166 155 125 95 + 60 79 129 230 194 139 + 181 148 178 114 91 99 + 52 43 37 57 42 53 + 70 58 100000000 16 25 89 + 103 25 20 36 50 35 + 46 56 62 53 67 78 + 100 55 84 97 84 70 + 88 93 70 104 125 128 + 88 87 107 117 129 134 + 159 153 154 144 155 166 + 179 85 99 114 125 139 + 182 161 201 214 201 132 + 119 134 222 168 187 166 + 153 151 138 161 174 101 + 81 69 53 72 37 56 + 69 81 74 65 77 134 + 146 179 186 179 193 175 + 182 158 149 137 167 183 + 180 147 166 161 179 195 + 183 195 141 134 126 113 + 119 101 81 73 91 110 + 124 129 142 153 161 179 + 189 188 204 217 163 148 + 137 130 164 155 143 102 + 98 70 80 158 145 135 + 152 166 119 89 71 96 + 107 200 183 113 127 100 + 76 42 57 205 164 146 + 135 105 75 40 59 109 + 210 174 119 161 128 158 + 94 71 79 36 27 21 + 41 26 37 54 42 62 + 100000000 9 73 87 87 82 + 98 112 97 91 79 88 + 97 111 122 144 117 131 + 141 128 114 132 133 110 + 139 129 117 118 102 96 + 106 118 152 177 137 143 + 133 144 155 168 69 83 + 98 109 123 166 145 185 + 198 185 116 103 118 206 + 152 171 150 137 135 122 + 145 158 85 65 53 37 + 56 21 40 53 65 58 + 49 61 118 130 163 170 + 163 177 159 166 142 133 + 121 151 167 164 131 150 + 145 163 179 167 179 125 + 118 110 97 103 85 65 + 57 75 94 108 113 126 + 137 145 163 173 172 188 + 201 147 132 121 114 166 + 157 127 86 82 54 64 + 142 147 137 154 168 121 + 80 73 98 109 202 185 + 115 129 102 127 93 78 + 189 148 145 125 132 105 + 102 110 134 194 158 103 + 145 112 142 78 55 63 + 188 179 185 205 225 236 + 253 229 249 244 100000000 64 + 78 92 230 149 120 102 + 82 70 79 88 102 113 + 135 146 122 132 119 105 + 123 124 101 133 154 145 + 109 104 124 134 146 163 + 188 188 171 161 172 183 + 196 137 151 166 177 191 + 217 196 236 249 236 184 + 196 211 257 245 251 243 + 230 228 215 238 251 187 + 167 153 28 47 12 166 + 179 198 205 201 187 270 + 268 256 263 265 293 311 + 318 294 285 273 303 319 + 316 283 302 297 315 331 + 319 331 277 270 262 249 + 255 237 217 209 227 246 + 260 265 278 289 297 315 + 325 324 340 353 299 284 + 273 266 310 301 279 279 + 234 247 257 294 291 281 + 298 312 273 254 236 261 + 261 346 329 259 232 205 + 174 208 222 305 300 173 + 153 126 96 153 191 207 + 346 310 255 297 264 235 + 158 254 143 146 137 143 + 163 183 194 211 187 207 + 202 10 100000000 14 28 188 + 107 78 38 18 28 37 + 46 60 71 93 104 80 + 90 77 63 81 82 59 + 91 112 103 67 62 82 + 92 104 121 146 146 129 + 119 130 141 154 95 109 + 124 135 149 175 154 194 + 207 194 142 154 169 215 + 203 209 201 188 186 173 + 196 209 145 125 111 38 + 57 22 124 137 156 163 + 159 145 228 226 214 221 + 223 251 269 276 252 243 + 231 261 277 274 241 260 + 255 273 289 277 289 235 + 228 220 207 213 195 175 + 167 185 204 218 223 236 + 247 255 273 283 282 298 + 311 257 242 231 224 268 + 259 237 237 192 205 215 + 252 249 239 256 270 231 + 212 194 219 219 304 287 + 217 190 163 132 166 180 + 263 258 131 111 84 54 + 111 149 165 304 268 213 + 255 222 193 116 212 101 + 138 129 135 155 175 186 + 203 179 199 194 92 82 + 100000000 14 180 99 70 24 + 10 20 29 38 52 63 + 85 96 72 82 69 55 + 73 74 51 83 104 95 + 59 54 74 84 96 113 + 138 138 121 111 122 133 + 146 87 101 116 127 141 + 167 146 186 199 186 134 + 146 161 207 195 201 193 + 180 178 165 188 201 137 + 117 103 117 65 104 116 + 129 148 155 151 137 220 + 218 206 213 215 243 261 + 268 244 235 223 253 269 + 266 233 252 247 265 281 + 269 281 227 220 212 199 + 205 187 167 159 177 196 + 210 215 228 239 247 265 + 275 274 290 303 249 234 + 223 216 260 251 229 229 + 184 197 207 244 241 231 + 248 262 223 204 186 211 + 211 296 279 209 182 155 + 124 158 172 255 250 123 + 103 76 46 103 141 157 + 296 260 205 247 214 185 + 108 204 93 146 137 143 + 163 183 194 211 169 189 + 202 100 90 104 100000000 170 + 89 60 10 21 31 37 + 28 42 53 75 86 62 + 72 59 45 63 68 45 + 79 100 103 63 62 82 + 92 104 109 134 146 129 + 119 130 141 154 95 109 + 124 135 149 175 154 194 + 207 194 142 154 169 215 + 203 209 201 188 186 173 + 196 209 145 125 111 125 + 73 112 124 137 156 163 + 159 145 228 226 214 221 + 223 251 269 276 252 243 + 231 261 277 274 241 260 + 255 273 289 277 289 235 + 228 220 207 213 195 175 + 167 185 204 218 223 236 + 247 255 273 283 282 298 + 311 257 242 231 224 250 + 241 237 232 192 205 210 + 250 231 221 238 252 213 + 194 176 201 201 286 269 + 199 172 145 114 148 162 + 263 258 121 110 80 50 + 93 131 147 304 268 213 + 255 222 193 116 212 101 + 115 106 100 120 105 116 + 91 43 63 79 88 95 + 109 5 100000000 16 30 15 + 26 36 42 33 47 58 + 80 35 64 77 64 50 + 68 73 50 84 105 108 + 68 67 87 97 109 114 + 139 151 134 124 135 146 + 159 100 114 129 140 154 + 180 159 199 212 199 147 + 159 174 220 208 214 206 + 193 191 178 201 214 150 + 130 116 116 78 100 119 + 132 144 137 128 140 197 + 209 219 226 228 256 238 + 245 221 212 200 230 225 + 238 189 208 203 221 237 + 195 207 153 176 189 176 + 182 164 144 136 154 122 + 164 141 154 165 173 191 + 201 200 216 229 175 160 + 149 142 144 135 155 107 + 126 133 85 144 125 115 + 132 146 99 69 51 76 + 87 180 163 93 107 80 + 56 22 37 268 227 126 + 115 85 55 20 39 89 + 222 216 131 203 191 198 + 121 134 106 164 155 159 + 179 164 175 149 102 122 + 138 118 108 122 20 103 + 100000000 14 28 39 49 55 + 46 60 57 79 19 48 + 61 74 63 81 86 63 + 97 118 121 81 80 100 + 110 122 127 152 164 147 + 137 148 159 172 113 127 + 142 153 167 193 172 212 + 225 212 160 172 187 233 + 221 227 219 206 204 191 + 214 227 163 143 129 143 + 91 130 142 155 174 181 + 177 163 246 244 232 239 + 241 269 287 294 270 261 + 249 279 283 292 247 266 + 261 279 295 253 265 211 + 234 238 225 231 213 193 + 185 203 180 222 199 212 + 223 231 249 247 240 256 + 273 215 218 207 200 183 + 174 198 165 184 192 143 + 183 164 154 171 185 146 + 127 109 134 134 219 202 + 132 105 78 47 81 95 + 281 276 139 128 98 68 + 4 64 80 280 274 189 + 261 240 211 134 193 119 + 150 141 147 167 187 198 + 215 173 193 206 104 94 + 108 113 174 93 100000000 14 + 25 35 41 32 46 57 + 79 90 66 76 63 49 + 67 72 49 83 104 107 + 67 66 86 96 108 113 + 138 150 133 123 134 145 + 158 99 113 128 139 153 + 179 158 198 211 198 146 + 158 173 219 207 213 205 + 192 190 177 200 213 149 + 129 115 129 77 116 128 + 141 160 167 163 149 232 + 230 218 225 227 255 273 + 280 256 247 235 265 281 + 278 245 264 259 277 293 + 281 293 239 232 224 211 + 217 199 179 171 189 208 + 222 227 240 251 259 277 + 287 286 302 315 261 246 + 235 228 254 245 241 236 + 196 209 214 254 235 225 + 242 256 217 198 180 205 + 205 290 273 203 176 149 + 118 152 166 267 262 125 + 114 84 54 97 135 151 + 308 272 217 259 226 197 + 120 216 105 136 127 133 + 153 173 184 201 159 179 + 192 90 80 94 99 160 + 79 50 100000000 11 21 27 + 18 32 43 65 76 52 + 62 49 35 53 58 35 + 69 90 93 53 52 72 + 82 94 99 124 136 119 + 109 120 131 144 85 99 + 114 125 139 165 144 184 + 197 184 132 144 159 205 + 193 199 191 178 176 163 + 186 199 135 115 101 115 + 63 102 114 127 146 153 + 149 135 218 216 204 211 + 213 241 259 266 242 233 + 221 251 267 264 231 250 + 245 263 279 267 279 225 + 218 210 197 203 185 165 + 157 175 194 208 213 226 + 237 245 263 273 272 288 + 301 247 232 221 214 240 + 231 227 222 182 195 200 + 240 221 211 228 242 203 + 184 166 191 191 276 259 + 189 162 135 104 138 152 + 253 248 111 100 70 40 + 83 121 137 294 258 203 + 245 212 183 106 202 91 + 128 119 125 145 165 176 + 193 169 189 184 82 72 + 86 100 170 89 60 46 + 100000000 10 19 28 42 53 + 75 86 62 72 59 45 + 63 64 41 73 94 85 + 49 44 64 74 86 103 + 128 128 111 101 112 123 + 136 77 91 106 117 131 + 157 136 176 189 176 124 + 136 151 197 185 191 183 + 170 168 155 178 191 127 + 107 93 107 55 94 106 + 119 138 145 141 127 210 + 208 196 203 205 233 251 + 258 234 225 213 243 259 + 256 223 242 237 255 271 + 259 271 217 210 202 189 + 195 177 157 149 167 186 + 200 205 218 229 237 255 + 265 264 280 293 239 224 + 213 206 250 241 219 219 + 174 187 197 234 231 221 + 238 252 213 194 176 201 + 201 286 269 199 172 145 + 114 148 162 245 240 113 + 93 66 36 93 131 147 + 286 250 195 237 204 175 + 98 194 83 118 109 115 + 135 155 166 183 159 179 + 174 72 62 76 90 160 + 79 50 36 47 100000000 9 + 18 32 43 65 76 52 + 62 49 35 53 54 31 + 63 84 75 39 34 54 + 64 76 93 118 118 101 + 91 102 113 126 67 81 + 96 107 121 147 126 166 + 179 166 114 126 141 187 + 175 181 173 160 158 145 + 168 181 117 97 83 97 + 45 84 96 109 128 135 + 131 117 200 198 186 193 + 195 223 241 248 224 215 + 203 233 249 246 213 232 + 227 245 261 249 261 207 + 200 192 179 185 167 147 + 139 157 176 190 195 208 + 219 227 245 255 254 270 + 283 229 214 203 196 240 + 231 209 209 164 177 187 + 224 221 211 228 242 203 + 184 166 191 191 276 259 + 189 162 135 104 138 152 + 235 230 103 83 56 26 + 83 121 137 276 240 185 + 227 194 165 88 184 73 + 109 100 106 126 146 157 + 174 150 170 165 63 53 + 67 81 151 70 41 27 + 38 48 100000000 9 23 34 + 56 67 43 53 40 26 + 44 45 22 54 75 66 + 30 25 45 55 67 84 + 109 109 92 82 93 104 + 117 58 72 87 98 112 + 138 117 157 170 157 105 + 117 132 178 166 172 164 + 151 149 136 159 172 108 + 88 74 88 36 75 87 + 100 119 126 122 108 191 + 189 177 184 186 214 232 + 239 215 206 194 224 240 + 237 204 223 218 236 252 + 240 252 198 191 183 170 + 176 158 138 130 148 167 + 181 186 199 210 218 236 + 246 245 261 274 220 205 + 194 187 231 222 200 200 + 155 168 178 215 212 202 + 219 233 194 175 157 182 + 182 267 250 180 153 126 + 95 129 143 226 221 94 + 74 47 17 74 112 128 + 267 231 176 218 185 156 + 79 175 64 118 109 115 + 135 155 166 183 141 161 + 174 72 62 76 81 142 + 61 32 18 29 39 9 + 100000000 14 25 47 58 34 + 44 31 17 35 40 17 + 51 72 75 35 34 54 + 64 76 81 106 118 101 + 91 102 113 126 67 81 + 96 107 121 147 126 166 + 179 166 114 126 141 187 + 175 181 173 160 158 145 + 168 181 117 97 83 97 + 45 84 96 109 128 135 + 131 117 200 198 186 193 + 195 223 241 248 224 215 + 203 233 249 246 213 232 + 227 245 261 249 261 207 + 200 192 179 185 167 147 + 139 157 176 190 195 208 + 219 227 245 255 254 270 + 283 229 214 203 196 222 + 213 209 204 164 177 182 + 222 203 193 210 224 185 + 166 148 173 173 258 241 + 171 144 117 86 120 134 + 235 230 93 82 52 22 + 65 103 119 276 240 185 + 227 194 165 88 184 73 + 132 123 129 149 169 180 + 174 127 147 163 86 76 + 90 67 128 47 18 32 + 43 53 23 14 100000000 11 + 33 44 20 33 45 31 + 49 54 31 65 86 89 + 49 48 68 78 90 95 + 120 132 115 105 116 127 + 140 81 95 110 121 135 + 161 140 180 193 180 128 + 140 155 201 189 195 187 + 174 172 159 182 195 131 + 111 97 111 59 98 110 + 123 142 149 145 131 214 + 212 200 207 209 237 255 + 262 238 229 217 247 263 + 260 227 246 241 259 275 + 263 275 221 214 206 193 + 199 181 161 153 171 190 + 204 209 222 233 241 259 + 269 265 281 297 240 228 + 217 210 208 199 223 190 + 178 191 168 208 189 179 + 196 210 171 152 134 159 + 159 244 227 157 130 103 + 72 106 120 249 244 107 + 96 66 36 51 89 105 + 290 254 199 241 208 179 + 102 198 87 143 134 140 + 160 178 189 163 116 136 + 152 97 87 101 56 117 + 36 29 43 54 64 34 + 25 11 100000000 22 33 9 + 22 35 42 50 65 42 + 76 97 100 60 59 79 + 89 101 106 131 143 126 + 116 127 138 151 92 106 + 121 132 146 172 151 191 + 204 191 139 151 166 212 + 200 206 198 185 183 170 + 193 206 142 122 108 122 + 70 109 121 134 153 160 + 156 142 225 223 211 218 + 220 248 266 273 249 240 + 228 258 274 271 238 257 + 252 270 286 267 279 225 + 225 217 204 210 192 172 + 164 182 194 215 213 226 + 237 245 263 261 254 270 + 287 229 232 221 214 197 + 188 212 179 189 202 157 + 197 178 168 185 199 160 + 141 123 148 148 233 216 + 146 119 92 61 95 109 + 260 255 118 107 77 47 + 40 78 94 294 265 203 + 252 219 190 113 207 98 + 166 157 151 171 156 167 + 141 94 114 130 132 122 + 136 34 95 14 28 42 + 53 63 69 60 60 49 + 100000000 11 40 53 66 77 + 81 98 77 109 130 135 + 95 94 114 124 136 139 + 164 178 161 151 162 173 + 186 127 141 156 167 181 + 207 186 226 239 226 174 + 186 201 247 235 241 233 + 220 218 205 228 241 177 + 157 143 157 105 144 156 + 169 188 188 179 177 248 + 258 246 253 255 283 289 + 296 272 263 251 281 275 + 288 239 258 253 271 287 + 245 257 203 226 240 227 + 233 215 195 187 205 172 + 214 191 204 215 223 241 + 239 232 248 265 207 210 + 199 192 175 166 190 157 + 176 184 135 175 156 146 + 163 177 138 119 101 126 + 126 211 194 124 97 70 + 39 73 87 295 278 151 + 140 112 82 18 56 72 + 272 266 181 253 242 225 + 148 185 133 155 146 140 + 160 145 156 130 83 103 + 119 128 125 139 89 84 + 74 67 81 92 102 72 + 63 49 38 60 100000000 29 + 42 55 69 70 87 80 + 98 119 131 98 97 117 + 127 136 128 153 178 161 + 151 162 173 186 130 144 + 159 170 184 207 186 226 + 239 226 177 189 204 247 + 238 241 236 223 221 208 + 231 244 180 160 146 156 + 108 140 159 172 184 177 + 168 180 237 249 249 256 + 258 286 278 285 261 252 + 240 270 264 277 228 247 + 242 260 276 234 246 192 + 215 229 216 222 204 184 + 176 194 161 203 180 193 + 204 212 230 228 221 237 + 254 196 199 188 181 164 + 155 179 146 165 173 124 + 164 145 135 152 166 127 + 108 90 115 115 200 183 + 113 86 59 28 62 76 + 298 267 140 129 115 85 + 78 45 61 261 255 170 + 242 231 228 151 174 136 + 152 143 149 169 174 185 + 159 112 132 148 106 96 + 110 65 113 45 38 52 + 63 73 43 34 20 9 + 31 29 100000000 13 26 40 + 41 58 51 69 90 102 + 69 68 88 98 107 99 + 124 149 132 122 133 144 + 157 101 115 130 141 155 + 178 157 197 210 197 148 + 160 175 218 209 212 207 + 194 192 179 202 215 151 + 131 117 131 79 118 130 + 143 162 169 165 151 234 + 232 220 227 229 257 275 + 282 258 249 237 267 283 + 280 247 266 261 279 295 + 263 275 221 234 226 213 + 219 201 181 173 191 190 + 224 209 222 233 241 259 + 257 250 266 283 225 228 + 217 210 193 184 208 175 + 194 202 153 193 174 164 + 181 195 156 137 119 144 + 144 229 212 142 115 88 + 57 91 105 269 264 111 + 100 86 56 49 74 90 + 290 274 199 261 228 199 + 122 203 107 162 153 159 + 179 187 198 172 125 145 + 161 116 106 120 78 126 + 58 51 62 73 83 53 + 44 33 22 44 42 13 + 100000000 13 27 28 45 61 + 56 77 89 79 78 98 + 106 94 86 111 136 119 + 109 120 131 144 111 125 + 140 147 161 165 144 184 + 197 184 158 170 185 205 + 219 199 217 204 202 189 + 212 225 161 141 127 141 + 89 128 140 153 172 179 + 175 161 244 242 230 237 + 239 267 285 292 268 259 + 247 277 293 290 257 276 + 271 289 305 276 288 234 + 244 236 223 229 211 191 + 183 201 203 234 222 235 + 246 254 272 270 263 279 + 296 238 241 230 223 206 + 197 221 188 207 215 166 + 206 187 177 194 208 169 + 150 132 157 157 242 225 + 155 128 101 70 104 118 + 279 274 98 87 96 66 + 62 87 103 303 284 212 + 271 238 209 132 216 117 + 149 140 146 166 186 197 + 185 138 158 174 103 93 + 107 78 139 58 43 49 + 60 70 40 31 25 22 + 44 55 26 13 100000000 14 + 15 32 48 43 64 76 + 66 65 85 93 81 73 + 98 123 106 96 107 118 + 131 98 112 127 134 148 + 152 131 171 184 171 145 + 157 172 192 206 186 204 + 191 189 176 199 212 148 + 128 114 128 76 115 127 + 140 159 166 162 148 231 + 229 217 224 226 254 272 + 279 255 246 234 264 280 + 277 244 263 258 276 292 + 280 292 238 231 223 210 + 216 198 178 170 188 207 + 221 226 239 250 258 276 + 283 276 292 309 251 245 + 234 227 219 210 234 201 + 195 208 179 219 200 190 + 207 221 182 163 145 170 + 170 255 238 168 141 114 + 83 117 131 266 261 85 + 74 83 53 62 100 116 + 307 271 216 258 225 196 + 119 215 104 135 126 132 + 152 172 183 185 138 158 + 174 89 79 93 78 139 + 58 29 35 46 56 26 + 17 11 22 44 55 31 + 27 14 100000000 18 35 34 + 46 67 79 52 51 71 + 81 84 76 101 126 109 + 99 110 121 134 84 98 + 113 124 138 155 134 174 + 187 174 131 143 158 195 + 192 189 190 177 175 162 + 185 198 134 114 100 114 + 62 101 113 126 145 152 + 148 134 217 215 203 210 + 212 240 258 265 241 232 + 220 250 266 263 230 249 + 244 262 278 266 278 224 + 217 209 196 202 184 164 + 156 174 193 207 212 225 + 236 244 262 272 271 287 + 300 246 231 220 213 219 + 210 226 201 181 194 179 + 219 200 190 207 221 182 + 163 145 170 170 255 238 + 168 141 114 83 117 131 + 252 247 88 77 69 39 + 62 100 116 293 257 202 + 244 211 182 105 201 90 + 164 155 161 181 201 212 + 200 153 173 189 118 108 + 122 93 154 73 58 64 + 75 85 55 46 40 37 + 59 70 41 28 15 29 + 100000000 17 40 28 49 61 + 58 80 88 78 66 58 + 83 108 91 81 92 103 + 116 113 127 127 119 133 + 137 116 156 169 156 145 + 157 172 177 202 171 203 + 191 189 176 199 212 163 + 143 129 143 91 130 142 + 155 174 181 177 163 239 + 229 217 224 226 253 271 + 278 257 248 241 266 295 + 279 259 278 273 291 307 + 295 307 253 246 238 225 + 231 213 193 185 203 222 + 236 241 254 265 273 291 + 298 291 307 324 266 260 + 249 242 234 225 249 216 + 210 223 194 234 215 205 + 222 236 197 178 160 185 + 185 270 253 183 156 129 + 98 132 146 265 263 70 + 59 75 45 77 115 131 + 322 286 231 273 240 196 + 134 230 119 154 145 151 + 171 191 202 217 170 190 + 206 108 98 112 110 171 + 90 72 58 69 79 49 + 40 54 54 76 87 58 + 45 32 46 17 100000000 23 + 11 32 44 41 70 71 + 61 49 41 66 91 74 + 64 75 86 99 103 117 + 110 102 116 120 99 139 + 152 139 128 140 155 160 + 185 154 186 174 172 159 + 182 195 153 133 119 133 + 81 120 132 145 164 171 + 167 153 222 212 200 207 + 209 236 254 261 240 231 + 224 249 285 262 249 268 + 263 281 297 285 297 243 + 236 228 215 221 203 183 + 175 193 212 226 231 244 + 255 263 281 291 290 306 + 319 265 250 239 232 251 + 242 245 233 200 213 211 + 251 232 222 239 253 214 + 195 177 202 202 287 270 + 200 173 146 115 149 163 + 248 246 53 42 58 28 + 94 132 148 312 276 221 + 263 230 179 124 220 109 + 131 122 128 148 168 179 + 196 158 178 187 85 75 + 89 98 159 78 49 35 + 46 56 26 17 31 42 + 64 75 51 61 48 34 + 40 23 100000000 34 55 67 + 18 47 67 77 72 64 + 89 114 97 87 98 109 + 122 80 94 109 120 134 + 143 122 162 175 162 127 + 139 154 183 188 177 186 + 173 171 158 181 194 130 + 110 96 110 58 97 109 + 122 141 148 144 130 213 + 211 199 206 208 236 254 + 261 237 228 216 246 262 + 259 226 245 240 258 274 + 262 274 220 213 205 192 + 198 180 160 152 170 189 + 203 208 221 232 240 258 + 268 267 283 296 242 227 + 216 209 239 230 222 221 + 177 190 199 237 220 210 + 227 241 202 183 165 190 + 190 275 258 188 161 134 + 103 137 151 248 243 76 + 65 35 5 82 120 136 + 289 253 198 240 207 178 + 101 197 86 152 143 149 + 169 189 200 217 181 201 + 208 113 103 117 121 182 + 101 83 69 80 90 60 + 51 65 65 87 98 69 + 56 43 57 28 11 34 + 100000000 21 33 46 75 60 + 50 38 30 55 80 63 + 53 64 75 88 101 115 + 99 91 105 109 88 128 + 141 128 117 129 144 149 + 174 143 175 163 161 148 + 171 184 151 131 117 131 + 86 125 130 143 162 169 + 165 151 211 201 189 196 + 198 225 243 250 229 220 + 213 238 283 251 247 266 + 261 279 295 283 295 241 + 234 226 213 219 201 181 + 173 191 210 224 229 242 + 253 261 279 289 288 304 + 317 263 248 237 230 262 + 253 243 243 198 211 221 + 258 243 233 250 264 225 + 206 188 213 213 298 281 + 211 184 157 126 160 174 + 237 235 42 31 48 39 + 105 143 159 310 274 219 + 261 222 168 122 218 107 + 131 122 128 148 168 179 + 196 184 204 187 92 82 + 96 110 203 122 104 90 + 100 88 79 72 86 86 + 108 119 90 77 64 78 + 49 32 55 21 100000000 12 + 25 54 39 29 17 23 + 48 59 42 32 43 54 + 67 80 94 78 70 84 + 88 67 107 120 107 96 + 108 123 128 153 122 154 + 142 140 127 150 163 130 + 110 96 110 65 104 109 + 122 141 148 144 130 190 + 180 168 175 177 204 222 + 229 208 199 192 217 262 + 230 226 245 240 258 274 + 262 274 220 213 205 192 + 198 180 160 152 170 189 + 203 208 221 232 240 258 + 268 267 283 296 242 227 + 216 209 271 262 222 222 + 177 190 200 237 259 254 + 249 263 246 216 209 234 + 234 307 290 232 205 178 + 147 181 195 216 214 30 + 10 27 60 126 164 180 + 289 253 198 240 201 147 + 101 197 86 126 117 123 + 143 163 174 191 179 199 + 182 80 70 84 98 204 + 123 105 91 88 76 67 + 73 87 87 109 120 91 + 78 65 79 50 33 56 + 22 12 100000000 13 42 51 + 41 29 35 60 71 54 + 44 55 66 79 75 89 + 90 82 96 100 79 119 + 132 119 108 120 135 140 + 165 134 166 154 152 139 + 162 175 125 105 91 105 + 53 92 104 117 136 143 + 139 125 202 192 180 187 + 189 216 234 241 220 211 + 204 229 257 242 221 240 + 235 253 269 257 269 215 + 208 200 187 193 175 155 + 147 165 184 198 203 216 + 227 235 253 263 262 278 + 291 237 222 211 204 266 + 257 217 217 172 185 195 + 232 254 255 244 258 247 + 211 210 235 235 302 285 + 233 206 179 148 182 196 + 228 226 42 22 15 61 + 127 165 181 284 248 193 + 235 202 159 96 192 81 + 113 104 110 130 150 161 + 178 166 186 169 67 57 + 71 85 192 111 93 79 + 75 63 54 61 75 75 + 97 108 79 66 53 67 + 38 21 44 24 45 57 + 100000000 29 49 59 62 54 + 79 104 87 77 88 99 + 112 62 76 91 102 116 + 133 112 152 165 152 109 + 121 136 173 170 167 168 + 155 153 140 163 176 112 + 92 78 92 40 79 91 + 104 123 130 126 112 195 + 193 181 188 190 218 236 + 243 219 210 198 228 244 + 241 208 227 222 240 256 + 244 256 202 195 187 174 + 180 162 142 134 152 171 + 185 190 203 214 222 240 + 250 249 265 278 224 209 + 198 191 253 244 204 204 + 159 172 182 219 241 243 + 231 245 235 198 197 222 + 223 289 272 221 194 167 + 136 170 184 230 225 66 + 55 17 49 115 153 169 + 271 235 180 222 189 160 + 83 179 68 84 75 81 + 101 121 132 149 137 157 + 140 38 28 42 56 176 + 95 66 52 46 34 25 + 34 48 59 81 92 68 + 78 65 51 69 70 47 + 63 53 41 54 100000000 20 + 30 42 76 101 84 67 + 57 68 79 92 33 47 + 62 73 87 113 92 132 + 145 132 80 92 107 153 + 141 147 139 126 124 111 + 134 147 83 63 49 63 + 11 50 62 75 94 101 + 97 83 166 164 152 159 + 161 189 207 214 190 181 + 169 199 215 212 179 198 + 193 211 227 215 227 173 + 166 158 145 151 133 113 + 105 123 142 156 161 174 + 185 193 211 221 220 236 + 249 195 180 169 162 224 + 215 175 175 130 143 153 + 190 212 222 202 216 216 + 169 168 193 204 260 243 + 205 178 151 120 154 168 + 201 196 69 49 56 42 + 99 137 153 242 206 151 + 193 160 131 54 150 39 + 104 95 101 121 141 152 + 169 157 177 160 58 48 + 62 76 196 115 86 72 + 66 54 45 54 68 79 + 101 112 88 98 85 71 + 71 54 67 43 33 21 + 34 20 100000000 10 22 56 + 81 64 47 37 48 59 + 72 53 67 82 75 89 + 93 72 112 125 112 100 + 112 127 133 158 127 159 + 146 144 131 154 167 103 + 83 69 83 31 70 82 + 95 114 121 117 103 186 + 184 172 179 181 209 227 + 234 210 201 189 219 235 + 232 199 218 213 231 247 + 235 247 193 186 178 165 + 171 153 133 125 143 162 + 176 181 194 205 213 231 + 241 240 256 269 215 200 + 189 182 244 235 195 195 + 150 163 173 210 232 242 + 222 236 236 189 188 213 + 224 280 263 225 198 171 + 140 174 188 221 216 49 + 29 36 62 119 157 173 + 262 226 171 213 180 151 + 74 170 59 114 105 111 + 131 151 162 179 167 187 + 170 68 58 72 86 206 + 125 96 82 76 64 55 + 64 78 89 111 122 98 + 106 93 81 78 61 77 + 50 29 31 44 30 10 + 100000000 12 51 76 54 37 + 27 38 49 62 63 77 + 73 65 79 83 62 102 + 115 102 91 103 118 123 + 148 117 149 137 135 122 + 145 158 113 93 79 93 + 41 80 92 105 124 131 + 127 113 185 175 163 170 + 172 199 217 224 203 194 + 187 212 245 225 209 228 + 223 241 257 245 257 203 + 196 188 175 181 163 143 + 135 153 172 186 191 204 + 215 223 241 251 250 266 + 279 225 210 199 192 254 + 245 205 205 160 173 183 + 220 242 252 232 246 246 + 199 198 223 234 290 273 + 235 208 181 150 184 198 + 211 209 39 19 46 72 + 129 167 183 272 236 181 + 223 190 142 84 180 69 + 114 105 111 131 151 162 + 179 167 187 170 80 70 + 84 98 207 137 108 94 + 88 76 67 76 90 101 + 123 134 107 94 81 93 + 66 49 72 38 17 29 + 42 42 22 12 100000000 39 + 64 42 25 15 26 37 + 50 63 77 61 53 67 + 71 50 90 103 90 79 + 91 106 111 136 105 137 + 125 123 110 133 146 113 + 93 79 93 53 92 92 + 105 124 131 127 113 173 + 163 151 158 160 187 205 + 212 191 182 175 200 245 + 213 209 228 223 241 257 + 245 257 203 196 188 175 + 181 163 143 135 153 172 + 186 191 204 215 223 241 + 251 250 266 279 225 210 + 199 192 254 245 205 205 + 160 173 183 220 242 252 + 232 246 246 199 198 223 + 234 290 273 240 220 193 + 162 196 203 199 197 27 + 7 44 77 141 179 195 + 272 236 181 223 184 130 + 84 180 69 153 144 150 + 170 190 201 218 206 226 + 209 115 105 119 133 212 + 131 113 99 110 111 90 + 81 95 95 117 128 99 + 86 73 87 58 41 64 + 30 23 35 48 77 61 + 51 39 100000000 25 81 64 + 54 65 76 89 102 116 + 100 92 94 85 64 104 + 117 104 113 125 140 125 + 150 119 151 159 157 144 + 167 180 152 132 118 132 + 88 127 131 144 163 170 + 166 152 207 197 185 192 + 194 201 219 226 225 216 + 209 234 282 247 248 265 + 262 280 296 284 296 242 + 235 227 214 220 202 182 + 174 192 211 225 230 243 + 254 262 280 290 289 305 + 318 264 249 238 231 292 + 283 244 244 199 212 222 + 259 273 263 271 285 255 + 236 218 243 243 328 311 + 241 214 187 156 190 204 + 213 231 12 32 50 69 + 135 173 189 311 275 220 + 262 218 164 123 219 108 + 133 124 130 150 170 181 + 198 186 206 189 129 119 + 133 147 226 156 138 124 + 135 125 115 106 120 120 + 142 153 124 111 98 112 + 83 66 89 55 48 60 + 73 91 71 61 49 25 + 100000000 61 44 34 45 56 + 69 82 96 80 72 69 + 60 39 79 92 79 88 + 100 115 100 125 94 126 + 134 132 119 142 155 132 + 112 98 112 102 141 111 + 124 143 150 146 132 182 + 172 160 167 169 176 194 + 201 200 191 184 209 257 + 222 228 240 242 260 276 + 264 276 222 215 207 194 + 200 182 162 154 172 191 + 205 210 223 234 242 260 + 270 269 285 298 244 229 + 218 211 273 264 224 224 + 179 192 202 239 261 271 + 251 265 265 218 217 242 + 253 309 292 259 239 212 + 181 215 222 188 206 37 + 56 75 94 160 198 214 + 291 255 200 242 193 139 + 103 199 88 129 120 126 + 146 166 177 194 182 202 + 185 125 115 129 143 222 + 182 153 139 133 121 112 + 121 135 146 168 179 152 + 139 126 138 111 94 117 + 83 62 74 87 87 67 + 57 45 72 47 100000000 20 + 30 41 52 65 78 84 + 76 68 38 29 8 48 + 61 48 57 69 84 69 + 94 63 95 103 101 88 + 111 124 128 108 94 108 + 98 137 107 120 139 146 + 142 128 151 141 129 136 + 138 145 163 170 169 160 + 153 178 226 191 201 209 + 215 233 246 247 259 218 + 204 196 183 171 178 158 + 150 168 187 201 206 219 + 230 238 256 266 265 281 + 268 240 225 214 207 269 + 260 220 220 175 188 198 + 235 257 267 247 261 261 + 214 213 238 249 305 288 + 255 265 238 207 233 218 + 157 175 72 52 89 122 + 186 224 240 274 228 196 + 215 162 108 99 195 84 + 109 100 106 126 146 157 + 174 162 182 165 105 95 + 109 123 202 162 133 119 + 113 101 92 101 115 126 + 148 159 132 119 106 118 + 91 74 97 63 42 54 + 67 67 47 37 25 64 + 84 37 100000000 10 21 32 + 45 58 72 56 48 62 + 66 45 85 98 85 74 + 86 101 106 131 100 132 + 120 118 105 128 141 108 + 88 74 88 78 117 87 + 100 119 126 122 108 168 + 158 146 153 155 182 200 + 207 186 177 170 195 240 + 208 204 223 218 236 252 + 240 252 198 191 183 170 + 176 158 138 130 148 167 + 181 186 199 210 218 236 + 246 245 261 274 220 205 + 194 187 249 240 200 200 + 155 168 178 215 237 247 + 227 241 241 194 193 218 + 229 285 268 235 245 218 + 187 213 198 194 192 52 + 32 69 102 166 204 220 + 267 231 176 218 179 125 + 79 175 64 99 90 96 + 116 136 147 164 152 172 + 155 95 85 99 113 192 + 152 123 109 103 91 82 + 91 105 116 138 149 122 + 109 96 108 81 64 87 + 53 32 44 57 57 37 + 27 15 54 74 27 10 + 100000000 11 22 35 48 62 + 46 38 52 56 35 75 + 88 75 64 76 91 96 + 121 90 122 110 108 95 + 118 131 98 78 64 78 + 68 107 77 90 109 116 + 112 98 158 148 136 143 + 145 172 190 197 176 167 + 160 185 230 198 194 213 + 208 226 242 230 242 188 + 181 173 160 166 148 128 + 120 138 157 171 176 189 + 200 208 226 236 235 251 + 264 210 195 184 177 239 + 230 190 190 145 158 168 + 205 227 237 217 231 231 + 184 183 208 219 275 258 + 225 235 208 177 203 188 + 184 182 42 22 59 92 + 156 194 210 257 221 166 + 208 169 115 69 165 54 + 88 79 85 105 125 136 + 153 141 161 144 95 85 + 99 113 181 152 123 109 + 103 91 82 91 105 116 + 138 149 125 133 120 108 + 105 88 104 77 56 58 + 71 57 37 27 39 78 + 102 55 64 54 100000000 11 + 24 37 51 35 27 41 + 84 63 103 116 103 53 + 65 80 124 114 118 112 + 99 97 84 107 120 87 + 67 53 67 68 107 66 + 79 98 105 101 87 147 + 137 125 132 134 162 180 + 187 165 156 149 174 219 + 187 183 202 197 215 231 + 219 231 177 170 162 149 + 155 137 117 109 127 146 + 160 165 178 189 197 215 + 225 224 240 253 199 184 + 173 166 228 219 179 179 + 134 147 157 194 216 226 + 206 220 220 173 172 197 + 208 264 247 214 228 201 + 177 192 177 174 171 66 + 46 73 99 156 194 210 + 246 210 155 197 158 104 + 58 154 43 77 68 74 + 94 114 125 142 130 150 + 133 84 74 88 102 170 + 141 112 98 92 80 71 + 80 94 105 127 138 114 + 122 109 97 94 77 93 + 66 45 47 60 46 26 + 16 28 67 91 44 53 + 43 51 100000000 13 26 40 + 24 16 30 73 52 92 + 105 92 42 54 69 113 + 103 107 101 88 86 73 + 96 109 76 56 42 56 + 57 96 55 68 87 94 + 90 76 136 126 114 121 + 123 151 169 176 154 145 + 138 163 208 176 172 191 + 186 204 220 208 220 166 + 159 151 138 144 126 106 + 98 116 135 149 154 167 + 178 186 204 214 213 229 + 242 188 173 162 155 217 + 208 168 168 123 136 146 + 183 205 215 195 209 209 + 162 161 186 197 253 236 + 203 217 190 166 181 166 + 163 160 55 35 62 88 + 145 183 199 235 199 144 + 186 147 93 47 143 32 + 64 55 61 81 101 112 + 129 117 137 120 84 74 + 88 102 157 141 112 98 + 92 80 71 80 94 105 + 127 138 114 124 111 97 + 111 94 93 83 73 61 + 74 46 40 50 62 96 + 97 50 70 77 57 68 + 100000000 13 27 11 22 36 + 79 58 98 111 98 29 + 41 56 119 90 109 88 + 75 73 60 83 96 63 + 43 29 43 57 96 42 + 55 74 81 77 63 123 + 113 101 108 110 138 156 + 163 141 132 125 150 195 + 163 159 178 173 191 207 + 195 207 153 146 138 125 + 131 113 93 85 103 122 + 136 141 154 165 173 191 + 201 200 216 229 175 160 + 149 142 204 195 155 155 + 110 123 133 170 192 202 + 182 196 196 149 148 173 + 184 240 223 190 204 177 + 166 168 153 150 147 89 + 69 76 88 145 183 199 + 222 186 131 173 134 80 + 34 130 19 51 42 48 + 68 88 99 116 104 124 + 107 71 61 75 89 144 + 128 99 85 79 67 58 + 67 81 92 114 125 101 + 111 98 84 98 81 80 + 70 60 48 61 33 27 + 37 49 83 108 68 74 + 64 75 86 99 100000000 14 + 29 40 54 97 76 116 + 129 116 47 59 74 137 + 108 127 106 93 91 78 + 101 114 50 30 16 30 + 44 83 29 42 61 68 + 64 50 133 131 119 126 + 128 156 174 181 157 148 + 136 166 182 179 146 165 + 160 178 194 182 194 140 + 133 125 112 118 100 80 + 72 90 109 123 128 141 + 152 160 178 188 187 203 + 216 162 147 136 129 191 + 182 142 142 97 110 120 + 157 179 189 169 183 183 + 136 135 160 171 227 210 + 177 191 164 153 155 140 + 168 163 76 56 63 75 + 132 170 186 209 173 118 + 160 127 98 21 117 6 + 65 56 62 82 102 113 + 130 118 138 121 85 75 + 89 103 158 142 113 99 + 93 81 72 81 95 106 + 128 139 115 125 112 98 + 112 95 94 84 74 62 + 75 47 41 51 63 97 + 101 54 74 78 61 72 + 85 14 100000000 15 26 40 + 83 62 102 115 102 33 + 45 60 123 94 113 92 + 79 77 64 87 100 64 + 44 30 44 58 97 43 + 56 75 82 78 64 127 + 117 105 112 114 142 160 + 167 145 136 129 154 196 + 167 160 179 174 192 208 + 196 208 154 147 139 126 + 132 114 94 86 104 123 + 137 142 155 166 174 192 + 202 201 217 230 176 161 + 150 143 205 196 156 156 + 111 124 134 171 193 203 + 183 197 197 150 149 174 + 185 241 224 191 205 178 + 167 169 154 154 151 90 + 70 77 89 146 184 200 + 223 187 132 174 138 84 + 35 131 20 110 101 107 + 127 147 158 175 163 183 + 166 130 120 134 148 203 + 187 158 144 138 126 117 + 126 140 151 173 184 160 + 170 157 143 150 133 139 + 122 101 104 117 92 83 + 73 84 111 86 39 59 + 69 46 57 70 59 45 + 100000000 11 25 68 47 87 + 100 87 18 30 45 108 + 79 98 77 64 62 49 + 72 85 109 89 75 89 + 103 142 88 101 120 127 + 123 109 112 102 90 97 + 99 127 145 152 130 121 + 114 139 198 152 162 181 + 176 194 210 208 220 193 + 165 157 144 132 159 139 + 131 149 168 182 187 200 + 211 219 237 235 242 249 + 232 221 206 195 188 250 + 241 201 201 156 169 179 + 216 238 248 228 242 242 + 195 194 219 230 286 269 + 236 250 223 212 214 199 + 139 136 111 91 119 134 + 191 229 245 235 189 177 + 176 123 69 80 176 65 + 123 114 120 140 160 171 + 188 176 196 179 130 120 + 134 148 216 187 158 144 + 138 126 117 126 140 151 + 173 184 160 167 154 143 + 139 122 139 111 90 93 + 106 92 72 62 73 100 + 75 28 48 58 35 46 + 59 72 86 70 100000000 14 + 57 36 76 89 76 85 + 97 112 97 122 91 123 + 131 129 116 139 152 122 + 102 88 102 103 142 101 + 114 133 140 136 122 179 + 169 157 164 166 173 191 + 198 197 188 181 206 254 + 219 218 237 232 250 266 + 254 266 212 205 197 184 + 190 172 152 144 162 181 + 195 200 213 224 232 250 + 260 259 275 288 234 219 + 208 201 263 254 214 214 + 169 182 192 229 251 261 + 241 255 255 208 207 232 + 243 299 282 249 263 236 + 212 227 212 185 203 100 + 80 108 134 191 229 245 + 281 245 190 232 190 136 + 93 189 78 109 100 106 + 126 146 157 174 162 182 + 165 116 106 120 134 202 + 173 144 130 124 112 103 + 112 126 137 159 170 146 + 153 140 129 125 108 125 + 97 76 79 92 78 58 + 48 59 86 61 14 34 + 44 21 32 45 58 72 + 56 48 100000000 43 22 62 + 75 62 71 83 98 83 + 108 77 109 117 115 102 + 125 138 108 88 74 88 + 89 128 87 100 119 126 + 122 108 165 155 143 150 + 152 159 177 184 183 174 + 167 192 240 205 204 223 + 218 236 252 240 252 198 + 191 183 170 176 158 138 + 130 148 167 181 186 199 + 210 218 236 246 245 261 + 274 220 205 194 187 249 + 240 200 200 155 168 178 + 215 237 247 227 241 241 + 194 193 218 229 285 268 + 235 249 222 198 213 198 + 171 189 86 66 94 120 + 177 215 231 267 231 176 + 218 176 122 79 175 64 + 118 109 115 135 155 166 + 183 171 191 174 125 115 + 129 143 211 182 153 139 + 133 121 112 121 135 146 + 168 179 155 162 149 138 + 134 117 134 106 85 88 + 101 87 67 57 68 95 + 70 23 43 53 30 41 + 54 67 55 65 57 9 + 100000000 31 71 32 19 28 + 40 55 40 65 60 87 + 74 72 59 82 95 117 + 97 83 97 98 137 96 + 109 128 135 131 117 122 + 112 100 107 109 137 155 + 162 140 131 124 149 208 + 162 172 191 186 204 220 + 218 230 203 175 167 154 + 142 167 147 139 157 176 + 190 195 208 219 227 245 + 245 252 259 242 229 214 + 203 196 258 249 209 209 + 164 177 187 224 246 256 + 236 250 250 203 202 227 + 238 294 277 244 258 231 + 207 222 207 149 146 95 + 75 103 129 186 224 240 + 245 199 185 186 133 79 + 88 184 73 139 130 136 + 156 176 187 204 192 212 + 195 146 136 150 164 232 + 195 174 160 154 142 133 + 142 156 159 181 192 163 + 150 137 151 122 105 128 + 94 87 99 112 108 88 + 78 88 64 39 44 64 + 73 51 62 75 88 76 + 86 78 30 21 100000000 40 + 53 40 49 61 76 61 + 86 55 87 95 93 80 + 103 116 138 118 104 118 + 119 158 117 130 149 156 + 152 138 143 133 121 128 + 130 137 155 162 161 152 + 145 170 218 183 193 201 + 207 225 238 239 251 224 + 196 188 175 163 188 168 + 160 178 197 211 216 229 + 240 248 266 266 273 277 + 260 250 235 224 217 279 + 270 230 230 185 198 208 + 245 267 277 257 271 271 + 224 223 248 259 315 298 + 265 278 251 220 243 228 + 149 167 76 95 114 133 + 199 237 253 266 220 206 + 207 154 100 109 205 94 + 179 170 176 196 216 227 + 244 232 252 235 186 176 + 190 204 272 235 214 200 + 194 182 173 182 196 199 + 221 232 203 190 177 191 + 162 145 168 134 127 139 + 152 148 128 118 128 104 + 79 84 104 113 91 102 + 115 128 116 126 118 70 + 61 40 100000000 22 80 89 + 101 46 30 55 15 47 + 65 70 57 80 93 129 + 158 144 158 159 198 157 + 170 189 196 192 178 120 + 110 98 105 107 97 115 + 122 138 129 122 147 178 + 160 170 161 184 202 198 + 216 228 201 173 165 152 + 140 228 208 200 218 237 + 212 256 269 245 253 271 + 243 250 237 220 275 275 + 264 257 319 310 270 270 + 225 238 248 285 307 317 + 297 311 311 264 263 288 + 299 355 338 305 318 291 + 260 283 268 109 128 116 + 135 154 173 239 277 293 + 227 197 246 184 131 77 + 149 245 134 205 196 202 + 222 242 253 270 258 278 + 261 225 215 229 243 298 + 278 253 239 233 221 212 + 221 235 242 264 275 246 + 233 220 234 205 188 211 + 177 170 182 195 187 171 + 161 171 147 122 127 147 + 156 134 145 158 154 140 + 155 161 113 104 83 43 + 100000000 123 132 125 24 8 + 33 28 56 43 48 35 + 58 71 107 184 170 184 + 198 237 183 196 215 222 + 218 204 98 88 76 83 + 85 106 124 131 116 107 + 100 125 184 138 148 167 + 162 180 196 194 206 179 + 151 143 130 118 213 226 + 226 244 215 190 234 247 + 223 231 249 221 228 235 + 218 253 253 242 235 297 + 288 248 261 251 264 274 + 263 285 295 275 289 298 + 290 289 314 325 333 316 + 317 344 318 303 309 294 + 118 122 159 178 197 216 + 282 320 336 221 175 224 + 162 109 55 175 271 160 + 101 92 98 118 138 149 + 166 154 174 157 121 111 + 125 139 194 178 149 135 + 129 117 108 117 131 142 + 164 175 151 161 148 134 + 148 131 130 120 110 98 + 111 83 77 87 99 133 + 135 90 110 114 97 108 + 121 50 36 51 62 76 + 117 96 56 13 100000000 9 + 21 36 21 46 41 68 + 55 53 40 63 76 100 + 80 66 80 94 133 79 + 92 111 118 114 100 103 + 93 81 88 90 118 136 + 143 121 112 105 130 189 + 143 153 172 167 185 201 + 199 211 184 156 148 135 + 123 150 130 122 140 159 + 173 178 191 202 210 228 + 226 233 240 223 212 197 + 186 179 241 232 192 192 + 147 160 170 207 229 239 + 219 233 233 186 185 210 + 221 277 260 227 241 214 + 203 205 190 130 127 126 + 106 113 125 182 220 236 + 226 180 168 167 114 60 + 71 167 56 92 83 89 + 109 129 140 157 145 165 + 148 112 102 116 130 185 + 169 140 126 120 108 99 + 108 122 133 155 166 142 + 152 139 125 139 122 121 + 111 101 89 102 74 68 + 78 90 124 128 81 101 + 105 88 99 112 41 27 + 42 53 67 110 89 95 + 117 129 100000000 12 27 125 + 61 80 59 46 44 31 + 54 67 91 71 57 71 + 85 124 70 83 102 109 + 105 91 94 84 72 79 + 81 109 127 134 112 103 + 96 121 180 134 144 163 + 158 176 192 190 202 175 + 147 139 126 114 141 121 + 113 131 150 164 169 182 + 193 201 219 217 224 231 + 214 203 188 177 170 232 + 223 183 183 138 151 161 + 198 220 230 210 224 224 + 177 176 201 212 268 251 + 218 232 205 194 196 181 + 121 118 117 97 104 116 + 173 211 227 217 171 159 + 158 105 51 62 158 47 + 80 71 77 97 117 128 + 145 133 153 136 100 90 + 104 118 173 157 128 114 + 108 96 87 96 110 121 + 143 154 130 140 127 113 + 127 110 109 99 89 77 + 90 62 56 66 78 112 + 116 69 89 93 76 87 + 100 29 15 30 41 55 + 98 77 83 105 117 48 + 100000000 15 113 49 68 47 + 34 32 19 42 55 79 + 59 45 59 73 112 58 + 71 90 97 93 79 82 + 72 60 67 69 97 115 + 122 100 91 84 109 168 + 122 132 151 146 164 180 + 178 190 163 135 127 114 + 102 129 109 101 119 138 + 152 157 170 181 189 207 + 205 212 219 202 191 176 + 165 158 220 211 171 171 + 126 139 149 186 208 218 + 198 212 212 165 164 189 + 200 256 239 206 220 193 + 182 184 169 109 106 105 + 85 92 104 161 199 215 + 205 159 147 146 93 39 + 50 146 35 181 172 178 + 198 218 229 246 234 254 + 237 201 191 205 219 274 + 258 229 215 209 197 188 + 197 211 222 244 255 231 + 241 228 214 228 211 210 + 200 190 178 191 163 157 + 167 179 172 147 152 172 + 181 159 170 183 130 116 + 131 142 138 129 108 68 + 90 148 149 101 100000000 98 + 34 53 32 19 24 11 + 34 47 83 160 146 160 + 174 213 159 172 191 198 + 194 180 74 64 52 59 + 61 82 100 107 92 83 + 76 101 160 114 124 143 + 138 156 172 170 182 155 + 127 119 106 94 189 202 + 202 220 191 166 210 223 + 199 207 225 197 204 211 + 194 229 229 218 211 273 + 264 224 237 227 240 250 + 239 261 271 251 265 274 + 266 265 290 301 309 292 + 293 320 294 283 285 270 + 94 98 184 186 193 205 + 262 300 316 197 151 200 + 138 85 31 151 247 136 + 197 188 194 214 234 245 + 262 250 270 253 217 207 + 221 235 290 274 245 231 + 225 213 204 213 227 238 + 260 271 247 249 236 230 + 221 204 226 193 186 194 + 207 179 173 177 187 163 + 138 143 163 172 150 161 + 174 146 132 147 158 129 + 120 99 59 81 139 148 + 117 16 100000000 25 44 48 + 35 40 27 50 63 99 + 176 162 176 190 229 175 + 188 207 214 210 196 90 + 80 68 75 77 98 116 + 123 108 99 92 117 176 + 130 140 159 154 172 188 + 186 198 171 143 135 122 + 110 205 218 218 236 207 + 182 226 239 215 223 241 + 213 220 227 210 245 245 + 234 227 289 280 240 253 + 243 256 266 255 277 287 + 267 281 290 282 281 306 + 317 325 308 309 336 310 + 299 301 286 110 114 175 + 194 209 221 278 316 332 + 213 167 216 154 101 47 + 167 263 152 213 204 210 + 230 250 261 278 266 286 + 269 220 210 224 238 306 + 269 248 234 228 216 207 + 216 230 233 255 266 237 + 224 211 225 196 179 202 + 168 161 173 186 182 162 + 152 162 138 113 118 138 + 147 125 136 149 162 150 + 160 152 104 95 74 34 + 56 114 123 135 80 64 + 100000000 19 51 99 104 91 + 114 127 163 192 178 192 + 193 232 191 204 223 230 + 226 212 154 144 132 139 + 125 101 119 126 144 147 + 156 161 182 174 184 165 + 198 216 202 230 242 215 + 195 187 186 174 249 242 + 234 252 251 226 270 283 + 259 267 285 254 257 241 + 224 282 289 278 271 332 + 323 284 297 259 272 282 + 299 321 331 311 325 334 + 298 297 322 333 368 351 + 339 352 325 294 317 302 + 113 132 150 169 188 207 + 273 311 327 231 211 260 + 198 165 111 183 279 168 + 194 185 191 211 231 242 + 259 247 267 250 201 191 + 205 219 287 250 229 215 + 209 197 188 197 211 214 + 236 247 218 205 192 206 + 177 160 183 149 142 154 + 167 163 143 133 143 119 + 94 99 119 128 106 117 + 130 143 131 141 133 85 + 76 55 15 37 95 104 + 116 61 45 70 100000000 32 + 80 85 72 95 108 144 + 173 159 173 174 213 172 + 185 204 211 207 193 135 + 125 113 120 106 82 100 + 107 125 128 137 142 163 + 155 165 146 179 197 183 + 211 223 196 176 168 167 + 155 230 223 215 233 232 + 207 251 264 240 248 266 + 235 238 222 205 263 270 + 259 252 313 304 265 278 + 240 253 263 280 302 312 + 292 306 315 279 278 303 + 314 349 332 320 333 306 + 275 298 283 94 113 131 + 150 169 188 254 292 308 + 212 192 241 179 146 92 + 164 260 149 217 208 214 + 234 254 265 282 270 290 + 273 233 223 237 251 310 + 282 261 247 241 229 220 + 229 243 246 268 279 250 + 237 224 238 209 192 215 + 181 174 186 199 195 175 + 165 175 151 126 131 151 + 160 138 149 162 166 152 + 167 165 117 108 87 47 + 69 127 136 137 93 77 + 102 32 100000000 112 113 104 + 103 88 119 196 182 196 + 206 245 195 208 227 234 + 230 216 104 100 88 89 + 74 50 68 75 93 96 + 106 110 131 123 133 114 + 147 165 151 179 191 164 + 144 136 136 124 198 211 + 238 256 200 175 219 232 + 208 216 234 203 206 190 + 173 231 238 227 220 281 + 272 233 246 263 276 273 + 248 270 280 260 274 283 + 289 301 326 337 317 300 + 302 329 330 307 321 306 + 62 81 163 182 201 220 + 286 324 340 180 160 209 + 147 115 120 187 283 172 + 228 219 225 245 265 276 + 293 281 301 284 235 225 + 239 253 321 284 263 249 + 243 231 222 231 245 248 + 270 281 252 239 226 240 + 211 194 217 183 176 188 + 201 197 177 167 177 153 + 128 133 153 162 140 151 + 164 177 165 175 167 119 + 110 89 49 71 129 138 + 150 95 79 15 34 13 + 100000000 119 106 116 101 132 + 207 193 207 208 247 206 + 219 238 245 241 227 117 + 113 101 102 87 63 81 + 88 106 109 119 123 144 + 136 146 127 160 178 164 + 192 204 177 157 149 149 + 137 211 224 249 267 213 + 188 232 245 221 229 247 + 216 219 203 186 244 251 + 240 233 294 285 246 259 + 274 287 286 261 283 293 + 273 287 296 302 312 337 + 348 330 313 315 342 340 + 309 332 317 75 94 165 + 184 203 222 288 326 342 + 193 173 222 160 128 126 + 198 294 183 157 148 154 + 174 194 205 222 210 230 + 213 177 167 181 195 250 + 234 205 191 185 173 164 + 173 187 198 220 231 207 + 217 204 190 204 187 186 + 176 166 154 167 139 133 + 143 155 167 142 146 166 + 170 153 164 177 106 92 + 107 118 132 124 103 63 + 85 143 125 77 92 93 + 29 48 27 14 100000000 96 + 10 23 59 136 122 136 + 150 189 135 148 167 174 + 170 156 50 40 28 35 + 37 77 85 92 68 59 + 52 77 136 90 100 119 + 114 132 148 146 158 131 + 103 95 82 70 165 178 + 178 196 167 142 186 199 + 175 183 201 173 180 187 + 170 205 205 194 187 249 + 240 200 213 203 216 226 + 215 237 247 227 241 250 + 242 241 266 277 285 268 + 269 296 270 259 261 246 + 89 74 179 162 169 181 + 238 276 292 173 127 176 + 114 61 7 127 223 112 + 170 161 167 187 207 218 + 235 223 243 226 190 180 + 194 208 263 247 218 204 + 198 186 177 186 200 211 + 233 244 220 230 217 203 + 217 200 199 189 179 167 + 180 152 146 156 168 180 + 155 159 179 183 166 177 + 190 119 105 120 131 145 + 137 116 76 98 156 138 + 90 105 106 42 61 40 + 27 13 100000000 23 36 72 + 149 135 149 163 202 148 + 161 180 187 183 169 63 + 53 41 48 50 90 98 + 105 81 72 65 90 149 + 103 113 132 127 145 161 + 159 171 144 116 108 95 + 83 178 191 191 209 180 + 155 199 212 188 196 214 + 186 193 200 183 218 218 + 207 200 262 253 213 226 + 216 229 239 228 250 260 + 240 254 263 255 254 279 + 290 298 281 282 309 283 + 272 274 259 102 87 192 + 175 182 194 251 289 305 + 186 140 189 127 74 20 + 140 236 125 147 138 144 + 164 184 195 212 200 220 + 203 167 157 171 185 240 + 224 195 181 175 163 154 + 163 177 188 210 221 197 + 207 194 180 194 177 176 + 166 156 144 157 129 123 + 133 145 177 152 136 156 + 160 143 154 167 96 82 + 97 108 122 134 113 73 + 95 153 115 67 82 103 + 39 58 37 24 10 86 + 100000000 33 49 126 112 126 + 140 179 125 138 157 164 + 160 146 40 30 18 25 + 47 87 80 87 63 54 + 42 72 131 85 95 114 + 109 127 143 141 153 126 + 93 85 72 60 160 173 + 168 186 162 137 181 194 + 170 178 196 168 175 182 + 165 200 200 189 182 244 + 235 195 208 193 206 216 + 210 232 242 222 236 245 + 232 231 256 267 280 263 + 264 287 260 249 251 236 + 99 69 172 152 159 171 + 228 266 282 168 122 171 + 109 51 17 117 213 102 + 157 148 154 174 194 205 + 222 210 230 213 177 167 + 181 195 250 234 205 191 + 185 173 164 173 187 198 + 220 231 207 217 204 190 + 204 187 186 176 166 154 + 167 139 133 143 155 189 + 167 146 166 170 153 164 + 177 106 92 107 118 132 + 149 128 88 110 168 125 + 77 92 118 54 73 52 + 39 25 96 15 100000000 59 + 136 122 136 150 189 135 + 148 167 174 170 156 44 + 40 28 29 14 80 62 + 69 45 36 46 54 113 + 67 77 96 91 109 125 + 123 135 108 88 80 76 + 64 142 155 178 196 144 + 119 163 176 152 160 178 + 150 157 164 147 182 182 + 171 164 226 217 177 190 + 203 216 217 192 214 224 + 204 218 227 233 241 266 + 277 262 245 246 273 270 + 259 261 246 92 51 182 + 162 169 181 238 276 292 + 150 104 153 91 55 32 + 127 223 112 98 89 95 + 115 135 146 163 151 171 + 154 118 108 122 136 191 + 175 146 132 126 114 105 + 114 128 139 161 172 148 + 158 145 131 145 128 127 + 117 107 95 108 80 74 + 84 96 130 134 87 107 + 111 94 105 118 47 33 + 48 59 73 116 95 101 + 123 135 66 18 33 131 + 67 86 65 52 50 37 + 60 73 100000000 77 63 77 + 91 130 76 89 108 115 + 111 97 100 90 78 85 + 87 115 133 140 118 109 + 102 127 186 140 150 169 + 164 182 198 196 208 181 + 153 145 132 120 147 127 + 119 137 156 170 175 188 + 199 207 225 223 230 237 + 220 209 194 183 176 238 + 229 189 189 144 157 167 + 204 226 236 216 230 230 + 183 182 207 218 274 257 + 224 238 211 200 202 187 + 127 124 123 103 110 122 + 179 217 233 223 177 165 + 164 111 57 68 164 53 + 47 38 44 64 84 95 + 112 100 120 103 74 64 + 78 92 140 149 120 102 + 82 70 79 88 102 113 + 135 146 122 132 119 105 + 123 111 101 100 90 78 + 91 63 57 67 79 113 + 138 98 104 94 105 116 + 129 30 44 59 70 84 + 127 106 121 143 146 77 + 38 53 151 87 106 85 + 72 70 57 80 93 20 + 100000000 14 28 47 86 25 + 12 31 38 47 20 120 + 110 98 105 107 135 153 + 160 138 129 122 147 178 + 160 142 161 156 174 190 + 178 190 136 129 121 108 + 114 96 76 68 86 105 + 119 124 137 148 156 174 + 184 183 199 212 158 143 + 132 125 187 178 138 138 + 93 106 116 153 175 185 + 165 179 179 132 131 156 + 167 223 206 173 187 160 + 174 151 136 147 144 106 + 86 93 96 153 168 192 + 205 169 114 156 123 77 + 39 113 24 35 26 32 + 52 72 83 100 88 108 + 91 60 50 64 78 128 + 135 106 88 68 56 65 + 74 88 99 121 132 108 + 118 105 91 109 97 87 + 86 76 64 77 49 43 + 53 65 99 124 84 90 + 80 91 102 115 16 30 + 45 56 70 113 92 132 + 145 132 63 72 87 153 + 121 140 119 106 104 91 + 114 127 54 34 100000000 14 + 33 72 13 26 45 52 + 48 34 117 129 132 139 + 141 169 158 165 141 132 + 120 150 166 163 130 149 + 144 162 178 166 178 124 + 117 109 96 102 84 64 + 56 74 93 107 112 125 + 136 144 162 172 171 187 + 200 146 131 120 113 175 + 166 126 126 81 94 104 + 141 163 173 153 167 167 + 120 119 144 155 211 194 + 161 175 148 160 139 124 + 181 147 92 72 79 82 + 139 156 180 193 157 102 + 144 111 111 25 101 10 + 160 151 157 177 197 208 + 225 201 221 216 46 36 + 50 64 202 121 92 74 + 54 42 51 60 74 85 + 107 118 94 104 91 77 + 95 96 73 105 126 117 + 81 76 96 106 118 135 + 160 160 143 133 144 155 + 168 109 123 138 149 163 + 189 168 208 221 208 156 + 168 183 229 217 223 215 + 202 200 187 210 223 159 + 139 125 100000000 19 58 138 + 151 170 177 173 159 242 + 240 228 235 237 265 283 + 290 266 257 245 275 291 + 288 255 274 269 287 303 + 291 303 249 242 234 221 + 227 209 189 181 199 218 + 232 237 250 261 269 287 + 297 296 312 325 271 256 + 245 238 282 273 251 251 + 206 219 229 266 263 253 + 270 284 245 226 208 233 + 233 318 301 231 204 177 + 146 180 194 277 272 145 + 125 98 68 125 163 179 + 318 282 227 269 236 207 + 130 226 115 141 132 138 + 158 178 189 206 182 202 + 197 27 17 31 45 183 + 102 73 55 35 23 32 + 41 55 66 88 99 75 + 85 72 58 76 77 54 + 86 107 98 62 57 77 + 87 99 116 141 141 124 + 114 125 136 149 90 104 + 119 130 144 170 149 189 + 202 189 137 149 164 210 + 198 204 196 183 181 168 + 191 204 140 120 106 55 + 100000000 39 119 132 151 158 + 154 140 223 221 209 216 + 218 246 264 271 247 238 + 226 256 272 269 236 255 + 250 268 284 272 284 230 + 223 215 202 208 190 170 + 162 180 199 213 218 231 + 242 250 268 278 277 293 + 306 252 237 226 219 263 + 254 232 232 187 200 210 + 247 244 234 251 265 226 + 207 189 214 214 299 282 + 212 185 158 127 161 175 + 258 253 126 106 79 49 + 106 144 160 299 263 208 + 250 217 188 111 207 96 + 176 167 173 193 213 224 + 241 217 237 232 62 52 + 66 80 218 137 108 90 + 70 58 67 76 90 101 + 123 134 110 120 107 93 + 111 112 89 121 142 133 + 97 92 112 122 134 151 + 176 176 159 149 160 171 + 184 125 139 154 165 179 + 205 184 224 237 224 172 + 184 199 245 233 239 231 + 218 216 203 226 239 175 + 155 141 16 35 100000000 154 + 167 186 193 189 175 258 + 256 244 251 253 281 299 + 306 282 273 261 291 307 + 304 271 290 285 303 319 + 307 319 265 258 250 237 + 243 225 205 197 215 234 + 248 253 266 277 285 303 + 313 312 328 341 287 272 + 261 254 298 289 267 267 + 222 235 245 282 279 269 + 286 300 261 242 224 249 + 249 334 317 247 220 193 + 162 196 210 293 288 161 + 141 114 84 141 179 195 + 334 298 243 285 252 223 + 146 242 131 22 13 19 + 39 59 70 87 75 95 + 78 73 63 77 91 115 + 131 119 101 81 69 78 + 87 101 112 134 145 121 + 131 118 104 122 110 100 + 99 89 77 90 62 56 + 66 78 112 137 97 103 + 93 104 115 128 29 43 + 58 69 83 126 105 145 + 158 145 76 63 78 166 + 112 131 110 97 95 82 + 105 118 45 25 13 27 + 46 85 100000000 13 32 39 + 35 21 104 116 123 130 + 132 160 145 152 128 119 + 107 137 153 150 117 136 + 131 149 165 153 165 111 + 104 96 83 89 71 51 + 43 61 80 94 99 112 + 123 131 149 159 158 174 + 187 133 118 107 100 162 + 153 113 113 68 81 91 + 128 150 160 140 154 154 + 107 106 131 142 198 181 + 148 162 135 160 126 111 + 172 134 105 85 92 95 + 135 143 167 180 144 89 + 131 98 102 38 88 23 + 35 26 32 52 72 83 + 100 88 108 91 86 76 + 90 104 128 144 132 114 + 94 82 91 100 114 125 + 147 158 134 144 131 117 + 135 123 113 112 102 90 + 103 75 69 79 91 125 + 150 110 116 106 117 128 + 141 42 56 71 82 96 + 139 118 133 155 158 89 + 50 65 163 99 118 97 + 84 82 69 92 105 32 + 12 26 40 59 98 13 + 100000000 19 26 35 8 117 + 122 110 117 119 147 158 + 165 141 132 120 150 166 + 163 130 149 144 162 178 + 166 178 124 117 109 96 + 102 84 64 56 74 93 + 107 112 125 136 144 162 + 172 171 187 200 146 131 + 120 113 175 166 126 126 + 81 94 104 141 163 173 + 153 167 167 120 119 144 + 155 211 194 161 175 148 + 173 139 124 159 147 118 + 98 105 108 148 156 180 + 193 157 102 144 111 89 + 51 101 36 29 38 44 + 48 68 79 96 84 104 + 87 96 95 109 123 124 + 140 151 133 113 101 110 + 119 133 144 166 159 153 + 163 150 136 154 142 132 + 131 121 109 122 94 88 + 98 110 144 169 129 135 + 125 136 147 160 61 75 + 90 101 115 158 137 152 + 174 177 108 69 84 182 + 118 137 116 103 101 88 + 111 124 51 31 45 59 + 78 108 32 19 100000000 7 + 16 11 111 123 129 136 + 138 166 152 159 135 126 + 114 144 160 157 124 143 + 138 156 172 160 172 118 + 111 103 90 96 78 58 + 50 68 87 101 106 119 + 130 138 156 166 165 181 + 194 140 125 114 107 169 + 160 120 120 75 88 98 + 135 157 167 147 161 163 + 114 115 140 151 205 188 + 157 171 144 169 135 120 + 178 141 137 117 124 127 + 144 152 176 187 151 96 + 138 105 108 70 97 55 + 22 31 37 41 61 72 + 89 77 97 80 89 91 + 105 119 117 133 147 129 + 109 97 106 115 129 140 + 162 152 149 159 146 132 + 150 138 128 127 117 105 + 118 90 84 94 106 140 + 165 125 131 121 132 143 + 156 57 71 86 97 111 + 154 133 148 170 173 104 + 65 80 178 114 133 112 + 99 97 84 107 120 47 + 27 41 55 74 101 28 + 15 7 100000000 9 18 104 + 116 125 132 134 162 145 + 152 128 119 107 137 153 + 150 117 136 131 149 165 + 153 165 111 104 96 83 + 89 71 51 43 61 80 + 94 99 112 123 131 149 + 159 158 174 187 133 118 + 107 100 162 153 113 113 + 68 81 91 128 150 160 + 140 154 156 107 108 133 + 144 198 181 150 164 137 + 162 128 113 174 134 133 + 113 120 123 137 145 169 + 180 144 89 131 98 104 + 66 90 51 13 22 28 + 32 52 63 80 68 88 + 71 80 98 112 113 108 + 124 138 123 116 104 113 + 122 136 147 169 143 156 + 166 153 139 157 145 135 + 134 124 112 125 97 91 + 101 113 147 172 132 138 + 128 139 150 163 64 78 + 93 104 118 161 140 157 + 179 180 111 74 89 187 + 123 142 121 108 106 93 + 116 129 56 36 48 62 + 81 92 35 24 16 9 + 100000000 27 95 107 134 141 + 140 154 136 143 119 110 + 98 128 144 141 108 127 + 122 140 156 144 156 102 + 95 87 74 80 62 42 + 34 52 71 85 90 103 + 114 122 140 150 149 165 + 178 124 109 98 91 153 + 144 104 104 59 72 82 + 119 141 151 131 145 147 + 98 99 124 135 189 172 + 141 155 128 153 119 104 + 166 125 140 120 127 130 + 128 136 160 171 135 80 + 122 89 113 73 81 58 + 40 34 40 59 79 90 + 107 95 115 98 94 84 + 98 112 135 151 140 122 + 102 90 99 108 122 133 + 155 166 142 152 139 125 + 143 131 121 120 110 98 + 111 83 77 87 99 133 + 158 118 124 114 125 136 + 149 50 64 79 90 104 + 147 126 141 163 166 97 + 58 73 171 107 126 105 + 92 90 77 100 113 40 + 20 34 48 67 106 21 + 8 11 18 27 100000000 122 + 130 118 125 127 155 163 + 170 146 137 125 155 171 + 168 135 154 149 167 183 + 171 183 129 122 114 101 + 107 89 69 61 79 98 + 112 117 130 141 149 167 + 177 176 192 205 151 136 + 125 118 180 171 131 131 + 86 99 109 146 168 178 + 158 172 174 125 126 151 + 162 216 199 168 182 155 + 180 146 131 167 152 126 + 106 113 116 155 163 187 + 198 162 107 149 116 97 + 59 108 44 129 120 126 + 146 166 177 194 182 202 + 185 149 139 153 167 222 + 206 177 163 157 145 136 + 145 159 170 192 203 179 + 189 176 162 176 159 158 + 148 138 126 139 111 105 + 115 127 161 165 118 138 + 142 125 136 149 78 64 + 79 90 104 147 126 106 + 128 166 97 49 64 136 + 72 91 70 57 43 68 + 33 66 31 108 94 108 + 122 161 107 120 139 146 + 142 128 100000000 12 51 58 + 80 120 113 120 96 87 + 75 105 164 118 128 147 + 142 160 176 174 186 159 + 126 118 105 93 178 158 + 150 168 187 170 206 219 + 203 211 229 201 208 215 + 198 233 225 214 207 269 + 260 220 220 175 188 198 + 235 257 267 247 261 261 + 214 213 238 249 305 288 + 255 269 242 231 233 218 + 132 102 154 134 141 153 + 210 248 264 201 155 196 + 142 84 50 99 195 84 + 117 108 114 134 154 165 + 182 170 190 173 137 127 + 141 155 210 194 165 151 + 145 133 124 133 147 158 + 180 191 167 177 164 150 + 164 147 146 136 126 114 + 127 99 93 103 115 149 + 153 106 126 130 113 124 + 137 66 52 67 78 92 + 135 114 94 116 154 85 + 37 52 124 60 79 58 + 45 31 56 21 54 19 + 96 82 96 110 149 95 + 108 127 134 130 116 61 + 100000000 39 46 68 108 101 + 108 84 75 63 93 152 + 106 116 135 130 148 164 + 162 174 147 114 106 93 + 81 166 146 138 156 175 + 158 194 207 191 199 217 + 189 196 203 186 221 213 + 202 195 257 248 208 208 + 163 176 186 223 245 255 + 235 249 249 202 201 226 + 237 293 276 243 257 230 + 219 221 206 120 90 142 + 122 129 141 198 236 252 + 189 143 184 130 72 38 + 87 183 72 129 120 126 + 146 166 177 194 182 202 + 185 149 139 153 167 222 + 206 177 163 157 145 136 + 145 159 170 192 203 179 + 189 176 162 176 159 158 + 148 138 126 139 111 105 + 115 127 161 165 118 138 + 142 125 136 149 78 64 + 79 90 104 147 126 106 + 128 166 97 49 64 136 + 72 91 70 57 43 68 + 33 66 31 108 94 108 + 122 161 107 120 139 146 + 142 128 22 12 100000000 7 + 66 80 62 69 45 36 + 24 54 113 67 77 96 + 91 109 125 123 135 108 + 75 67 54 42 142 155 + 150 168 144 119 163 176 + 152 160 178 150 157 164 + 147 182 182 171 164 226 + 217 177 190 175 188 198 + 192 214 224 204 218 227 + 214 213 238 249 262 245 + 246 269 242 231 233 218 + 92 51 154 134 141 153 + 210 248 264 150 104 153 + 91 33 50 99 195 84 + 136 127 133 153 173 184 + 201 189 209 192 156 146 + 160 174 229 213 184 170 + 164 152 143 152 166 177 + 199 210 186 196 183 169 + 183 166 165 155 145 133 + 146 118 112 122 134 168 + 172 125 145 149 132 143 + 156 85 71 86 97 111 + 154 133 113 135 173 104 + 56 71 143 79 98 77 + 64 50 75 40 73 38 + 115 101 115 129 168 114 + 127 146 153 149 135 15 + 19 7 100000000 59 73 55 + 62 38 29 17 47 106 + 60 70 89 84 102 118 + 116 128 101 68 60 47 + 35 135 148 157 175 137 + 112 156 169 145 153 171 + 143 150 157 140 175 175 + 164 157 219 210 170 183 + 182 195 205 185 207 217 + 197 211 220 221 220 245 + 256 255 238 239 266 249 + 238 240 225 85 44 161 + 141 148 160 217 255 271 + 143 97 146 84 26 57 + 106 202 91 143 134 140 + 160 180 191 208 196 216 + 199 163 153 167 181 236 + 220 191 177 171 159 150 + 159 173 184 206 217 193 + 203 190 176 190 173 172 + 162 152 140 153 125 119 + 129 141 175 179 132 152 + 156 139 150 163 92 78 + 93 104 118 161 140 102 + 124 180 111 63 78 132 + 68 87 66 53 39 82 + 29 14 45 122 108 122 + 136 175 121 134 153 160 + 156 142 30 26 14 15 + 100000000 66 48 55 31 22 + 32 40 99 53 63 82 + 77 95 111 109 121 94 + 74 66 62 50 128 141 + 164 182 130 105 149 162 + 138 146 164 136 143 150 + 133 168 168 157 150 212 + 203 163 176 189 202 203 + 178 200 210 190 204 213 + 219 227 252 263 248 231 + 232 259 256 245 247 232 + 78 37 168 148 155 167 + 224 262 278 136 90 139 + 77 41 46 113 209 98 + 167 158 164 184 204 215 + 232 220 240 223 187 177 + 191 205 260 244 215 201 + 195 183 174 183 197 208 + 230 241 217 227 214 200 + 214 197 196 186 176 164 + 177 149 143 153 165 199 + 176 156 176 180 163 174 + 187 116 102 117 128 142 + 158 137 97 119 177 135 + 87 102 127 92 82 50 + 77 63 106 53 38 69 + 146 132 146 160 199 145 + 158 177 184 180 166 54 + 50 38 39 24 100000000 18 + 25 43 46 56 60 81 + 73 83 64 97 115 101 + 129 141 114 94 86 86 + 74 148 161 188 206 150 + 125 169 182 158 166 184 + 153 156 140 123 181 188 + 177 170 231 222 183 196 + 213 226 223 198 220 230 + 210 224 233 239 251 276 + 287 267 250 252 279 280 + 269 271 256 12 31 192 + 172 179 191 248 286 302 + 130 110 159 97 65 70 + 137 233 122 185 176 182 + 202 222 233 234 238 258 + 241 205 195 209 223 278 + 262 233 219 213 201 192 + 201 215 226 248 259 235 + 245 232 218 232 215 214 + 204 194 182 195 167 161 + 171 183 217 194 174 194 + 198 181 192 205 134 120 + 135 146 160 176 155 115 + 137 195 153 105 120 145 + 110 100 68 95 81 124 + 71 56 87 164 150 164 + 178 217 163 176 195 202 + 198 184 72 68 56 57 + 42 18 100000000 7 25 60 + 72 42 63 55 65 46 + 79 97 83 111 123 96 + 76 68 102 90 130 143 + 206 224 132 107 151 164 + 140 148 166 135 138 122 + 105 163 170 159 152 213 + 204 165 178 197 210 205 + 180 202 212 192 206 215 + 221 253 278 274 249 232 + 234 261 282 287 273 258 + 30 31 210 190 197 209 + 266 290 314 112 92 141 + 79 81 88 155 225 140 + 182 173 179 199 219 230 + 227 235 255 238 202 192 + 206 220 275 259 230 216 + 210 198 189 198 212 223 + 245 256 232 242 229 215 + 229 212 211 201 191 179 + 192 164 158 168 180 214 + 201 171 191 195 178 189 + 202 131 117 132 143 157 + 183 162 122 144 202 150 + 102 117 152 107 107 75 + 92 78 121 68 53 84 + 161 147 161 175 214 160 + 173 192 199 195 181 69 + 65 53 54 39 25 7 + 100000000 18 53 65 35 56 + 48 58 39 72 90 76 + 104 116 89 69 61 95 + 83 123 136 203 221 125 + 100 144 157 133 141 159 + 128 131 115 98 156 163 + 152 145 206 197 158 171 + 190 203 198 173 195 205 + 185 199 208 214 246 271 + 267 242 225 227 254 275 + 284 266 251 37 24 207 + 187 194 206 263 283 307 + 105 85 134 72 74 85 + 152 218 137 164 155 161 + 181 201 212 209 217 237 + 220 184 174 188 202 257 + 241 212 198 192 180 171 + 180 194 205 227 238 214 + 224 211 197 211 194 193 + 183 173 161 174 146 140 + 150 162 196 200 153 173 + 177 160 171 184 113 99 + 114 125 139 182 161 123 + 145 201 132 84 99 153 + 89 108 85 74 60 103 + 50 35 66 143 129 143 + 157 196 142 155 174 181 + 177 163 51 47 35 36 + 21 35 17 24 100000000 35 + 47 17 76 30 40 59 + 54 72 88 86 98 71 + 51 43 77 65 105 118 + 185 203 107 82 126 139 + 115 123 141 113 120 127 + 110 145 145 134 127 189 + 180 140 153 172 185 180 + 155 177 187 167 181 190 + 196 228 253 250 225 208 + 209 236 257 266 248 233 + 47 6 189 169 176 188 + 245 265 289 113 67 116 + 54 56 67 134 200 119 + 173 164 170 190 210 221 + 210 220 240 229 193 183 + 197 211 260 250 221 207 + 201 189 180 189 203 214 + 236 247 223 233 220 206 + 220 203 202 192 182 170 + 183 155 149 159 171 205 + 209 162 182 186 169 180 + 193 122 108 123 134 148 + 191 170 132 154 210 141 + 93 108 162 98 117 94 + 83 69 112 59 44 75 + 152 138 152 166 205 151 + 164 183 190 186 172 45 + 56 44 45 30 44 26 + 33 9 100000000 12 18 77 + 31 41 60 55 73 89 + 87 99 72 52 44 42 + 30 106 119 190 208 108 + 83 127 140 116 124 142 + 114 121 128 111 146 146 + 135 128 190 181 141 154 + 173 186 181 156 178 188 + 168 182 191 197 229 254 + 251 226 209 210 237 258 + 275 249 234 56 15 198 + 178 185 197 254 266 290 + 114 68 117 55 21 76 + 143 201 128 162 153 159 + 179 199 210 222 215 235 + 218 182 172 186 200 255 + 239 210 196 190 178 169 + 178 192 203 225 236 212 + 222 209 195 209 192 191 + 181 171 159 172 144 138 + 148 160 194 198 151 171 + 175 158 169 182 111 97 + 112 123 137 180 159 139 + 161 199 130 82 97 169 + 105 124 103 90 76 101 + 66 56 64 141 127 141 + 155 194 140 153 172 179 + 175 161 33 45 56 57 + 42 56 38 45 21 12 + 100000000 30 89 43 53 72 + 67 85 101 99 111 84 + 51 43 30 18 118 131 + 183 201 120 95 139 152 + 128 136 154 126 133 140 + 123 158 158 147 140 202 + 193 153 166 185 198 193 + 168 190 200 180 194 203 + 209 241 266 263 238 221 + 222 249 270 264 261 246 + 68 27 187 167 174 186 + 243 278 297 126 80 129 + 67 9 83 132 213 117 + 191 182 188 188 208 219 + 192 202 222 227 211 201 + 215 229 242 258 239 225 + 219 207 198 207 221 232 + 254 265 241 251 238 224 + 238 221 220 210 200 188 + 201 173 167 177 189 223 + 227 180 200 204 187 198 + 211 140 126 141 152 166 + 209 188 150 172 228 159 + 111 126 180 116 135 112 + 101 87 130 77 62 93 + 170 156 170 184 223 169 + 182 201 208 204 190 63 + 74 62 63 48 62 44 + 51 27 18 30 100000000 59 + 13 23 42 37 55 71 + 69 81 54 34 26 60 + 48 88 101 172 190 90 + 65 109 122 98 106 124 + 96 103 110 93 128 128 + 117 110 172 163 123 136 + 155 168 163 138 160 170 + 150 164 173 179 211 236 + 233 208 191 192 219 240 + 265 231 216 74 33 216 + 196 203 215 262 248 272 + 96 50 99 37 39 94 + 161 183 146 193 198 204 + 188 208 219 192 202 222 + 227 227 217 231 245 242 + 258 255 241 235 223 214 + 223 237 248 270 277 257 + 267 254 240 254 237 236 + 226 216 204 217 189 183 + 193 205 239 243 196 216 + 220 203 214 227 156 142 + 157 168 182 225 204 166 + 188 244 175 127 142 196 + 132 151 128 117 103 146 + 93 78 109 186 172 186 + 200 239 185 198 217 215 + 206 206 79 90 78 79 + 64 78 60 67 43 34 + 46 16 100000000 13 23 42 + 37 55 71 69 81 54 + 50 42 76 64 88 101 + 172 190 90 65 109 122 + 98 106 124 96 103 110 + 93 128 128 117 110 172 + 163 123 136 155 168 163 + 138 160 170 150 164 173 + 179 211 236 233 208 191 + 192 219 240 265 231 216 + 90 49 232 212 219 231 + 262 248 272 96 50 99 + 37 55 110 177 183 162 + 180 189 195 175 195 206 + 179 189 209 214 223 247 + 261 234 229 245 259 244 + 255 253 244 253 267 278 + 300 264 287 297 284 270 + 284 267 266 256 246 234 + 247 219 213 223 235 269 + 269 226 246 250 233 244 + 257 186 172 187 198 212 + 251 230 190 212 270 205 + 157 172 220 175 175 143 + 160 146 176 136 121 139 + 216 202 216 230 235 202 + 215 209 202 193 220 108 + 120 121 122 107 93 75 + 68 86 80 92 62 46 + 100000000 10 29 24 42 58 + 56 68 41 64 88 87 + 93 75 88 159 177 77 + 52 96 109 85 93 111 + 83 90 97 80 115 115 + 104 97 159 150 110 123 + 142 155 150 125 147 157 + 137 151 160 166 198 223 + 220 195 178 179 206 227 + 252 218 203 105 92 262 + 242 249 261 249 235 259 + 83 37 86 24 101 153 + 207 170 192 170 179 185 + 165 185 196 169 179 199 + 204 213 237 251 224 219 + 235 249 234 245 243 234 + 243 257 268 290 254 277 + 287 274 260 274 257 256 + 246 236 224 237 209 203 + 213 225 259 259 216 236 + 240 223 234 247 176 162 + 177 188 202 241 220 180 + 202 260 195 147 162 210 + 165 165 133 150 136 166 + 126 111 129 206 192 206 + 220 225 192 205 199 192 + 183 210 98 110 111 112 + 97 83 65 58 76 70 + 82 52 36 49 100000000 19 + 14 32 48 46 58 31 + 54 78 77 83 65 78 + 149 167 67 42 86 99 + 75 83 101 73 80 87 + 70 105 105 94 87 149 + 140 100 113 132 145 140 + 115 137 147 127 141 150 + 156 188 213 210 185 168 + 169 196 217 242 208 193 + 95 82 252 232 239 251 + 239 225 249 73 27 76 + 14 91 143 197 160 182 + 210 212 218 205 225 236 + 209 219 239 244 241 231 + 245 259 259 275 269 255 + 249 237 228 237 251 262 + 284 294 271 281 268 254 + 268 251 250 240 230 218 + 231 203 197 207 219 253 + 240 210 230 234 217 228 + 241 170 156 171 182 196 + 222 201 161 183 241 189 + 141 156 191 146 146 114 + 131 117 160 107 92 123 + 200 186 200 214 253 199 + 212 231 232 223 220 96 + 104 92 93 78 64 46 + 39 57 51 63 33 17 + 30 40 100000000 54 53 37 + 67 79 71 67 59 93 + 81 105 118 189 207 107 + 82 126 139 96 104 122 + 89 92 76 59 117 145 + 134 127 167 158 140 153 + 172 185 180 155 168 178 + 167 181 190 196 228 239 + 228 203 186 200 227 254 + 282 248 233 76 63 246 + 226 233 245 279 265 286 + 66 67 116 54 72 124 + 191 200 176 207 216 222 + 202 222 233 206 216 236 + 241 250 249 263 261 256 + 272 286 271 267 255 246 + 255 269 280 302 287 289 + 299 286 272 286 269 268 + 258 248 236 249 221 215 + 225 237 271 258 228 248 + 252 235 246 259 188 174 + 189 200 214 240 219 179 + 201 259 207 159 174 209 + 164 164 132 149 135 178 + 125 110 141 218 204 218 + 232 262 217 230 236 229 + 220 238 114 122 110 111 + 96 82 64 57 75 69 + 81 51 35 48 58 18 + 100000000 18 34 32 44 68 + 85 77 111 99 102 115 + 186 204 104 79 123 136 + 61 69 87 59 66 73 + 56 91 142 131 124 141 + 132 137 150 169 182 177 + 152 142 152 164 178 187 + 193 225 213 202 177 160 + 174 201 228 259 245 230 + 94 81 264 244 251 263 + 276 262 260 59 63 113 + 72 90 142 209 197 194 + 189 198 204 184 204 215 + 188 198 218 223 232 256 + 270 243 238 254 268 253 + 264 262 253 262 276 287 + 309 269 296 306 293 279 + 293 276 275 265 255 243 + 256 228 222 232 244 278 + 282 235 255 259 242 253 + 266 195 181 196 207 221 + 264 243 214 236 283 214 + 166 181 244 189 199 167 + 174 160 185 150 145 148 + 225 211 225 239 244 211 + 224 218 211 202 229 117 + 129 145 146 131 117 99 + 92 110 104 116 86 70 + 83 86 53 53 100000000 16 + 14 26 50 73 109 96 + 102 84 97 168 186 86 + 61 105 118 43 51 69 + 41 48 55 38 73 124 + 113 106 123 114 119 132 + 151 164 159 134 124 134 + 146 160 169 175 207 195 + 184 159 142 156 183 210 + 241 227 212 129 116 271 + 251 258 270 258 244 242 + 41 45 95 100 111 167 + 216 179 201 205 214 220 + 200 220 231 204 214 234 + 239 248 268 282 259 254 + 270 284 269 280 274 265 + 274 288 299 321 276 305 + 318 305 291 305 288 287 + 277 267 255 268 240 234 + 244 256 290 277 247 267 + 271 254 265 278 207 193 + 208 219 233 259 238 198 + 220 278 226 178 193 228 + 183 183 151 168 154 197 + 144 129 160 237 223 237 + 251 260 227 240 234 227 + 218 245 133 141 129 130 + 115 101 83 76 94 88 + 100 70 54 67 77 37 + 69 16 100000000 30 42 66 + 89 96 112 118 100 113 + 184 202 102 77 121 134 + 59 67 85 52 55 39 + 22 80 140 129 122 130 + 121 135 148 167 180 175 + 150 131 141 158 172 181 + 191 223 202 191 166 149 + 163 190 217 248 243 228 + 113 100 283 263 270 282 + 274 260 249 29 61 111 + 91 109 161 228 195 213 + 175 184 190 170 190 201 + 174 184 204 209 218 242 + 256 229 224 240 254 239 + 250 248 239 248 262 273 + 295 255 282 292 279 265 + 279 262 261 251 241 229 + 242 214 208 218 230 264 + 268 221 241 245 228 239 + 252 181 167 182 193 207 + 250 229 209 231 269 200 + 152 167 239 175 194 171 + 160 146 171 136 149 134 + 211 197 211 225 230 197 + 210 204 197 188 215 103 + 115 149 150 135 121 103 + 96 114 108 106 90 74 + 87 72 57 39 33 49 + 100000000 12 36 59 95 82 + 88 70 83 154 172 72 + 47 91 104 29 37 55 + 27 34 50 34 59 110 + 99 92 109 100 105 118 + 137 150 145 120 110 120 + 132 146 155 161 193 181 + 170 145 128 142 169 196 + 227 213 198 133 120 257 + 237 244 256 244 230 228 + 27 31 81 86 97 153 + 202 165 187 163 172 178 + 158 178 189 162 172 192 + 197 206 230 244 217 212 + 228 242 227 238 236 227 + 236 250 261 283 247 270 + 280 267 253 267 250 249 + 239 229 217 230 202 196 + 206 218 252 256 209 229 + 233 216 227 240 169 155 + 170 181 195 238 217 197 + 219 257 188 140 155 227 + 163 182 159 148 134 159 + 124 137 122 199 185 199 + 213 218 185 198 192 185 + 176 203 91 103 137 138 + 123 109 91 84 102 96 + 94 78 62 75 60 45 + 27 21 37 35 100000000 24 + 47 83 70 76 58 71 + 142 160 60 35 79 92 + 17 25 43 53 60 76 + 59 59 98 87 80 109 + 100 93 106 125 138 133 + 108 110 120 120 134 143 + 149 181 181 170 145 128 + 142 169 196 227 201 186 + 121 108 245 225 232 244 + 232 218 228 62 19 69 + 74 85 141 190 153 175 + 139 148 154 134 154 165 + 138 148 168 173 182 206 + 220 193 188 204 218 203 + 214 212 203 212 226 237 + 259 223 246 256 243 229 + 243 226 225 215 205 193 + 206 178 172 182 194 228 + 232 185 205 209 192 203 + 216 145 131 146 157 171 + 214 193 173 195 233 164 + 116 131 203 139 158 137 + 124 110 135 100 126 98 + 175 161 175 189 194 161 + 174 168 161 152 179 67 + 79 118 125 112 119 101 + 94 91 82 70 88 72 + 85 36 55 50 68 84 + 82 94 100000000 23 59 46 + 52 34 47 118 136 36 + 11 55 68 79 87 105 + 109 114 123 106 89 74 + 63 56 118 109 69 82 + 101 114 109 84 106 116 + 96 110 119 125 157 182 + 179 154 137 138 165 186 + 211 177 162 131 97 221 + 201 208 220 208 194 218 + 109 63 45 50 61 117 + 166 129 151 183 192 198 + 178 198 209 182 192 212 + 217 226 250 264 237 232 + 248 262 247 258 256 247 + 256 270 281 303 267 290 + 300 287 273 287 270 269 + 259 249 237 250 222 216 + 226 238 272 272 229 249 + 253 236 247 260 189 175 + 190 201 215 254 233 193 + 215 273 208 160 175 223 + 178 178 146 163 149 179 + 139 124 142 219 205 219 + 233 238 205 218 212 205 + 196 223 111 123 124 125 + 110 96 78 71 89 83 + 95 65 49 62 13 32 + 27 45 61 59 71 44 + 100000000 91 90 96 78 91 + 162 180 80 55 99 112 + 88 96 114 86 93 100 + 83 118 118 107 100 162 + 153 113 126 145 158 153 + 128 150 160 140 154 163 + 169 201 226 223 198 181 + 182 209 230 255 221 206 + 108 95 265 245 252 264 + 252 238 262 86 40 89 + 27 104 156 210 173 195 + 191 200 206 186 206 217 + 190 200 220 225 234 258 + 272 245 240 256 270 255 + 266 264 255 264 278 289 + 311 275 298 308 295 281 + 295 278 277 267 257 245 + 258 230 224 234 246 280 + 280 237 257 261 244 255 + 268 197 183 198 209 223 + 262 241 201 223 281 216 + 168 183 231 186 186 154 + 171 157 187 147 132 150 + 227 213 227 241 246 213 + 226 220 213 204 231 119 + 131 132 133 118 104 86 + 79 97 91 103 73 57 + 70 21 40 35 53 69 + 67 79 52 8 100000000 98 + 104 86 99 170 188 88 + 63 107 120 96 104 122 + 94 101 108 91 126 126 + 115 108 170 161 121 134 + 153 166 161 136 158 168 + 148 162 171 177 209 234 + 231 206 189 190 217 238 + 263 229 214 116 103 273 + 253 260 272 260 246 270 + 94 48 97 35 112 164 + 218 181 203 204 213 219 + 199 219 230 203 213 233 + 238 247 271 285 258 253 + 269 283 268 279 277 268 + 277 291 302 324 288 311 + 321 308 294 308 291 290 + 280 270 258 271 243 237 + 247 259 293 293 250 270 + 274 257 268 281 210 196 + 211 222 236 275 254 214 + 236 294 229 181 196 244 + 199 199 167 184 170 200 + 160 145 163 240 226 240 + 254 259 226 239 233 226 + 217 244 132 144 145 146 + 131 117 99 92 110 104 + 116 86 70 83 34 53 + 48 66 82 80 92 65 + 21 13 100000000 117 99 112 + 183 201 101 76 120 133 + 109 117 135 107 114 121 + 104 139 139 128 121 183 + 174 134 147 166 179 174 + 149 171 181 161 175 184 + 190 222 247 244 219 202 + 203 230 251 276 242 227 + 129 116 286 266 273 285 + 273 259 283 107 61 110 + 48 125 177 231 194 216 + 144 135 141 161 181 192 + 209 197 217 200 164 154 + 168 182 237 221 192 178 + 172 160 151 160 174 185 + 207 218 194 204 191 177 + 191 174 173 163 153 141 + 154 126 120 130 142 176 + 180 133 153 157 140 151 + 164 93 79 94 105 119 + 162 141 121 143 181 112 + 64 79 151 87 106 85 + 72 58 83 48 74 46 + 123 109 123 137 176 122 + 135 154 161 157 143 15 + 27 66 73 60 74 56 + 63 39 30 18 48 100 + 61 64 83 78 96 112 + 110 122 95 51 43 30 + 100000000 129 142 165 183 131 + 106 150 163 139 147 165 + 137 144 151 134 169 169 + 158 151 213 204 164 177 + 190 203 204 179 201 211 + 191 205 214 220 228 253 + 264 249 232 233 260 257 + 246 248 233 86 45 169 + 149 156 168 225 263 279 + 137 91 140 78 9 65 + 114 210 99 151 153 159 + 146 166 177 150 160 180 + 185 182 172 186 200 200 + 216 210 196 190 178 169 + 178 192 203 225 235 212 + 222 209 195 209 192 191 + 181 171 159 172 144 138 + 148 160 194 198 151 171 + 175 158 169 182 111 97 + 112 123 137 180 159 139 + 161 199 130 82 97 169 + 105 124 103 90 76 101 + 66 92 64 141 127 141 + 155 194 140 153 172 173 + 164 161 33 45 84 91 + 78 92 74 81 57 48 + 36 66 82 79 46 65 + 60 78 94 92 104 77 + 33 25 12 18 100000000 59 + 130 148 48 23 67 80 + 91 99 117 119 126 133 + 116 101 86 75 68 130 + 121 81 94 113 126 121 + 96 118 128 108 122 131 + 137 169 194 191 166 149 + 150 177 198 223 189 174 + 104 63 187 167 174 186 + 220 206 230 119 73 57 + 60 27 83 132 141 117 + 171 173 179 166 186 197 + 170 180 200 205 202 192 + 206 220 220 236 230 216 + 210 198 189 198 212 223 + 245 255 232 242 229 215 + 229 212 211 201 191 179 + 192 164 158 168 180 214 + 218 171 191 195 178 189 + 202 131 117 132 143 157 + 200 179 159 181 219 150 + 102 117 189 125 144 123 + 110 96 121 86 112 84 + 161 147 161 175 214 160 + 173 192 193 184 181 53 + 65 104 111 98 112 94 + 101 77 68 56 86 102 + 99 66 85 80 98 114 + 112 124 97 53 45 32 + 38 20 100000000 150 168 68 + 43 87 100 111 119 137 + 139 146 153 136 121 106 + 95 88 150 141 101 114 + 133 146 141 116 138 148 + 128 142 151 157 189 214 + 211 186 169 170 197 218 + 243 209 194 124 83 207 + 187 194 206 240 226 250 + 139 93 77 80 47 103 + 152 161 137 21 30 36 + 16 36 47 64 52 72 + 55 64 106 120 97 92 + 108 122 107 118 112 121 + 125 139 150 172 127 156 + 169 156 142 160 153 142 + 142 132 120 133 105 99 + 109 121 155 180 140 146 + 136 147 158 171 72 86 + 101 112 126 169 148 167 + 189 188 119 106 121 197 + 133 152 131 118 104 125 + 94 120 88 68 56 70 + 89 76 43 56 50 43 + 34 61 61 73 112 119 + 106 120 102 109 85 76 + 64 94 110 107 74 93 + 88 106 122 110 122 68 + 61 53 40 46 28 8 + 100000000 18 37 51 56 69 + 80 88 106 116 115 131 + 144 90 75 64 57 119 + 110 70 70 25 38 48 + 85 107 117 97 111 120 + 64 83 108 119 155 138 + 125 139 112 137 103 88 + 132 91 148 128 135 138 + 112 120 144 137 101 46 + 88 55 111 81 53 66 + 45 54 60 40 60 71 + 59 69 89 79 88 130 + 144 114 109 125 139 124 + 135 136 145 142 156 167 + 189 144 173 186 173 159 + 177 177 159 166 156 144 + 157 129 123 133 145 179 + 204 164 170 160 171 182 + 195 96 110 125 136 150 + 193 172 191 213 212 143 + 130 145 221 157 176 155 + 142 128 149 118 144 112 + 92 80 94 113 100 67 + 80 74 67 58 85 85 + 97 136 143 130 144 126 + 133 109 100 88 118 122 + 131 86 105 100 118 134 + 92 104 50 73 77 64 + 70 52 32 24 100000000 19 + 61 38 51 62 70 88 + 98 97 113 126 72 57 + 46 39 101 92 52 52 + 7 20 30 67 89 99 + 79 93 102 46 78 103 + 114 137 120 120 134 107 + 132 98 83 156 115 172 + 152 159 162 129 115 139 + 119 113 28 100 79 135 + 105 35 90 103 112 118 + 98 118 129 102 112 132 + 137 146 188 202 157 152 + 168 182 167 178 188 194 + 185 199 210 232 187 216 + 229 216 202 220 225 202 + 224 214 202 215 187 181 + 191 203 237 262 216 228 + 218 223 234 247 154 162 + 177 188 202 245 224 204 + 226 264 195 147 162 234 + 170 189 168 155 141 166 + 131 157 129 150 138 152 + 171 158 125 138 132 125 + 116 143 98 110 149 156 + 143 150 132 125 122 113 + 101 119 103 116 67 86 + 81 99 115 73 85 31 + 54 90 77 83 65 78 + 82 100 100000000 42 19 32 + 43 51 69 79 78 94 + 107 53 38 27 20 82 + 73 33 46 65 78 73 + 48 70 80 60 74 83 + 89 121 146 143 118 101 + 102 129 150 175 141 126 + 162 128 230 210 217 207 + 172 158 182 100 94 9 + 81 92 148 163 93 148 + 128 137 143 123 143 154 + 127 137 157 162 171 195 + 209 182 177 193 207 192 + 203 201 192 201 215 226 + 248 212 235 245 232 218 + 232 215 214 204 194 182 + 195 167 161 171 183 217 + 221 174 194 198 181 192 + 205 134 120 135 146 160 + 203 182 162 184 222 153 + 105 120 192 128 147 126 + 113 99 124 89 115 87 + 164 150 164 178 183 150 + 163 157 150 141 168 56 + 68 107 114 101 115 97 + 104 80 71 59 89 105 + 102 69 88 83 101 117 + 98 110 56 56 48 35 + 41 23 36 107 125 25 + 100000000 44 57 68 76 94 + 104 103 119 132 78 63 + 52 45 107 98 58 71 + 90 103 98 73 95 105 + 85 99 108 114 146 171 + 168 143 126 127 154 175 + 200 166 151 127 86 210 + 190 197 209 197 183 207 + 125 96 34 83 50 106 + 155 118 140 151 160 166 + 146 166 177 150 160 180 + 185 194 218 232 205 200 + 216 230 215 226 224 215 + 224 238 249 271 235 258 + 268 255 241 255 238 237 + 227 217 205 218 190 184 + 194 206 240 244 197 217 + 221 204 215 228 157 143 + 158 169 183 226 205 185 + 207 245 176 128 143 215 + 151 170 149 136 122 147 + 112 138 110 187 173 187 + 201 206 173 186 180 173 + 164 191 79 91 130 137 + 124 131 113 106 103 94 + 82 100 84 97 48 67 + 62 80 96 54 66 12 + 35 71 58 64 46 59 + 130 148 48 23 100000000 13 + 24 32 50 60 67 83 + 88 66 86 75 68 116 + 107 81 94 113 126 121 + 96 117 127 108 122 131 + 137 169 188 177 152 135 + 149 176 198 223 189 174 + 143 109 233 213 220 232 + 220 206 230 81 75 57 + 62 73 129 178 141 163 + 188 197 203 183 203 214 + 187 197 217 222 231 273 + 287 242 237 253 267 252 + 263 273 279 270 284 287 + 309 249 278 291 301 287 + 305 303 287 292 282 270 + 283 255 249 259 271 305 + 309 262 282 286 269 280 + 293 222 208 223 234 248 + 291 270 250 272 310 241 + 193 208 280 216 235 212 + 201 187 212 177 190 175 + 235 223 237 256 243 210 + 223 217 210 201 228 144 + 156 190 191 176 162 144 + 137 155 149 147 131 115 + 128 113 98 80 74 90 + 41 53 77 100 136 123 + 129 111 124 167 185 113 + 88 132 100000000 11 19 37 + 47 54 70 75 53 145 + 134 133 103 94 118 131 + 150 163 158 133 104 114 + 131 145 154 174 200 175 + 164 139 122 136 163 190 + 221 226 211 174 161 298 + 278 285 292 257 237 222 + 68 72 122 127 138 194 + 243 178 228 177 186 192 + 172 192 203 176 186 206 + 211 220 262 276 231 226 + 242 256 241 252 262 268 + 259 273 276 298 238 267 + 280 290 276 294 292 276 + 281 271 259 272 244 238 + 248 260 294 298 251 271 + 275 258 269 282 211 197 + 212 223 237 280 259 239 + 261 299 230 182 197 269 + 205 224 201 190 176 201 + 166 179 164 224 212 226 + 245 232 199 212 206 199 + 190 217 133 145 179 180 + 165 151 133 126 144 138 + 136 120 104 117 102 87 + 69 63 79 30 42 66 + 89 125 112 118 100 113 + 156 174 102 77 121 134 + 100000000 8 26 36 43 59 + 64 42 134 123 122 92 + 83 107 120 139 152 147 + 122 93 103 120 134 143 + 163 189 164 153 128 111 + 125 152 179 210 215 200 + 163 150 287 267 274 281 + 246 226 211 57 61 111 + 116 127 183 232 167 217 + 169 178 184 164 184 195 + 168 178 198 203 212 254 + 268 223 218 234 248 233 + 244 254 260 251 265 268 + 290 230 259 272 282 268 + 286 284 268 273 263 251 + 264 236 230 240 252 286 + 290 243 263 267 250 261 + 274 203 189 204 215 229 + 272 251 231 253 291 222 + 174 189 261 197 216 193 + 182 168 193 158 171 156 + 216 204 218 237 224 191 + 204 198 191 182 209 125 + 137 171 172 157 143 125 + 118 136 130 128 112 96 + 109 94 79 61 55 71 + 22 34 58 81 117 104 + 110 92 105 148 166 94 + 69 113 126 51 100000000 18 + 28 35 51 56 34 126 + 115 114 84 75 99 112 + 131 144 139 114 85 95 + 112 126 135 155 181 156 + 145 120 103 117 144 171 + 202 207 192 155 142 279 + 259 266 273 238 218 203 + 49 53 103 108 119 175 + 224 159 209 151 160 166 + 146 166 177 150 160 180 + 185 194 236 250 205 200 + 216 230 215 226 236 242 + 233 247 250 272 212 241 + 254 264 250 268 273 250 + 272 262 250 263 235 229 + 239 251 285 305 258 276 + 266 265 276 289 202 204 + 219 230 244 287 266 246 + 268 306 237 189 204 276 + 212 231 208 197 183 208 + 173 186 171 198 186 200 + 219 206 173 186 180 173 + 164 191 140 152 186 187 + 172 158 140 133 151 145 + 143 127 111 124 109 94 + 76 70 72 37 49 73 + 96 132 119 125 107 120 + 130 148 109 84 128 141 + 66 74 100000000 10 17 33 + 50 16 108 97 129 66 + 57 81 94 113 126 121 + 96 67 77 94 108 117 + 137 163 138 127 102 85 + 99 126 153 184 189 174 + 170 157 278 258 265 255 + 220 200 185 57 68 118 + 123 134 190 211 141 196 + 167 176 182 162 182 193 + 166 176 196 201 210 252 + 266 221 216 232 246 231 + 242 252 258 249 263 266 + 288 228 257 270 280 266 + 284 289 266 278 268 256 + 269 241 235 245 257 291 + 295 248 268 272 255 266 + 279 208 194 209 220 234 + 277 256 236 258 296 227 + 179 194 266 202 221 198 + 187 173 198 163 176 161 + 214 202 216 235 222 189 + 202 196 189 180 207 130 + 142 176 177 162 148 130 + 123 141 135 133 117 101 + 114 99 84 66 60 62 + 27 39 63 86 122 109 + 115 97 110 146 164 99 + 74 118 131 56 64 82 + 100000000 7 23 40 32 124 + 113 119 82 73 97 110 + 129 142 137 112 83 93 + 110 124 133 153 179 154 + 143 118 101 115 142 169 + 200 205 190 160 147 284 + 264 271 271 236 216 201 + 47 58 108 113 124 180 + 227 157 212 160 169 175 + 155 175 186 159 169 189 + 194 203 245 259 214 209 + 225 239 224 235 245 251 + 242 256 259 281 221 250 + 263 273 259 277 282 259 + 281 271 259 272 244 238 + 248 260 294 302 255 275 + 275 262 273 286 211 201 + 216 227 241 284 263 243 + 265 303 234 186 201 273 + 209 228 205 194 180 205 + 170 183 168 207 195 209 + 228 215 182 195 189 182 + 173 200 137 149 183 184 + 169 155 137 130 148 142 + 140 124 108 121 106 91 + 73 67 55 34 46 70 + 93 129 116 122 104 117 + 139 157 106 81 125 138 + 63 71 89 7 100000000 16 + 33 25 117 106 126 75 + 66 90 103 122 135 130 + 105 76 86 103 117 126 + 146 172 147 136 111 94 + 108 135 162 193 198 183 + 167 154 287 267 274 264 + 229 209 194 40 65 115 + 120 131 187 220 150 205 + 176 185 191 171 191 202 + 175 185 205 210 219 261 + 275 230 225 241 255 240 + 251 261 267 258 272 275 + 297 237 266 279 289 275 + 293 298 275 297 287 275 + 288 260 254 264 276 310 + 316 271 291 291 278 289 + 302 227 217 232 243 257 + 298 277 237 259 317 250 + 202 217 267 222 222 190 + 207 193 221 183 168 184 + 223 211 225 244 231 198 + 211 205 198 189 216 153 + 165 168 169 154 140 122 + 115 133 127 139 109 93 + 106 116 76 89 55 39 + 50 62 86 109 135 132 + 138 120 133 155 173 122 + 97 141 154 79 87 105 + 23 16 100000000 17 41 133 + 122 142 91 82 106 119 + 138 151 146 121 92 102 + 119 133 142 162 188 163 + 152 127 110 124 151 178 + 209 214 199 152 139 303 + 283 290 280 245 225 210 + 24 81 131 130 147 200 + 236 166 221 193 202 208 + 188 208 219 192 202 222 + 227 236 276 290 247 242 + 258 272 257 268 278 273 + 275 289 292 314 254 283 + 296 306 292 310 296 292 + 285 275 263 276 248 242 + 252 264 298 299 255 275 + 279 262 273 286 215 201 + 216 227 241 281 260 220 + 242 300 234 186 201 250 + 205 205 173 190 176 205 + 166 151 168 240 228 242 + 259 248 215 228 222 215 + 206 233 137 149 151 152 + 137 123 105 98 116 110 + 122 92 76 89 99 59 + 73 38 22 34 46 70 + 93 118 116 122 104 117 + 172 190 106 81 125 138 + 63 71 89 30 33 17 + 100000000 58 144 133 126 108 + 99 123 136 155 168 163 + 138 109 119 136 150 159 + 179 205 180 169 144 127 + 141 168 195 226 231 216 + 135 122 291 271 278 290 + 262 242 227 7 65 115 + 113 131 183 236 183 221 + 135 144 150 130 150 161 + 134 144 164 169 178 220 + 234 189 184 200 214 199 + 210 220 226 217 231 234 + 256 196 225 238 248 234 + 252 257 234 256 246 234 + 247 219 213 223 235 269 + 294 254 260 250 261 272 + 285 186 200 215 226 240 + 283 262 268 290 302 233 + 211 226 298 234 253 230 + 219 205 230 195 208 193 + 182 170 184 203 190 157 + 170 164 157 148 175 162 + 174 208 209 194 180 162 + 155 173 167 165 149 133 + 146 131 116 98 92 80 + 59 71 95 118 154 141 + 147 129 122 114 132 93 + 106 112 125 88 96 114 + 32 25 41 58 100000000 92 + 81 113 50 41 65 78 + 97 110 105 80 51 61 + 78 92 101 121 147 122 + 111 86 69 83 110 137 + 168 173 158 192 179 262 + 242 249 239 204 184 169 + 65 90 102 145 156 212 + 195 125 180 129 138 144 + 124 144 155 128 138 158 + 163 172 214 228 183 178 + 194 208 193 204 214 220 + 211 225 228 250 190 219 + 232 242 228 246 251 228 + 250 240 228 241 213 207 + 217 229 263 288 248 254 + 244 255 266 279 180 194 + 209 220 234 277 256 248 + 270 296 227 191 206 278 + 214 233 210 199 185 210 + 175 188 173 176 164 178 + 197 184 151 164 158 151 + 142 169 142 154 188 189 + 174 160 142 135 153 147 + 145 129 113 126 111 96 + 78 72 88 39 51 75 + 98 134 121 127 109 116 + 108 126 87 86 106 119 + 68 17 35 45 40 56 + 73 15 100000000 75 107 44 + 35 59 72 91 104 99 + 74 45 55 72 86 95 + 115 141 116 105 80 63 + 77 104 131 162 167 152 + 172 159 256 236 243 233 + 198 178 163 66 70 96 + 125 136 192 189 119 174 + 140 149 155 135 155 166 + 139 149 169 174 183 225 + 239 194 189 205 219 204 + 215 225 231 222 236 239 + 261 201 230 243 253 239 + 257 262 239 261 251 239 + 252 224 218 228 240 274 + 299 259 265 255 266 277 + 290 191 205 220 231 245 + 288 267 259 281 307 238 + 202 217 289 225 244 221 + 210 196 221 186 199 184 + 187 175 189 208 195 162 + 175 169 162 153 180 153 + 165 199 200 185 171 153 + 146 164 158 156 140 124 + 137 122 107 89 83 99 + 50 62 86 109 145 132 + 138 120 127 119 137 98 + 97 117 130 79 28 46 + 56 51 67 84 26 11 + 100000000 118 55 46 70 83 + 102 115 110 85 56 66 + 83 97 106 126 152 127 + 116 91 74 88 115 142 + 173 178 163 183 170 267 + 247 254 244 209 189 174 + 77 81 107 136 147 203 + 200 130 185 147 156 162 + 142 162 173 146 156 176 + 181 190 232 246 201 196 + 212 226 211 222 232 238 + 229 243 246 268 208 237 + 250 260 246 264 269 246 + 268 258 246 259 231 225 + 235 247 281 306 266 272 + 262 273 284 297 198 212 + 227 238 252 295 274 264 + 286 314 245 207 222 294 + 230 249 226 215 201 226 + 191 204 189 194 182 196 + 215 202 169 182 176 169 + 160 187 158 170 204 205 + 190 176 158 151 169 163 + 161 145 129 142 127 112 + 94 88 104 55 67 91 + 114 150 137 143 125 134 + 126 144 105 102 124 14 + 25 33 51 61 58 74 + 89 33 18 7 100000000 62 + 53 77 90 109 122 117 + 92 63 73 90 104 113 + 133 159 134 123 98 81 + 95 122 149 180 185 170 + 188 175 274 254 261 251 + 216 196 181 82 86 114 + 141 152 208 207 137 192 + 85 94 100 80 100 111 + 84 94 114 119 128 170 + 184 139 134 150 164 149 + 160 170 176 167 181 192 + 214 169 198 211 198 184 + 202 207 184 206 196 184 + 197 169 163 173 185 219 + 244 204 210 200 211 222 + 235 136 150 165 176 190 + 233 212 231 253 252 183 + 170 185 261 197 216 195 + 182 168 189 158 184 152 + 132 120 134 153 140 107 + 120 114 107 98 125 125 + 137 176 183 170 184 166 + 168 149 140 128 158 146 + 159 110 129 120 114 130 + 81 93 74 97 117 104 + 110 92 72 64 82 43 + 85 62 75 86 59 77 + 87 82 98 115 57 42 + 31 63 100000000 62 15 28 + 47 60 55 30 52 62 + 42 56 65 71 103 128 + 132 107 90 84 111 132 + 157 123 108 196 155 212 + 192 199 189 154 140 164 + 108 112 52 124 119 175 + 145 75 130 94 103 109 + 89 109 120 93 103 123 + 128 137 179 193 148 143 + 159 173 158 169 179 185 + 176 190 193 215 155 184 + 197 207 193 211 216 193 + 215 205 193 206 178 172 + 182 194 228 253 213 219 + 209 220 231 244 145 159 + 174 185 199 242 221 240 + 262 261 192 179 194 270 + 206 225 204 191 177 198 + 167 193 161 141 129 143 + 162 149 116 129 123 116 + 107 134 134 146 185 192 + 179 193 175 177 158 149 + 137 167 155 168 119 138 + 129 123 121 90 102 83 + 106 126 113 119 101 81 + 73 91 52 94 71 84 + 95 68 86 73 66 82 + 99 41 51 40 72 9 + 100000000 24 37 56 69 64 + 39 10 20 37 51 60 + 80 106 81 70 45 28 + 42 69 96 127 132 117 + 205 164 221 201 208 198 + 163 143 128 106 121 61 + 133 128 184 154 84 139 + 70 79 85 65 85 96 + 69 79 99 104 113 155 + 169 124 119 135 149 134 + 145 155 161 152 166 177 + 199 154 183 196 183 169 + 187 192 169 191 181 169 + 182 154 148 158 170 204 + 229 189 195 185 196 207 + 220 121 135 150 161 175 + 218 197 216 238 237 168 + 155 170 246 182 201 180 + 167 153 174 143 169 137 + 117 105 119 138 125 92 + 105 99 92 83 110 110 + 122 161 168 155 169 151 + 153 134 125 113 143 131 + 144 95 114 109 127 143 + 101 113 59 82 102 89 + 95 77 57 49 67 28 + 70 47 60 71 79 97 + 107 106 122 135 81 66 + 55 48 56 47 100000000 13 + 32 45 40 15 37 47 + 27 41 50 56 88 113 + 117 92 75 69 96 117 + 142 108 93 181 140 197 + 177 184 174 139 125 149 + 128 122 37 109 104 160 + 130 60 115 57 66 72 + 52 72 83 71 81 101 + 91 100 142 156 126 121 + 137 151 136 147 148 157 + 154 168 179 201 156 185 + 198 185 171 189 189 171 + 178 168 156 169 141 135 + 145 157 191 216 176 182 + 172 183 194 207 108 122 + 137 148 162 205 184 203 + 225 224 155 142 157 233 + 169 188 167 154 140 161 + 130 156 124 104 92 106 + 125 112 79 92 86 79 + 70 97 97 109 148 155 + 142 156 138 140 121 112 + 100 130 118 131 82 101 + 96 114 130 88 100 46 + 69 89 76 82 64 44 + 36 54 15 57 34 47 + 58 66 84 94 93 109 + 122 68 53 42 35 97 + 88 48 100000000 19 32 42 + 63 85 95 75 89 98 + 58 90 115 126 133 116 + 117 144 119 144 110 95 + 168 127 184 164 171 174 + 141 127 151 115 109 24 + 96 91 147 117 47 102 + 38 47 53 33 53 64 + 52 62 82 72 81 123 + 137 107 102 118 132 117 + 128 129 138 135 149 160 + 182 137 166 179 166 152 + 170 170 152 159 149 137 + 150 122 116 126 138 172 + 197 157 163 153 164 175 + 188 89 103 118 129 143 + 186 165 184 206 205 136 + 123 138 214 150 169 148 + 135 121 142 111 137 105 + 85 73 87 106 93 60 + 73 67 60 51 78 78 + 90 129 136 123 137 119 + 126 102 93 81 111 127 + 124 91 110 105 123 139 + 127 139 85 78 70 57 + 63 45 25 17 35 54 + 68 73 86 97 105 123 + 133 132 148 161 107 92 + 81 74 136 127 87 45 + 100000000 13 23 102 124 134 + 114 128 119 39 71 96 + 107 172 155 113 127 100 + 125 91 76 149 108 165 + 145 152 155 122 108 132 + 154 118 63 105 72 128 + 98 28 83 44 53 59 + 39 59 70 39 49 69 + 78 87 129 143 94 89 + 105 119 104 115 125 131 + 122 136 147 169 124 153 + 166 153 139 157 162 139 + 165 155 143 156 128 122 + 132 144 178 203 163 169 + 159 170 181 194 95 109 + 124 135 149 192 171 190 + 212 211 142 129 144 220 + 156 175 154 141 127 148 + 117 143 111 91 79 93 + 112 99 66 79 73 66 + 57 84 84 96 135 142 + 129 143 125 132 108 99 + 87 117 133 130 97 116 + 111 129 145 120 132 78 + 84 76 63 69 51 31 + 23 41 47 74 66 79 + 90 98 116 126 125 141 + 154 100 85 74 67 129 + 120 80 32 48 100000000 10 + 95 117 122 107 121 106 + 26 58 83 94 165 148 + 100 114 87 112 78 63 + 155 114 171 151 158 144 + 109 95 119 147 124 56 + 111 78 134 104 15 89 + 79 88 94 74 94 105 + 29 39 59 75 84 148 + 162 84 79 95 109 94 + 105 115 121 112 126 137 + 159 114 143 156 143 129 + 147 152 129 163 184 178 + 147 146 157 167 179 193 + 218 198 204 194 205 216 + 229 130 144 159 170 184 + 227 206 225 247 246 177 + 164 179 255 191 210 189 + 176 162 183 152 178 146 + 126 114 112 131 96 101 + 114 108 101 92 119 119 + 131 170 177 164 178 160 + 162 143 134 122 152 140 + 153 104 123 118 136 152 + 110 122 68 91 111 98 + 104 86 66 58 76 37 + 79 56 69 80 88 106 + 116 115 131 144 90 75 + 64 57 119 110 70 22 + 41 54 100000000 85 107 112 + 97 111 96 16 48 73 + 84 155 138 90 104 77 + 102 68 53 190 149 205 + 186 164 134 99 85 109 + 137 131 46 118 113 169 + 139 69 124 104 113 119 + 99 119 130 54 64 84 + 100 109 173 187 109 104 + 120 134 119 130 140 146 + 137 151 162 184 139 168 + 181 168 154 172 177 154 + 188 209 203 172 171 182 + 192 204 218 243 223 229 + 219 230 241 254 155 169 + 184 195 209 252 231 250 + 272 271 202 189 204 280 + 216 235 214 201 187 208 + 177 203 171 151 139 137 + 156 121 126 139 133 126 + 117 144 144 156 195 202 + 189 203 185 187 168 159 + 147 177 165 178 129 148 + 143 155 153 122 134 93 + 116 136 123 129 111 91 + 83 101 62 104 81 94 + 105 100 118 105 98 114 + 131 73 83 72 82 41 + 32 56 47 66 79 25 + 100000000 22 32 12 26 35 + 41 73 98 102 77 60 + 54 81 102 127 93 78 + 215 174 230 211 189 159 + 124 110 134 138 153 71 + 143 138 194 164 94 149 + 104 113 119 99 119 130 + 93 103 123 138 147 189 + 203 148 143 159 173 158 + 169 179 185 176 190 183 + 205 145 174 187 200 193 + 211 216 193 225 215 203 + 211 188 182 192 204 238 + 263 223 229 219 230 241 + 254 155 169 184 195 209 + 252 231 250 272 271 202 + 189 204 280 216 235 214 + 201 187 208 177 203 171 + 151 139 153 172 159 126 + 139 133 126 117 144 144 + 156 195 202 189 203 185 + 187 168 159 147 177 165 + 178 129 148 139 133 131 + 100 112 93 116 136 123 + 129 111 91 83 101 62 + 104 81 94 105 78 96 + 83 76 92 109 51 61 + 50 82 19 10 34 47 + 66 79 64 39 100000000 10 + 27 41 50 75 112 91 + 80 55 38 32 59 86 + 117 132 117 215 174 231 + 211 218 198 163 133 118 + 116 131 71 143 138 194 + 164 94 149 114 123 129 + 109 129 140 83 93 113 + 129 138 199 213 138 133 + 149 163 148 159 169 175 + 166 180 173 195 135 164 + 177 190 183 201 206 183 + 217 225 213 201 198 192 + 202 214 247 272 233 239 + 229 240 251 264 165 179 + 194 205 219 262 241 260 + 282 281 212 199 214 290 + 226 245 224 211 197 218 + 187 213 181 161 149 163 + 182 150 136 149 143 136 + 127 154 154 166 205 212 + 199 213 195 197 178 169 + 157 187 175 188 139 158 + 149 143 141 110 122 103 + 126 146 133 139 121 101 + 93 111 72 114 91 104 + 115 88 106 93 86 102 + 119 61 71 60 92 29 + 20 44 57 76 89 54 + 29 10 100000000 17 31 40 + 65 102 89 78 65 48 + 22 49 76 107 122 107 + 225 184 241 221 218 188 + 153 123 108 126 141 81 + 153 148 204 174 104 159 + 116 125 131 111 131 142 + 66 76 96 112 121 185 + 199 121 116 132 146 131 + 142 152 158 149 163 174 + 196 151 180 193 180 166 + 184 189 166 200 221 215 + 184 183 194 204 216 230 + 255 235 241 231 242 253 + 266 167 181 196 207 221 + 264 243 262 284 283 214 + 201 216 292 228 247 226 + 213 199 220 189 215 183 + 163 151 149 168 133 138 + 151 145 138 129 156 156 + 168 207 214 201 215 197 + 199 180 171 159 189 177 + 190 141 160 155 167 165 + 134 146 105 128 148 135 + 141 123 103 95 113 74 + 116 93 106 117 112 130 + 117 110 126 143 85 95 + 84 94 53 44 68 59 + 78 91 37 12 34 44 + 100000000 14 23 48 85 110 + 114 89 72 66 93 114 + 139 105 90 227 186 242 + 223 201 171 136 122 146 + 150 165 83 155 150 206 + 176 106 161 129 129 123 + 124 128 139 56 66 86 + 102 111 175 189 111 106 + 122 136 121 132 142 148 + 139 153 164 186 141 170 + 183 170 156 174 179 156 + 190 211 214 174 173 193 + 203 215 220 245 239 240 + 230 241 252 265 171 185 + 200 211 225 268 247 275 + 297 287 218 205 220 305 + 241 260 239 226 212 224 + 202 228 187 167 155 139 + 158 123 142 155 158 151 + 142 163 169 181 220 227 + 214 228 210 212 193 184 + 172 202 190 203 154 173 + 168 186 202 160 172 118 + 141 161 148 154 136 116 + 108 126 87 129 106 119 + 130 138 156 166 165 181 + 194 140 125 114 107 168 + 159 120 72 91 104 50 + 135 149 139 147 100000000 9 + 34 75 100 111 204 187 + 117 131 104 129 95 80 + 240 199 232 221 191 161 + 126 112 136 187 181 96 + 168 163 219 180 119 165 + 120 120 114 115 119 130 + 47 57 77 93 102 166 + 180 102 97 113 127 112 + 123 133 139 130 144 155 + 177 132 161 174 161 147 + 165 170 147 181 202 205 + 165 164 184 194 206 211 + 236 230 231 221 232 243 + 256 162 176 191 202 216 + 259 238 266 288 278 209 + 196 211 296 232 251 230 + 217 203 215 193 219 178 + 158 146 130 149 114 133 + 146 149 142 133 154 160 + 172 211 218 205 219 201 + 203 184 175 163 193 181 + 194 145 164 159 177 193 + 151 163 109 132 152 139 + 145 127 107 99 117 78 + 120 97 110 121 129 147 + 157 156 172 185 131 116 + 105 98 159 150 111 63 + 82 95 41 126 140 130 + 138 152 100000000 25 66 91 + 102 195 178 108 122 95 + 120 86 71 231 190 223 + 212 182 152 117 103 127 + 178 172 87 159 154 210 + 171 110 156 95 95 89 + 90 94 105 22 32 52 + 68 77 141 155 77 72 + 88 102 87 98 108 114 + 105 119 130 152 107 136 + 149 136 122 140 145 122 + 156 177 180 140 139 159 + 169 181 186 211 205 206 + 196 207 218 231 137 151 + 166 177 191 234 213 241 + 263 253 184 171 186 271 + 207 226 205 192 178 190 + 168 194 153 133 121 105 + 124 89 108 121 124 117 + 108 129 135 147 186 193 + 180 194 176 178 159 150 + 138 168 156 169 120 139 + 134 152 168 126 138 84 + 107 127 114 120 102 82 + 74 92 53 95 72 85 + 96 104 122 132 131 147 + 160 106 91 80 73 134 + 125 86 38 57 70 16 + 101 115 105 113 127 89 + 100000000 41 66 77 170 153 + 83 97 70 95 61 46 + 206 165 198 187 157 127 + 92 78 102 153 147 62 + 134 129 185 146 85 131 + 113 113 107 108 112 123 + 40 50 70 86 95 146 + 160 56 51 67 81 66 + 77 87 93 84 98 109 + 131 86 115 128 115 101 + 119 124 101 135 156 159 + 119 118 138 148 160 165 + 190 202 185 175 186 197 + 210 151 165 180 191 205 + 231 210 250 263 250 198 + 189 204 271 225 244 223 + 210 196 208 186 212 171 + 151 139 123 129 107 126 + 139 142 135 126 147 153 + 165 204 211 198 212 194 + 196 177 168 156 186 174 + 187 138 157 152 170 186 + 144 156 102 125 145 132 + 138 120 100 92 110 71 + 113 90 103 114 122 140 + 150 149 165 178 124 109 + 98 91 93 84 104 56 + 75 88 34 93 74 64 + 81 95 48 18 100000000 25 + 36 129 112 42 56 29 + 60 29 14 224 183 177 + 166 136 106 71 46 61 + 171 165 80 152 147 203 + 164 103 149 138 138 132 + 133 137 148 65 75 95 + 111 120 171 185 81 76 + 92 106 91 102 112 118 + 109 123 134 156 111 140 + 153 140 126 144 149 126 + 160 181 184 144 143 163 + 173 185 190 215 227 210 + 200 211 222 235 176 190 + 205 216 230 256 235 275 + 288 275 223 214 229 296 + 250 269 248 235 221 233 + 211 237 196 176 164 148 + 154 132 151 164 167 160 + 151 172 178 190 229 236 + 223 237 219 221 202 193 + 181 211 199 212 163 182 + 177 182 180 149 161 127 + 150 170 157 163 145 125 + 117 135 96 138 115 128 + 139 127 145 132 125 141 + 158 100 110 99 116 68 + 59 83 81 100 113 59 + 68 49 39 56 70 23 + 43 25 100000000 11 104 87 + 17 44 54 85 54 39 + 249 208 202 191 161 131 + 96 71 86 165 180 105 + 177 172 228 189 128 174 + 132 132 126 127 131 142 + 59 69 89 105 114 178 + 192 92 87 103 117 102 + 113 123 129 120 134 145 + 167 122 151 164 151 137 + 155 160 137 171 192 195 + 155 154 174 184 196 201 + 226 238 221 211 222 233 + 246 174 188 203 214 228 + 267 246 278 299 286 221 + 208 223 307 244 263 242 + 229 215 227 205 231 190 + 170 158 142 161 126 145 + 158 161 154 145 166 172 + 184 223 230 217 231 213 + 215 196 187 175 205 193 + 206 157 176 171 189 191 + 160 172 121 144 164 151 + 157 139 119 111 129 90 + 132 109 122 133 138 156 + 143 136 152 169 111 121 + 110 110 79 70 94 75 + 94 107 53 79 60 50 + 67 81 12 37 36 11 + 100000000 115 98 28 55 65 + 96 65 50 243 202 213 + 202 172 142 107 82 97 + 176 184 99 171 166 222 + 183 122 168 157 157 151 + 152 156 167 84 94 114 + 130 139 203 217 117 112 + 128 142 127 138 148 154 + 145 159 170 192 147 176 + 189 176 162 180 185 162 + 196 217 220 180 179 199 + 209 221 226 251 263 246 + 236 247 258 271 199 213 + 228 239 253 292 271 303 + 324 311 246 233 248 332 + 269 288 267 254 240 252 + 230 256 215 195 183 167 + 186 151 170 183 186 179 + 170 191 197 209 248 255 + 242 256 238 240 221 212 + 200 230 218 231 182 201 + 196 214 216 185 197 146 + 169 189 176 182 164 144 + 136 154 115 157 134 147 + 158 163 181 168 161 177 + 194 136 146 135 135 104 + 95 119 100 119 132 78 + 104 85 75 92 106 37 + 62 61 36 25 100000000 123 + 53 80 90 121 90 75 + 268 227 238 227 197 167 + 132 107 122 201 209 124 + 196 191 247 208 147 193 + 174 174 168 169 173 184 + 101 111 131 147 156 220 + 234 134 129 145 159 144 + 155 165 171 162 176 187 + 209 164 193 206 193 179 + 197 202 179 213 234 237 + 197 196 216 226 238 243 + 268 280 263 253 264 275 + 288 216 230 245 256 270 + 309 288 320 341 328 263 + 250 265 349 286 305 284 + 271 257 269 247 273 232 + 212 200 184 203 168 187 + 200 203 196 187 208 214 + 226 265 272 259 273 255 + 257 238 229 217 247 235 + 248 199 218 213 231 233 + 202 214 163 186 206 193 + 199 181 161 153 171 132 + 174 151 164 175 180 198 + 185 178 194 211 153 163 + 152 152 121 112 136 117 + 136 149 95 121 102 92 + 109 123 54 79 78 53 + 42 17 100000000 70 97 107 + 138 107 92 285 244 255 + 244 214 184 149 124 139 + 218 226 141 213 208 264 + 225 164 210 136 145 151 + 131 151 162 105 115 135 + 151 160 221 235 143 138 + 154 168 153 164 174 180 + 171 162 151 173 113 142 + 155 168 182 183 200 188 + 211 232 235 206 205 214 + 224 236 241 266 255 261 + 251 262 273 286 187 201 + 216 227 241 284 263 282 + 304 303 234 221 236 312 + 248 267 246 233 219 240 + 209 235 203 183 171 185 + 204 172 158 171 165 158 + 149 176 176 188 227 234 + 221 235 217 219 200 191 + 179 209 197 210 161 180 + 171 165 163 132 144 125 + 148 168 155 161 143 123 + 115 133 94 136 113 126 + 137 110 128 115 108 124 + 141 83 93 82 114 51 + 42 66 79 98 111 76 + 51 32 22 39 53 62 + 87 92 67 56 87 70 + 100000000 27 54 85 116 101 + 247 206 253 242 223 193 + 158 101 86 148 163 103 + 175 170 226 196 126 181 + 161 161 155 156 160 171 + 88 98 118 134 143 206 + 220 116 111 127 141 126 + 137 147 153 144 135 124 + 146 86 115 128 141 155 + 156 173 161 184 205 217 + 179 178 198 208 220 214 + 239 262 245 235 246 257 + 270 203 217 232 243 257 + 291 270 307 323 310 250 + 237 252 331 273 292 271 + 258 244 256 234 260 219 + 199 187 171 189 155 174 + 187 190 183 174 195 201 + 213 252 259 246 260 242 + 244 225 216 204 234 222 + 235 186 205 198 192 190 + 159 171 150 173 193 180 + 186 168 148 140 158 119 + 161 138 151 162 137 155 + 142 135 151 168 110 120 + 109 139 78 69 93 104 + 123 136 82 78 59 49 + 66 80 41 66 65 40 + 29 114 97 27 100000000 27 + 58 89 74 272 231 226 + 215 196 166 131 74 59 + 175 190 128 200 195 251 + 212 151 197 155 146 140 + 160 145 156 101 83 103 + 119 128 179 193 89 84 + 100 114 99 110 120 126 + 117 108 97 119 59 88 + 101 114 128 129 146 134 + 157 178 190 152 151 171 + 181 193 187 212 235 218 + 208 219 230 243 184 198 + 213 224 238 264 243 283 + 296 283 231 222 237 304 + 271 290 269 256 254 241 + 247 273 204 184 172 156 + 162 140 159 172 184 177 + 168 180 214 226 265 272 + 259 273 255 257 238 229 + 217 247 235 248 199 218 + 213 219 217 186 198 163 + 186 206 193 199 181 161 + 153 171 132 174 151 164 + 175 164 182 169 162 178 + 195 137 147 136 152 105 + 96 120 117 136 149 95 + 105 86 76 93 107 68 + 79 61 67 56 141 124 + 54 27 100000000 31 62 47 + 285 244 199 188 169 139 + 104 47 32 202 217 141 + 213 208 261 197 164 182 + 127 118 112 132 117 128 + 102 55 75 91 100 151 + 165 61 56 72 86 71 + 82 92 98 89 77 66 + 88 28 57 70 83 97 + 98 115 106 126 147 159 + 124 123 143 153 164 156 + 181 206 189 179 190 201 + 214 156 170 185 196 210 + 235 214 254 267 254 203 + 194 209 275 243 262 241 + 228 226 213 236 249 176 + 156 144 128 134 112 131 + 144 156 149 140 152 209 + 221 254 261 254 268 250 + 257 233 224 212 242 236 + 249 200 219 214 232 248 + 206 218 164 187 201 188 + 194 176 156 148 166 133 + 175 152 165 176 184 202 + 200 193 209 226 168 171 + 160 153 136 127 151 118 + 137 145 96 136 117 107 + 124 138 99 80 62 87 + 87 172 155 85 58 31 + 100000000 34 48 280 239 168 + 157 141 111 76 17 33 + 233 227 142 214 203 233 + 169 146 154 93 84 78 + 98 83 94 69 21 41 + 57 66 117 131 27 22 + 38 52 37 48 58 64 + 55 69 80 102 57 86 + 99 86 72 90 95 72 + 106 127 130 90 89 109 + 119 131 136 161 173 156 + 146 157 168 181 122 136 + 151 162 176 202 181 221 + 234 221 169 160 175 242 + 209 228 207 194 192 179 + 202 215 142 122 110 94 + 100 78 97 110 122 115 + 106 118 175 187 220 227 + 220 234 216 223 199 190 + 178 208 203 216 167 186 + 181 199 215 173 185 131 + 154 167 154 160 142 122 + 114 132 100 142 119 132 + 143 151 169 179 178 194 + 207 153 138 127 120 122 + 113 133 85 104 111 63 + 122 103 93 110 124 77 + 47 29 54 65 158 141 + 71 85 58 34 100000000 15 + 246 205 148 137 107 77 + 42 17 67 200 194 109 + 181 169 199 135 112 120 + 108 99 93 113 98 109 + 54 36 56 72 81 132 + 146 42 37 53 67 52 + 63 73 79 70 84 95 + 117 72 101 114 101 87 + 105 110 87 121 142 145 + 105 104 124 134 146 151 + 176 188 171 161 172 183 + 196 137 151 166 177 191 + 217 196 236 249 236 184 + 175 190 257 224 243 222 + 209 207 194 200 226 157 + 137 125 109 115 93 112 + 125 137 130 121 133 167 + 179 218 225 212 226 208 + 210 191 182 170 200 188 + 201 152 171 166 184 200 + 158 170 116 139 159 146 + 152 134 114 106 124 85 + 127 104 117 128 136 154 + 164 163 179 192 138 123 + 112 105 107 98 118 70 + 89 102 48 107 88 78 + 95 109 62 32 14 39 + 50 143 126 56 70 43 + 49 15 100000000 238 197 163 + 152 122 92 57 32 75 + 185 179 94 166 161 214 + 150 117 135 155 146 152 + 172 192 203 220 208 228 + 211 175 165 179 193 248 + 232 203 189 183 171 162 + 171 185 196 218 229 205 + 215 202 188 202 185 184 + 174 164 152 165 137 131 + 141 153 187 191 144 164 + 168 151 162 175 104 90 + 105 116 130 173 152 114 + 136 192 123 75 90 144 + 80 99 78 65 51 94 + 41 26 57 134 120 134 + 148 187 133 146 165 172 + 168 154 42 38 26 27 + 12 48 30 37 43 34 + 44 52 93 65 75 76 + 89 107 113 121 133 106 + 86 78 74 62 140 153 + 176 194 142 117 161 174 + 150 158 176 148 155 152 + 135 180 180 169 162 224 + 215 175 188 201 214 215 + 190 212 222 202 216 225 + 231 239 264 275 260 243 + 244 271 268 257 259 244 + 100000000 19 180 160 167 179 + 236 274 290 142 102 151 + 89 53 58 125 221 110 + 196 187 193 213 233 244 + 245 249 269 252 216 206 + 220 234 289 273 244 230 + 224 212 203 212 226 237 + 259 270 246 256 243 229 + 243 226 225 215 205 193 + 206 178 172 182 194 228 + 205 185 205 209 192 203 + 216 145 131 146 157 171 + 187 166 126 148 206 164 + 116 131 156 121 111 79 + 106 92 135 82 67 98 + 175 161 175 189 228 174 + 187 206 213 209 195 83 + 79 67 68 53 29 11 + 18 36 71 83 53 74 + 66 76 57 90 108 94 + 122 134 107 87 79 113 + 101 141 154 217 235 143 + 118 162 175 151 159 177 + 146 149 133 116 174 181 + 170 163 224 215 176 189 + 208 221 216 191 213 223 + 203 217 226 232 264 289 + 285 260 243 245 272 293 + 298 284 269 41 100000000 221 + 201 208 220 277 301 325 + 123 103 152 90 92 99 + 166 236 151 141 132 138 + 158 178 189 206 194 214 + 197 107 97 111 125 224 + 143 125 111 115 103 94 + 93 107 107 129 140 111 + 98 85 99 70 53 76 + 42 30 42 55 69 49 + 39 27 12 37 69 52 + 42 53 64 77 90 104 + 88 80 94 97 76 116 + 129 116 106 118 133 137 + 162 131 163 152 150 137 + 160 173 140 120 106 120 + 80 119 119 132 151 158 + 154 140 200 190 178 185 + 187 213 231 238 218 209 + 202 227 272 240 236 255 + 250 268 284 272 284 230 + 223 215 202 208 190 170 + 162 180 199 213 218 231 + 242 250 268 278 277 293 + 306 252 237 226 219 281 + 272 232 232 187 200 210 + 247 269 275 259 273 267 + 226 225 250 255 317 300 + 253 226 199 168 202 216 + 225 224 100000000 20 57 81 + 147 185 201 299 263 208 + 250 211 157 111 207 96 + 121 112 118 138 158 169 + 186 174 194 177 87 77 + 91 105 213 132 114 100 + 95 83 74 82 96 96 + 118 129 100 87 74 88 + 59 42 65 31 10 22 + 35 49 29 19 7 32 + 57 49 32 22 33 44 + 57 70 84 68 60 74 + 78 57 97 110 97 86 + 98 113 118 143 112 144 + 132 130 117 140 153 120 + 100 86 100 60 99 99 + 112 131 138 134 120 180 + 170 158 165 167 194 212 + 219 198 189 182 207 252 + 220 216 235 230 248 264 + 252 264 210 203 195 182 + 188 170 150 142 160 179 + 193 198 211 222 230 248 + 258 257 273 286 232 217 + 206 199 261 252 212 212 + 167 180 190 227 249 259 + 239 253 253 206 205 230 + 241 297 280 242 215 188 + 157 191 205 206 204 20 + 100000000 37 70 136 174 190 + 279 243 188 230 191 137 + 91 187 76 159 150 156 + 176 196 207 224 188 208 + 215 120 110 124 128 189 + 108 90 76 87 97 67 + 58 72 72 94 105 76 + 63 50 64 35 18 41 + 7 28 40 53 82 67 + 57 45 37 62 87 70 + 60 71 82 95 108 122 + 106 98 112 116 95 135 + 148 135 124 136 151 156 + 181 150 182 170 168 155 + 178 191 158 138 124 138 + 93 132 137 150 169 176 + 172 158 218 208 196 203 + 205 232 250 257 236 227 + 220 245 290 258 254 273 + 268 286 302 290 302 248 + 241 233 220 226 208 188 + 180 198 217 231 236 249 + 260 268 286 296 295 311 + 324 270 255 244 237 269 + 260 250 250 205 218 228 + 265 250 240 257 271 232 + 213 195 220 220 305 288 + 218 191 164 133 167 181 + 244 242 49 38 100000000 46 + 112 150 166 317 281 226 + 268 229 175 129 225 114 + 126 117 123 143 163 174 + 191 163 183 182 80 70 + 84 98 164 83 54 40 + 51 61 31 22 36 47 + 69 80 56 66 53 39 + 45 28 5 37 58 70 + 13 42 62 72 75 67 + 92 117 100 90 101 112 + 125 75 89 104 115 129 + 146 125 165 178 165 122 + 134 149 186 183 180 181 + 168 166 153 176 189 125 + 105 91 105 53 92 104 + 117 136 143 139 125 208 + 206 194 201 203 231 249 + 256 232 223 211 241 257 + 254 221 240 235 253 269 + 257 269 215 208 200 187 + 193 175 155 147 165 184 + 198 203 216 227 235 253 + 263 262 278 291 237 222 + 211 204 244 235 217 217 + 172 185 195 232 225 215 + 232 246 207 188 170 195 + 195 280 263 193 166 139 + 108 142 156 243 238 79 + 68 30 100000000 87 125 141 + 284 248 193 235 202 173 + 96 192 81 160 151 157 + 177 197 208 225 183 203 + 216 114 104 118 16 184 + 103 10 24 35 45 51 + 42 56 67 89 100 76 + 86 73 59 77 82 59 + 93 114 117 77 76 96 + 106 118 123 148 160 143 + 133 144 155 168 109 123 + 138 149 163 189 168 208 + 221 208 156 168 183 229 + 217 223 215 202 200 187 + 210 223 159 139 125 139 + 87 126 138 151 170 177 + 173 159 242 240 228 235 + 237 265 283 290 266 257 + 245 275 291 288 255 274 + 269 287 303 291 303 249 + 242 234 221 227 209 189 + 181 199 218 232 237 250 + 261 269 287 297 296 312 + 325 271 256 245 238 264 + 255 251 246 206 219 224 + 264 245 235 252 266 227 + 208 190 215 215 300 283 + 213 186 159 128 162 176 + 277 272 135 124 94 64 + 100000000 145 161 318 282 227 + 269 236 207 130 226 115 + 110 101 95 115 100 111 + 86 38 58 74 83 134 + 148 44 39 55 69 54 + 65 75 81 72 86 83 + 105 45 74 87 100 89 + 107 112 89 123 144 147 + 107 106 126 136 148 153 + 178 190 173 163 174 185 + 198 139 153 168 179 193 + 219 198 238 251 238 186 + 177 192 259 226 245 224 + 211 209 196 219 232 159 + 139 127 111 117 95 114 + 127 139 132 123 135 192 + 204 237 244 237 251 233 + 240 216 207 195 225 220 + 233 184 203 198 216 232 + 190 202 148 171 184 171 + 177 159 139 131 149 117 + 159 136 149 160 168 186 + 196 195 211 224 170 155 + 144 137 139 130 150 102 + 121 128 80 139 120 110 + 127 141 94 64 46 71 + 82 175 158 88 75 48 + 17 17 32 263 222 165 + 154 124 94 59 100000000 50 + 217 211 126 198 186 216 + 152 129 137 123 114 108 + 128 113 124 69 51 71 + 87 96 147 161 57 52 + 68 82 67 78 88 94 + 85 99 98 120 60 89 + 102 115 102 120 125 102 + 136 157 160 120 119 139 + 149 161 166 191 203 186 + 176 187 198 211 152 166 + 181 192 206 232 211 251 + 264 251 199 190 205 272 + 239 258 237 224 222 209 + 215 241 172 152 140 124 + 130 108 127 140 152 145 + 136 148 182 194 233 240 + 227 241 223 225 206 197 + 185 215 203 216 167 186 + 181 199 215 173 185 131 + 154 174 161 167 149 129 + 121 139 100 142 119 132 + 143 151 169 179 178 194 + 207 153 138 127 120 122 + 113 133 85 104 117 63 + 122 103 93 110 124 77 + 47 29 54 65 158 141 + 71 85 58 32 30 15 + 253 212 178 167 137 107 + 72 15 100000000 200 194 109 + 181 176 229 165 132 150 + 190 199 205 185 205 216 + 189 199 219 224 233 269 + 283 244 239 255 269 254 + 265 275 266 272 286 289 + 311 251 280 293 303 289 + 306 289 288 278 268 256 + 269 241 235 245 257 291 + 295 248 268 272 255 266 + 279 208 194 209 220 234 + 277 256 227 249 296 227 + 179 194 257 202 212 180 + 187 173 198 163 158 161 + 237 224 238 252 245 212 + 225 219 212 203 230 130 + 142 158 159 144 130 112 + 105 123 117 129 99 83 + 96 99 66 66 45 29 + 27 39 63 86 122 109 + 115 97 110 169 187 99 + 74 118 131 56 64 82 + 23 30 24 7 55 137 + 126 119 105 96 120 133 + 152 165 160 135 106 116 + 133 147 156 176 202 177 + 166 141 124 138 165 192 + 223 228 213 142 129 284 + 264 271 283 259 239 224 + 100000000 58 108 113 124 180 + 229 180 214 215 224 230 + 210 230 241 214 224 244 + 249 258 257 271 269 264 + 280 294 279 275 263 254 + 263 277 288 310 295 297 + 307 294 280 294 277 276 + 266 256 244 257 229 223 + 233 245 279 266 236 256 + 260 243 254 267 196 182 + 197 208 222 248 227 187 + 209 267 215 167 182 217 + 172 172 140 157 143 186 + 133 118 149 226 212 226 + 240 270 225 238 244 237 + 228 246 122 130 118 119 + 104 90 72 65 83 77 + 89 59 43 56 66 26 + 8 26 42 40 52 76 + 93 85 119 107 110 123 + 194 212 112 87 131 144 + 69 77 95 67 74 81 + 64 99 150 139 132 149 + 140 145 158 177 190 185 + 160 150 160 172 186 195 + 201 233 221 210 185 168 + 182 209 236 267 253 238 + 102 89 272 252 259 271 + 284 270 268 67 100000000 121 + 80 98 150 217 205 202 + 94 103 109 89 109 120 + 93 103 123 128 137 179 + 193 148 143 159 173 158 + 169 179 185 176 190 201 + 223 178 207 220 207 193 + 211 216 193 215 205 193 + 206 178 172 182 194 228 + 253 213 219 209 220 231 + 244 145 159 174 185 199 + 242 221 240 262 261 192 + 179 194 270 206 225 204 + 191 177 198 167 193 161 + 141 129 143 162 149 116 + 129 123 116 107 134 134 + 146 185 192 179 187 169 + 162 158 149 137 156 140 + 153 119 123 105 99 115 + 66 78 83 106 126 113 + 119 101 81 73 91 52 + 94 71 25 36 44 62 + 72 69 85 100 44 29 + 18 11 73 64 24 37 + 56 69 64 39 61 71 + 51 65 74 80 112 137 + 134 109 92 93 120 141 + 166 132 117 199 164 221 + 201 208 198 163 149 173 + 93 97 100000000 133 128 184 + 154 84 139 156 165 171 + 151 171 182 155 165 185 + 190 199 223 237 210 205 + 221 235 220 231 229 220 + 229 243 254 276 240 263 + 273 260 246 260 243 242 + 232 222 210 223 195 189 + 199 211 245 249 202 222 + 226 209 220 233 162 148 + 163 174 188 231 210 190 + 212 250 181 133 148 220 + 156 175 153 141 127 152 + 117 131 115 192 178 192 + 206 211 178 191 185 178 + 169 196 84 96 131 132 + 117 103 85 78 96 90 + 87 72 56 69 53 39 + 21 39 55 53 65 17 + 40 76 63 69 51 64 + 135 153 53 28 72 85 + 82 90 108 80 87 94 + 77 106 91 80 73 135 + 126 86 99 118 131 126 + 101 123 133 113 127 136 + 142 174 199 196 171 154 + 155 182 203 228 194 179 + 115 102 238 218 225 237 + 225 211 235 80 13 62 + 100000000 78 134 183 146 168 + 153 144 150 170 190 201 + 218 206 226 209 173 163 + 177 191 246 230 201 187 + 181 169 160 169 183 194 + 216 227 203 213 200 186 + 200 183 182 172 162 150 + 163 135 129 139 151 185 + 189 142 162 166 149 160 + 173 102 88 103 114 128 + 171 150 130 152 190 121 + 73 88 160 96 115 94 + 81 67 92 57 65 55 + 132 118 132 146 185 131 + 144 163 170 166 152 24 + 36 65 66 51 65 47 + 54 30 21 9 39 91 + 52 55 74 69 87 103 + 101 113 86 42 34 21 + 9 120 133 174 192 122 + 97 141 154 130 138 156 + 128 135 142 125 160 160 + 149 142 204 195 155 168 + 187 200 195 170 192 202 + 182 196 205 211 237 262 + 265 240 223 224 251 266 + 255 257 242 77 36 178 + 158 165 177 234 272 288 + 128 82 131 69 100000000 74 + 123 215 108 173 164 170 + 190 210 221 238 226 246 + 229 193 183 197 211 266 + 250 221 207 201 189 180 + 189 203 214 236 247 223 + 233 220 206 220 203 202 + 192 182 170 183 155 149 + 159 171 205 183 162 182 + 186 169 180 193 122 108 + 123 134 148 165 144 104 + 126 184 141 93 108 134 + 70 89 68 55 41 112 + 31 16 75 152 138 152 + 166 205 151 164 183 190 + 186 172 60 56 44 45 + 30 96 78 85 61 52 + 62 70 129 83 93 112 + 107 125 141 139 151 124 + 104 96 92 80 158 171 + 194 212 160 135 179 192 + 168 176 194 166 173 180 + 163 198 198 187 180 242 + 233 193 206 219 232 233 + 208 230 240 220 234 243 + 249 257 282 293 278 261 + 262 289 286 275 277 262 + 108 67 198 178 185 197 + 254 292 308 166 120 169 + 107 71 100000000 143 239 128 + 56 47 53 73 93 104 + 121 109 129 112 83 73 + 87 101 149 158 129 111 + 91 79 88 97 111 122 + 144 155 131 141 128 114 + 132 120 110 109 99 87 + 100 72 66 76 88 122 + 147 107 113 103 114 125 + 138 39 53 68 79 93 + 136 115 130 152 155 86 + 47 62 160 96 115 94 + 81 79 66 89 102 29 + 9 23 37 56 95 34 + 21 40 47 56 29 129 + 119 107 114 116 144 162 + 169 147 138 131 156 187 + 169 151 170 165 183 199 + 187 199 145 138 130 117 + 123 105 85 77 95 114 + 128 133 146 157 165 183 + 193 192 208 221 167 152 + 141 134 196 187 147 147 + 102 115 125 162 184 194 + 174 188 188 141 140 165 + 176 232 215 182 196 169 + 183 160 145 156 153 115 + 95 102 105 162 177 201 + 214 178 123 165 132 86 + 100000000 122 33 29 38 44 + 24 44 55 72 60 80 + 63 72 114 128 105 100 + 116 130 115 126 120 129 + 133 147 158 180 135 164 + 177 164 150 168 161 150 + 150 140 128 141 113 107 + 117 129 163 188 148 154 + 144 155 166 179 80 94 + 109 120 134 177 156 175 + 197 196 127 114 129 205 + 141 160 139 126 112 133 + 102 128 96 76 64 78 + 97 84 51 64 58 51 + 42 69 69 81 120 127 + 114 128 110 117 93 84 + 72 102 118 115 82 101 + 96 114 130 118 130 76 + 69 61 48 54 36 16 + 8 26 45 59 64 77 + 88 96 114 124 123 139 + 152 98 83 72 65 127 + 118 78 78 33 46 56 + 93 115 125 105 119 128 + 72 91 116 127 163 146 + 133 147 120 145 111 96 + 140 99 156 136 143 146 + 120 128 152 145 109 54 + 96 63 119 89 100000000 74 + 45 36 42 62 82 93 + 110 98 118 101 70 60 + 74 88 138 134 105 91 + 78 66 64 73 87 98 + 120 131 107 117 104 90 + 104 87 86 76 66 54 + 67 39 33 43 55 89 + 114 74 80 70 81 92 + 105 6 20 35 46 60 + 103 82 122 135 122 53 + 62 77 143 111 130 109 + 96 94 81 104 117 44 + 24 10 24 43 82 23 + 36 55 62 58 44 127 + 134 122 129 131 159 168 + 175 151 142 130 160 176 + 173 140 159 154 172 188 + 176 188 134 127 119 106 + 112 94 74 66 84 103 + 117 122 135 146 154 172 + 182 181 197 210 156 141 + 130 123 185 176 136 136 + 91 104 114 151 173 183 + 163 177 177 130 129 154 + 165 221 204 171 185 158 + 159 149 134 171 157 82 + 62 69 81 138 166 190 + 203 167 112 154 121 101 + 15 111 100000000 +EOF diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/ATSP-instances/ftv70.atsp b/ProyectoFinal/CHC/malva/ProblemInstances/ATSP-instances/ftv70.atsp new file mode 100644 index 0000000000000000000000000000000000000000..a966e4930c1e78bad7ec1f7e9e9745792f5b332e --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/ATSP-instances/ftv70.atsp @@ -0,0 +1,849 @@ +NAME: ftv70 +TYPE: ATSP +COMMENT: Asymmetric TSP (Fischetti) +DIMENSION: 71 +EDGE_WEIGHT_TYPE: EXPLICIT +EDGE_WEIGHT_FORMAT: FULL_MATRIX +EDGE_WEIGHT_SECTION + 100000000 26 46 74 82 65 + 90 104 102 100 147 134 + 90 75 69 106 117 42 + 71 96 158 89 76 125 + 38 40 58 59 13 38 + 31 22 103 143 106 94 + 137 104 123 140 98 70 + 58 38 30 48 67 118 + 120 105 149 140 100 55 + 115 141 94 93 122 113 + 162 154 76 118 36 21 + 62 165 92 94 66 66 + 100000000 20 48 56 39 126 + 81 76 109 156 140 156 + 141 135 172 183 108 137 + 162 224 155 142 190 104 + 76 124 95 79 104 97 + 88 130 176 133 121 164 + 131 150 167 125 97 85 + 65 57 75 94 145 147 + 132 160 151 80 82 142 + 162 74 67 96 87 189 + 128 103 145 102 66 128 + 176 119 121 40 46 53 + 100000000 28 36 19 106 61 + 56 89 136 120 136 121 + 115 152 163 88 117 142 + 204 135 122 170 84 56 + 104 75 59 84 77 68 + 110 156 113 101 144 111 + 130 147 105 77 65 45 + 37 55 74 125 127 112 + 140 131 60 62 122 142 + 54 47 76 67 169 108 + 83 125 82 46 108 156 + 99 101 20 73 87 72 + 100000000 30 46 133 55 50 + 83 130 114 158 117 137 + 174 185 115 144 169 231 + 162 149 198 111 83 131 + 102 86 111 104 95 176 + 216 179 167 210 176 195 + 182 140 143 131 111 103 + 121 109 160 162 147 131 + 122 94 113 131 133 56 + 38 67 39 235 99 118 + 190 109 94 135 147 162 + 167 70 43 57 42 70 + 100000000 16 103 25 20 53 + 100 84 128 87 107 144 + 155 85 114 139 201 132 + 119 168 81 53 101 72 + 56 81 74 65 146 186 + 149 137 180 147 166 183 + 141 113 101 81 73 91 + 110 161 163 148 164 155 + 102 98 158 166 89 71 + 100 42 205 109 119 161 + 79 64 105 180 135 137 + 62 27 41 26 54 62 + 100000000 87 87 82 97 144 + 131 117 102 96 133 144 + 69 98 123 185 116 103 + 152 65 37 85 56 40 + 65 58 49 130 170 133 + 121 164 131 150 167 125 + 97 85 65 57 75 94 + 145 147 132 166 157 86 + 82 142 168 80 73 102 + 93 189 134 103 145 63 + 48 89 182 119 121 46 + 129 155 175 203 199 194 + 100000000 14 180 38 85 72 + 95 54 74 111 122 87 + 116 141 186 134 146 195 + 117 117 137 65 116 148 + 155 151 218 213 235 223 + 266 233 252 269 227 199 + 187 167 159 177 196 247 + 249 234 260 251 229 184 + 244 262 204 186 155 158 + 255 157 205 247 93 150 + 80 276 221 223 195 137 + 163 183 211 189 202 104 + 100000000 170 28 75 62 103 + 62 82 119 130 95 124 + 149 194 142 154 203 125 + 125 145 73 124 156 163 + 159 226 221 243 231 274 + 241 260 277 235 207 195 + 175 167 185 204 255 257 + 242 250 241 232 192 250 + 252 194 176 145 148 263 + 147 213 255 101 158 88 + 266 229 231 203 106 120 + 105 91 63 79 109 5 + 100000000 33 80 64 108 67 + 87 124 135 100 129 154 + 199 147 159 208 130 116 + 150 78 119 144 137 128 + 209 226 212 200 238 189 + 208 195 153 176 164 144 + 136 154 122 173 175 160 + 144 135 107 126 144 146 + 69 51 80 22 268 89 + 131 203 106 127 93 160 + 175 200 83 109 135 155 + 183 161 174 76 81 142 + 100000000 47 34 75 34 54 + 91 102 67 96 121 166 + 114 126 175 97 97 117 + 45 96 128 135 131 198 + 193 215 203 246 213 232 + 249 207 179 167 147 139 + 157 176 227 229 214 222 + 213 204 164 222 224 166 + 148 117 120 235 119 185 + 227 73 130 60 238 201 + 203 175 157 171 156 141 + 114 130 136 34 95 60 + 100000000 40 135 94 114 151 + 162 127 156 181 226 174 + 186 235 157 157 177 105 + 156 188 188 179 258 253 + 263 251 288 239 258 245 + 203 227 215 195 187 205 + 172 223 207 210 175 166 + 157 176 175 177 119 101 + 70 73 295 72 181 253 + 133 178 120 191 225 251 + 133 143 169 174 159 132 + 148 110 65 113 34 31 + 100000000 102 68 88 122 133 + 101 130 155 197 148 160 + 209 131 131 151 79 130 + 162 169 165 232 227 249 + 237 280 247 266 263 221 + 213 201 181 173 191 190 + 241 225 228 193 184 175 + 194 193 195 137 119 88 + 91 269 90 199 261 107 + 164 94 209 235 237 151 + 117 143 163 191 199 182 + 84 98 204 73 109 91 + 100000000 42 51 44 55 75 + 90 96 119 108 120 165 + 105 105 125 53 104 136 + 143 139 192 187 211 204 + 242 221 240 257 215 187 + 175 155 147 165 184 235 + 237 222 266 257 217 172 + 232 258 211 210 179 182 + 228 181 193 235 81 138 + 68 282 209 211 183 75 + 101 121 149 157 140 42 + 56 176 34 81 68 41 + 100000000 20 57 68 33 62 + 87 132 80 92 141 63 + 63 83 11 62 94 101 + 97 164 159 181 169 212 + 179 198 215 173 145 133 + 113 105 123 142 193 195 + 180 224 215 175 130 190 + 216 169 168 151 154 201 + 153 151 193 39 96 26 + 240 167 169 141 95 121 + 141 169 177 160 62 76 + 196 54 101 88 21 20 + 100000000 37 48 53 82 89 + 112 100 112 158 83 83 + 103 31 82 114 121 117 + 184 179 201 189 232 199 + 218 235 193 165 153 133 + 125 143 162 213 215 200 + 244 235 195 150 210 236 + 189 188 171 174 221 173 + 171 213 59 116 46 260 + 187 189 161 90 116 136 + 164 172 155 99 113 192 + 91 138 122 44 57 37 + 100000000 11 48 46 52 75 + 64 76 121 78 78 98 + 68 77 109 116 112 148 + 143 167 160 198 194 213 + 230 188 160 148 128 120 + 138 157 208 210 195 239 + 230 190 145 205 231 184 + 183 208 203 184 210 166 + 208 54 111 68 255 182 + 178 156 79 105 125 153 + 161 144 99 113 181 91 + 138 125 58 57 37 54 + 100000000 37 35 41 103 53 + 65 114 67 67 87 68 + 66 98 105 101 137 132 + 156 149 187 183 202 219 + 177 149 137 117 109 127 + 146 197 199 184 228 219 + 179 134 194 220 173 172 + 201 192 174 210 155 197 + 43 100 57 244 171 167 + 145 42 68 88 116 124 + 107 75 89 144 67 114 + 101 48 33 27 64 75 + 100000000 29 54 116 47 59 + 108 30 30 50 44 29 + 61 68 64 131 126 148 + 136 179 146 165 182 140 + 112 100 80 72 90 109 + 160 162 147 191 182 142 + 97 157 183 136 135 164 + 155 168 186 118 160 6 + 63 20 207 134 136 108 + 101 127 147 175 183 166 + 134 148 203 126 173 160 + 104 92 83 69 46 59 + 100000000 25 87 18 30 79 + 89 89 109 103 88 120 + 127 123 102 97 121 114 + 152 162 181 208 193 144 + 159 139 131 149 168 219 + 221 206 250 241 201 156 + 216 242 195 194 223 214 + 139 245 177 176 65 122 + 79 266 193 132 167 100 + 126 146 174 182 165 120 + 134 202 112 159 146 79 + 78 58 44 21 58 56 + 100000000 62 71 83 108 88 + 88 108 89 87 119 126 + 122 155 150 174 167 205 + 204 223 240 198 170 158 + 138 130 148 167 218 220 + 205 249 240 200 155 215 + 241 194 193 222 213 171 + 231 176 218 64 121 78 + 265 192 185 166 92 118 + 138 166 174 157 125 139 + 194 117 164 151 98 83 + 77 114 97 50 51 76 + 100000000 9 21 46 80 80 + 100 94 79 111 118 114 + 93 88 112 105 143 153 + 172 199 184 135 150 130 + 122 140 159 210 212 197 + 241 232 192 147 207 233 + 186 185 214 205 130 236 + 168 167 56 113 70 257 + 184 123 158 83 109 129 + 157 165 148 116 130 185 + 108 155 142 89 74 68 + 105 88 41 42 67 129 + 100000000 12 61 71 71 91 + 85 70 102 109 105 84 + 79 103 96 134 144 163 + 190 175 126 141 121 113 + 131 150 201 203 188 232 + 223 183 138 198 224 177 + 176 205 196 121 227 159 + 158 47 104 61 248 175 + 114 149 71 97 117 145 + 153 136 104 118 173 96 + 143 130 77 62 56 93 + 76 29 30 55 117 48 + 100000000 49 59 59 79 73 + 58 90 97 93 72 67 + 91 84 122 132 151 178 + 163 114 129 109 101 119 + 138 189 191 176 220 211 + 171 126 186 212 165 164 + 193 184 109 215 147 146 + 35 92 49 236 163 102 + 137 204 230 250 278 286 + 269 224 238 306 216 255 + 237 173 182 162 147 125 + 162 160 104 114 123 135 + 100000000 192 192 163 193 191 + 223 230 226 144 139 147 + 156 174 184 165 230 215 + 186 249 242 234 252 251 + 267 282 289 332 323 297 + 259 299 325 298 297 325 + 317 113 327 260 198 168 + 225 182 348 237 174 270 + 38 64 84 112 120 103 + 78 92 140 88 135 122 + 78 63 57 94 105 30 + 59 84 146 77 38 87 + 100000000 28 20 47 25 31 + 38 47 110 105 129 122 + 160 142 161 178 136 108 + 96 76 68 86 105 156 + 158 143 187 178 138 93 + 153 179 132 131 160 151 + 147 192 114 156 24 59 + 50 203 130 132 104 151 + 177 197 225 221 216 50 + 64 202 60 107 94 117 + 76 96 133 144 109 138 + 163 208 156 168 217 139 + 100000000 159 19 138 170 177 + 173 240 235 257 245 288 + 255 274 291 249 221 209 + 189 181 199 218 269 271 + 256 282 273 251 206 266 + 284 226 208 177 180 277 + 179 227 269 115 172 102 + 298 243 245 217 89 115 + 135 163 171 154 122 136 + 191 114 161 148 95 80 + 74 111 94 47 48 73 + 135 66 18 67 77 77 + 100000000 91 76 108 115 111 + 90 85 109 102 140 150 + 169 196 181 132 147 127 + 119 137 156 207 209 194 + 238 229 189 144 204 230 + 183 182 211 202 127 233 + 165 164 53 110 67 254 + 181 120 155 132 158 178 + 206 202 197 31 45 183 + 41 88 75 98 57 77 + 114 125 90 119 144 189 + 137 149 198 120 55 140 + 100000000 119 151 158 154 221 + 216 238 226 269 236 255 + 272 230 202 190 170 162 + 180 199 250 252 237 263 + 254 232 187 247 265 207 + 189 158 161 258 160 208 + 250 96 153 83 279 224 + 226 198 13 39 59 87 + 95 78 77 91 115 87 + 134 121 77 62 56 93 + 104 29 58 83 145 76 + 63 112 25 27 45 46 + 100000000 32 39 35 116 130 + 119 107 150 117 136 153 + 111 83 71 51 43 61 + 80 131 133 118 162 153 + 113 68 128 154 107 106 + 135 126 172 167 89 131 + 23 34 49 178 105 107 + 79 38 48 68 96 104 + 87 109 123 124 119 166 + 153 109 94 88 125 136 + 61 90 115 177 108 69 + 118 31 59 51 78 32 + 100000000 7 16 123 136 126 + 114 157 124 143 160 118 + 90 78 58 50 68 87 + 138 140 125 169 160 120 + 75 135 161 114 115 144 + 135 178 176 96 138 55 + 41 81 185 112 114 88 + 31 41 61 89 97 80 + 105 119 117 115 162 149 + 105 90 84 121 132 57 + 86 111 173 104 65 114 + 27 55 47 74 28 7 + 100000000 9 116 132 119 107 + 150 117 136 153 111 83 + 71 51 43 61 80 131 + 133 118 162 153 113 68 + 128 154 107 108 137 128 + 174 169 89 131 51 34 + 77 178 105 107 81 22 + 32 52 80 88 71 112 + 113 108 122 169 156 112 + 97 91 128 139 64 93 + 118 180 111 74 123 36 + 62 56 81 35 16 9 + 100000000 107 141 110 98 141 + 108 127 144 102 74 62 + 42 34 52 71 122 124 + 109 153 144 104 59 119 + 145 98 99 128 119 166 + 160 80 122 58 25 84 + 169 96 98 72 108 134 + 154 182 190 173 141 155 + 210 133 180 167 114 99 + 93 130 113 66 67 92 + 154 85 37 60 96 96 + 19 110 95 127 134 130 + 100000000 46 75 63 106 116 + 135 162 147 93 166 146 + 138 156 175 199 221 213 + 257 248 208 163 223 249 + 202 201 230 221 120 252 + 184 130 72 129 86 273 + 169 81 174 127 153 173 + 201 209 192 160 174 229 + 152 199 186 133 118 112 + 149 132 85 86 111 173 + 104 56 79 115 115 38 + 129 114 146 153 149 19 + 100000000 29 17 60 70 89 + 116 101 47 135 148 157 + 175 137 153 175 175 219 + 210 183 182 185 211 221 + 220 249 240 85 271 146 + 84 91 148 105 235 123 + 35 193 164 190 210 210 + 240 229 197 211 260 189 + 236 223 170 155 149 186 + 169 122 123 148 210 141 + 93 98 152 152 75 166 + 151 183 190 186 56 45 + 100000000 12 31 41 60 87 + 72 42 106 119 190 208 + 108 124 146 146 190 181 + 154 173 156 182 197 229 + 258 249 56 290 117 55 + 128 185 142 206 94 30 + 202 153 179 199 222 235 + 218 186 200 255 178 225 + 212 159 144 138 175 158 + 111 112 137 199 130 82 + 105 141 141 64 155 140 + 172 179 175 45 57 12 + 100000000 43 53 72 99 84 + 30 118 131 183 201 120 + 136 158 158 202 193 166 + 185 168 194 209 241 270 + 261 68 297 129 67 117 + 174 131 218 106 18 214 + 189 175 195 179 209 214 + 261 234 229 253 300 287 + 234 219 213 250 233 186 + 187 212 270 205 157 175 + 216 216 139 230 202 209 + 202 193 120 122 80 92 + 100000000 10 29 56 41 87 + 75 88 159 177 77 93 + 115 115 159 150 123 142 + 125 151 166 198 227 218 + 105 259 86 24 192 168 + 206 175 63 110 171 179 + 165 185 169 199 204 251 + 224 219 243 290 277 224 + 209 203 240 223 176 177 + 202 260 195 147 165 206 + 206 129 220 192 199 192 + 183 110 112 70 82 49 + 100000000 19 46 31 77 65 + 78 149 167 67 83 105 + 105 149 140 113 132 115 + 141 156 188 217 208 95 + 249 76 14 182 158 196 + 165 53 100 161 212 205 + 225 209 239 244 245 259 + 259 237 284 271 218 203 + 197 234 217 170 171 196 + 241 189 141 146 200 200 + 123 214 199 231 232 223 + 104 93 51 63 30 40 + 100000000 67 71 93 105 118 + 189 207 107 104 117 145 + 167 158 153 172 155 181 + 196 228 254 248 76 286 + 116 54 176 198 190 183 + 93 81 201 184 170 190 + 174 204 209 256 229 224 + 248 295 282 229 214 208 + 245 228 181 182 207 269 + 200 152 175 211 211 134 + 225 197 204 197 188 115 + 150 108 106 87 72 57 + 100000000 36 82 70 83 154 + 172 72 37 59 110 109 + 100 118 137 120 146 161 + 193 196 213 133 228 81 + 86 187 163 201 125 58 + 106 166 148 134 154 138 + 168 173 220 193 188 212 + 259 246 193 178 172 209 + 192 145 146 171 233 164 + 116 139 175 175 98 189 + 161 168 161 152 79 125 + 82 70 85 36 55 82 + 100000000 46 34 47 118 136 + 36 87 89 74 118 109 + 82 101 84 110 125 157 + 186 177 131 218 45 50 + 151 127 165 134 22 70 + 130 213 199 219 203 233 + 238 285 258 253 277 324 + 311 258 243 237 274 257 + 210 211 236 294 229 181 + 199 240 240 163 254 226 + 233 226 217 144 146 104 + 116 83 34 53 80 65 + 100000000 99 112 183 201 101 + 117 139 139 183 174 147 + 166 149 175 190 222 251 + 242 129 283 110 48 216 + 192 230 199 87 134 195 + 153 146 166 150 180 185 + 186 200 200 178 225 212 + 159 144 138 175 158 111 + 112 137 199 130 82 105 + 141 141 64 155 140 172 + 173 164 45 91 48 36 + 79 46 65 92 77 12 + 100000000 59 130 148 48 99 + 101 86 130 121 94 113 + 96 122 137 169 198 189 + 104 230 57 60 117 139 + 131 146 34 36 142 173 + 166 186 170 200 205 206 + 220 220 198 245 232 179 + 164 158 195 178 131 132 + 157 219 150 102 125 161 + 161 84 175 160 192 193 + 184 65 111 68 56 99 + 66 85 112 97 32 20 + 100000000 150 168 68 119 121 + 106 150 141 114 133 116 + 142 157 189 218 209 124 + 250 77 80 137 159 151 + 166 54 56 162 30 16 + 36 64 72 55 120 97 + 92 125 172 156 120 105 + 99 136 147 72 101 126 + 188 119 106 133 68 70 + 88 89 43 50 43 34 + 73 119 76 64 107 74 + 93 110 68 40 28 8 + 100000000 18 37 88 90 75 + 119 110 70 25 85 111 + 64 83 112 103 132 144 + 46 88 66 9 92 135 + 62 64 56 54 40 60 + 59 89 79 144 114 109 + 142 189 173 144 129 123 + 160 171 96 125 150 212 + 143 130 157 92 94 112 + 113 67 74 67 58 97 + 143 100 88 131 86 105 + 92 50 64 52 32 24 + 100000000 19 70 72 57 101 + 92 52 7 67 93 46 + 78 107 98 156 139 28 + 100 90 33 116 117 72 + 88 51 112 98 118 102 + 132 137 202 157 152 185 + 232 216 202 187 181 218 + 223 154 177 202 264 195 + 147 170 150 152 129 171 + 125 132 125 116 110 156 + 113 101 116 67 86 73 + 31 77 65 78 82 100 + 100000000 51 53 38 82 73 + 46 65 48 74 89 121 + 150 141 162 182 9 81 + 148 91 174 98 53 101 + 94 178 164 184 168 198 + 203 268 223 218 251 290 + 259 251 236 230 267 250 + 203 204 229 291 222 174 + 197 216 218 156 237 191 + 198 191 182 137 172 130 + 128 109 94 79 22 58 + 104 92 105 148 166 94 + 100000000 34 126 84 75 112 + 131 114 126 155 181 171 + 207 155 203 103 108 209 + 157 223 100 80 128 160 + 144 130 150 134 164 169 + 234 189 184 217 256 225 + 234 219 213 250 261 186 + 215 240 302 233 211 234 + 182 184 193 203 157 164 + 157 148 174 209 167 165 + 146 131 116 59 95 141 + 129 122 114 132 93 96 + 100000000 92 50 41 78 97 + 80 92 121 147 137 173 + 192 169 102 145 180 123 + 206 66 117 165 126 138 + 124 144 128 158 163 228 + 183 178 211 250 219 228 + 213 207 244 255 180 209 + 234 296 227 191 214 176 + 178 173 197 151 158 151 + 142 154 189 147 145 126 + 111 96 39 75 121 109 + 116 108 126 87 17 15 + 100000000 44 35 72 91 74 + 86 115 141 131 167 172 + 163 96 125 174 117 200 + 60 97 145 120 94 80 + 100 84 114 119 184 139 + 134 167 214 198 184 169 + 163 200 211 136 165 190 + 252 183 170 197 132 134 + 152 153 107 114 107 98 + 137 183 140 128 159 110 + 129 81 74 104 92 72 + 64 82 43 59 57 42 + 100000000 62 28 47 30 56 + 71 103 132 123 196 164 + 52 124 130 73 156 16 + 96 128 76 103 89 109 + 93 123 128 193 148 143 + 176 215 184 193 178 172 + 209 220 145 174 199 261 + 192 179 206 141 143 161 + 162 116 123 116 107 146 + 192 149 137 168 119 138 + 90 83 113 101 81 73 + 91 52 68 41 51 9 + 100000000 37 56 39 51 80 + 106 96 132 205 128 61 + 133 139 82 165 25 105 + 137 85 66 52 72 71 + 101 91 156 126 121 154 + 201 185 156 141 135 172 + 183 108 137 162 224 155 + 142 169 104 106 124 125 + 79 86 79 70 109 155 + 112 100 131 82 101 88 + 46 76 64 44 36 54 + 15 66 68 53 97 88 + 100000000 19 63 89 58 90 + 119 110 168 151 24 96 + 102 45 128 113 68 100 + 63 47 33 53 52 82 + 72 137 107 102 135 182 + 166 137 122 116 153 164 + 89 118 143 205 136 123 + 150 85 87 105 106 60 + 67 60 51 90 136 93 + 81 124 91 110 127 85 + 57 45 25 17 35 54 + 105 107 92 136 127 45 + 100000000 102 128 39 71 100 + 91 149 132 63 105 83 + 26 109 152 79 81 44 + 113 99 119 54 84 100 + 187 109 104 137 184 168 + 203 171 182 219 230 155 + 184 209 271 202 189 216 + 151 137 171 156 126 133 + 126 117 156 202 159 147 + 178 129 148 122 93 123 + 111 91 83 101 62 100 + 73 83 41 32 47 66 + 100000000 26 41 73 102 93 + 215 134 71 143 149 92 + 175 57 115 147 46 129 + 124 128 56 86 102 189 + 111 106 139 186 170 214 + 173 193 230 241 171 200 + 225 287 218 205 241 167 + 139 187 158 142 158 151 + 142 181 227 184 172 203 + 154 173 160 118 148 136 + 116 108 126 87 138 140 + 125 168 159 72 91 135 + 100000000 34 75 104 95 240 + 136 96 168 165 117 191 + 184 140 172 48 95 90 + 94 22 52 68 155 77 + 72 105 152 136 180 139 + 159 196 207 137 166 191 + 253 184 171 207 133 105 + 153 124 108 124 117 108 + 147 193 150 138 169 120 + 139 126 84 114 102 82 + 74 92 53 104 106 91 + 134 125 38 57 101 127 + 100000000 41 70 61 206 102 + 62 134 131 83 157 150 + 106 138 14 113 108 112 + 40 70 86 160 56 51 + 84 131 115 159 118 138 + 175 186 151 180 205 250 + 198 189 225 151 123 171 + 129 126 142 135 126 165 + 211 168 156 187 138 157 + 144 102 132 120 100 92 + 110 71 122 124 109 93 + 84 56 75 93 95 18 + 100000000 29 29 224 61 80 + 152 149 101 144 109 124 + 156 32 146 160 145 101 + 103 119 193 89 84 117 + 119 88 190 151 171 208 + 219 184 213 238 283 231 + 222 271 184 156 204 162 + 159 184 177 168 226 272 + 229 217 248 199 218 186 + 163 193 181 161 153 171 + 132 164 137 147 105 96 + 117 136 105 107 79 61 + 100000000 62 285 32 141 213 + 182 162 177 121 185 217 + 93 84 98 83 69 41 + 57 131 27 22 55 102 + 86 130 89 109 146 157 + 122 151 176 221 169 160 + 209 122 94 142 100 97 + 122 115 106 187 227 190 + 178 216 167 186 173 131 + 154 142 122 114 132 100 + 151 153 138 122 113 85 + 104 122 124 47 29 58 + 100000000 246 67 109 181 120 + 105 115 138 153 178 61 + 146 172 192 220 228 211 + 179 193 248 171 218 205 + 152 137 131 168 151 104 + 105 130 192 123 75 80 + 134 134 57 148 133 165 + 172 168 38 27 34 44 + 65 75 76 121 106 74 + 140 153 176 194 142 158 + 180 180 224 215 188 201 + 190 216 231 239 268 259 + 100000000 290 151 89 110 167 + 124 240 128 62 212 114 + 128 113 69 71 87 161 + 57 52 85 120 89 160 + 119 139 176 187 152 181 + 206 251 199 190 239 152 + 124 172 130 127 152 145 + 136 194 240 197 185 216 + 167 186 173 131 161 149 + 129 121 139 100 151 153 + 138 122 113 85 104 122 + 124 47 29 58 30 253 + 100000000 109 181 150 130 145 + 138 153 185 61 103 89 + 109 93 123 128 193 148 + 143 176 223 207 193 178 + 172 209 220 145 174 199 + 261 192 179 206 141 143 + 161 162 116 123 116 107 + 146 192 149 137 153 119 + 123 66 83 113 101 81 + 73 91 52 44 44 29 + 73 64 37 56 39 65 + 80 112 141 132 199 173 + 100000000 133 139 82 165 89 + 105 137 85 165 151 171 + 155 185 190 237 210 205 + 229 276 263 210 195 189 + 226 209 162 163 188 250 + 181 133 156 192 192 115 + 206 178 185 178 169 96 + 132 90 87 69 53 39 + 53 17 63 51 64 135 + 153 53 90 106 91 135 + 126 99 118 101 127 142 + 174 203 194 115 235 62 + 100000000 168 144 182 151 39 + 87 147 36 62 82 110 + 118 101 74 88 138 73 + 120 107 54 39 33 70 + 81 6 35 60 122 53 + 62 111 24 24 44 43 + 23 55 62 58 134 129 + 142 130 173 140 159 176 + 134 106 94 74 66 84 + 103 154 156 141 185 176 + 136 91 151 177 130 129 + 158 149 171 190 112 154 + 100000000 57 26 201 128 130 + 102 21 7 27 55 63 + 46 111 88 83 116 163 + 147 111 96 90 127 138 + 63 92 117 179 110 97 + 142 59 61 79 80 34 + 41 34 25 82 128 85 + 73 116 83 102 119 77 + 49 37 17 9 27 46 + 97 99 84 128 119 79 + 34 94 120 73 74 103 + 94 141 135 55 97 57 + 100000000 83 144 71 73 47 + 102 128 148 176 184 167 + 69 83 203 61 108 95 + 28 27 7 44 55 60 + 89 96 119 107 119 165 + 90 90 110 38 89 121 + 128 124 191 186 208 196 + 239 206 225 242 200 172 + 160 140 132 150 169 220 + 222 207 251 242 202 157 + 217 243 196 195 178 181 + 228 180 178 220 66 123 + 100000000 267 194 196 168 164 + 150 170 154 184 189 254 + 209 204 237 276 245 254 + 239 233 270 281 206 235 + 260 322 253 217 240 202 + 204 199 223 177 184 177 + 168 180 215 173 171 152 + 137 122 65 101 147 135 + 142 134 152 113 43 41 + 26 70 61 98 117 100 + 112 141 167 157 193 198 + 189 122 151 200 143 226 + 100000000 123 171 146 126 112 + 132 116 146 151 216 171 + 166 199 246 230 216 201 + 195 232 237 168 191 216 + 278 209 161 184 164 166 + 143 185 139 146 139 130 + 124 170 127 115 130 81 + 100 87 45 91 79 92 + 96 114 14 65 67 52 + 96 87 60 79 62 88 + 103 135 164 155 176 196 + 23 95 162 105 188 112 + 100000000 115 108 225 211 231 + 215 245 250 297 270 265 + 289 336 323 270 255 249 + 286 269 222 223 248 306 + 241 193 211 252 252 175 + 266 238 245 238 229 156 + 158 116 128 95 46 65 + 92 77 12 111 124 195 + 213 113 129 151 151 195 + 186 159 178 161 187 202 + 234 263 254 141 295 122 + 60 228 204 242 211 99 + 100000000 207 81 95 80 8 + 38 54 141 63 58 91 + 138 122 166 125 145 182 + 193 123 152 177 239 170 + 157 206 119 91 139 110 + 94 119 112 103 184 224 + 187 175 214 165 184 171 + 129 151 139 119 111 129 + 98 149 151 136 120 111 + 83 102 120 122 45 27 + 56 47 243 88 107 179 + 117 102 143 136 151 175 + 0 +EOF diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/ATSP-instances/rbg323.atsp b/ProyectoFinal/CHC/malva/ProblemInstances/ATSP-instances/rbg323.atsp new file mode 100644 index 0000000000000000000000000000000000000000..c19aa72c455db30b9d4c75672b2e085cd4d5f268 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/ATSP-instances/rbg323.atsp @@ -0,0 +1,6467 @@ +NAME: rbg323 +TYPE: ATSP +COMMENT: Stacker crane application (Ascheuer) +DIMENSION: 323 +EDGE_WEIGHT_TYPE: EXPLICIT +EDGE_WEIGHT_FORMAT: FULL_MATRIX +EDGE_WEIGHT_SECTION + 0 18 20 18 27 18 7 20 22 14 11 10 14 14 23 10 24 + 16 12 12 15 12 12 16 24 18 18 18 14 18 14 23 23 18 + 18 18 19 18 18 21 18 18 18 15 18 21 11 18 24 21 11 + 12 23 12 5 27 16 18 11 18 18 4 15 27 16 23 24 15 + 18 18 14 20 18 18 22 10 18 10 18 27 18 25 18 18 18 + 18 18 18 18 18 18 18 15 18 18 18 18 16 7 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 18 18 18 12 + 18 18 24 18 18 18 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 12 12 16 15 13 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 20 24 27 + 18 25 23 16 11 27 23 27 13 18 14 18 23 10 24 11 27 + 15 14 18 23 27 18 16 18 15 23 20 23 16 27 16 24 18 + 21 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 18 + 21 18 14 11 12 24 12 27 12 18 23 10 23 21 24 23 13 + 18 23 23 23 14 18 23 27 14 27 18 21 18 16 26 18 10 + 26 27 24 12 14 9 15 20 20 24 16 11 20 27 12 18 13 + 24 15 16 15 13 24 13 24 16 24 7 12 18 20 15 16 24 + 12 23 23 27 14 18 11 18 16 13 10 20 23 14 24 23 11 + 27 18 15 14 26 10 14 10 16 24 14 18 16 12 10 27 24 + + 18 0 20 18 27 18 7 20 22 14 11 10 14 14 23 10 24 + 16 12 12 15 12 12 16 24 18 18 18 14 18 14 23 23 18 + 18 18 19 18 18 21 18 18 18 15 18 21 11 18 24 21 11 + 12 23 12 5 27 16 18 11 18 18 4 15 27 16 23 24 15 + 18 18 14 20 18 18 22 10 18 10 18 27 18 25 18 18 18 + 18 18 18 18 18 18 18 15 18 18 18 18 16 7 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 18 18 18 12 + 18 18 24 18 18 18 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 12 12 16 15 13 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 20 24 27 + 18 25 23 16 11 27 23 27 13 18 14 18 23 10 24 11 27 + 15 14 18 23 27 18 16 18 15 23 20 23 16 27 16 24 18 + 21 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 18 + 21 18 14 11 12 24 12 27 12 18 23 10 23 21 24 23 13 + 18 23 23 23 14 18 23 27 14 27 18 21 18 16 26 18 10 + 26 27 24 12 14 9 15 20 20 24 16 11 20 27 12 18 13 + 24 15 16 15 13 24 13 24 16 24 7 12 18 20 15 16 24 + 12 23 23 27 14 18 11 18 16 13 10 20 23 14 24 23 11 + 27 18 15 14 26 10 14 10 16 24 14 18 16 12 10 27 24 + + 15 10 0 25 23 25 20 11 22 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 18 25 25 24 25 12 11 12 25 + 25 25 19 25 25 21 25 25 25 24 25 10 23 25 14 21 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 13 16 24 + 25 25 13 9 25 25 22 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 9 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 18 16 24 16 23 10 + 18 12 12 11 12 14 18 24 15 23 24 24 23 14 24 24 10 + 4 7 15 23 23 12 12 12 24 20 21 12 12 12 20 15 23 + 10 20 12 24 21 23 12 23 23 18 24 24 11 21 18 23 23 + 12 24 23 11 23 10 13 25 24 12 9 12 11 23 24 14 11 + 21 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 18 24 16 23 14 15 23 16 24 13 21 12 10 14 12 14 + 25 12 11 12 24 15 13 23 24 23 24 10 18 11 21 13 21 + 21 23 14 14 12 20 24 7 5 15 24 23 4 23 23 18 23 + 18 24 24 24 23 15 23 18 24 18 20 23 18 6 24 24 14 + 23 12 18 23 12 10 23 10 24 23 21 7 12 24 14 13 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 20 20 21 0 27 16 10 21 24 15 11 11 15 15 24 0 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 21 16 16 23 16 16 16 14 16 23 10 16 24 23 10 + 14 23 12 10 27 15 19 10 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 24 11 16 11 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 20 16 16 16 18 10 16 21 12 + 6 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 5 9 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 14 11 15 14 15 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 22 24 27 + 20 26 24 15 12 27 24 27 15 19 12 19 23 0 24 10 27 + 16 15 19 23 27 20 18 19 14 23 21 24 18 27 15 24 20 + 23 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 19 + 23 20 12 12 12 24 12 27 14 19 23 6 24 23 24 23 15 + 19 23 23 23 12 20 24 28 15 28 19 23 19 18 27 20 10 + 27 27 24 14 15 10 14 21 21 24 15 10 21 27 11 19 15 + 25 14 15 14 15 24 15 25 15 24 10 12 19 21 14 15 24 + 11 23 23 27 15 20 10 20 15 15 9 21 23 12 24 23 10 + 27 19 15 12 27 8 12 6 15 25 15 19 15 12 11 28 24 + + 23 23 23 33 0 33 27 23 24 24 28 27 24 24 18 28 14 + 31 25 25 31 25 30 31 14 23 33 33 31 33 24 21 20 33 + 33 33 23 33 33 23 33 33 33 31 33 23 28 33 16 23 28 + 25 20 25 27 10 31 29 28 33 33 27 31 6 31 20 15 31 + 33 33 24 23 33 33 24 27 33 27 33 10 33 12 33 33 33 + 33 33 33 33 33 23 33 31 23 33 33 33 24 27 33 23 26 + 28 31 24 25 24 25 24 20 33 33 33 33 33 33 33 33 25 + 33 33 15 33 33 33 33 23 15 28 28 19 26 31 26 10 23 + 15 18 20 21 24 16 19 31 25 29 31 31 29 23 31 31 23 + 23 23 23 10 6 20 18 18 31 12 15 18 18 18 23 15 10 + 23 12 18 31 28 10 18 10 30 24 31 31 21 28 19 28 19 + 24 31 30 21 10 23 24 33 31 20 23 18 24 10 31 16 23 + 23 23 23 10 15 31 26 25 12 23 14 24 20 15 31 25 27 + 23 23 31 26 30 16 25 10 26 31 20 28 18 23 16 20 25 + 33 20 21 20 31 23 18 10 31 10 31 23 25 24 11 23 28 + 15 10 16 25 24 27 31 23 23 15 31 28 23 10 29 25 30 + 19 31 31 31 29 15 28 19 31 19 27 30 26 23 31 31 16 + 29 20 21 10 24 23 28 23 31 29 28 23 20 31 16 20 28 + 10 31 31 31 15 28 31 28 31 15 24 31 31 25 27 15 16 + + 17 14 12 27 16 0 23 12 24 18 24 23 18 18 0 24 12 + 27 21 21 26 20 25 27 12 19 27 27 25 27 18 11 10 27 + 27 27 21 27 27 23 27 27 27 26 27 12 24 27 10 23 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 15 15 26 + 27 27 18 12 27 27 24 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 19 23 27 23 16 14 + 15 0 10 11 18 15 19 27 21 24 27 26 24 16 27 27 14 + 12 12 17 16 18 10 10 10 26 14 15 12 10 0 22 11 16 + 14 14 5 27 24 16 12 16 25 19 25 26 11 24 19 24 19 + 16 25 25 11 16 14 15 27 26 10 12 0 15 16 27 10 14 + 23 14 12 16 16 26 23 20 14 14 12 16 10 15 27 20 23 + 12 19 25 23 25 15 21 16 23 25 15 24 10 12 15 10 20 + 27 10 11 10 25 17 15 18 25 18 26 12 21 15 15 15 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 19 26 27 26 24 11 24 19 27 19 23 25 23 12 26 27 10 + 24 10 19 16 18 14 24 14 27 24 24 12 10 25 10 15 24 + 16 25 26 25 15 24 25 24 27 15 18 25 27 21 23 18 10 + + 18 18 20 18 27 18 0 20 22 14 11 10 14 14 23 10 24 + 16 12 12 15 12 12 16 24 18 18 18 14 18 14 23 23 18 + 18 18 19 18 18 21 18 18 18 15 18 21 11 18 24 21 11 + 12 23 12 5 27 16 18 11 18 18 4 15 27 16 23 24 15 + 18 18 14 20 18 18 22 10 18 10 18 27 18 25 18 18 18 + 18 18 18 18 18 18 18 15 18 18 18 18 16 7 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 18 18 18 12 + 18 18 24 18 18 18 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 12 12 16 15 13 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 20 24 27 + 18 25 23 16 11 27 23 27 13 18 14 18 23 10 24 11 27 + 15 14 18 23 27 18 16 18 15 23 20 23 16 27 16 24 18 + 21 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 18 + 21 18 14 11 12 24 12 27 12 18 23 10 23 21 24 23 13 + 18 23 23 23 14 18 23 27 14 27 18 21 18 16 26 18 10 + 26 27 24 12 14 9 15 20 20 24 16 11 20 27 12 18 13 + 24 15 16 15 13 24 13 24 16 24 7 12 18 20 15 16 24 + 12 23 23 27 14 18 11 18 16 13 10 20 23 14 24 23 11 + 27 18 15 14 26 10 14 10 16 24 14 18 16 12 10 27 24 + + 17 10 11 25 23 25 20 0 24 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 19 25 25 24 25 12 11 12 25 + 25 25 21 25 25 23 25 25 25 24 25 10 23 25 14 23 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 15 16 24 + 25 25 15 10 25 25 24 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 10 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 19 16 24 16 23 10 + 18 12 12 11 12 15 19 24 15 23 24 24 23 16 24 24 10 + 5 9 17 23 23 12 12 12 24 20 21 12 12 12 22 15 23 + 10 20 12 24 21 23 12 23 23 19 24 24 11 21 19 23 23 + 12 24 23 11 23 10 15 25 24 12 10 12 11 23 24 14 12 + 23 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 19 + 10 19 24 16 23 15 15 23 16 24 15 21 12 10 15 12 15 + 25 12 11 12 24 17 15 23 24 23 24 10 19 11 21 15 21 + 21 23 14 14 12 20 24 9 6 15 24 23 5 23 23 19 23 + 19 24 24 24 23 15 23 19 24 19 20 23 19 8 24 24 14 + 23 12 19 23 14 10 23 10 24 23 21 9 12 24 14 15 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 14 10 8 25 23 25 20 9 0 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 16 25 25 24 25 12 11 12 25 + 25 25 18 25 25 20 25 25 25 24 25 10 23 25 14 20 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 12 16 24 + 25 25 12 7 25 25 21 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 7 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 16 16 24 16 23 10 + 18 12 12 11 12 14 16 24 15 23 24 24 23 13 24 24 10 + 2 6 14 23 23 12 12 12 24 20 21 12 12 12 19 15 23 + 10 20 12 24 21 23 12 23 23 16 24 24 11 21 16 23 23 + 12 24 23 11 23 10 12 25 24 12 7 12 11 23 24 14 10 + 20 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 16 24 16 23 14 15 23 16 24 12 21 12 10 14 12 14 + 25 12 11 12 24 14 12 23 24 23 24 10 16 11 21 12 21 + 21 23 14 14 12 20 24 6 3 15 24 23 2 23 23 16 23 + 16 24 24 24 23 15 23 16 24 16 20 23 16 5 24 24 14 + 23 12 16 23 12 10 23 10 24 23 21 6 12 24 14 12 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 17 14 15 23 25 23 12 15 24 0 14 11 11 11 21 12 23 + 21 6 11 20 10 16 21 23 19 23 23 18 23 11 18 20 23 + 23 23 21 23 23 23 23 23 23 20 23 16 14 23 23 23 14 + 10 20 8 12 25 21 19 14 23 23 12 20 25 21 20 23 20 + 23 23 15 15 23 23 24 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 8 12 5 12 20 23 23 23 23 23 23 23 23 11 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 14 15 21 20 15 16 21 21 14 + 15 15 17 25 25 20 21 21 20 24 24 21 21 21 22 23 25 + 14 24 21 21 12 25 21 25 16 19 18 20 18 12 23 14 25 + 12 18 19 18 25 14 15 23 20 20 15 21 12 25 21 23 14 + 23 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 19 + 16 19 18 10 16 23 11 25 14 19 20 12 21 16 23 20 15 + 23 20 18 20 18 17 21 25 18 25 20 16 19 12 24 15 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 19 16 + 23 20 21 20 15 23 15 23 21 23 12 16 19 15 20 21 23 + 15 20 19 25 14 14 14 14 21 15 12 15 20 18 23 20 14 + 25 19 20 18 24 12 18 12 21 23 11 19 21 0 11 25 23 + + 21 21 23 15 28 15 11 23 22 16 0 12 16 16 24 10 25 + 14 14 14 12 15 11 14 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 21 15 15 15 12 15 23 1 15 24 21 7 + 15 24 14 11 28 14 18 9 15 15 11 12 28 14 24 25 12 + 15 15 16 23 15 15 22 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 10 14 12 13 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 21 25 28 + 21 27 24 14 11 28 24 28 13 18 12 18 23 10 25 5 28 + 18 13 18 23 28 21 20 18 12 24 23 24 20 28 14 24 21 + 21 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 18 + 23 21 12 12 11 24 14 28 12 18 24 10 24 23 24 24 15 + 18 24 23 24 12 21 24 28 13 28 18 23 18 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 7 23 28 10 18 13 + 25 12 14 12 13 25 13 25 14 24 11 11 18 23 12 14 24 + 10 24 23 28 16 21 7 21 14 13 10 23 24 12 24 24 1 + 28 18 13 12 27 10 12 10 14 25 16 18 14 14 12 28 24 + + 24 24 25 0 31 0 18 25 24 23 15 0 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 17 14 15 23 25 23 12 15 24 11 14 11 0 11 21 12 23 + 21 6 11 20 10 16 21 23 19 23 23 18 23 11 18 20 23 + 23 23 21 23 23 23 23 23 23 20 23 16 14 23 23 23 14 + 10 20 8 12 25 21 19 14 23 23 12 20 25 21 20 23 20 + 23 23 15 15 23 23 24 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 8 12 5 12 20 23 23 23 23 23 23 23 23 11 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 14 15 21 20 15 16 21 21 14 + 15 15 17 25 25 20 21 21 20 24 24 21 21 21 22 23 25 + 14 24 21 21 12 25 21 25 16 19 18 20 18 12 23 14 25 + 12 18 19 18 25 14 15 23 20 20 15 21 12 25 21 23 14 + 23 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 19 + 16 19 18 10 16 23 11 25 14 19 20 12 21 16 23 20 15 + 23 20 18 20 18 17 21 25 18 25 20 16 19 12 24 15 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 19 16 + 23 20 21 20 15 23 15 23 21 23 12 16 19 15 20 21 23 + 15 20 19 25 14 14 14 14 21 15 12 15 20 18 23 20 14 + 25 19 20 18 24 12 18 12 21 23 11 19 21 0 11 25 23 + + 17 14 15 23 25 23 12 15 24 11 14 11 11 0 21 12 23 + 21 6 11 20 10 16 21 23 19 23 23 18 23 11 18 20 23 + 23 23 21 23 23 23 23 23 23 20 23 16 14 23 23 23 14 + 10 20 8 12 25 21 19 14 23 23 12 20 25 21 20 23 20 + 23 23 15 15 23 23 24 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 8 12 5 12 20 23 23 23 23 23 23 23 23 11 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 14 15 21 20 15 16 21 21 14 + 15 15 17 25 25 20 21 21 20 24 24 21 21 21 22 23 25 + 14 24 21 21 12 25 21 25 16 19 18 20 18 12 23 14 25 + 12 18 19 18 25 14 15 23 20 20 15 21 12 25 21 23 14 + 23 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 19 + 16 19 18 10 16 23 11 25 14 19 20 12 21 16 23 20 15 + 23 20 18 20 18 17 21 25 18 25 20 16 19 12 24 15 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 19 16 + 23 20 21 20 15 23 15 23 21 23 12 16 19 15 20 21 23 + 15 20 19 25 14 14 14 14 21 15 12 15 20 18 23 20 14 + 25 19 20 18 24 12 18 12 21 23 11 19 21 0 11 25 23 + + 15 15 14 28 15 28 24 14 15 20 24 23 20 20 0 24 15 + 27 23 23 27 21 25 27 11 15 28 28 26 28 20 15 11 28 + 28 28 15 28 28 15 28 28 28 27 28 15 24 28 15 15 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 11 11 27 + 28 28 20 14 28 28 15 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 28 27 15 28 28 28 16 24 28 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 15 24 24 10 23 27 23 15 15 + 12 15 15 15 20 0 4 27 23 25 27 27 25 15 27 27 15 + 14 14 15 15 16 15 10 10 27 15 14 10 10 15 15 15 15 + 15 12 10 27 24 15 10 15 25 18 26 27 12 24 10 24 15 + 18 26 25 15 15 15 16 28 27 15 14 15 16 15 27 9 15 + 15 15 15 15 15 27 23 21 15 15 15 18 15 12 27 21 23 + 15 15 26 23 25 0 23 15 23 26 11 24 10 12 0 11 21 + 28 15 15 11 26 15 10 16 26 16 27 12 23 16 14 15 24 + 14 15 15 21 20 24 27 14 14 15 27 24 14 15 25 21 25 + 11 27 27 27 25 15 24 11 27 4 24 25 23 14 27 27 15 + 25 15 12 15 20 15 24 15 27 25 24 14 15 26 15 11 24 + 15 26 27 26 14 24 26 24 27 11 20 26 27 23 23 16 4 + + 23 23 23 14 29 14 12 23 23 20 11 15 20 20 25 0 27 + 15 16 16 15 18 4 12 27 23 14 14 15 14 20 24 24 14 + 14 14 23 14 14 23 14 14 14 15 14 24 15 14 25 23 11 + 18 24 16 12 29 15 10 11 14 14 12 15 30 12 24 27 11 + 14 14 20 23 14 14 23 14 14 12 14 29 14 27 14 14 14 + 14 14 14 14 14 23 14 15 23 14 14 14 23 12 14 23 15 + 12 15 23 16 23 16 21 24 14 14 14 14 14 14 14 14 16 + 14 14 26 14 14 14 14 23 26 12 12 26 15 15 15 29 23 + 27 25 24 24 20 25 25 15 16 15 15 15 10 23 15 12 23 + 23 23 23 29 30 24 25 25 15 28 28 25 25 25 23 26 29 + 23 28 25 15 12 29 25 29 0 21 10 11 24 15 26 11 29 + 21 10 4 24 29 23 23 12 15 24 23 25 23 29 15 25 23 + 23 23 24 29 29 15 15 18 28 23 27 21 24 27 15 18 14 + 24 23 15 15 15 25 16 29 15 10 24 12 25 24 25 24 18 + 12 24 24 24 15 23 25 30 10 30 11 24 16 23 28 23 12 + 28 29 25 18 20 12 15 23 23 26 15 11 23 29 10 18 0 + 27 11 12 15 10 26 11 27 15 25 12 15 15 23 15 12 25 + 10 24 24 29 20 23 11 23 15 10 12 23 24 10 25 24 15 + 29 10 11 15 28 12 15 12 15 27 20 10 15 16 15 30 25 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 0 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 0 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 17 14 15 23 25 23 12 15 24 11 14 11 11 11 21 12 23 + 21 0 11 20 10 16 21 23 19 23 23 18 23 11 18 20 23 + 23 23 21 23 23 23 23 23 23 20 23 16 14 23 23 23 14 + 10 20 8 12 25 21 19 14 23 23 12 20 25 21 20 23 20 + 23 23 15 15 23 23 24 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 8 12 5 12 20 23 23 23 23 23 23 23 23 11 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 14 15 21 20 15 16 21 21 14 + 15 15 17 25 25 20 21 21 20 24 24 21 21 21 22 23 25 + 14 24 21 21 12 25 21 25 16 19 18 20 18 12 23 14 25 + 12 18 19 18 25 14 15 23 20 20 15 21 12 25 21 23 14 + 23 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 19 + 16 19 18 10 16 23 11 25 14 19 20 12 21 16 23 20 15 + 23 20 18 20 18 17 21 25 18 25 20 16 19 12 24 15 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 19 16 + 23 20 21 20 15 23 15 23 21 23 12 16 19 15 20 21 23 + 15 20 19 25 14 14 14 14 21 15 12 15 20 18 23 20 14 + 25 19 20 18 24 12 18 12 21 23 11 19 21 0 11 25 23 + + 17 14 15 23 25 23 12 15 24 11 14 11 11 11 21 12 23 + 21 6 0 20 10 16 21 23 19 23 23 18 23 11 18 20 23 + 23 23 21 23 23 23 23 23 23 20 23 16 14 23 23 23 14 + 10 20 8 12 25 21 19 14 23 23 12 20 25 21 20 23 20 + 23 23 15 15 23 23 24 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 8 12 5 12 20 23 23 23 23 23 23 23 23 11 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 14 15 21 20 15 16 21 21 14 + 15 15 17 25 25 20 21 21 20 24 24 21 21 21 22 23 25 + 14 24 21 21 12 25 21 25 16 19 18 20 18 12 23 14 25 + 12 18 19 18 25 14 15 23 20 20 15 21 12 25 21 23 14 + 23 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 19 + 16 19 18 10 16 23 11 25 14 19 20 12 21 16 23 20 15 + 23 20 18 20 18 17 21 25 18 25 20 16 19 12 24 15 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 19 16 + 23 20 21 20 15 23 15 23 21 23 12 16 19 15 20 21 23 + 15 20 19 25 14 14 14 14 21 15 12 15 20 18 23 20 14 + 25 19 20 18 24 12 18 12 21 23 11 19 21 0 11 25 23 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 0 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 17 16 18 20 26 20 10 18 24 12 12 0 12 12 23 11 24 + 18 11 11 16 0 14 18 24 19 20 20 15 20 12 21 23 20 + 20 20 21 20 20 23 20 20 20 16 20 20 12 20 23 23 12 + 12 23 11 10 26 18 19 12 20 20 10 16 27 18 23 24 16 + 20 20 15 18 20 20 24 8 20 11 20 26 20 24 20 20 20 + 20 20 20 20 20 16 20 16 16 20 20 20 15 10 20 18 10 + 11 18 15 11 15 11 14 23 20 20 20 20 20 20 20 20 11 + 20 20 24 20 20 20 20 16 24 11 11 24 10 18 10 26 16 + 24 23 23 21 12 23 23 18 14 12 18 16 15 16 18 18 16 + 18 18 17 26 27 23 23 23 16 25 25 23 23 23 22 24 26 + 16 25 23 18 12 26 23 26 15 19 15 19 21 11 24 12 26 + 14 15 19 21 26 16 15 20 16 23 18 23 15 26 18 23 16 + 23 16 20 26 26 16 10 12 25 16 24 14 23 24 18 12 19 + 20 19 15 10 14 23 11 26 14 19 23 11 23 20 23 23 15 + 20 23 21 23 15 17 23 27 15 27 19 20 19 15 25 16 11 + 25 26 23 12 12 10 16 18 18 24 18 12 18 26 12 19 15 + 24 16 18 16 15 24 15 24 18 23 10 14 19 18 16 18 23 + 12 23 21 26 14 16 12 16 18 15 11 18 23 15 23 23 12 + 26 19 16 15 25 11 15 11 18 24 12 19 18 11 0 27 23 + + 18 18 16 29 15 29 24 16 24 23 25 24 23 23 12 25 0 + 28 23 23 28 23 0 28 10 19 29 29 27 29 23 14 12 29 + 29 29 21 29 29 23 29 29 29 28 29 15 25 29 11 23 25 + 23 12 23 24 12 28 26 25 29 29 24 28 14 28 15 15 28 + 29 29 23 16 29 29 24 24 29 24 29 12 29 10 29 29 29 + 29 29 29 29 29 18 29 28 18 29 29 29 20 24 29 16 24 + 25 28 20 23 20 23 21 12 29 29 29 29 29 29 29 29 23 + 29 29 10 29 29 29 29 18 10 25 25 19 24 28 24 12 18 + 15 12 12 14 23 15 19 28 23 26 28 28 26 18 28 28 18 + 16 16 18 12 14 12 12 12 28 11 15 12 12 12 22 10 12 + 18 11 12 28 25 12 12 12 27 21 27 28 14 25 19 25 19 + 21 27 27 14 12 18 20 29 28 12 16 12 20 12 28 11 18 + 23 18 15 12 15 28 24 23 11 18 0 21 12 15 28 23 24 + 15 19 27 24 27 15 23 12 24 27 15 25 12 15 15 12 23 + 29 12 14 12 27 18 15 14 27 14 28 15 23 20 12 18 25 + 15 12 11 23 23 24 28 16 16 10 28 25 16 12 26 23 27 + 19 28 28 28 26 10 25 19 28 19 24 27 24 16 28 28 11 + 26 12 19 12 23 18 25 18 28 26 25 16 12 27 11 15 25 + 12 27 28 27 15 25 27 25 28 15 23 27 28 23 24 15 11 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 0 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 0 21 11 15 0 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 0 11 24 12 11 27 24 12 + 21 25 20 15 31 10 19 12 11 11 15 0 31 15 25 28 6 + 11 11 23 24 11 11 24 16 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 0 24 11 11 11 23 15 11 24 18 + 14 10 23 20 23 20 23 25 11 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 0 15 24 10 10 24 + 24 24 24 31 31 25 26 26 0 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 15 23 10 19 25 14 27 12 31 + 23 15 19 25 31 24 23 19 0 25 24 26 23 31 10 27 24 + 24 24 24 31 31 0 18 21 29 24 28 23 25 28 10 21 19 + 24 24 10 18 11 27 20 31 18 19 25 14 26 24 27 25 21 + 19 25 25 25 10 24 26 31 15 31 19 24 20 23 30 24 14 + 30 31 27 21 23 15 0 24 24 27 10 12 24 31 12 21 15 + 28 10 10 0 15 27 15 28 10 27 15 11 19 24 0 15 27 + 12 25 25 31 23 24 12 24 10 15 14 24 25 10 27 25 12 + 31 19 15 10 30 14 10 14 10 28 23 19 10 20 16 31 27 + + 15 10 10 25 23 25 20 11 22 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 0 25 25 24 25 12 11 12 25 + 25 25 19 25 25 21 25 25 25 24 25 10 23 25 14 21 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 13 16 24 + 25 25 13 9 25 25 22 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 9 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 18 16 24 16 23 10 + 18 12 12 11 12 14 18 24 15 23 24 24 23 14 24 24 10 + 4 7 15 23 23 12 12 12 24 20 21 12 12 12 20 15 23 + 10 20 12 24 21 23 12 23 23 18 24 24 11 21 18 23 23 + 12 24 23 11 23 10 13 25 24 12 9 12 11 23 24 14 11 + 21 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 18 24 16 23 14 15 23 16 24 13 21 12 10 14 12 14 + 25 12 11 12 24 15 13 23 24 23 24 10 18 11 21 13 21 + 21 23 14 14 12 20 24 7 5 15 24 23 4 23 23 18 23 + 18 24 24 24 23 15 23 18 24 18 20 23 18 6 24 24 14 + 23 12 18 23 12 10 23 10 24 23 21 7 12 24 14 13 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 24 24 24 14 31 14 16 24 24 23 14 18 23 23 27 15 28 + 15 21 21 15 23 12 0 28 24 0 14 15 14 23 25 26 14 + 14 14 24 14 14 24 14 14 14 15 14 25 15 14 27 24 14 + 23 26 21 16 31 15 12 14 14 14 16 15 31 0 26 28 10 + 14 14 23 24 14 14 24 18 14 16 14 31 14 29 14 14 14 + 14 14 14 14 14 24 14 15 24 14 14 14 24 16 14 24 20 + 15 15 24 21 24 21 23 26 14 14 14 14 14 14 14 14 21 + 14 14 28 14 14 14 14 24 28 15 15 28 20 15 20 31 24 + 29 27 26 25 23 27 27 15 21 15 15 15 12 24 15 9 24 + 24 24 24 31 31 26 27 27 15 30 31 27 27 27 24 28 31 + 24 30 27 15 15 31 27 31 12 23 11 10 25 15 28 14 31 + 23 11 12 25 31 24 24 10 15 26 24 27 24 31 15 27 24 + 24 24 25 31 31 15 20 23 30 24 28 23 26 29 15 23 18 + 25 24 15 20 15 27 21 31 20 11 26 15 27 25 27 26 23 + 10 26 25 26 15 24 27 31 11 31 10 25 21 24 31 24 15 + 31 31 27 23 23 16 15 24 24 28 15 14 24 31 12 23 12 + 28 10 9 15 12 28 14 28 15 27 16 15 20 24 15 0 27 + 12 26 25 31 23 24 14 24 15 12 15 24 26 11 27 26 15 + 31 11 10 15 31 15 15 15 15 28 23 11 15 21 18 31 27 + + 23 23 23 12 29 12 12 23 23 20 11 14 20 20 25 12 27 + 12 16 16 11 18 0 12 27 23 12 0 10 12 20 24 24 12 + 12 12 23 12 12 23 12 12 12 11 12 24 11 12 25 23 11 + 18 24 16 12 29 12 10 11 12 12 12 11 30 12 24 27 11 + 12 12 20 23 12 12 23 14 12 12 12 29 12 27 12 12 12 + 12 12 12 12 12 23 12 11 23 12 12 12 23 12 12 23 15 + 12 12 23 16 23 16 21 24 12 12 12 12 12 12 12 12 16 + 12 12 26 12 12 12 12 23 26 12 12 26 15 12 15 29 23 + 27 25 24 24 20 25 25 12 16 10 12 11 10 23 12 12 23 + 23 23 23 29 30 24 25 25 11 28 28 25 25 25 23 26 29 + 23 28 25 12 12 29 25 29 4 21 10 11 24 12 26 11 29 + 21 10 9 24 29 23 23 12 11 24 23 25 23 29 12 25 23 + 23 23 24 29 29 11 15 18 28 23 27 21 24 27 12 18 14 + 24 23 10 15 10 25 16 29 15 10 24 12 25 24 25 24 18 + 12 24 24 24 10 23 25 30 10 30 11 24 16 23 28 23 12 + 28 29 25 18 20 12 11 23 23 26 12 11 23 29 10 18 4 + 27 11 12 11 10 26 11 27 12 25 12 10 15 23 11 12 25 + 10 24 24 29 20 23 11 23 12 10 12 23 24 10 25 24 11 + 29 10 11 10 28 12 10 12 12 27 20 10 12 16 14 30 25 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 0 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 12 12 14 23 24 23 12 14 14 10 15 12 10 10 20 14 23 + 23 10 10 21 0 18 23 23 12 23 23 20 0 10 16 18 23 + 23 23 12 23 23 12 23 23 23 21 23 15 15 23 21 12 15 + 4 18 10 12 24 23 16 15 23 23 12 21 25 23 18 23 21 + 23 23 10 14 23 23 14 12 23 12 23 24 23 23 23 23 23 + 23 23 23 23 23 12 23 21 12 23 23 23 12 12 23 14 11 + 14 23 12 10 12 10 11 18 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 12 23 14 14 23 11 23 11 24 12 + 23 20 18 16 10 21 21 23 10 16 23 21 16 12 23 23 12 + 14 14 12 24 25 18 20 20 21 24 24 20 20 20 12 23 24 + 12 24 20 23 14 24 20 24 18 11 20 21 16 14 23 15 24 + 11 20 18 16 24 12 12 23 21 18 14 20 12 24 23 21 12 + 12 12 15 24 24 21 11 3 24 12 23 11 18 23 23 10 12 + 15 12 20 11 18 21 10 24 11 20 18 14 20 15 21 18 4 + 23 18 16 18 20 12 20 25 20 25 21 15 10 12 24 12 14 + 24 24 21 10 10 12 21 14 14 23 23 15 14 24 16 9 18 + 23 21 23 21 16 23 15 23 23 21 12 18 11 14 21 23 21 + 16 18 16 24 10 12 15 12 23 16 14 14 18 20 21 18 15 + 24 20 21 20 24 14 20 14 23 23 10 20 23 10 12 25 21 + + 23 23 24 12 30 12 14 24 24 21 12 15 21 21 25 12 27 + 11 18 18 10 20 10 15 27 23 12 12 0 12 0 24 25 12 + 12 12 23 12 12 23 12 12 12 10 12 24 12 12 26 23 12 + 20 25 18 14 30 11 19 12 12 12 14 10 31 15 25 27 10 + 12 12 21 24 12 12 24 15 12 14 12 30 12 28 12 12 12 + 12 12 12 12 12 23 12 10 23 12 12 12 23 14 12 24 16 + 12 11 23 18 23 18 23 25 12 12 12 12 12 12 12 12 18 + 12 12 27 12 12 12 12 23 27 12 12 27 16 11 16 30 23 + 28 25 25 24 21 26 26 11 18 11 11 10 15 23 11 11 23 + 24 24 23 30 31 25 25 25 10 28 29 25 25 25 23 27 30 + 23 28 25 11 12 30 25 30 15 23 10 19 24 12 27 12 30 + 23 15 19 24 30 23 23 19 10 25 24 25 23 30 11 26 23 + 23 23 24 30 30 10 16 20 28 23 27 23 25 28 11 20 19 + 24 23 0 16 10 26 18 30 16 19 25 12 25 24 26 25 20 + 19 25 24 25 0 23 25 31 15 31 19 24 19 23 29 23 12 + 29 30 26 20 21 14 10 24 24 27 11 12 24 30 11 20 15 + 27 10 11 10 15 27 15 27 11 26 14 10 19 24 10 15 26 + 11 25 24 30 21 23 12 23 11 15 12 24 25 6 26 25 12 + 30 19 15 0 29 12 0 12 11 27 21 19 11 18 15 31 26 + + 12 12 12 27 18 27 23 12 12 16 24 23 16 16 15 23 15 + 26 20 20 25 18 24 26 12 12 27 27 25 27 16 0 9 27 + 27 27 12 27 27 12 27 27 27 25 27 15 24 27 15 12 24 + 18 9 20 23 18 26 24 24 27 27 23 25 20 26 0 12 25 + 27 27 16 12 27 27 12 23 27 23 27 18 27 14 27 27 27 + 27 27 27 27 27 12 27 25 12 27 27 27 15 23 27 12 21 + 23 26 14 20 14 20 15 9 27 27 27 27 27 27 27 27 20 + 27 27 12 27 27 27 27 12 15 23 23 12 21 26 21 18 12 + 14 15 15 15 16 11 11 26 20 24 26 25 24 12 26 26 12 + 12 12 12 18 20 15 10 10 25 15 16 10 10 15 12 15 18 + 15 15 10 26 23 18 10 18 24 15 25 25 10 23 12 24 18 + 15 25 24 15 18 12 14 27 25 15 12 15 15 18 26 11 12 + 12 15 15 18 18 25 21 18 15 15 15 15 15 14 26 18 23 + 15 12 25 21 24 11 20 18 21 25 0 23 10 11 11 9 18 + 27 15 15 9 25 12 10 20 25 20 25 11 20 14 16 12 23 + 16 18 15 18 16 23 25 12 12 15 26 24 12 18 24 18 24 + 12 25 26 25 24 15 24 12 26 11 23 24 21 12 25 26 15 + 24 15 10 18 16 12 24 12 26 24 23 12 15 25 15 0 24 + 18 25 25 25 16 23 25 23 26 12 16 25 26 20 23 20 11 + + 17 12 11 26 20 26 23 12 24 15 23 21 15 15 11 23 14 + 25 18 18 25 16 24 25 14 19 26 26 24 26 15 0 0 26 + 26 26 21 26 26 23 26 26 26 25 26 10 23 26 12 23 23 + 16 10 18 23 20 25 24 23 26 26 23 25 21 25 15 15 25 + 26 26 15 11 26 26 24 21 26 23 26 20 26 15 26 26 26 + 26 26 26 26 26 12 26 25 12 26 26 26 12 23 26 11 20 + 23 25 12 18 12 18 14 10 26 26 26 26 26 26 26 26 18 + 26 26 12 26 26 26 26 12 12 23 23 19 20 25 20 20 12 + 15 11 10 0 15 15 19 25 18 24 25 25 24 16 25 25 12 + 11 11 17 20 21 10 11 11 25 16 18 12 11 11 22 12 20 + 12 16 11 25 23 20 12 20 24 19 24 25 10 23 19 23 20 + 14 24 24 0 20 12 15 26 25 10 11 11 12 20 25 12 12 + 23 12 10 20 20 25 20 16 16 12 14 14 10 15 25 16 21 + 10 19 24 20 24 15 18 20 20 24 15 23 11 10 15 10 16 + 26 10 0 10 24 17 15 21 24 21 25 10 19 12 18 15 23 + 18 20 12 16 15 23 25 11 11 12 25 23 11 20 24 19 24 + 19 25 25 25 24 12 23 19 25 19 23 24 20 11 25 25 12 + 24 10 19 20 15 12 23 12 25 24 23 11 10 24 12 15 23 + 20 24 25 24 18 23 24 23 25 15 15 24 25 18 21 21 12 + + 18 18 20 18 27 18 7 20 22 14 11 10 14 14 23 10 24 + 16 12 12 15 12 12 16 24 18 18 18 14 18 14 23 23 0 + 18 18 19 18 18 21 18 18 18 15 18 21 11 18 24 21 11 + 12 23 12 5 27 16 18 11 18 18 4 15 27 16 23 24 15 + 18 18 14 20 18 18 22 10 18 10 18 27 18 25 18 18 18 + 18 18 18 18 18 18 18 15 18 18 18 18 16 7 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 18 18 18 12 + 18 18 24 18 18 18 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 12 12 16 15 13 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 20 24 27 + 18 25 23 16 11 27 23 27 13 18 14 18 23 10 24 11 27 + 15 14 18 23 27 18 16 18 15 23 20 23 16 27 16 24 18 + 21 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 18 + 21 18 14 11 12 24 12 27 12 18 23 10 23 21 24 23 13 + 18 23 23 23 14 18 23 27 14 27 18 21 18 16 26 18 10 + 26 27 24 12 14 9 15 20 20 24 16 11 20 27 12 18 13 + 24 15 16 15 13 24 13 24 16 24 7 12 18 20 15 16 24 + 12 23 23 27 14 18 11 18 16 13 10 20 23 14 24 23 11 + 27 18 15 14 26 10 14 10 16 24 14 18 16 12 10 27 24 + + 11 0 10 24 23 24 18 10 18 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 14 24 24 23 24 12 12 12 24 + 0 24 15 24 24 17 24 24 24 24 24 11 21 24 15 17 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 12 18 24 + 24 24 12 10 24 24 18 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 1 24 24 4 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 0 16 20 20 16 15 24 15 23 3 + 20 14 12 12 12 15 15 24 14 23 24 24 23 10 24 24 0 + 10 10 11 23 23 12 14 14 24 21 23 14 14 14 16 16 23 + 5 21 14 24 20 23 14 23 23 14 23 24 12 20 16 21 23 + 11 23 23 12 23 4 10 24 24 12 10 14 10 23 24 15 7 + 17 5 11 23 23 24 15 12 21 5 18 11 12 20 24 12 16 + 11 14 23 15 23 15 14 23 15 23 12 20 14 11 15 12 12 + 24 12 12 12 23 11 14 23 23 23 24 11 14 10 23 9 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 14 23 + 18 24 24 24 23 16 21 18 24 15 18 23 15 10 24 24 15 + 23 12 14 23 12 3 21 1 24 23 20 10 12 23 15 12 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 14 2 10 24 23 24 18 10 21 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 16 24 24 23 24 12 12 12 24 + 24 0 18 24 24 20 24 24 24 24 24 11 21 24 15 20 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 12 18 24 + 24 24 12 10 24 24 21 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 3 24 24 7 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 2 16 20 20 16 15 24 15 23 6 + 20 14 12 12 12 15 16 24 14 23 24 24 23 13 24 24 2 + 10 10 14 23 23 12 14 14 24 21 23 14 14 14 19 16 23 + 3 21 14 24 20 23 14 23 23 16 23 24 12 20 16 21 23 + 11 23 23 12 23 7 12 24 24 12 10 14 10 23 24 15 9 + 20 3 11 23 23 24 15 12 21 3 18 11 12 20 24 12 16 + 11 16 23 15 23 15 14 23 15 23 12 20 14 11 15 12 12 + 24 12 12 12 23 14 14 23 23 23 24 11 16 10 23 12 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 16 23 + 18 24 24 24 23 16 21 18 24 16 18 23 16 10 24 24 15 + 23 12 16 23 12 6 21 3 24 23 20 10 12 23 15 12 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 17 10 11 25 23 25 20 12 24 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 19 25 25 24 25 12 11 12 25 + 25 25 0 25 25 23 25 25 25 24 25 10 23 25 14 23 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 15 16 24 + 25 25 15 10 25 25 24 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 10 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 19 16 24 16 23 10 + 18 12 12 11 12 15 19 24 15 23 24 24 23 16 24 24 10 + 5 9 17 23 23 12 12 12 24 20 21 12 12 12 22 15 23 + 10 20 12 24 21 23 12 23 23 19 24 24 11 21 19 23 23 + 12 24 23 11 23 10 15 25 24 12 10 12 11 23 24 14 12 + 23 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 19 + 10 19 24 16 23 15 15 23 16 24 15 21 12 10 15 12 15 + 25 12 11 12 24 17 15 23 24 23 24 10 19 11 21 15 21 + 21 23 14 14 12 20 24 9 6 15 24 23 5 23 23 19 23 + 19 24 24 24 23 15 23 19 24 19 20 23 19 8 24 24 14 + 23 12 19 23 14 10 23 10 24 23 21 9 12 24 14 15 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 14 14 15 23 25 23 12 15 17 11 14 11 11 11 21 12 23 + 21 0 4 20 10 16 21 23 14 23 23 18 23 11 18 20 23 + 23 23 14 0 23 16 23 23 23 20 23 16 14 23 23 16 14 + 10 20 1 12 25 21 15 14 23 23 12 20 25 21 20 23 20 + 23 23 11 15 23 23 17 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 1 12 1 12 20 23 23 23 23 23 23 23 23 4 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 7 15 21 20 15 14 21 21 14 + 15 15 14 25 25 20 21 21 20 24 24 21 21 21 15 23 25 + 14 24 21 21 12 25 21 25 16 12 18 20 18 12 23 14 25 + 12 18 16 18 25 14 12 23 20 20 15 21 12 25 21 23 14 + 16 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 12 + 16 14 18 10 16 23 4 25 10 18 20 12 21 16 23 20 10 + 23 20 18 20 18 14 21 25 18 25 20 16 12 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 12 16 + 23 20 21 20 15 23 14 23 21 23 12 16 12 15 20 21 23 + 15 20 18 25 11 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 6 11 25 23 + + 10 10 4 25 23 25 20 6 17 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 12 25 25 24 25 12 11 12 25 + 25 25 14 25 0 16 25 25 25 24 25 10 23 25 14 16 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 12 16 24 + 25 25 12 3 25 25 17 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 3 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 15 16 24 16 23 10 + 18 12 12 11 12 14 14 24 15 23 24 24 23 10 24 24 10 + 1 2 10 23 23 12 12 12 24 20 21 12 12 12 15 15 23 + 10 20 12 24 21 23 12 23 23 12 24 24 11 21 15 23 23 + 12 24 23 11 23 10 11 25 24 12 3 12 11 23 24 14 10 + 16 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 12 24 16 23 14 15 23 16 24 12 21 12 10 14 12 14 + 25 12 11 12 24 10 12 23 24 23 24 10 15 11 21 10 21 + 21 23 14 14 12 20 24 2 0 15 24 23 1 23 23 14 23 + 16 24 24 24 23 15 23 16 24 14 20 23 16 1 24 24 14 + 23 12 12 23 12 10 23 10 24 23 21 2 12 24 14 12 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 14 10 8 25 23 25 20 9 21 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 16 25 25 24 25 12 11 12 25 + 25 25 18 25 25 0 25 25 25 24 25 10 23 25 14 20 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 12 16 24 + 25 25 12 7 25 25 21 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 7 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 16 16 24 16 23 10 + 18 12 12 11 12 14 16 24 15 23 24 24 23 13 24 24 10 + 2 6 14 23 23 12 12 12 24 20 21 12 12 12 19 15 23 + 10 20 12 24 21 23 12 23 23 16 24 24 11 21 16 23 23 + 12 24 23 11 23 10 12 25 24 12 7 12 11 23 24 14 10 + 20 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 16 24 16 23 14 15 23 16 24 12 21 12 10 14 12 14 + 25 12 11 12 24 14 12 23 24 23 24 10 16 11 21 12 21 + 21 23 14 14 12 20 24 6 3 15 24 23 2 23 23 16 23 + 16 24 24 24 23 15 23 16 24 16 20 23 16 5 24 24 14 + 23 12 16 23 12 10 23 10 24 23 21 6 12 24 14 12 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 10 10 0 25 23 25 20 1 12 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 10 25 25 24 25 12 11 12 25 + 25 25 10 25 25 11 0 25 25 24 25 11 23 25 14 11 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 12 16 24 + 25 25 12 1 25 25 12 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 1 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 15 16 24 16 23 10 + 18 12 12 11 12 14 14 24 15 23 24 24 23 10 24 24 10 + 6 2 10 23 23 12 12 12 24 20 21 12 12 12 10 15 23 + 11 20 12 24 21 23 12 23 23 12 24 24 11 21 15 23 23 + 12 24 23 11 23 10 11 25 24 12 1 12 11 23 24 14 10 + 11 11 11 23 23 24 16 14 20 11 16 12 12 18 24 14 18 + 11 10 24 16 23 14 15 23 16 24 12 21 12 10 14 12 14 + 25 12 11 12 24 10 12 23 24 23 24 10 15 11 21 10 21 + 21 23 14 14 12 20 24 2 4 15 24 23 6 23 23 14 23 + 16 24 24 24 23 15 23 16 24 14 20 23 16 3 24 24 14 + 23 12 11 23 12 10 23 10 24 23 21 2 12 24 14 12 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 9 2 10 24 23 24 18 10 16 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 11 24 24 23 24 12 12 12 24 + 24 24 12 24 24 15 24 0 24 24 24 11 21 24 15 15 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 12 18 24 + 24 24 12 10 24 24 16 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 1 24 24 2 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 2 16 20 20 16 15 24 15 23 1 + 20 14 12 12 12 15 15 24 14 23 24 24 23 8 24 24 2 + 10 10 9 23 23 12 14 14 24 21 23 14 14 14 14 16 23 + 8 21 14 24 20 23 14 23 23 11 23 24 12 20 16 21 23 + 11 23 23 12 23 2 10 24 24 12 10 14 10 23 24 15 4 + 15 8 11 23 23 24 15 12 21 8 18 11 12 20 24 12 16 + 11 11 23 15 23 15 14 23 15 23 12 20 14 11 15 12 12 + 24 12 12 12 23 9 14 23 23 23 24 11 14 10 23 7 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 12 23 + 18 24 24 24 23 16 21 18 24 15 18 23 15 10 24 24 15 + 23 12 12 23 12 1 21 1 24 23 20 10 12 23 15 12 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 10 10 1 25 23 25 20 0 11 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 10 25 25 24 25 12 12 12 25 + 25 25 10 25 25 10 25 25 0 24 25 12 23 25 14 10 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 12 16 24 + 25 25 12 2 25 25 11 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 12 20 25 2 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 15 16 24 16 23 10 + 18 12 12 12 12 14 14 24 15 23 24 24 23 10 24 24 10 + 7 3 10 23 23 12 12 12 24 20 21 12 12 12 10 15 23 + 12 20 12 24 21 23 12 23 23 12 24 24 11 21 15 23 23 + 12 24 23 12 23 10 11 25 24 12 2 12 12 23 24 14 10 + 10 12 12 23 23 24 16 14 20 12 16 12 12 18 24 14 18 + 12 10 24 16 23 14 15 23 16 24 12 21 12 10 14 12 14 + 25 12 12 12 24 10 12 23 24 23 24 10 15 11 21 10 21 + 21 23 14 14 12 20 24 3 6 15 24 23 7 23 23 14 23 + 16 24 24 24 23 15 23 16 24 14 20 23 16 4 24 24 14 + 23 12 11 23 12 10 23 10 24 23 21 3 12 24 14 12 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 0 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 10 10 1 25 23 25 20 0 11 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 10 25 25 24 25 12 12 12 25 + 25 25 10 25 25 10 25 25 25 24 0 12 23 25 14 10 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 12 16 24 + 25 25 12 2 25 25 11 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 12 20 25 2 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 15 16 24 16 23 10 + 18 12 12 12 12 14 14 24 15 23 24 24 23 10 24 24 10 + 7 3 10 23 23 12 12 12 24 20 21 12 12 12 10 15 23 + 12 20 12 24 21 23 12 23 23 12 24 24 11 21 15 23 23 + 12 24 23 12 23 10 11 25 24 12 2 12 12 23 24 14 10 + 10 12 12 23 23 24 16 14 20 12 16 12 12 18 24 14 18 + 12 10 24 16 23 14 15 23 16 24 12 21 12 10 14 12 14 + 25 12 12 12 24 10 12 23 24 23 24 10 15 11 21 10 21 + 21 23 14 14 12 20 24 3 6 15 24 23 7 23 23 14 23 + 16 24 24 24 23 15 23 16 24 14 20 23 16 4 24 24 14 + 23 12 11 23 12 10 23 10 24 23 21 3 12 24 14 12 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 0 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 0 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 6 4 10 24 23 24 18 10 13 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 9 24 24 23 24 12 12 12 24 + 24 24 10 24 24 12 24 24 24 24 24 11 21 0 15 12 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 12 18 24 + 24 24 12 10 24 24 13 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 3 24 24 0 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 4 16 20 20 16 15 24 15 23 1 + 20 14 12 12 12 15 15 24 14 23 24 24 23 5 24 24 4 + 10 10 6 23 23 12 14 14 24 21 23 14 14 14 11 16 23 + 10 21 14 24 20 23 14 23 23 11 23 24 12 20 16 21 23 + 11 23 23 12 23 0 10 24 24 12 10 14 10 23 24 15 2 + 12 10 11 23 23 24 15 12 21 10 18 11 12 20 24 12 16 + 11 9 23 15 23 15 14 23 15 23 12 20 14 11 15 12 12 + 24 12 12 12 23 6 14 23 23 23 24 11 14 10 23 4 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 12 23 + 18 24 24 24 23 16 21 18 24 15 18 23 15 10 24 24 15 + 23 12 12 23 12 1 21 3 24 23 20 10 12 23 15 12 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 0 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 17 10 11 25 23 25 20 12 24 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 19 25 25 24 25 12 11 12 25 + 25 25 21 25 25 23 25 25 25 24 25 10 23 25 14 0 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 15 16 24 + 25 25 15 10 25 25 24 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 10 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 19 16 24 16 23 10 + 18 12 12 11 12 15 19 24 15 23 24 24 23 16 24 24 10 + 5 9 17 23 23 12 12 12 24 20 21 12 12 12 22 15 23 + 10 20 12 24 21 23 12 23 23 19 24 24 11 21 19 23 23 + 12 24 23 11 23 10 15 25 24 12 10 12 11 23 24 14 12 + 23 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 19 + 10 19 24 16 23 15 15 23 16 24 15 21 12 10 15 12 15 + 25 12 11 12 24 17 15 23 24 23 24 10 19 11 21 15 21 + 21 23 14 14 12 20 24 9 6 15 24 23 5 23 23 19 23 + 19 24 24 24 23 15 23 19 24 19 20 23 19 8 24 24 14 + 23 12 19 23 14 10 23 10 24 23 21 9 12 24 14 15 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 21 21 23 15 28 15 11 23 22 16 10 12 16 16 24 10 25 + 14 14 14 12 15 11 14 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 21 15 15 15 12 15 23 1 15 24 21 0 + 15 24 14 11 28 14 18 9 15 15 11 12 28 14 24 25 12 + 15 15 16 23 15 15 22 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 10 14 12 13 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 21 25 28 + 21 27 24 14 11 28 24 28 13 18 12 18 23 10 25 5 28 + 18 13 18 23 28 21 20 18 12 24 23 24 20 28 14 24 21 + 21 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 18 + 23 21 12 12 11 24 14 28 12 18 24 10 24 23 24 24 15 + 18 24 23 24 12 21 24 28 13 28 18 23 18 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 7 23 28 10 18 13 + 25 12 14 12 13 25 13 25 14 24 11 11 18 23 12 14 24 + 10 24 23 28 16 21 7 21 14 13 10 23 24 12 24 24 1 + 28 18 13 12 27 10 12 10 14 25 16 18 14 14 12 28 24 + + 21 21 23 15 28 15 11 23 24 16 11 12 16 16 24 10 25 + 14 14 14 12 15 11 15 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 23 15 15 15 12 15 23 0 15 24 23 9 + 0 24 14 11 28 14 19 10 15 15 11 12 28 15 24 25 12 + 15 15 16 23 15 15 24 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 10 14 12 15 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 22 25 28 + 21 27 24 14 12 28 24 28 15 19 12 19 23 10 25 6 28 + 18 15 19 23 28 21 20 19 12 24 23 24 20 28 14 24 21 + 23 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 19 + 23 21 12 12 11 24 14 28 14 19 24 10 24 23 24 24 15 + 19 24 23 24 12 21 24 28 15 28 19 23 19 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 9 23 28 10 19 15 + 25 12 14 12 15 25 15 25 14 24 11 11 19 23 12 15 24 + 10 24 23 28 16 21 9 21 14 15 10 23 24 12 24 24 0 + 28 19 15 12 27 10 12 10 14 25 16 19 14 14 12 28 24 + + 17 11 12 24 24 24 15 12 24 10 18 14 10 10 16 16 21 + 23 12 12 23 11 21 23 21 19 24 24 23 24 10 14 15 24 + 24 24 21 24 24 23 24 24 24 23 24 12 18 24 18 23 18 + 11 0 12 15 24 23 20 18 24 24 15 23 24 23 15 21 23 + 24 24 15 12 24 24 24 14 24 15 24 24 24 23 24 24 24 + 24 24 24 24 24 11 24 23 11 24 24 24 10 15 24 12 12 + 16 23 10 12 10 12 0 15 24 24 24 24 24 24 24 24 12 + 24 24 20 24 24 24 24 11 20 16 16 20 12 23 12 24 11 + 23 16 15 14 10 18 19 23 14 20 23 23 20 16 23 23 11 + 12 12 17 24 24 15 16 16 23 23 23 16 16 16 22 20 24 + 11 23 16 23 16 24 16 24 21 19 23 23 14 16 20 18 24 + 10 23 21 14 24 11 15 24 23 15 12 16 10 24 23 18 12 + 23 11 12 24 24 23 12 11 23 11 21 0 15 23 23 11 19 + 12 19 23 12 21 18 12 24 14 23 15 16 16 12 18 15 15 + 24 15 14 15 23 17 16 24 23 24 23 12 19 10 23 15 16 + 23 24 18 11 10 15 23 12 12 20 23 18 12 24 20 19 21 + 21 23 23 23 20 20 18 21 23 19 15 21 19 12 23 23 18 + 20 15 19 24 14 11 18 11 23 20 16 12 15 23 18 15 18 + 24 23 23 23 23 16 23 16 23 21 10 23 23 12 14 24 18 + + 15 14 15 23 25 23 12 15 22 11 14 11 11 11 21 12 23 + 21 5 10 20 10 16 21 23 18 23 23 18 23 11 18 20 23 + 23 23 19 23 23 21 23 23 23 20 23 16 14 23 23 21 14 + 10 20 0 12 25 21 18 14 23 23 12 20 25 21 20 23 20 + 23 23 13 15 23 23 22 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 6 12 4 12 20 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 12 15 21 20 15 14 21 21 14 + 15 15 15 25 25 20 21 21 20 24 24 21 21 21 20 23 25 + 14 24 21 21 12 25 21 25 16 18 18 20 18 12 23 14 25 + 12 18 18 18 25 14 13 23 20 20 15 21 12 25 21 23 14 + 21 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 18 + 16 18 18 10 16 23 10 25 12 18 20 12 21 16 23 20 13 + 23 20 18 20 18 15 21 25 18 25 20 16 18 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 18 16 + 23 20 21 20 15 23 14 23 21 23 12 16 18 15 20 21 23 + 15 20 18 25 12 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 1 11 25 23 + + 15 14 15 23 25 23 12 15 22 11 14 11 11 11 21 12 23 + 21 5 10 20 10 16 21 23 18 23 23 18 23 11 18 20 23 + 23 23 19 23 23 21 23 23 23 20 23 16 14 23 23 21 14 + 10 20 6 0 25 21 18 14 23 23 12 20 25 21 20 23 20 + 23 23 13 15 23 23 22 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 6 12 4 12 20 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 12 15 21 20 15 14 21 21 14 + 15 15 15 25 25 20 21 21 20 24 24 21 21 21 20 23 25 + 14 24 21 21 12 25 21 25 16 18 18 20 18 12 23 14 25 + 12 18 18 18 25 14 13 23 20 20 15 21 12 25 21 23 14 + 21 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 18 + 16 18 18 10 16 23 10 25 12 18 20 12 21 16 23 20 13 + 23 20 18 20 18 15 21 25 18 25 20 16 18 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 18 16 + 23 20 21 20 15 23 14 23 21 23 12 16 18 15 20 21 23 + 15 20 18 25 12 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 1 11 25 23 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 0 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 24 14 31 14 16 24 24 23 14 18 23 23 27 15 28 + 15 21 21 15 23 12 0 28 24 14 14 15 14 23 25 26 14 + 14 14 24 14 14 24 14 14 14 15 14 25 15 14 27 24 14 + 23 26 21 16 31 0 12 14 14 14 16 15 31 0 26 28 10 + 14 14 23 24 14 14 24 18 14 16 14 31 14 29 14 14 14 + 14 14 14 14 14 24 14 15 24 14 14 14 24 16 14 24 20 + 15 15 24 21 24 21 23 26 14 14 14 14 14 14 14 14 21 + 14 14 28 14 14 14 14 24 28 15 15 28 20 15 20 31 24 + 29 27 26 25 23 27 27 15 21 15 15 15 12 24 15 9 24 + 24 24 24 31 31 26 27 27 15 30 31 27 27 27 24 28 31 + 24 30 27 15 15 31 27 31 12 23 11 10 25 15 28 14 31 + 23 11 12 25 31 24 24 10 15 26 24 27 24 31 15 27 24 + 24 24 25 31 31 15 20 23 30 24 28 23 26 29 15 23 18 + 25 24 15 20 15 27 21 31 20 11 26 15 27 25 27 26 23 + 10 26 25 26 15 24 27 31 11 31 10 25 21 24 31 24 15 + 31 31 27 23 23 16 15 24 24 28 15 14 24 31 12 23 12 + 28 10 9 15 12 28 14 28 15 27 16 15 20 24 15 0 27 + 12 26 25 31 23 24 14 24 15 12 15 24 26 11 27 26 15 + 31 11 10 15 31 15 15 15 15 28 23 11 15 21 18 31 27 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 0 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 20 20 21 16 27 16 10 21 24 15 11 11 15 15 24 0 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 21 16 16 23 16 16 16 14 16 23 10 16 24 23 10 + 14 23 12 10 27 15 19 0 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 24 11 16 11 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 20 16 16 16 18 10 16 21 12 + 6 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 5 9 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 14 11 15 14 15 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 22 24 27 + 20 26 24 15 12 27 24 27 15 19 12 19 23 0 24 10 27 + 16 15 19 23 27 20 18 19 14 23 21 24 18 27 15 24 20 + 23 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 19 + 23 20 12 12 12 24 12 27 14 19 23 6 24 23 24 23 15 + 19 23 23 23 12 20 24 28 15 28 19 23 19 18 27 20 10 + 27 27 24 14 15 10 14 21 21 24 15 10 21 27 11 19 15 + 25 14 15 14 15 24 15 25 15 24 10 12 19 21 14 15 24 + 11 23 23 27 15 20 10 20 15 15 9 21 23 12 24 23 10 + 27 19 15 12 27 8 12 6 15 25 15 19 15 12 11 28 24 + + 21 21 23 15 28 15 11 23 21 16 2 12 16 16 24 10 25 + 14 14 14 12 15 11 14 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 21 15 15 15 12 15 23 9 15 24 21 0 + 15 24 14 11 28 14 10 1 0 15 11 12 28 14 24 25 12 + 15 15 16 23 15 15 21 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 10 14 12 10 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 21 25 28 + 21 27 24 14 10 28 24 28 11 18 12 12 23 10 25 2 28 + 18 12 11 23 28 21 20 15 12 24 23 24 20 28 14 24 21 + 21 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 12 + 23 21 12 12 11 24 14 28 12 12 24 10 24 23 24 24 15 + 15 24 23 24 12 21 24 28 12 28 12 23 14 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 0 23 28 10 15 11 + 25 12 14 12 10 25 5 25 14 24 11 11 12 23 12 14 24 + 10 24 23 28 16 21 0 21 14 10 10 23 24 12 24 24 9 + 28 12 12 12 27 10 12 10 14 25 16 12 14 14 12 28 24 + + 14 14 12 27 16 27 23 12 17 18 24 23 18 18 6 24 12 + 27 21 21 26 20 25 27 12 14 27 27 25 27 18 11 10 27 + 27 27 14 27 27 16 27 27 27 26 27 12 24 27 10 16 24 + 20 10 21 23 16 27 24 24 27 0 23 26 18 27 10 12 26 + 27 27 18 12 27 27 17 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 12 23 27 23 16 14 + 12 6 10 11 18 10 12 27 21 24 27 26 24 14 27 27 14 + 12 12 14 16 18 10 3 3 26 14 15 6 3 6 15 11 16 + 14 14 1 27 24 16 6 16 25 16 25 26 11 24 12 24 16 + 16 25 25 11 16 14 15 27 26 10 12 6 15 16 27 10 14 + 16 14 12 16 16 26 23 20 14 14 12 16 10 12 27 20 23 + 12 14 25 23 25 10 21 16 23 25 10 24 3 12 10 10 20 + 27 10 11 10 25 14 8 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 12 26 27 26 24 11 24 12 27 12 23 25 23 12 26 27 10 + 24 10 12 16 18 14 24 14 27 24 24 12 10 25 10 10 24 + 16 25 26 25 15 24 25 24 27 12 18 25 27 21 23 18 10 + + 15 15 16 21 25 21 11 16 22 12 12 10 12 12 23 12 24 + 20 10 10 18 11 15 20 24 18 21 21 16 21 12 20 21 21 + 21 21 19 21 21 21 21 21 21 18 21 18 12 21 23 21 12 + 11 21 10 11 25 20 18 12 21 21 0 18 26 20 21 24 18 + 21 21 13 16 21 21 22 10 21 11 21 25 21 24 21 21 21 + 21 21 21 21 21 15 21 18 15 21 21 21 14 11 21 16 5 + 12 20 14 10 14 10 12 21 21 21 21 21 21 21 21 21 10 + 21 21 23 21 21 21 21 15 23 12 12 23 5 20 6 25 15 + 24 23 21 20 12 23 23 20 12 14 20 18 14 15 20 20 15 + 16 16 15 25 26 21 23 23 18 24 25 23 23 23 20 23 25 + 15 24 23 20 12 25 23 25 15 18 16 18 20 12 23 12 25 + 12 16 18 20 25 15 14 21 18 21 16 23 14 25 20 23 15 + 21 15 18 25 25 18 6 11 24 15 24 12 21 24 20 11 18 + 18 18 16 4 15 23 10 25 12 18 21 12 23 18 23 21 13 + 21 21 20 21 16 15 23 26 16 26 18 18 18 14 25 15 12 + 25 25 23 11 12 11 18 16 16 23 20 12 16 25 14 18 15 + 24 18 20 18 14 23 13 24 20 23 11 15 18 16 18 20 23 + 14 21 20 25 12 15 12 15 20 14 12 16 21 16 23 21 12 + 25 18 18 16 25 12 16 12 20 24 12 18 20 10 10 26 23 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 0 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 23 23 23 33 15 33 27 23 24 24 28 27 24 24 18 28 14 + 31 25 25 31 25 30 31 14 23 33 33 31 33 24 21 20 33 + 33 33 23 33 33 23 33 33 33 31 33 23 28 33 16 23 28 + 25 20 25 27 10 31 29 28 33 33 27 31 0 31 20 15 31 + 33 33 24 23 33 33 24 27 33 27 33 10 33 12 33 33 33 + 33 33 33 33 33 23 33 31 23 33 33 33 24 27 33 23 26 + 28 31 24 25 24 25 24 20 33 33 33 33 33 33 33 33 25 + 33 33 15 33 33 33 33 23 15 28 28 19 26 31 26 10 23 + 15 18 20 21 24 16 19 31 25 29 31 31 29 23 31 31 23 + 23 23 23 10 6 20 18 18 31 12 15 18 18 18 23 15 10 + 23 12 18 31 28 10 18 10 30 24 31 31 21 28 19 28 19 + 24 31 30 21 10 23 24 33 31 20 23 18 24 10 31 16 23 + 23 23 23 10 15 31 26 25 12 23 14 24 20 15 31 25 27 + 23 23 31 26 30 16 25 10 26 31 20 28 18 23 16 20 25 + 33 20 21 20 31 23 18 10 31 10 31 23 25 24 11 23 28 + 15 10 16 25 24 27 31 23 23 15 31 28 23 10 29 25 30 + 19 31 31 31 29 15 28 19 31 19 27 30 26 23 31 31 16 + 29 20 21 10 24 23 28 23 31 29 28 23 20 31 16 20 28 + 10 31 31 31 15 28 31 28 31 15 24 31 31 25 27 15 16 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 0 21 11 15 28 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 0 11 24 12 11 27 24 12 + 21 25 20 15 31 10 19 12 11 11 15 0 31 0 25 28 6 + 11 11 23 24 11 11 24 16 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 0 24 11 11 11 23 15 11 24 18 + 14 10 23 20 23 20 23 25 11 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 0 15 24 10 10 24 + 24 24 24 31 31 25 26 26 0 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 15 23 10 19 25 14 27 12 31 + 23 15 19 25 31 24 23 19 0 25 24 26 23 31 10 27 24 + 24 24 24 31 31 0 18 21 29 24 28 23 25 28 10 21 19 + 24 24 10 18 11 27 20 31 18 19 25 14 26 24 27 25 21 + 19 25 25 25 10 24 26 31 15 31 19 24 20 23 30 24 14 + 30 31 27 21 23 15 0 24 24 27 10 12 24 31 12 21 15 + 28 10 10 0 15 27 15 28 10 27 15 11 19 24 0 15 27 + 12 25 25 31 23 24 12 24 10 15 14 24 25 10 27 25 12 + 31 19 15 10 30 14 10 14 10 28 23 19 10 20 16 31 27 + + 17 11 11 25 21 25 21 12 24 14 23 20 14 14 12 23 15 + 25 16 16 24 15 24 25 15 19 25 25 24 25 14 10 11 25 + 25 25 21 25 25 23 25 25 25 24 25 0 23 25 12 23 23 + 15 11 16 21 21 25 23 23 25 25 21 24 23 25 0 15 24 + 25 25 15 10 25 25 24 20 25 21 25 21 25 16 25 25 25 + 25 25 25 25 25 11 25 24 11 25 25 25 12 21 25 10 18 + 23 25 12 16 12 16 12 11 25 25 25 25 25 25 25 25 16 + 25 25 14 25 25 25 25 11 14 23 23 19 18 25 18 21 11 + 16 12 11 10 14 15 19 25 16 23 25 24 23 16 25 25 11 + 10 10 17 21 23 11 12 12 24 18 20 12 12 12 22 14 21 + 11 18 12 25 23 21 12 21 24 19 24 24 10 23 19 23 21 + 12 24 24 10 21 11 15 25 24 11 10 12 12 21 25 12 12 + 23 11 0 21 21 24 18 15 18 11 15 12 11 16 25 15 20 + 0 19 24 18 24 15 16 21 18 24 15 23 12 6 15 11 15 + 25 11 10 11 24 17 15 23 24 23 24 10 19 12 20 15 23 + 20 21 12 15 14 21 24 10 10 14 25 23 10 21 23 19 24 + 19 24 25 24 23 14 23 19 25 19 21 24 19 10 24 25 12 + 23 11 19 21 14 11 23 11 25 23 23 10 11 24 12 15 23 + 21 24 24 24 20 23 24 23 25 15 14 24 25 16 20 23 12 + + 21 21 23 15 28 15 11 23 24 16 11 12 16 16 24 10 25 + 14 14 14 12 15 11 15 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 23 15 15 15 12 15 23 0 15 24 23 9 + 15 24 14 11 28 14 19 10 15 15 11 12 28 15 24 0 12 + 15 15 16 23 15 15 24 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 10 14 12 15 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 22 25 28 + 21 27 24 14 12 28 24 28 15 19 12 19 23 10 25 6 28 + 18 15 19 23 28 21 20 19 12 24 23 24 20 28 14 24 21 + 23 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 19 + 23 21 12 12 11 24 14 28 14 19 24 10 24 23 24 24 15 + 19 24 23 24 12 21 24 28 15 28 19 23 19 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 9 23 28 10 19 15 + 25 12 14 12 15 25 15 25 14 24 11 11 19 23 12 15 24 + 10 24 23 28 16 21 9 21 14 15 10 23 24 12 24 24 0 + 28 19 15 12 27 10 12 10 14 25 16 19 14 14 12 28 24 + + 17 15 14 28 15 28 24 14 24 20 24 23 20 20 10 24 11 + 27 23 23 27 21 25 27 11 19 28 28 26 28 20 12 11 28 + 28 28 21 28 28 23 28 28 28 27 28 12 24 28 0 23 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 15 15 0 + 28 28 20 14 28 28 24 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 28 27 15 28 28 28 16 24 28 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 10 24 24 19 23 27 23 15 15 + 15 10 11 12 20 15 19 27 23 25 27 27 25 16 27 27 15 + 14 14 17 15 16 11 10 10 27 12 15 12 10 10 22 10 15 + 15 12 10 27 24 15 12 15 25 19 26 27 12 24 19 24 19 + 18 26 25 12 15 15 16 28 27 11 14 10 16 15 27 5 15 + 23 15 12 15 15 27 23 21 12 15 11 18 11 15 27 21 23 + 12 19 26 23 25 15 23 15 23 26 15 24 10 12 15 11 21 + 28 11 12 11 26 17 15 16 26 16 27 12 23 16 14 15 24 + 15 15 0 21 20 24 27 14 14 10 27 24 14 15 25 21 25 + 19 27 27 27 25 10 24 19 27 19 24 25 23 14 27 27 0 + 25 11 19 15 20 15 24 15 27 25 24 14 11 26 0 15 24 + 15 26 27 26 15 24 26 24 27 15 20 26 27 23 23 16 10 + + 14 14 12 27 16 27 23 12 17 18 24 23 18 18 6 24 12 + 27 21 21 26 20 25 27 12 14 27 27 25 27 18 11 10 27 + 27 27 14 27 27 16 27 27 27 26 27 12 24 27 10 16 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 10 12 26 + 0 27 18 12 27 27 17 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 12 23 27 23 16 14 + 12 6 10 11 18 10 12 27 21 24 27 26 24 14 27 27 14 + 12 12 14 16 18 10 3 3 26 14 15 6 3 6 15 11 16 + 14 14 1 27 24 16 6 16 25 16 25 26 11 24 12 24 16 + 16 25 25 11 16 14 15 27 26 10 12 6 15 16 27 10 14 + 16 14 12 16 16 26 23 20 14 14 12 16 10 12 27 20 23 + 12 14 25 23 25 10 21 16 23 25 10 24 3 12 10 10 20 + 27 10 11 10 25 14 8 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 12 26 27 26 24 11 24 12 27 12 23 25 23 12 26 27 10 + 24 10 12 16 18 14 24 14 27 24 24 12 10 25 10 10 24 + 16 25 26 25 15 24 25 24 27 12 18 25 27 21 23 18 10 + + 21 21 23 15 28 15 11 23 21 16 0 12 16 16 24 11 25 + 14 14 14 12 15 11 14 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 21 15 15 15 12 15 23 11 15 24 21 2 + 15 24 14 11 28 14 10 1 15 15 11 12 28 14 24 25 12 + 15 0 16 23 15 15 21 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 11 14 12 10 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 21 25 28 + 21 27 24 14 10 28 24 28 11 18 12 12 23 11 25 4 28 + 18 12 11 23 28 21 20 15 12 24 23 24 20 28 14 24 21 + 21 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 12 + 23 21 12 12 11 24 14 28 12 12 24 10 24 23 24 24 15 + 15 24 23 24 12 21 24 28 12 28 12 23 14 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 2 23 28 10 15 11 + 25 12 14 12 10 25 3 25 14 24 11 11 12 23 12 14 24 + 10 24 23 28 16 21 2 21 14 10 10 23 24 12 24 24 11 + 28 12 12 12 27 10 12 10 14 25 16 12 14 14 12 28 24 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 0 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 17 10 11 25 23 25 20 12 24 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 19 25 25 24 25 12 11 12 25 + 25 25 21 25 25 23 25 25 25 24 25 10 23 25 14 23 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 15 16 24 + 25 25 15 0 25 25 24 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 10 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 19 16 24 16 23 10 + 18 12 12 11 12 15 19 24 15 23 24 24 23 16 24 24 10 + 5 9 17 23 23 12 12 12 24 20 21 12 12 12 22 15 23 + 10 20 12 24 21 23 12 23 23 19 24 24 11 21 19 23 23 + 12 24 23 11 23 10 15 25 24 12 10 12 11 23 24 14 12 + 23 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 19 + 10 19 24 16 23 15 15 23 16 24 15 21 12 10 15 12 15 + 25 12 11 12 24 17 15 23 24 23 24 10 19 11 21 15 21 + 21 23 14 14 12 20 24 9 6 15 24 23 5 23 23 19 23 + 19 24 24 24 23 15 23 19 24 19 20 23 19 8 24 24 14 + 23 12 19 23 14 10 23 10 24 23 21 9 12 24 14 15 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 21 21 23 15 28 15 11 23 21 16 2 12 16 16 24 10 25 + 14 14 14 12 15 11 14 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 21 15 15 15 12 15 23 9 15 24 21 0 + 15 24 14 11 28 14 10 1 15 15 11 12 28 14 24 25 12 + 15 15 16 23 0 15 21 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 10 14 12 10 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 21 25 28 + 21 27 24 14 10 28 24 28 11 18 12 12 23 10 25 2 28 + 18 12 11 23 28 21 20 15 12 24 23 24 20 28 14 24 21 + 21 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 12 + 23 21 12 12 11 24 14 28 12 12 24 10 24 23 24 24 15 + 15 24 23 24 12 21 24 28 12 28 12 23 14 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 0 23 28 10 15 11 + 25 12 14 12 10 25 5 25 14 24 11 11 12 23 12 14 24 + 10 24 23 28 16 21 0 21 14 10 10 23 24 12 24 24 9 + 28 12 12 12 27 10 12 10 14 25 16 12 14 14 12 28 24 + + 21 21 23 15 28 15 11 23 21 16 1 12 16 16 24 10 25 + 14 14 14 12 15 11 14 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 21 15 15 15 12 15 23 10 15 24 21 1 + 15 24 14 11 28 14 10 0 15 15 11 12 28 14 24 25 12 + 15 15 16 23 15 0 21 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 10 14 12 10 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 21 25 28 + 21 27 24 14 10 28 24 28 11 18 12 12 23 10 25 3 28 + 18 12 11 23 28 21 20 15 12 24 23 24 20 28 14 24 21 + 21 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 12 + 23 21 12 12 11 24 14 28 12 12 24 10 24 23 24 24 15 + 15 24 23 24 12 21 24 28 12 28 12 23 14 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 1 23 28 10 15 11 + 25 12 14 12 10 25 4 25 14 24 11 11 12 23 12 14 24 + 10 24 23 28 16 21 1 21 14 10 10 23 24 12 24 24 10 + 28 12 12 12 27 10 12 10 14 25 16 12 14 14 12 28 24 + + 17 10 11 25 23 25 20 12 24 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 19 25 25 24 25 12 11 12 25 + 25 25 21 25 25 23 25 25 25 24 25 10 23 25 14 23 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 15 16 24 + 25 25 15 10 25 25 0 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 10 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 19 16 24 16 23 10 + 18 12 12 11 12 15 19 24 15 23 24 24 23 16 24 24 10 + 5 9 17 23 23 12 12 12 24 20 21 12 12 12 22 15 23 + 10 20 12 24 21 23 12 23 23 19 24 24 11 21 19 23 23 + 12 24 23 11 23 10 15 25 24 12 10 12 11 23 24 14 12 + 23 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 19 + 10 19 24 16 23 15 15 23 16 24 15 21 12 10 15 12 15 + 25 12 11 12 24 17 15 23 24 23 24 10 19 11 21 15 21 + 21 23 14 14 12 20 24 9 6 15 24 23 5 23 23 19 23 + 19 24 24 24 23 15 23 19 24 19 20 23 19 8 24 24 14 + 23 12 19 23 14 10 23 10 24 23 21 9 12 24 14 15 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 0 21 11 15 28 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 0 11 24 12 11 27 24 12 + 21 25 20 15 31 10 19 12 11 11 15 0 31 15 25 28 6 + 11 11 23 24 11 11 24 0 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 0 24 11 11 11 23 15 11 24 18 + 14 10 23 20 23 20 23 25 11 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 0 15 24 10 10 24 + 24 24 24 31 31 25 26 26 0 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 15 23 10 19 25 14 27 12 31 + 23 15 19 25 31 24 23 19 0 25 24 26 23 31 10 27 24 + 24 24 24 31 31 0 18 21 29 24 28 23 25 28 10 21 19 + 24 24 10 18 11 27 20 31 18 19 25 14 26 24 27 25 21 + 19 25 25 25 10 24 26 31 15 31 19 24 20 23 30 24 14 + 30 31 27 21 23 15 0 24 24 27 10 12 24 31 12 21 15 + 28 10 10 0 15 27 15 28 10 27 15 11 19 24 0 15 27 + 12 25 25 31 23 24 12 24 10 15 14 24 25 10 27 25 12 + 31 19 15 10 30 14 10 14 10 28 23 19 10 20 16 31 27 + + 14 14 12 27 16 27 23 12 15 18 24 23 18 18 9 24 12 + 27 21 21 26 20 25 27 12 14 27 27 25 27 18 11 10 27 + 27 27 14 27 27 14 27 27 27 26 27 12 24 27 10 14 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 10 12 26 + 27 27 18 12 27 27 15 23 0 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 11 23 27 23 16 14 + 12 9 10 11 18 10 10 27 21 24 27 26 24 14 27 27 14 + 12 12 14 16 18 10 1 1 26 14 15 3 1 9 14 11 16 + 14 14 3 27 24 16 3 16 25 16 25 26 11 24 11 24 16 + 16 25 25 11 16 14 15 27 26 10 12 9 15 16 27 10 14 + 14 14 12 16 16 26 23 20 14 14 12 16 10 12 27 20 23 + 12 14 25 23 25 10 21 16 23 25 10 24 1 12 10 10 20 + 27 10 11 10 25 14 5 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 12 26 27 26 24 11 24 12 27 10 23 25 23 12 26 27 10 + 24 10 11 16 18 14 24 14 27 24 24 12 10 25 10 10 24 + 16 25 26 25 15 24 25 24 27 12 18 25 27 21 23 18 10 + + 15 14 15 23 25 23 12 15 22 11 14 11 11 11 21 12 23 + 21 5 10 20 10 16 21 23 18 23 23 18 23 11 18 20 23 + 23 23 19 23 23 21 23 23 23 20 23 16 14 23 23 21 14 + 10 20 6 12 25 21 18 14 23 23 12 20 25 21 20 23 20 + 23 23 13 15 23 23 22 11 23 0 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 6 12 4 12 20 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 12 15 21 20 15 14 21 21 14 + 15 15 15 25 25 20 21 21 20 24 24 21 21 21 20 23 25 + 14 24 21 21 12 25 21 25 16 18 18 20 18 12 23 14 25 + 12 18 18 18 25 14 13 23 20 20 15 21 12 25 21 23 14 + 21 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 18 + 16 18 18 10 16 23 10 25 12 18 20 12 21 16 23 20 13 + 23 20 18 20 18 15 21 25 18 25 20 16 18 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 18 16 + 23 20 21 20 15 23 14 23 21 23 12 16 18 15 20 21 23 + 15 20 18 25 12 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 1 11 25 23 + + 14 14 12 27 16 27 23 12 16 18 24 23 18 18 8 24 12 + 27 21 21 26 20 25 27 12 14 27 27 25 27 18 11 10 27 + 27 27 14 27 27 15 27 27 27 26 27 12 24 27 10 15 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 10 12 26 + 27 27 18 12 27 27 16 23 27 23 0 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 11 23 27 23 16 14 + 12 8 10 11 18 10 11 27 21 24 27 26 24 14 27 27 14 + 12 12 14 16 18 10 2 2 26 14 15 4 2 8 14 11 16 + 14 14 2 27 24 16 4 16 25 16 25 26 11 24 11 24 16 + 16 25 25 11 16 14 15 27 26 10 12 8 15 16 27 10 14 + 15 14 12 16 16 26 23 20 14 14 12 16 10 12 27 20 23 + 12 14 25 23 25 10 21 16 23 25 10 24 2 12 10 10 20 + 27 10 11 10 25 14 7 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 12 26 27 26 24 11 24 12 27 11 23 25 23 12 26 27 10 + 24 10 11 16 18 14 24 14 27 24 24 12 10 25 10 10 24 + 16 25 26 25 15 24 25 24 27 12 18 25 27 21 23 18 10 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 0 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 14 14 15 23 25 23 12 15 16 11 14 11 11 11 21 12 23 + 21 1 3 20 10 16 21 23 14 23 23 18 23 11 18 20 23 + 23 23 14 23 23 15 23 23 23 20 23 16 14 23 23 15 14 + 10 20 0 12 25 21 15 14 23 23 12 20 25 21 20 23 20 + 23 23 11 15 23 23 16 11 23 12 23 25 0 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 0 12 2 12 20 23 23 23 23 23 23 23 23 3 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 6 15 21 20 15 14 21 21 14 + 15 15 14 25 25 20 21 21 20 24 24 21 21 21 14 23 25 + 14 24 21 21 12 25 21 25 16 12 18 20 18 12 23 14 25 + 12 18 16 18 25 14 12 23 20 20 15 21 12 25 21 23 14 + 15 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 11 + 16 14 18 10 16 23 3 25 10 18 20 12 21 16 23 20 10 + 23 20 18 20 18 14 21 25 18 25 20 16 11 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 11 16 + 23 20 21 20 15 23 14 23 21 23 12 16 11 15 20 21 23 + 15 20 18 25 11 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 8 11 25 23 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 0 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 18 18 20 18 27 18 9 20 24 14 11 10 14 14 23 10 24 + 16 12 12 15 12 12 16 24 19 18 18 14 18 14 23 23 18 + 18 18 21 18 18 23 18 18 18 15 18 21 11 18 24 23 11 + 12 23 12 6 27 16 19 11 18 18 5 15 27 16 23 24 15 + 18 18 15 20 18 18 24 10 18 11 18 27 18 25 0 18 18 + 18 18 18 18 18 18 18 15 18 18 18 18 16 9 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 18 18 18 12 + 18 18 24 18 18 18 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 14 12 16 15 15 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 22 24 27 + 18 25 23 16 12 27 23 27 15 19 14 19 23 10 24 11 27 + 15 15 19 23 27 18 16 19 15 23 20 23 16 27 16 24 18 + 23 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 19 + 21 19 14 11 12 24 12 27 14 19 23 10 23 21 24 23 15 + 19 23 23 23 14 18 23 27 15 27 19 21 19 16 26 18 10 + 26 27 24 12 14 10 15 20 20 24 16 11 20 27 12 19 15 + 24 15 16 15 15 24 15 24 16 24 9 12 19 20 15 16 24 + 12 23 23 27 14 18 11 18 16 15 10 20 23 14 24 23 11 + 27 19 15 14 26 10 14 10 16 24 14 19 16 12 10 27 24 + + 11 11 12 24 24 24 15 12 14 10 18 14 10 10 16 16 21 + 23 12 12 23 11 21 23 21 11 24 24 23 24 10 14 15 24 + 24 24 11 24 24 12 24 24 24 23 24 12 18 24 18 12 18 + 11 15 12 15 24 23 20 18 24 24 15 23 24 23 15 21 23 + 24 24 10 12 24 24 14 14 24 15 24 24 24 23 24 0 24 + 24 24 24 24 24 11 24 23 11 24 24 24 10 15 24 12 12 + 16 23 10 12 10 12 10 15 24 24 24 24 24 24 24 24 12 + 24 24 20 24 24 24 24 11 20 16 16 20 12 23 12 24 11 + 23 16 15 14 10 18 18 23 12 20 23 23 20 11 23 23 11 + 12 12 11 24 24 15 16 16 23 23 23 16 16 16 11 20 24 + 11 23 16 23 16 24 16 24 21 9 23 23 14 16 20 18 24 + 0 23 21 14 24 11 10 24 23 15 12 16 10 24 23 18 11 + 12 11 12 24 24 23 12 11 23 11 21 10 15 23 23 11 14 + 12 11 23 12 21 18 12 24 12 23 15 16 16 12 18 15 11 + 24 15 14 15 23 11 16 24 23 24 23 12 12 10 23 11 16 + 23 24 18 11 10 15 23 12 12 20 23 18 12 24 20 11 21 + 21 23 23 23 20 20 18 21 23 18 15 21 12 12 23 23 18 + 20 15 14 24 10 11 18 11 23 20 16 12 15 23 18 15 18 + 24 23 23 23 23 16 23 16 23 21 10 23 23 12 14 24 18 + + 12 12 12 27 18 27 23 12 18 16 24 23 16 16 10 23 12 + 26 20 20 25 18 24 26 12 13 27 27 25 27 16 10 0 27 + 27 27 15 27 27 17 27 27 27 25 27 11 24 27 11 17 24 + 18 0 20 23 18 26 24 24 27 27 23 25 20 26 9 12 25 + 27 27 16 12 27 27 18 23 27 23 27 18 27 14 27 27 0 + 27 27 27 27 27 12 27 25 12 27 27 27 14 23 27 12 21 + 23 26 14 20 14 20 15 0 27 27 27 27 27 27 27 27 20 + 27 27 12 27 27 27 27 12 12 23 23 13 21 26 21 18 12 + 14 10 6 10 16 11 13 26 20 24 26 25 24 12 26 26 12 + 12 12 12 18 20 6 10 10 25 15 16 10 10 10 16 12 18 + 12 15 10 26 23 18 10 18 24 15 25 25 10 23 13 24 18 + 15 25 24 10 18 12 14 27 25 6 12 10 14 18 26 11 12 + 17 12 11 18 18 25 21 18 15 12 12 15 6 14 26 18 23 + 11 13 25 21 24 11 20 18 21 25 9 23 10 11 11 0 18 + 27 6 10 0 25 12 10 20 25 20 25 11 20 14 16 12 23 + 16 18 11 18 16 23 25 12 12 12 26 24 12 18 24 18 24 + 13 25 26 25 24 12 24 13 26 13 23 24 21 12 25 26 11 + 24 6 13 18 16 12 24 12 26 24 23 12 6 25 11 9 24 + 18 25 25 25 16 23 25 23 26 12 16 25 26 20 23 20 11 + + 17 14 15 23 25 23 12 15 24 11 14 11 11 11 21 12 23 + 21 6 11 20 10 16 21 23 19 23 23 18 23 11 18 20 23 + 23 23 21 23 23 23 23 23 23 20 23 16 14 23 23 23 14 + 10 20 8 12 25 21 19 14 23 23 12 20 25 21 20 23 20 + 23 23 15 15 23 23 24 11 23 12 23 25 23 24 23 23 23 + 0 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 8 12 5 12 20 23 23 23 23 23 23 23 23 11 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 14 15 21 20 15 16 21 21 14 + 15 15 17 25 25 20 21 21 20 24 24 21 21 21 22 23 25 + 14 24 21 21 12 25 21 25 16 19 18 20 18 12 23 14 25 + 12 18 19 18 25 14 15 23 20 20 15 21 12 25 21 23 14 + 23 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 19 + 16 19 18 10 16 23 11 25 14 19 20 12 21 16 23 20 15 + 23 20 18 20 18 17 21 25 18 25 20 16 19 12 24 15 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 19 16 + 23 20 21 20 15 23 15 23 21 23 12 16 19 15 20 21 23 + 15 20 19 25 14 14 14 14 21 15 12 15 20 18 23 20 14 + 25 19 20 18 24 12 18 12 21 23 11 19 21 0 11 25 23 + + 14 14 15 23 25 23 12 15 14 11 14 11 11 11 21 12 23 + 21 4 0 20 10 16 21 23 14 23 23 18 23 11 18 20 23 + 23 23 14 23 23 14 23 23 23 20 23 16 14 23 23 14 14 + 10 20 3 12 25 21 15 14 23 23 12 20 25 21 20 23 20 + 23 23 11 15 23 23 14 11 23 12 23 25 23 24 23 23 23 + 23 0 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 3 12 6 12 20 23 23 23 23 23 23 23 23 0 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 2 15 21 20 15 14 21 21 14 + 15 15 14 25 25 20 21 21 20 24 24 21 21 21 14 23 25 + 14 24 21 21 12 25 21 25 16 12 18 20 18 12 23 14 25 + 12 18 16 18 25 14 12 23 20 20 15 21 12 25 21 23 14 + 14 14 16 25 25 20 10 10 24 14 23 12 20 24 21 11 11 + 16 14 18 10 16 23 0 25 10 18 20 12 21 16 23 20 10 + 23 20 18 20 18 14 21 25 18 25 20 16 8 12 24 14 12 + 24 25 23 11 11 12 20 15 15 23 21 14 15 25 15 10 16 + 23 20 21 20 15 23 14 23 21 23 12 16 10 15 20 21 23 + 15 20 18 25 11 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 11 11 25 23 + + 14 14 12 27 16 27 23 12 15 18 24 23 18 18 9 24 12 + 27 21 21 26 20 25 27 12 14 27 27 25 27 18 11 10 27 + 27 27 14 27 27 14 27 27 27 26 27 12 24 27 10 14 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 10 12 26 + 27 27 18 12 27 27 15 23 27 23 27 16 27 12 27 27 27 + 27 27 0 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 11 23 27 23 16 14 + 12 9 10 11 18 10 10 27 21 24 27 26 24 14 27 27 14 + 12 12 14 16 18 10 1 1 26 14 15 3 1 9 14 11 16 + 14 14 3 27 24 16 3 16 25 16 25 26 11 24 11 24 16 + 16 25 25 11 16 14 15 27 26 10 12 9 15 16 27 10 14 + 14 14 12 16 16 26 23 20 14 14 12 16 10 12 27 20 23 + 12 14 25 23 25 10 21 16 23 25 10 24 1 12 10 10 20 + 27 10 11 10 25 14 5 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 12 26 27 26 24 11 24 12 27 10 23 25 23 12 26 27 10 + 24 10 11 16 18 14 24 14 27 24 24 12 10 25 10 10 24 + 16 25 26 25 15 24 25 24 27 12 18 25 27 21 23 18 10 + + 18 18 20 18 27 18 2 20 18 14 11 10 14 14 23 10 24 + 16 12 12 15 12 12 16 24 18 18 18 14 18 14 23 23 18 + 18 18 18 18 18 18 18 18 18 15 18 21 11 18 24 18 11 + 12 23 12 0 27 16 12 11 18 18 1 15 27 16 23 24 15 + 18 18 14 20 18 18 18 10 18 4 18 27 18 25 18 18 18 + 18 18 18 0 18 18 18 15 18 18 18 18 16 2 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 18 18 18 12 + 18 18 24 18 18 18 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 12 12 16 15 12 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 18 24 27 + 18 25 23 16 10 27 23 27 12 15 14 15 23 10 24 11 27 + 15 14 12 23 27 18 16 18 15 23 20 23 16 27 16 24 18 + 18 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 12 + 21 18 14 11 12 24 12 27 11 14 23 10 23 21 24 23 12 + 18 23 23 23 14 18 23 27 14 27 15 21 12 16 26 18 10 + 26 27 24 12 14 3 15 20 20 24 16 11 20 27 12 12 12 + 24 15 16 15 12 24 11 24 16 24 2 12 12 20 15 16 24 + 12 23 23 27 14 18 11 18 16 12 10 20 23 14 24 23 11 + 27 14 15 14 26 10 14 10 16 24 14 14 16 12 10 27 24 + + 12 12 14 23 24 23 12 14 18 10 15 12 10 10 20 14 23 + 23 10 10 21 4 18 23 23 14 23 23 20 23 10 16 18 23 + 23 23 15 23 23 17 23 23 23 21 23 15 15 23 21 17 15 + 0 18 10 12 24 23 16 15 23 23 12 21 25 23 18 23 21 + 23 23 10 14 23 23 18 12 23 12 23 24 23 23 23 23 23 + 23 23 23 23 0 12 23 21 12 23 23 23 12 12 23 14 11 + 14 23 12 10 12 10 11 18 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 12 23 14 14 23 11 23 11 24 12 + 23 20 18 16 10 21 21 23 10 16 23 21 16 12 23 23 12 + 14 14 12 24 25 18 20 20 21 24 24 20 20 20 16 23 24 + 12 24 20 23 14 24 20 24 18 14 20 21 16 14 23 15 24 + 11 20 18 16 24 12 12 23 21 18 14 20 12 24 23 21 12 + 17 12 15 24 24 21 11 1 24 12 23 11 18 23 23 5 14 + 15 14 20 11 18 21 10 24 11 20 18 14 20 15 21 18 9 + 23 18 16 18 20 12 20 25 20 25 21 15 14 12 24 12 14 + 24 24 21 5 10 12 21 14 14 23 23 15 14 24 16 14 18 + 23 21 23 21 16 23 15 23 23 21 12 18 14 14 21 23 21 + 16 18 16 24 10 12 15 12 23 16 14 14 18 20 21 18 15 + 24 20 21 20 24 14 20 14 23 23 10 20 23 10 12 25 21 + + 15 14 15 23 25 23 12 15 22 11 14 11 11 11 21 12 23 + 21 5 10 20 10 16 21 23 18 23 23 18 23 11 18 20 23 + 23 23 19 23 23 21 23 23 23 20 23 16 14 23 23 21 14 + 10 20 6 12 25 21 18 14 23 23 12 20 25 21 20 23 20 + 23 23 13 15 23 23 22 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 0 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 6 12 4 12 20 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 12 15 21 20 15 14 21 21 14 + 15 15 15 25 25 20 21 21 20 24 24 21 21 21 20 23 25 + 14 24 21 21 12 25 21 25 16 18 18 20 18 12 23 14 25 + 12 18 18 18 25 14 13 23 20 20 15 21 12 25 21 23 14 + 21 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 18 + 16 18 18 10 16 23 10 25 12 18 20 12 21 16 23 20 13 + 23 20 18 20 18 15 21 25 18 25 20 16 18 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 18 16 + 23 20 21 20 15 23 14 23 21 23 12 16 18 15 20 21 23 + 15 20 18 25 12 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 1 11 25 23 + + 15 15 14 28 15 28 24 14 17 20 24 23 20 20 10 24 11 + 27 23 23 27 21 25 27 11 15 28 28 26 28 20 12 11 28 + 28 28 15 28 28 16 28 28 28 27 28 12 24 28 6 16 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 11 11 27 + 28 28 20 14 28 28 17 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 0 27 15 28 28 28 16 24 28 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 10 24 24 12 23 27 23 15 15 + 12 10 11 12 20 8 12 27 23 25 27 27 25 15 27 27 15 + 14 14 15 15 16 11 10 10 27 12 14 10 10 10 15 10 15 + 15 12 10 27 24 15 10 15 25 18 26 27 12 24 12 24 15 + 18 26 25 12 15 15 16 28 27 11 14 10 16 15 27 1 15 + 16 15 12 15 15 27 23 21 12 15 11 18 11 12 27 21 23 + 12 15 26 23 25 8 23 15 23 26 11 24 10 12 8 11 21 + 28 11 12 11 26 15 10 16 26 16 27 12 23 16 14 15 24 + 14 15 6 21 20 24 27 14 14 10 27 24 14 15 25 21 25 + 12 27 27 27 25 10 24 12 27 12 24 25 23 14 27 27 6 + 25 11 12 15 20 15 24 15 27 25 24 14 11 26 6 11 24 + 15 26 27 26 14 24 26 24 27 11 20 26 27 23 23 16 3 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 0 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 20 20 21 16 27 16 10 21 24 15 11 11 15 15 24 0 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 21 16 16 23 16 16 16 14 16 23 10 16 24 23 10 + 14 23 12 10 27 15 19 10 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 24 11 16 11 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 0 16 16 16 18 10 16 21 12 + 6 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 5 9 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 14 11 15 14 15 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 22 24 27 + 20 26 24 15 12 27 24 27 15 19 12 19 23 0 24 10 27 + 16 15 19 23 27 20 18 19 14 23 21 24 18 27 15 24 20 + 23 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 19 + 23 20 12 12 12 24 12 27 14 19 23 6 24 23 24 23 15 + 19 23 23 23 12 20 24 28 15 28 19 23 19 18 27 20 10 + 27 27 24 14 15 10 14 21 21 24 15 10 21 27 11 19 15 + 25 14 15 14 15 24 15 25 15 24 10 12 19 21 14 15 24 + 11 23 23 27 15 20 10 20 15 15 9 21 23 12 24 23 10 + 27 19 15 12 27 8 12 6 15 25 15 19 15 12 11 28 24 + + 18 18 20 18 27 18 3 20 18 14 11 10 14 14 23 10 24 + 16 12 12 15 12 12 16 24 18 18 18 14 18 14 23 23 18 + 18 18 18 18 18 18 18 18 18 15 18 21 11 18 24 18 11 + 12 23 12 1 27 16 14 11 18 18 0 15 27 16 23 24 15 + 18 18 14 20 18 18 18 10 18 6 18 27 18 25 18 18 18 + 18 18 18 18 18 18 18 15 18 0 18 18 16 3 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 18 18 18 12 + 18 18 24 18 18 18 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 12 12 16 15 12 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 18 24 27 + 18 25 23 16 10 27 23 27 12 15 14 15 23 10 24 11 27 + 15 14 14 23 27 18 16 18 15 23 20 23 16 27 16 24 18 + 18 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 14 + 21 18 14 11 12 24 12 27 11 14 23 10 23 21 24 23 12 + 18 23 23 23 14 18 23 27 14 27 15 21 14 16 26 18 10 + 26 27 24 12 14 4 15 20 20 24 16 11 20 27 12 14 12 + 24 15 16 15 12 24 11 24 16 24 3 12 14 20 15 16 24 + 12 23 23 27 14 18 11 18 16 12 10 20 23 14 24 23 11 + 27 14 15 14 26 10 14 10 16 24 14 14 16 12 10 27 24 + + 15 15 14 28 15 28 24 14 17 20 24 23 20 20 10 24 11 + 27 23 23 27 21 25 27 11 15 28 28 26 28 20 12 11 28 + 28 28 15 28 28 16 28 28 28 27 28 12 24 28 6 16 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 11 11 27 + 28 28 20 14 28 28 17 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 28 27 15 28 0 28 16 24 28 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 10 24 24 12 23 27 23 15 15 + 12 10 11 12 20 8 12 27 23 25 27 27 25 15 27 27 15 + 14 14 15 15 16 11 10 10 27 12 14 10 10 10 15 10 15 + 15 12 10 27 24 15 10 15 25 18 26 27 12 24 12 24 15 + 18 26 25 12 15 15 16 28 27 11 14 10 16 15 27 1 15 + 16 15 12 15 15 27 23 21 12 15 11 18 11 12 27 21 23 + 12 15 26 23 25 8 23 15 23 26 11 24 10 12 8 11 21 + 28 11 12 11 26 15 10 16 26 16 27 12 23 16 14 15 24 + 14 15 6 21 20 24 27 14 14 10 27 24 14 15 25 21 25 + 12 27 27 27 25 10 24 12 27 12 24 25 23 14 27 27 6 + 25 11 12 15 20 15 24 15 27 25 24 14 11 26 6 11 24 + 15 26 27 26 14 24 26 24 27 11 20 26 27 23 23 16 3 + + 15 15 14 28 15 28 24 14 17 20 24 23 20 20 10 24 11 + 27 23 23 27 21 25 27 11 15 28 28 26 28 20 12 11 28 + 28 28 15 28 28 16 28 28 28 27 28 12 24 28 6 16 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 11 11 27 + 28 28 20 14 28 28 17 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 28 27 15 28 28 0 16 24 28 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 10 24 24 12 23 27 23 15 15 + 12 10 11 12 20 8 12 27 23 25 27 27 25 15 27 27 15 + 14 14 15 15 16 11 10 10 27 12 14 10 10 10 15 10 15 + 15 12 10 27 24 15 10 15 25 18 26 27 12 24 12 24 15 + 18 26 25 12 15 15 16 28 27 11 14 10 16 15 27 1 15 + 16 15 12 15 15 27 23 21 12 15 11 18 11 12 27 21 23 + 12 15 26 23 25 8 23 15 23 26 11 24 10 12 8 11 21 + 28 11 12 11 26 15 10 16 26 16 27 12 23 16 14 15 24 + 14 15 6 21 20 24 27 14 14 10 27 24 14 15 25 21 25 + 12 27 27 27 25 10 24 12 27 12 24 25 23 14 27 27 6 + 25 11 12 15 20 15 24 15 27 25 24 14 11 26 6 11 24 + 15 26 27 26 14 24 26 24 27 11 20 26 27 23 23 16 3 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 0 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 18 18 20 18 27 18 7 20 22 14 11 10 14 14 23 10 24 + 16 12 12 15 12 12 16 24 18 18 18 14 18 14 23 23 18 + 18 18 19 18 18 21 18 18 18 15 18 21 11 18 24 21 11 + 12 23 12 5 27 16 18 11 18 18 4 15 27 16 23 24 15 + 18 18 14 20 18 18 22 10 18 10 18 27 18 25 18 18 18 + 18 18 18 18 18 18 18 15 18 18 18 18 16 0 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 18 18 18 12 + 18 18 24 18 18 18 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 12 12 16 15 13 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 20 24 27 + 18 25 23 16 11 27 23 27 13 18 14 18 23 10 24 11 27 + 15 14 18 23 27 18 16 18 15 23 20 23 16 27 16 24 18 + 21 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 18 + 21 18 14 11 12 24 12 27 12 18 23 10 23 21 24 23 13 + 18 23 23 23 14 18 23 27 14 27 18 21 18 16 26 18 10 + 26 27 24 12 14 9 15 20 20 24 16 11 20 27 12 18 13 + 24 15 16 15 13 24 13 24 16 24 7 12 18 20 15 16 24 + 12 23 23 27 14 18 11 18 16 13 10 20 23 14 24 23 11 + 27 18 15 14 26 10 14 10 16 24 14 18 16 12 10 27 24 + + 15 15 14 28 15 28 24 14 16 20 24 23 20 20 10 24 11 + 27 23 23 27 21 25 27 11 15 28 28 26 28 20 12 11 28 + 28 28 15 28 28 15 28 28 28 27 28 12 24 28 8 15 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 11 11 27 + 28 28 20 14 28 28 16 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 28 27 15 28 28 28 16 24 0 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 10 24 24 11 23 27 23 15 15 + 12 10 11 12 20 7 11 27 23 25 27 27 25 15 27 27 15 + 14 14 15 15 16 11 10 10 27 12 14 10 10 10 15 10 15 + 15 12 10 27 24 15 10 15 25 18 26 27 12 24 11 24 15 + 18 26 25 12 15 15 16 28 27 11 14 10 16 15 27 2 15 + 15 15 12 15 15 27 23 21 12 15 11 18 11 12 27 21 23 + 12 15 26 23 25 7 23 15 23 26 11 24 10 12 7 11 21 + 28 11 12 11 26 15 10 16 26 16 27 12 23 16 14 15 24 + 14 15 8 21 20 24 27 14 14 10 27 24 14 15 25 21 25 + 11 27 27 27 25 10 24 11 27 11 24 25 23 14 27 27 8 + 25 11 12 15 20 15 24 15 27 25 24 14 11 26 8 11 24 + 15 26 27 26 14 24 26 24 27 11 20 26 27 23 23 16 2 + + 15 10 10 25 23 25 20 11 22 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 18 25 25 24 25 12 11 12 25 + 25 25 19 25 25 21 25 25 25 24 25 10 23 25 14 21 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 13 16 24 + 25 25 13 9 25 25 22 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 0 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 18 16 24 16 23 10 + 18 12 12 11 12 14 18 24 15 23 24 24 23 14 24 24 10 + 4 7 15 23 23 12 12 12 24 20 21 12 12 12 20 15 23 + 10 20 12 24 21 23 12 23 23 18 24 24 11 21 18 23 23 + 12 24 23 11 23 10 13 25 24 12 9 12 11 23 24 14 11 + 21 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 18 24 16 23 14 15 23 16 24 13 21 12 10 14 12 14 + 25 12 11 12 24 15 13 23 24 23 24 10 18 11 21 13 21 + 21 23 14 14 12 20 24 7 5 15 24 23 4 23 23 18 23 + 18 24 24 24 23 15 23 18 24 18 20 23 18 6 24 24 14 + 23 12 18 23 12 10 23 10 24 23 21 7 12 24 14 13 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 15 15 16 21 25 21 11 16 21 12 12 10 12 12 23 12 24 + 20 10 10 18 11 15 20 24 16 21 21 16 21 12 20 21 21 + 21 21 18 21 21 20 21 21 21 18 21 18 12 21 23 20 12 + 11 21 10 11 25 20 16 12 21 21 11 18 26 20 21 24 18 + 21 21 12 16 21 21 21 10 21 11 21 25 21 24 21 21 21 + 21 21 21 21 21 15 21 18 15 21 21 21 14 11 21 16 0 + 12 20 14 10 14 10 12 21 21 21 21 21 21 21 21 21 10 + 21 21 23 21 21 21 21 15 23 12 12 23 3 20 5 25 15 + 24 23 21 20 12 23 23 20 11 14 20 18 14 15 20 20 15 + 16 16 15 25 26 21 23 23 18 24 25 23 23 23 19 23 25 + 15 24 23 20 12 25 23 25 15 16 16 18 20 12 23 12 25 + 12 16 16 20 25 15 14 21 18 21 16 23 14 25 20 23 15 + 20 15 18 25 25 18 5 11 24 15 24 12 21 24 20 11 16 + 18 16 16 2 15 23 10 25 11 16 21 12 23 18 23 21 12 + 21 21 20 21 16 15 23 26 16 26 18 18 16 14 25 15 12 + 25 25 23 11 12 11 18 16 16 23 20 12 16 25 14 16 15 + 24 18 20 18 14 23 12 24 20 23 11 15 16 16 18 20 23 + 14 21 20 25 12 15 12 15 20 14 12 16 21 16 23 21 12 + 25 16 18 16 25 12 16 12 20 24 12 16 20 10 10 26 23 + + 17 15 16 21 25 21 11 16 24 12 12 10 12 12 23 12 24 + 20 10 11 18 11 15 20 24 19 21 21 16 21 12 20 21 21 + 21 21 21 21 21 23 21 21 21 18 21 18 12 21 23 23 12 + 11 21 10 11 25 20 19 12 21 21 11 18 26 20 21 24 18 + 21 21 15 16 21 21 24 10 21 11 21 25 21 24 21 21 21 + 21 21 21 21 21 15 21 18 15 21 21 21 14 11 21 16 6 + 0 20 14 10 14 10 12 21 21 21 21 21 21 21 21 21 11 + 21 21 23 21 21 21 21 15 23 12 12 23 6 20 8 25 15 + 24 23 21 20 12 23 23 20 14 14 20 18 15 16 20 20 15 + 16 16 17 25 26 21 23 23 18 24 25 23 23 23 22 23 25 + 15 24 23 20 12 25 23 25 15 19 16 19 20 12 23 12 25 + 12 16 19 20 25 15 15 21 18 21 16 23 14 25 20 23 15 + 23 15 18 25 25 18 8 11 24 15 24 12 21 24 20 11 19 + 18 19 16 5 15 23 11 25 14 19 21 12 23 18 23 21 15 + 21 21 20 21 16 17 23 26 16 26 19 18 19 14 25 15 12 + 25 25 23 11 12 11 18 16 16 23 20 12 16 25 14 19 15 + 24 18 20 18 15 23 15 24 20 23 11 15 19 16 18 20 23 + 14 21 20 25 14 15 12 15 20 15 12 16 21 16 23 21 12 + 25 19 18 16 25 12 16 12 20 24 12 19 20 10 10 26 23 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 0 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 0 21 11 15 28 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 0 11 24 12 11 27 24 12 + 21 25 20 15 31 10 19 12 11 11 15 0 31 15 25 28 6 + 11 11 23 24 11 11 24 16 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 0 24 11 11 11 23 15 11 24 18 + 14 10 0 20 23 20 23 25 11 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 0 15 24 10 10 24 + 24 24 24 31 31 25 26 26 0 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 15 23 10 19 25 14 27 12 31 + 23 15 19 25 31 24 23 19 0 25 24 26 23 31 10 27 24 + 24 24 24 31 31 0 18 21 29 24 28 23 25 28 10 21 19 + 24 24 10 18 11 27 20 31 18 19 25 14 26 24 27 25 21 + 19 25 25 25 10 24 26 31 15 31 19 24 20 23 30 24 14 + 30 31 27 21 23 15 0 24 24 27 10 12 24 31 12 21 15 + 28 10 10 0 15 27 15 28 10 27 15 11 19 24 0 15 27 + 12 25 25 31 23 24 12 24 10 15 14 24 25 10 27 25 12 + 31 19 15 10 30 14 10 14 10 28 23 19 10 20 16 31 27 + + 17 10 11 24 23 24 16 12 24 11 20 15 11 11 15 18 20 + 24 12 12 23 12 23 24 20 19 24 24 23 24 11 12 14 24 + 24 24 21 24 24 23 24 24 24 23 24 12 20 24 16 23 20 + 12 14 12 16 23 24 21 20 24 24 16 23 24 24 15 20 23 + 24 24 15 11 24 24 24 15 24 16 24 23 24 21 24 24 24 + 24 24 24 24 24 10 24 23 10 24 24 24 0 16 24 11 14 + 18 24 10 0 10 12 10 14 24 24 24 24 24 24 24 24 12 + 24 24 18 24 24 24 24 10 18 18 18 19 14 24 14 23 10 + 21 15 14 12 11 16 19 24 14 21 24 23 21 16 24 24 10 + 11 11 17 23 24 14 15 15 23 23 23 15 15 15 22 18 23 + 10 23 15 24 18 23 15 23 23 19 23 23 12 18 19 20 23 + 10 23 23 12 23 10 15 24 23 14 11 15 0 23 24 16 12 + 23 10 12 23 23 23 14 12 23 10 20 10 14 21 24 12 19 + 12 19 23 14 23 16 12 23 14 23 15 18 15 12 16 14 15 + 24 14 12 14 23 17 15 24 23 24 23 12 19 6 23 15 18 + 23 23 16 12 11 16 23 11 11 18 24 20 11 23 21 19 23 + 20 23 24 23 21 18 20 20 24 19 16 23 19 11 23 24 16 + 21 14 19 23 14 10 20 10 24 21 18 11 14 23 16 15 20 + 23 23 23 23 23 18 23 18 24 20 11 23 24 12 15 24 16 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 0 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 15 14 15 23 25 23 12 15 22 11 14 11 11 11 21 12 23 + 21 5 10 20 10 16 21 23 18 23 23 18 23 11 18 20 23 + 23 23 19 23 23 21 23 23 23 20 23 16 14 23 23 21 14 + 10 20 6 12 25 21 18 14 23 23 12 20 25 21 20 23 20 + 23 23 13 15 23 23 22 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 6 12 0 12 20 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 12 15 21 20 15 14 21 21 14 + 15 15 15 25 25 20 21 21 20 24 24 21 21 21 20 23 25 + 14 24 21 21 12 25 21 25 16 18 18 20 18 12 23 14 25 + 12 18 18 18 25 14 13 23 20 20 15 21 12 25 21 23 14 + 21 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 18 + 16 18 18 10 16 23 10 25 12 18 20 12 21 16 23 20 13 + 23 20 18 20 18 15 21 25 18 25 20 16 18 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 18 16 + 23 20 21 20 15 23 14 23 21 23 12 16 18 15 20 21 23 + 15 20 18 25 12 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 1 11 25 23 + + 10 10 11 24 23 24 16 11 14 11 20 15 11 11 15 18 20 + 24 12 12 23 12 23 24 20 10 24 24 23 24 11 12 14 24 + 24 24 10 24 24 12 24 24 24 23 24 12 20 24 16 12 20 + 12 14 12 16 23 24 21 20 24 24 16 23 24 24 14 20 23 + 24 24 11 11 24 24 14 15 24 16 24 23 24 21 24 24 24 + 24 24 24 24 24 10 24 23 10 24 24 24 10 16 24 11 14 + 18 24 0 12 0 12 0 14 24 24 24 24 24 24 24 24 12 + 24 24 18 24 24 24 24 10 18 18 18 18 14 24 14 23 10 + 21 15 14 12 11 16 16 24 12 21 24 23 21 10 24 24 10 + 11 11 10 23 24 14 15 15 23 23 23 15 15 15 11 18 23 + 10 23 15 24 18 23 15 23 23 10 23 23 12 18 18 20 23 + 10 23 23 12 23 10 4 24 23 14 11 15 10 23 24 16 10 + 12 10 12 23 23 23 14 12 23 10 20 10 14 21 24 12 15 + 12 10 23 14 23 16 12 23 14 23 14 18 15 12 16 14 12 + 24 14 12 14 23 10 15 24 23 24 23 12 12 4 23 10 18 + 23 23 16 12 11 16 23 11 11 18 24 20 11 23 21 12 23 + 20 23 24 23 21 18 20 20 24 16 16 23 14 11 23 24 16 + 21 14 12 23 11 10 20 10 24 21 18 11 14 23 16 14 20 + 23 23 23 23 23 18 23 18 24 20 11 23 24 12 15 24 16 + + 17 11 12 24 24 24 15 12 24 10 18 14 10 10 16 16 21 + 23 12 12 23 11 21 23 21 19 24 24 23 24 10 14 15 24 + 24 24 21 24 24 23 24 24 24 23 24 12 18 24 18 23 18 + 11 15 12 15 24 23 20 18 24 24 15 23 24 23 15 21 23 + 24 24 15 12 24 24 24 14 24 15 24 24 24 23 24 24 24 + 24 24 24 24 24 11 24 23 11 24 24 24 10 15 24 12 12 + 16 23 10 12 10 12 0 0 24 24 24 24 24 24 24 24 12 + 24 24 20 24 24 24 24 11 20 16 16 20 12 23 12 24 11 + 23 16 15 14 10 18 19 23 14 20 23 23 20 16 23 23 11 + 12 12 17 24 24 15 16 16 23 23 23 16 16 16 22 20 24 + 11 23 16 23 16 24 16 24 21 19 23 23 14 16 20 18 24 + 10 23 21 14 24 11 15 24 23 15 12 16 10 24 23 18 12 + 23 11 12 24 24 23 12 11 23 11 21 0 15 23 23 11 19 + 12 19 23 12 21 18 12 24 14 23 15 16 16 12 18 15 15 + 24 15 14 15 23 17 16 24 23 24 23 12 19 10 23 15 16 + 23 24 18 11 10 15 23 12 12 20 23 18 12 24 20 19 21 + 21 23 23 23 20 20 18 21 23 19 15 21 19 12 23 23 18 + 20 15 19 24 14 11 18 11 23 20 16 12 15 23 18 15 18 + 24 23 23 23 23 16 23 16 23 21 10 23 23 12 14 24 18 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 6 21 11 10 28 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 6 11 24 12 11 27 24 12 + 21 25 20 15 31 10 13 12 11 11 15 6 31 10 25 28 0 + 11 11 23 24 11 11 24 16 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 6 24 11 11 11 23 15 11 24 18 + 14 10 23 20 23 20 23 25 0 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 6 12 24 10 10 24 + 24 24 24 31 31 25 26 26 6 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 11 23 10 13 25 14 27 12 31 + 23 10 13 25 31 24 23 13 6 25 24 26 23 31 10 27 24 + 24 24 24 31 31 6 18 21 29 24 28 23 25 28 10 21 16 + 24 24 10 18 11 27 20 31 18 13 25 14 26 24 27 25 21 + 13 25 25 25 10 24 26 31 10 31 13 24 20 23 30 24 14 + 30 31 27 21 23 15 6 24 24 27 10 12 24 31 12 21 11 + 28 4 10 6 12 27 12 28 10 27 15 11 18 24 6 10 27 + 12 25 25 31 23 24 12 24 10 12 14 24 25 10 27 25 12 + 31 13 9 10 30 14 10 14 10 28 23 13 10 20 16 31 27 + + 23 23 23 18 28 18 12 23 23 18 10 19 18 18 24 19 26 + 19 15 15 19 16 10 12 26 23 18 18 19 18 18 24 24 18 + 18 18 23 18 18 23 18 18 18 19 18 23 19 18 25 23 10 + 16 24 15 12 28 19 0 10 18 18 14 19 29 12 24 26 13 + 18 18 18 23 18 18 23 12 18 12 18 28 18 27 18 18 18 + 18 18 18 18 18 23 18 19 23 18 18 18 21 12 18 23 14 + 12 19 21 15 21 15 20 24 18 0 18 18 18 18 18 18 15 + 18 18 25 18 18 18 18 23 25 14 11 25 14 19 14 28 23 + 27 24 24 24 18 25 25 19 15 19 19 19 4 23 19 13 23 + 23 23 23 28 29 24 24 24 19 27 28 24 24 24 23 25 28 + 23 27 24 19 11 28 24 28 10 20 11 12 24 19 25 12 28 + 20 11 10 24 28 23 21 14 19 24 23 24 21 28 19 25 23 + 23 23 23 28 28 19 14 16 27 23 26 20 24 27 19 19 12 + 23 23 19 14 19 25 15 28 14 11 24 13 24 23 25 24 16 + 14 24 24 24 19 23 24 29 11 29 12 23 15 21 28 23 11 + 28 28 25 19 18 12 19 23 23 25 19 10 23 28 9 16 10 + 26 12 13 19 4 25 10 26 19 25 12 19 14 23 19 12 25 + 13 24 24 28 18 23 10 23 19 4 11 23 24 13 25 24 19 + 28 11 12 19 28 11 19 13 19 26 19 11 19 19 19 29 25 + + 12 12 12 23 24 23 14 12 12 9 16 15 8 8 18 15 23 + 23 11 11 23 10 20 23 23 12 23 23 21 23 4 15 16 23 + 23 23 12 23 23 12 23 23 23 23 23 15 16 23 20 12 16 + 10 16 11 14 24 23 18 16 23 23 14 23 24 23 16 23 23 + 23 23 0 12 23 23 12 12 23 14 23 24 23 23 23 23 23 + 23 23 23 23 23 12 23 23 12 23 23 23 15 14 23 12 12 + 15 23 11 11 11 11 15 16 23 23 0 23 23 23 23 23 11 + 23 23 21 23 23 23 23 12 21 15 15 21 12 23 12 24 12 + 23 18 16 15 4 20 20 23 11 18 23 23 18 12 23 23 12 + 12 12 12 24 24 16 18 18 23 23 24 18 18 18 12 21 24 + 15 23 18 23 15 24 18 24 20 10 21 23 15 15 21 16 24 + 10 21 20 15 24 12 11 23 23 16 12 18 15 24 23 20 12 + 12 15 15 24 24 23 12 10 23 15 23 15 16 23 23 15 12 + 15 12 21 12 20 20 11 24 12 21 16 15 18 14 20 16 10 + 23 16 15 16 21 12 18 24 21 24 23 14 11 11 24 12 15 + 24 24 20 15 9 14 23 12 12 21 23 16 12 24 18 10 20 + 23 23 23 23 18 21 16 23 23 20 14 20 12 12 23 23 20 + 18 16 15 24 0 12 16 12 23 18 15 12 16 21 20 16 16 + 24 21 23 21 24 15 21 15 23 23 15 21 23 15 15 24 20 + + 12 12 12 27 18 27 23 12 18 16 24 23 16 16 10 23 12 + 26 20 20 25 18 24 26 12 13 27 27 25 27 16 10 0 27 + 27 27 15 27 27 17 27 27 27 25 27 11 24 27 11 17 24 + 18 0 20 23 18 26 24 24 27 27 23 25 20 26 9 12 25 + 27 27 16 12 27 27 18 23 27 23 27 18 27 14 27 27 27 + 27 27 27 27 27 12 27 25 12 27 27 27 14 23 27 12 21 + 23 26 14 20 14 20 15 0 27 27 27 0 27 27 27 27 20 + 27 27 12 27 27 27 27 12 12 23 23 13 21 26 21 18 12 + 14 10 6 10 16 11 13 26 20 24 26 25 24 12 26 26 12 + 12 12 12 18 20 6 10 10 25 15 16 10 10 10 16 12 18 + 12 15 10 26 23 18 10 18 24 15 25 25 10 23 13 24 18 + 15 25 24 10 18 12 14 27 25 6 12 10 14 18 26 11 12 + 17 12 11 18 18 25 21 18 15 12 12 15 6 14 26 18 23 + 11 13 25 21 24 11 20 18 21 25 9 23 10 11 11 0 18 + 27 6 10 0 25 12 10 20 25 20 25 11 20 14 16 12 23 + 16 18 11 18 16 23 25 12 12 12 26 24 12 18 24 18 24 + 13 25 26 25 24 12 24 13 26 13 23 24 21 12 25 26 11 + 24 6 13 18 16 12 24 12 26 24 23 12 6 25 11 9 24 + 18 25 25 25 16 23 25 23 26 12 16 25 26 20 23 20 11 + + 12 12 12 27 18 27 23 12 12 16 24 23 16 16 15 23 15 + 26 20 20 25 18 24 26 12 12 27 27 25 27 16 15 9 27 + 27 27 12 27 27 12 27 27 27 25 27 15 24 27 15 12 24 + 18 9 20 23 18 26 24 24 27 27 23 25 20 26 0 12 25 + 27 27 16 12 27 27 12 23 27 23 27 18 27 14 27 27 27 + 27 27 27 27 27 12 27 25 12 27 27 27 15 23 27 12 21 + 23 26 14 20 14 20 15 9 27 27 27 27 0 27 27 27 20 + 27 27 12 27 27 27 27 12 15 23 23 12 21 26 21 18 12 + 14 15 15 15 16 11 11 26 20 24 26 25 24 12 26 26 12 + 12 12 12 18 20 15 10 10 25 15 16 10 10 15 12 15 18 + 15 15 10 26 23 18 10 18 24 15 25 25 10 23 12 24 18 + 15 25 24 15 18 12 14 27 25 15 12 15 15 18 26 11 12 + 12 15 15 18 18 25 21 18 15 15 15 15 15 14 26 18 23 + 15 12 25 21 24 11 20 18 21 25 0 23 10 11 11 9 18 + 27 15 15 9 25 12 10 20 25 20 25 11 20 14 16 12 23 + 16 18 15 18 16 23 25 12 12 15 26 24 12 18 24 18 24 + 12 25 26 25 24 15 24 12 26 11 23 24 21 12 25 26 15 + 24 15 10 18 16 12 24 12 26 24 23 12 15 25 15 0 24 + 18 25 25 25 16 23 25 23 26 12 16 25 26 20 23 20 11 + + 18 18 20 18 27 18 2 20 18 14 11 11 14 14 23 11 24 + 16 12 12 15 12 12 16 24 18 18 18 14 18 14 23 23 18 + 18 18 18 18 18 18 18 18 18 15 18 21 11 18 24 18 11 + 12 23 12 4 27 16 12 11 18 18 6 15 27 16 23 24 15 + 18 18 14 20 18 18 18 10 18 0 18 27 18 25 18 18 18 + 18 18 18 18 18 18 18 15 18 18 18 18 16 2 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 0 18 18 12 + 18 18 24 18 18 18 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 12 12 16 15 12 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 18 24 27 + 18 25 23 16 10 27 23 27 12 15 14 15 23 11 24 11 27 + 15 14 12 23 27 18 16 18 15 23 20 23 16 27 16 24 18 + 18 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 10 + 21 18 14 11 12 24 12 27 11 14 23 10 23 21 24 23 12 + 18 23 23 23 14 18 23 27 14 27 15 21 12 16 26 18 10 + 26 27 24 12 14 1 15 20 20 24 16 11 20 27 12 12 12 + 24 15 16 15 12 24 11 24 16 24 2 12 11 20 15 16 24 + 12 23 23 27 14 18 11 18 16 12 10 20 23 14 24 23 11 + 27 14 15 14 26 10 14 10 16 24 14 14 16 12 11 27 24 + + 21 21 23 15 28 15 11 23 21 16 1 12 16 16 24 10 25 + 14 14 14 12 15 11 14 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 21 15 15 15 12 15 23 10 15 24 21 1 + 15 24 14 11 28 14 10 0 15 15 11 12 28 14 24 25 12 + 15 15 16 23 15 15 21 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 0 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 10 14 12 10 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 21 25 28 + 21 27 24 14 10 28 24 28 11 18 12 12 23 10 25 3 28 + 18 12 11 23 28 21 20 15 12 24 23 24 20 28 14 24 21 + 21 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 12 + 23 21 12 12 11 24 14 28 12 12 24 10 24 23 24 24 15 + 15 24 23 24 12 21 24 28 12 28 12 23 14 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 1 23 28 10 15 11 + 25 12 14 12 10 25 4 25 14 24 11 11 12 23 12 14 24 + 10 24 23 28 16 21 1 21 14 10 10 23 24 12 24 24 10 + 28 12 12 12 27 10 12 10 14 25 16 12 14 14 12 28 24 + + 12 12 12 23 24 23 14 12 18 0 16 12 1 1 18 15 23 + 23 11 11 23 10 20 23 23 14 23 23 21 23 4 15 16 23 + 23 23 15 23 23 17 23 23 23 23 23 14 16 23 20 17 16 + 10 16 11 14 24 23 18 16 23 23 14 23 24 23 16 23 23 + 23 23 9 12 23 23 18 12 23 14 23 24 23 23 23 23 23 + 23 23 23 23 23 12 23 23 12 23 23 23 11 14 23 12 12 + 15 23 11 11 11 11 10 16 23 23 23 23 23 23 23 0 11 + 23 23 21 23 23 23 23 12 21 15 15 21 12 23 12 24 12 + 23 18 16 15 4 20 20 23 11 18 23 23 18 12 23 23 12 + 12 12 12 24 24 16 18 18 23 23 24 18 18 18 16 21 24 + 12 23 18 23 15 24 18 24 20 14 21 23 15 15 21 16 24 + 10 21 20 15 24 12 11 23 23 16 12 18 11 24 23 20 12 + 17 12 14 24 24 23 12 10 23 12 23 10 16 23 23 10 14 + 14 14 21 12 20 20 11 24 12 21 16 15 18 14 20 16 10 + 23 16 15 16 21 12 18 24 21 24 23 14 14 11 24 12 15 + 24 24 20 10 0 14 23 12 12 21 23 16 12 24 18 14 20 + 23 23 23 23 18 21 16 23 23 20 14 20 14 12 23 23 20 + 18 16 15 24 8 12 16 12 23 18 15 12 16 21 20 16 16 + 24 21 23 21 24 15 21 15 23 23 5 21 23 11 12 24 20 + + 17 14 15 23 25 23 12 15 24 11 14 11 11 11 21 12 23 + 21 6 11 20 10 16 21 23 19 23 23 18 23 11 18 20 23 + 23 23 21 23 23 23 23 23 23 20 23 16 14 23 23 23 14 + 10 20 8 12 25 21 19 14 23 23 12 20 25 21 20 23 20 + 23 23 15 15 23 23 24 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 8 12 5 12 20 23 23 23 23 23 23 23 23 0 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 14 15 21 20 15 16 21 21 14 + 15 15 17 25 25 20 21 21 20 24 24 21 21 21 22 23 25 + 14 24 21 21 12 25 21 25 16 19 18 20 18 12 23 14 25 + 12 18 19 18 25 14 15 23 20 20 15 21 12 25 21 23 14 + 23 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 19 + 16 19 18 10 16 23 11 25 14 19 20 12 21 16 23 20 15 + 23 20 18 20 18 17 21 25 18 25 20 16 19 12 24 15 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 19 16 + 23 20 21 20 15 23 15 23 21 23 12 16 19 15 20 21 23 + 15 20 19 25 14 14 14 14 21 15 12 15 20 18 23 20 14 + 25 19 20 18 24 12 18 12 21 23 11 19 21 0 11 25 23 + + 10 10 11 24 23 24 16 11 14 11 20 15 11 11 15 18 20 + 24 12 12 23 12 23 24 20 10 24 24 23 24 11 12 14 24 + 24 24 10 24 24 12 24 24 24 23 24 12 20 24 16 12 20 + 12 14 12 16 23 24 21 20 24 24 16 23 24 24 14 20 23 + 24 24 11 11 24 24 14 15 24 16 24 23 24 21 24 24 24 + 24 24 24 24 24 10 24 23 10 24 24 24 10 16 24 11 14 + 18 24 0 12 0 12 10 14 24 24 24 24 24 24 24 24 12 + 0 24 18 24 24 24 24 10 18 18 18 18 14 24 14 23 10 + 21 15 14 12 11 16 16 24 12 21 24 23 21 10 24 24 10 + 11 11 10 23 24 14 15 15 23 23 23 15 15 15 11 18 23 + 10 23 15 24 18 23 15 23 23 10 23 23 12 18 18 20 23 + 10 23 23 12 23 10 4 24 23 14 11 15 10 23 24 16 10 + 12 10 12 23 23 23 14 12 23 10 20 10 14 21 24 12 15 + 12 10 23 14 23 16 12 23 14 23 14 18 15 12 16 14 12 + 24 14 12 14 23 10 15 24 23 24 23 12 12 4 23 10 18 + 23 23 16 12 11 16 23 11 11 18 24 20 11 23 21 12 23 + 20 23 24 23 21 18 20 20 24 16 16 23 14 11 23 24 16 + 21 14 12 23 11 10 20 10 24 21 18 11 14 23 16 14 20 + 23 23 23 23 23 18 23 18 24 20 11 23 24 12 15 24 16 + + 16 16 15 28 14 28 24 15 16 21 25 24 21 21 11 24 10 + 28 23 23 27 23 26 28 10 16 28 28 27 28 21 12 12 28 + 28 28 16 28 28 16 28 28 28 27 28 14 25 28 10 16 25 + 23 12 23 24 14 28 25 25 28 28 24 27 15 28 12 10 27 + 28 28 21 15 28 28 16 24 28 24 28 14 28 11 28 28 28 + 28 28 28 28 28 16 28 27 16 28 28 28 18 24 28 15 23 + 24 28 18 23 18 23 20 12 28 28 28 28 28 28 28 28 23 + 28 0 4 28 28 28 28 16 10 24 24 9 23 28 23 14 16 + 11 11 12 12 21 10 10 28 23 25 28 27 25 16 28 28 16 + 15 15 16 14 15 12 11 11 27 12 12 11 11 11 16 10 14 + 16 12 11 28 24 14 11 14 26 20 27 27 12 24 9 25 14 + 20 27 26 12 14 16 18 28 27 12 15 11 18 14 28 10 16 + 16 16 14 14 14 27 23 23 12 16 10 20 12 11 28 23 24 + 14 16 27 23 26 10 23 14 23 27 12 24 11 14 10 12 23 + 28 12 12 12 27 16 11 15 27 15 27 14 23 18 12 16 24 + 12 14 10 23 21 24 27 15 15 10 28 25 15 14 25 23 26 + 10 27 28 27 25 10 25 10 28 10 24 26 23 15 27 28 10 + 25 12 12 14 21 16 25 16 28 25 24 15 12 27 10 12 25 + 14 27 27 27 12 24 27 24 28 10 21 27 28 23 24 15 10 + + 23 23 23 33 15 33 27 23 24 24 28 27 24 24 18 28 14 + 31 25 25 31 25 30 31 14 23 33 33 31 33 24 21 20 33 + 33 33 23 33 33 23 33 33 33 31 33 23 28 33 16 23 28 + 25 20 25 27 10 31 29 28 33 33 27 31 6 31 20 15 31 + 33 33 24 23 33 33 24 27 33 27 33 10 33 12 33 33 33 + 33 33 33 33 33 23 33 31 23 33 33 33 24 27 33 23 26 + 28 31 24 25 24 25 24 20 33 33 33 33 33 33 33 33 25 + 33 33 0 33 33 33 33 23 15 28 28 19 26 31 26 10 23 + 15 18 20 21 24 16 19 31 25 29 31 31 29 23 31 31 23 + 23 23 23 10 6 20 18 18 31 12 15 18 18 18 23 15 10 + 23 12 18 31 28 10 18 10 30 24 31 31 21 28 19 28 19 + 24 31 30 21 10 23 24 33 31 20 23 18 24 10 31 16 23 + 23 23 23 10 15 31 26 25 12 23 14 24 20 15 31 25 27 + 23 23 31 26 30 16 25 10 26 31 20 28 18 23 16 20 25 + 33 20 21 20 31 23 18 10 31 10 31 23 25 24 11 23 28 + 15 10 16 25 24 27 31 23 23 15 31 28 23 10 29 25 30 + 19 31 31 31 29 15 28 19 31 19 27 30 26 23 31 31 16 + 29 20 21 10 24 23 28 23 31 29 28 23 20 31 16 20 28 + 10 31 31 31 15 28 31 28 31 15 24 31 31 25 27 15 16 + + 18 18 16 29 12 29 24 16 18 23 25 24 23 23 12 25 6 + 28 23 23 28 23 27 28 4 18 29 29 27 29 23 14 12 29 + 29 29 18 29 29 18 29 29 29 28 29 15 25 29 11 18 25 + 23 12 23 24 12 28 26 25 29 29 24 28 14 28 12 9 28 + 29 29 23 16 29 29 18 24 29 24 29 12 29 10 29 29 29 + 29 29 29 29 29 18 29 28 18 29 29 29 20 24 29 16 24 + 25 28 20 23 20 23 21 12 29 29 29 29 29 29 29 29 23 + 29 29 10 0 29 29 29 18 10 25 25 13 24 28 24 12 18 + 10 12 12 14 23 11 13 28 23 26 28 28 26 18 28 28 18 + 16 16 18 12 14 12 12 12 28 11 12 12 12 12 18 10 12 + 18 11 12 28 25 12 12 12 27 21 27 28 14 25 13 25 13 + 21 27 27 14 12 18 20 29 28 12 16 12 20 12 28 11 18 + 18 18 15 12 12 28 24 23 11 18 6 21 12 10 28 23 24 + 15 18 27 24 27 11 23 12 24 27 12 25 12 15 11 12 23 + 29 12 14 12 27 18 12 14 27 14 28 15 23 20 12 18 25 + 12 12 11 23 23 24 28 16 16 10 28 25 16 12 26 23 27 + 13 28 28 28 26 10 25 13 28 13 24 27 24 16 28 28 11 + 26 12 14 12 23 18 25 18 28 26 25 16 12 27 11 12 25 + 12 27 28 27 12 25 27 25 28 9 23 27 28 23 24 14 11 + + 18 18 16 29 12 29 24 16 18 23 25 24 23 23 12 25 10 + 28 23 23 28 23 27 28 0 18 29 29 27 29 23 14 12 29 + 29 29 18 29 29 18 29 29 29 28 29 15 25 29 11 18 25 + 23 12 23 24 12 28 26 25 29 29 24 28 14 28 12 4 28 + 29 29 23 16 29 29 18 24 29 24 29 12 29 10 29 29 29 + 29 29 29 29 29 18 29 28 18 29 29 29 20 24 29 16 24 + 25 28 20 23 20 23 21 12 29 29 29 29 29 29 29 29 23 + 29 29 10 29 0 29 29 18 10 25 25 10 24 28 24 12 18 + 10 12 12 14 23 11 11 28 23 26 28 28 26 18 28 28 18 + 16 16 18 12 14 12 12 12 28 11 12 12 12 12 18 10 12 + 18 11 12 28 25 12 12 12 27 21 27 28 14 25 10 25 12 + 21 27 27 14 12 18 20 29 28 12 16 12 20 12 28 11 18 + 18 18 15 12 12 28 24 23 11 18 10 21 12 10 28 23 24 + 15 18 27 24 27 11 23 12 24 27 12 25 12 15 11 12 23 + 29 12 14 12 27 18 12 14 27 14 28 15 23 20 12 18 25 + 12 12 11 23 23 24 28 16 16 10 28 25 16 12 26 23 27 + 9 28 28 28 26 10 25 9 28 11 24 27 24 16 28 28 11 + 26 12 14 12 23 18 25 18 28 26 25 16 12 27 11 12 25 + 12 27 28 27 12 25 27 25 28 4 23 27 28 23 24 14 11 + + 18 18 20 18 27 18 0 20 18 14 11 10 14 14 23 10 24 + 16 12 12 15 12 12 16 24 18 18 18 14 18 14 23 23 18 + 18 18 18 18 18 18 18 18 18 15 18 21 11 18 24 18 11 + 12 23 12 2 27 16 12 11 18 18 3 15 27 16 23 24 15 + 18 18 14 20 18 18 18 10 18 2 18 27 18 25 18 18 18 + 18 18 18 18 18 18 18 15 18 18 18 18 16 0 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 18 18 18 12 + 18 18 24 18 18 0 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 12 12 16 15 12 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 18 24 27 + 18 25 23 16 10 27 23 27 12 15 14 15 23 10 24 11 27 + 15 14 12 23 27 18 16 18 15 23 20 23 16 27 16 24 18 + 18 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 10 + 21 18 14 11 12 24 12 27 11 14 23 10 23 21 24 23 12 + 18 23 23 23 14 18 23 27 14 27 15 21 12 16 26 18 10 + 26 27 24 12 14 1 15 20 20 24 16 11 20 27 12 12 12 + 24 15 16 15 12 24 11 24 16 24 0 12 11 20 15 16 24 + 12 23 23 27 14 18 11 18 16 12 10 20 23 14 24 23 11 + 27 14 15 14 26 10 14 10 16 24 14 14 16 12 10 27 24 + + 18 18 16 29 12 29 24 16 18 23 25 24 23 23 19 25 19 + 28 23 23 28 23 27 28 9 18 29 29 27 29 23 19 13 29 + 29 29 18 29 29 18 29 29 29 28 29 19 25 29 19 18 25 + 23 13 23 24 19 28 26 25 29 29 24 28 14 28 12 4 28 + 29 29 23 16 29 29 18 24 29 24 29 19 29 10 29 29 29 + 29 29 29 29 29 18 29 28 18 29 29 29 20 24 29 16 24 + 25 28 20 23 20 23 21 13 29 29 29 29 29 29 29 29 23 + 29 29 13 29 29 29 0 18 19 25 25 10 24 28 24 19 18 + 10 19 19 19 23 11 11 28 23 26 28 28 26 18 28 28 18 + 16 16 18 19 14 19 12 12 28 19 12 12 12 19 18 19 19 + 19 14 14 28 25 19 12 19 27 21 27 28 14 25 10 25 12 + 21 27 27 19 19 18 20 29 28 19 16 19 20 19 28 14 18 + 18 19 19 19 12 28 24 23 19 19 19 21 19 10 28 23 24 + 19 18 27 24 27 11 23 19 24 27 12 25 12 15 11 13 23 + 29 19 19 13 27 18 12 14 27 14 28 15 23 20 13 18 25 + 12 13 19 23 23 24 28 16 16 19 28 25 16 19 26 23 27 + 0 28 28 28 26 19 25 0 28 11 24 27 24 16 28 28 19 + 26 19 14 19 23 18 25 18 28 26 25 16 19 27 19 12 25 + 19 27 28 27 12 25 27 25 28 4 23 27 28 23 24 14 11 + + 15 4 10 24 23 24 18 11 22 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 18 24 24 23 24 12 12 12 24 + 24 24 19 24 24 21 24 24 24 24 24 11 21 24 15 21 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 13 18 24 + 24 24 13 10 24 24 22 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 5 24 24 9 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 0 16 20 20 18 15 24 15 23 7 + 20 14 12 12 12 15 18 24 14 23 24 24 23 14 24 24 4 + 10 10 15 23 23 12 14 14 24 21 23 14 14 14 20 16 23 + 1 21 14 24 20 23 14 23 23 18 23 24 12 20 18 21 23 + 11 23 23 12 23 9 13 24 24 12 10 14 10 23 24 15 11 + 21 1 11 23 23 24 15 12 21 1 18 11 12 20 24 12 18 + 11 18 23 15 23 15 14 23 15 23 13 20 14 11 15 12 13 + 24 12 12 12 23 15 14 23 23 23 24 11 18 10 23 13 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 18 23 + 18 24 24 24 23 16 21 18 24 18 18 23 18 10 24 24 15 + 23 12 18 23 12 7 21 5 24 23 20 10 12 23 15 13 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 0 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 20 20 21 16 27 16 10 21 21 15 10 11 15 15 24 3 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 20 16 16 20 16 16 16 14 16 23 10 16 24 20 10 + 14 23 12 10 27 15 16 10 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 21 11 16 10 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 20 16 16 16 18 10 16 21 12 + 3 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 0 6 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 12 11 15 14 12 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 20 24 27 + 20 26 24 15 9 27 24 27 12 16 12 16 23 3 24 10 27 + 16 12 16 23 27 20 18 16 14 23 21 24 18 27 15 24 20 + 20 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 16 + 23 20 12 12 12 24 12 27 12 16 23 3 24 23 24 23 14 + 16 23 23 23 12 20 24 28 12 28 16 23 16 18 27 20 7 + 27 27 24 14 15 10 14 21 21 24 15 10 21 27 11 16 12 + 25 14 15 14 12 24 12 25 15 24 10 12 16 21 14 15 24 + 11 23 23 27 15 20 10 20 15 12 6 21 23 12 24 23 10 + 27 16 14 12 27 5 12 3 15 25 15 16 15 12 11 28 24 + + 15 14 15 23 25 23 12 15 22 11 14 11 11 11 21 12 23 + 21 5 10 20 10 16 21 23 18 23 23 18 23 11 18 20 23 + 23 23 19 23 23 21 23 23 23 20 23 16 14 23 23 21 14 + 10 20 6 12 25 21 18 14 23 23 12 20 25 21 20 23 20 + 23 23 13 15 23 23 22 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 6 12 4 12 20 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 14 23 12 0 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 12 15 21 20 15 14 21 21 14 + 15 15 15 25 25 20 21 21 20 24 24 21 21 21 20 23 25 + 14 24 21 21 12 25 21 25 16 18 18 20 18 12 23 14 25 + 12 18 18 18 25 14 13 23 20 20 15 21 12 25 21 23 14 + 21 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 18 + 16 18 18 10 16 23 10 25 12 18 20 12 21 16 23 20 13 + 23 20 18 20 18 15 21 25 18 25 20 16 18 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 18 16 + 23 20 21 20 15 23 14 23 21 23 12 16 18 15 20 21 23 + 15 20 18 25 12 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 1 11 25 23 + + 17 16 15 28 15 28 24 15 24 21 25 24 21 21 11 24 10 + 28 23 23 27 23 26 28 10 19 28 28 27 28 21 12 12 28 + 28 28 21 28 28 23 28 28 28 27 28 14 25 28 10 23 25 + 23 12 23 24 14 28 25 25 28 28 24 27 15 28 15 15 27 + 28 28 21 15 28 28 24 24 28 24 28 14 28 11 28 28 28 + 28 28 28 28 28 16 28 27 16 28 28 28 18 24 28 15 23 + 24 28 18 23 18 23 20 12 28 28 28 28 28 28 28 28 23 + 28 28 6 28 28 28 28 16 0 24 24 0 23 28 23 14 16 + 15 11 12 12 21 15 19 28 23 25 28 27 25 16 28 28 16 + 15 15 17 14 15 12 11 11 27 12 15 12 11 11 22 0 14 + 16 12 11 28 24 14 12 14 26 20 27 27 12 24 19 25 19 + 20 27 26 12 14 16 18 28 27 12 15 11 18 14 28 10 16 + 23 16 14 14 15 27 23 23 12 16 10 20 12 15 28 23 24 + 14 19 27 23 26 15 23 14 23 27 15 24 11 14 15 12 23 + 28 12 12 12 27 17 15 15 27 15 27 14 23 18 12 16 24 + 15 14 10 23 21 24 27 15 15 0 28 25 15 14 25 23 26 + 19 27 28 27 25 0 25 19 28 19 24 26 23 15 27 28 10 + 25 12 19 14 21 16 25 16 28 25 24 15 12 27 10 15 25 + 14 27 27 27 15 24 27 24 28 15 21 27 28 23 24 15 10 + + 15 14 15 23 25 23 12 15 22 11 14 11 11 11 21 12 23 + 21 5 10 20 10 16 21 23 18 23 23 18 23 11 18 20 23 + 23 23 19 23 23 21 23 23 23 20 23 16 14 23 23 21 14 + 10 20 6 12 25 21 18 14 23 23 12 20 25 21 20 23 20 + 23 23 13 15 23 23 22 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 6 12 4 12 20 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 14 23 12 12 23 0 21 10 25 14 + 24 21 20 18 11 23 23 21 12 15 21 20 15 14 21 21 14 + 15 15 15 25 25 20 21 21 20 24 24 21 21 21 20 23 25 + 14 24 21 21 12 25 21 25 16 18 18 20 18 12 23 14 25 + 12 18 18 18 25 14 13 23 20 20 15 21 12 25 21 23 14 + 21 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 18 + 16 18 18 10 16 23 10 25 12 18 20 12 21 16 23 20 13 + 23 20 18 20 18 15 21 25 18 25 20 16 18 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 18 16 + 23 20 21 20 15 23 14 23 21 23 12 16 18 15 20 21 23 + 15 20 18 25 12 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 1 11 25 23 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 0 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 0 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 0 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 21 21 23 15 28 15 11 23 24 16 11 12 16 16 24 10 25 + 14 14 14 12 15 11 15 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 23 15 15 15 12 15 23 0 15 24 23 9 + 15 24 14 11 28 14 19 10 15 15 11 12 28 15 24 25 12 + 15 15 16 23 15 15 24 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 0 + 26 24 24 23 16 24 24 14 14 10 14 12 15 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 22 25 28 + 21 27 24 14 12 28 24 28 15 19 12 19 23 10 25 6 28 + 18 15 19 23 28 21 20 19 12 24 23 24 20 28 14 24 21 + 23 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 19 + 23 21 12 12 11 24 14 28 14 19 24 10 24 23 24 24 15 + 19 24 23 24 12 21 24 28 15 28 19 23 19 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 9 23 28 10 19 15 + 25 12 14 12 15 25 15 25 14 24 11 11 19 23 12 15 24 + 10 24 23 28 16 21 9 21 14 15 10 23 24 12 24 24 0 + 28 19 15 12 27 10 12 10 14 25 16 19 14 14 12 28 24 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 0 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 0 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 0 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 20 20 18 30 12 30 25 18 20 23 26 24 23 23 15 25 15 + 29 24 24 28 23 27 29 10 20 30 30 28 30 23 15 14 30 + 30 30 20 30 30 20 30 30 30 28 30 16 26 30 15 20 26 + 23 14 24 25 15 29 27 26 30 30 25 28 12 29 14 10 28 + 30 30 23 18 30 30 20 24 30 25 30 15 30 4 30 30 30 + 30 30 30 30 30 20 30 28 20 30 30 30 21 25 30 18 24 + 25 29 21 24 21 24 23 14 30 30 30 30 30 30 30 30 24 + 30 30 11 30 30 30 30 20 15 25 25 11 24 29 24 15 20 + 0 15 15 0 23 12 12 29 24 27 29 28 27 20 29 29 20 + 18 18 20 15 12 15 12 12 28 15 11 12 12 15 20 15 15 + 20 10 12 29 25 15 12 15 27 23 28 28 15 25 11 26 12 + 23 28 27 15 15 20 21 30 28 15 18 15 21 15 29 12 20 + 20 20 16 15 12 28 24 23 15 20 15 23 15 0 29 23 24 + 16 20 28 24 27 12 24 15 24 28 14 25 12 16 12 14 23 + 30 15 15 14 28 20 12 12 28 12 28 16 24 21 11 20 25 + 11 12 15 23 23 25 28 18 18 15 29 26 18 15 27 23 27 + 10 28 29 28 27 15 26 10 29 12 25 27 24 18 28 29 15 + 27 15 15 15 23 20 26 20 29 27 25 18 15 28 15 14 26 + 15 28 28 28 11 25 28 25 29 10 23 28 29 24 24 12 12 + + 17 12 11 26 20 26 23 12 24 15 23 21 15 15 11 23 14 + 25 18 18 25 16 24 25 14 19 26 26 24 26 15 0 10 26 + 26 26 21 26 26 23 26 26 26 25 26 10 23 26 12 23 23 + 16 10 18 23 20 25 24 23 26 26 23 25 21 25 15 15 25 + 26 26 15 11 26 26 24 21 26 23 26 20 26 15 26 26 26 + 26 26 26 26 26 12 26 25 12 26 26 26 12 23 26 11 20 + 23 25 12 18 12 18 14 10 26 26 26 26 26 26 26 26 18 + 26 26 12 26 26 26 26 12 12 23 23 19 20 25 20 20 12 + 15 11 10 0 0 15 19 25 18 24 25 25 24 16 25 25 12 + 11 11 17 20 21 10 11 11 25 16 18 12 11 11 22 12 20 + 12 16 11 25 23 20 12 20 24 19 24 25 10 23 19 23 20 + 14 24 24 0 20 12 15 26 25 10 11 11 12 20 25 12 12 + 23 12 10 20 20 25 20 16 16 12 14 14 10 15 25 16 21 + 10 19 24 20 24 15 18 20 20 24 15 23 11 10 15 10 16 + 26 10 0 10 24 17 15 21 24 21 25 10 19 12 18 15 23 + 18 20 12 16 15 23 25 11 11 12 25 23 11 20 24 19 24 + 19 25 25 25 24 12 23 19 25 19 23 24 20 11 25 25 12 + 24 10 19 20 15 12 23 12 25 24 23 11 10 24 12 15 23 + 20 24 25 24 18 23 24 23 25 15 15 24 25 18 21 21 12 + + 17 14 12 27 16 27 23 12 24 18 24 23 18 18 0 24 12 + 27 21 21 26 20 25 27 12 19 27 27 25 27 18 11 10 27 + 27 27 21 27 27 23 27 27 27 26 27 12 24 27 10 23 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 15 15 26 + 27 27 18 12 27 27 24 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 19 23 27 23 16 14 + 15 0 10 11 18 0 19 27 21 24 27 26 24 16 27 27 14 + 12 12 17 16 18 10 10 10 26 14 15 12 10 0 22 11 16 + 14 14 5 27 24 16 12 16 25 19 25 26 11 24 19 24 19 + 16 25 25 11 16 14 15 27 26 10 12 0 15 16 27 10 14 + 23 14 12 16 16 26 23 20 14 14 12 16 10 15 27 20 23 + 12 19 25 23 25 15 21 16 23 25 15 24 10 12 15 10 20 + 27 10 11 10 25 17 15 18 25 18 26 12 21 15 15 15 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 19 26 27 26 24 11 24 19 27 19 23 25 23 12 26 27 10 + 24 10 19 16 18 14 24 14 27 24 24 12 10 25 10 15 24 + 16 25 26 25 15 24 25 24 27 15 18 25 27 21 23 18 10 + + 17 12 12 27 18 27 23 12 24 16 24 23 16 16 10 23 12 + 26 20 20 25 18 24 26 12 19 27 27 25 27 16 10 6 27 + 27 27 21 27 27 23 27 27 27 25 27 11 24 27 11 23 24 + 18 6 20 23 18 26 24 24 27 27 23 25 20 26 15 15 25 + 27 27 16 12 27 27 24 23 27 23 27 18 27 14 27 27 27 + 27 27 27 27 27 12 27 25 12 27 27 27 14 23 27 12 21 + 23 26 14 20 14 20 15 6 27 27 27 27 27 27 27 27 20 + 27 27 12 27 27 27 27 12 12 23 23 19 21 26 21 18 12 + 15 10 0 10 16 15 0 26 20 24 26 25 24 16 26 26 12 + 12 12 17 18 20 0 10 10 25 15 16 12 10 10 22 12 18 + 12 15 10 26 23 18 12 18 24 19 25 25 10 23 19 24 19 + 15 25 24 10 18 12 15 27 25 0 12 10 14 18 26 11 12 + 23 12 11 18 18 25 21 18 15 12 12 15 0 15 26 18 23 + 11 19 25 21 24 15 20 18 21 25 15 23 10 11 15 6 18 + 27 0 10 6 25 17 15 20 25 20 25 11 20 14 16 15 23 + 16 18 11 18 16 23 25 12 12 12 26 24 12 18 24 19 24 + 19 25 26 25 24 12 24 19 26 19 23 24 21 12 25 26 11 + 24 0 19 18 16 12 24 12 26 24 23 12 0 25 11 15 24 + 18 25 25 25 16 23 25 23 26 15 16 25 26 20 23 20 11 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 0 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 0 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 0 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 0 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 15 15 14 28 15 28 24 14 15 20 24 23 20 20 15 24 15 + 27 23 23 27 21 25 27 11 15 28 28 26 28 20 15 11 28 + 28 28 15 28 28 15 28 28 28 27 28 15 24 28 15 15 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 11 11 27 + 28 28 20 14 28 28 15 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 28 27 15 28 28 28 16 24 28 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 15 24 24 10 23 27 23 15 15 + 12 15 15 15 20 0 4 27 23 25 27 0 25 15 27 27 15 + 14 14 15 15 16 15 10 10 27 15 14 10 10 15 15 15 15 + 15 12 10 27 24 15 10 15 25 18 26 27 12 24 10 24 15 + 18 26 25 15 15 15 16 28 27 15 14 15 16 15 27 9 15 + 15 15 15 15 15 27 23 21 15 15 15 18 15 12 27 21 23 + 15 15 26 23 25 0 23 15 23 26 11 24 10 12 0 11 21 + 28 15 15 11 26 15 10 16 26 16 27 12 23 16 14 15 24 + 14 15 15 21 20 24 27 14 14 15 27 24 14 15 25 21 25 + 11 27 27 27 25 15 24 11 27 4 24 25 23 14 27 27 15 + 25 15 12 15 20 15 24 15 27 25 24 14 15 26 15 11 24 + 15 26 27 26 14 24 26 24 27 11 20 26 27 23 23 16 4 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 0 21 11 15 28 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 0 11 24 12 11 27 24 12 + 21 25 20 15 31 10 19 12 11 11 15 0 31 15 25 28 6 + 11 11 23 24 11 11 24 16 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 0 24 11 11 11 23 15 11 24 18 + 14 10 23 20 23 20 23 25 11 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 0 0 24 10 10 24 + 24 24 24 31 31 25 26 26 0 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 15 23 10 19 25 14 27 12 31 + 23 15 19 25 31 24 23 19 0 25 24 26 23 31 10 27 24 + 24 24 24 31 31 0 18 21 29 24 28 23 25 28 10 21 19 + 24 24 10 18 11 27 20 31 18 19 25 14 26 24 27 25 21 + 19 25 25 25 10 24 26 31 15 31 19 24 20 23 30 24 14 + 30 31 27 21 23 15 0 24 24 27 10 12 24 31 12 21 15 + 28 10 10 0 15 27 15 28 10 27 15 11 19 24 0 15 27 + 12 25 25 31 23 24 12 24 10 15 14 24 25 10 27 25 12 + 31 19 15 10 30 14 10 14 10 28 23 19 10 20 16 31 27 + + 17 5 11 24 23 24 18 12 24 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 19 24 24 23 24 12 12 12 24 + 24 24 21 24 24 23 24 24 24 24 24 11 21 24 15 23 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 15 18 24 + 24 24 15 10 24 24 24 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 6 24 24 10 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 5 16 20 20 19 15 24 15 23 9 + 20 14 12 12 12 15 19 24 14 23 24 24 23 0 24 24 5 + 10 10 17 23 23 12 14 14 24 21 23 14 14 14 22 16 23 + 0 21 14 24 20 23 14 23 23 19 23 24 12 20 19 21 23 + 11 23 23 12 23 10 15 24 24 12 10 14 10 23 24 15 12 + 23 0 11 23 23 24 15 12 21 0 18 11 12 20 24 12 19 + 11 19 23 15 23 15 14 23 15 23 15 20 14 11 15 12 15 + 24 12 12 12 23 17 15 23 23 23 24 11 19 10 23 15 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 19 23 + 19 24 24 24 23 16 21 19 24 19 18 23 19 10 24 24 15 + 23 12 19 23 14 9 21 6 24 23 20 10 12 23 15 15 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 15 15 16 21 25 21 11 16 16 12 12 10 12 12 23 12 24 + 20 10 10 18 11 15 20 24 15 21 21 16 21 12 20 21 21 + 21 21 15 21 21 15 21 21 21 18 21 18 12 21 23 15 12 + 11 21 10 11 25 20 14 12 21 21 11 18 26 20 21 24 18 + 21 21 12 16 21 21 16 10 21 11 21 25 21 24 21 21 21 + 21 21 21 21 21 15 21 18 15 21 21 21 14 11 21 16 1 + 12 20 14 10 14 10 12 21 21 21 21 21 21 21 21 21 10 + 21 21 23 21 21 21 21 15 23 12 12 23 1 20 0 25 15 + 24 23 21 20 12 23 23 20 10 14 20 18 14 15 0 20 15 + 16 16 15 25 26 21 23 23 18 24 25 23 23 23 15 23 25 + 15 24 23 20 12 25 23 25 15 12 16 18 20 12 23 12 25 + 12 16 15 20 25 15 14 21 18 21 16 23 14 25 20 23 15 + 15 15 18 25 25 18 0 11 24 15 24 12 21 24 20 11 11 + 18 15 16 2 15 23 10 25 6 16 21 12 23 18 23 21 11 + 21 21 20 21 16 15 23 26 16 26 18 18 11 14 25 15 12 + 25 25 23 11 12 11 18 16 16 23 20 12 16 25 14 11 15 + 24 18 20 18 14 23 12 24 20 23 11 15 11 16 18 20 23 + 14 21 20 25 12 15 12 15 20 14 12 16 21 16 23 21 12 + 25 16 18 16 25 12 16 12 20 24 12 16 20 10 10 26 23 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 0 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 14 2 10 24 23 24 18 10 21 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 16 24 24 23 24 12 12 12 24 + 24 24 18 24 24 20 24 24 24 24 24 11 21 24 15 20 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 12 18 24 + 24 24 12 10 24 24 21 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 3 24 24 7 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 2 16 20 20 16 15 24 15 23 6 + 20 14 12 12 12 15 16 24 14 23 24 24 23 13 24 24 0 + 10 10 14 23 23 12 14 14 24 21 23 14 14 14 19 16 23 + 3 21 14 24 20 23 14 23 23 16 23 24 12 20 16 21 23 + 11 23 23 12 23 7 12 24 24 12 10 14 10 23 24 15 9 + 20 3 11 23 23 24 15 12 21 3 18 11 12 20 24 12 16 + 11 16 23 15 23 15 14 23 15 23 12 20 14 11 15 12 12 + 24 12 12 12 23 14 14 23 23 23 24 11 16 10 23 12 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 16 23 + 18 24 24 24 23 16 21 18 24 16 18 23 16 10 24 24 15 + 23 12 16 23 12 6 21 3 24 23 20 10 12 23 15 12 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 14 10 8 25 23 25 20 9 21 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 16 25 25 24 25 12 11 12 25 + 25 25 18 25 25 20 25 25 25 24 25 10 23 25 14 20 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 12 16 24 + 25 25 12 7 25 25 21 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 7 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 16 16 24 16 23 10 + 18 12 12 11 12 14 16 24 15 23 24 24 23 13 24 24 10 + 0 6 14 23 23 12 12 12 24 20 21 12 12 12 19 15 23 + 10 20 12 24 21 23 12 23 23 16 24 24 11 21 16 23 23 + 12 24 23 11 23 10 12 25 24 12 7 12 11 23 24 14 10 + 20 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 16 24 16 23 14 15 23 16 24 12 21 12 10 14 12 14 + 25 12 11 12 24 14 12 23 24 23 24 10 16 11 21 12 21 + 21 23 14 14 12 20 24 6 3 15 24 23 2 23 23 16 23 + 16 24 24 24 23 15 23 16 24 16 20 23 16 5 24 24 14 + 23 12 16 23 12 10 23 10 24 23 21 6 12 24 14 12 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 14 10 8 25 23 25 20 9 21 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 16 25 25 24 25 12 11 12 25 + 25 25 18 25 25 20 25 25 25 24 25 10 23 25 14 20 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 12 16 24 + 25 25 12 7 25 25 21 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 7 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 16 16 24 16 23 10 + 18 12 12 11 12 14 16 24 15 23 24 24 23 13 24 24 10 + 2 0 14 23 23 12 12 12 24 20 21 12 12 12 19 15 23 + 10 20 12 24 21 23 12 23 23 16 24 24 11 21 16 23 23 + 12 24 23 11 23 10 12 25 24 12 7 12 11 23 24 14 10 + 20 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 16 24 16 23 14 15 23 16 24 12 21 12 10 14 12 14 + 25 12 11 12 24 14 12 23 24 23 24 10 16 11 21 12 21 + 21 23 14 14 12 20 24 6 3 15 24 23 2 23 23 16 23 + 16 24 24 24 23 15 23 16 24 16 20 23 16 5 24 24 14 + 23 12 16 23 12 10 23 10 24 23 21 6 12 24 14 12 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 17 5 11 24 23 24 18 12 24 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 19 24 24 23 24 12 12 12 24 + 24 24 21 24 24 23 24 24 24 24 24 11 21 24 15 23 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 15 18 24 + 24 24 15 10 24 24 24 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 6 24 24 10 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 5 16 20 20 19 15 24 15 23 9 + 20 14 12 12 12 15 19 24 14 23 24 24 23 16 24 24 5 + 10 10 0 23 23 12 14 14 24 21 23 14 14 14 22 16 23 + 0 21 14 24 20 23 14 23 23 19 23 24 12 20 19 21 23 + 11 23 23 12 23 10 15 24 24 12 10 14 10 23 24 15 12 + 23 0 11 23 23 24 15 12 21 0 18 11 12 20 24 12 19 + 11 19 23 15 23 15 14 23 15 23 15 20 14 11 15 12 15 + 24 12 12 12 23 17 15 23 23 23 24 11 19 10 23 15 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 19 23 + 19 24 24 24 23 16 21 19 24 19 18 23 19 10 24 24 15 + 23 12 19 23 14 9 21 6 24 23 20 10 12 23 15 15 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 23 23 23 31 0 31 27 23 23 24 28 26 24 24 16 27 15 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 15 31 28 28 31 31 27 31 10 31 18 12 31 + 31 31 24 23 31 31 23 26 31 27 31 15 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 15 27 27 14 25 31 25 15 23 + 12 16 18 20 24 15 15 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 15 10 16 16 16 23 15 15 + 23 11 16 31 27 15 16 15 29 24 30 31 20 27 14 28 4 + 24 30 29 20 15 23 23 31 31 18 23 16 23 15 31 15 23 + 23 23 21 15 0 31 25 24 15 23 15 24 18 12 31 24 26 + 21 23 30 25 29 15 25 15 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 10 9 15 24 24 27 31 23 23 15 31 28 23 15 28 24 29 + 12 31 31 31 28 15 28 12 31 15 27 29 25 23 31 31 15 + 28 18 20 15 24 23 28 23 31 28 27 23 18 30 15 18 28 + 15 30 31 30 10 27 30 27 31 12 24 30 31 25 26 10 15 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 0 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 0 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 15 14 12 27 16 27 23 12 22 18 24 23 18 18 1 24 12 + 27 21 21 26 20 25 27 12 18 27 27 25 27 18 11 10 27 + 27 27 19 27 27 21 27 27 27 26 27 12 24 27 10 21 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 13 13 26 + 27 27 18 12 27 27 22 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 18 23 27 23 16 14 + 13 1 10 11 18 13 18 27 21 24 27 26 24 14 27 27 14 + 12 12 15 16 18 10 0 9 26 14 15 11 9 1 20 11 16 + 14 14 4 27 24 16 11 16 25 18 25 26 11 24 18 24 18 + 16 25 25 11 16 14 15 27 26 10 12 1 15 16 27 10 14 + 21 14 12 16 16 26 23 20 14 14 12 16 10 13 27 20 23 + 12 18 25 23 25 13 21 16 23 25 13 24 8 12 13 10 20 + 27 10 11 10 25 15 13 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 18 26 27 26 24 11 24 18 27 18 23 25 23 12 26 27 10 + 24 10 18 16 18 14 24 14 27 24 24 12 10 25 10 13 24 + 16 25 26 25 15 24 25 24 27 13 18 25 27 21 23 18 10 + + 14 14 12 27 16 27 23 12 21 18 24 23 18 18 3 24 12 + 27 21 21 26 20 25 27 12 16 27 27 25 27 18 11 10 27 + 27 27 18 27 27 20 27 27 27 26 27 12 24 27 10 20 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 12 12 26 + 27 27 18 12 27 27 21 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 16 23 27 23 16 14 + 12 3 10 11 18 12 16 27 21 24 27 26 24 14 27 27 14 + 12 12 14 16 18 10 7 0 26 14 15 9 7 3 19 11 16 + 14 14 2 27 24 16 9 16 25 16 25 26 11 24 16 24 16 + 16 25 25 11 16 14 15 27 26 10 12 3 15 16 27 10 14 + 20 14 12 16 16 26 23 20 14 14 12 16 10 12 27 20 23 + 12 16 25 23 25 12 21 16 23 25 12 24 7 12 12 10 20 + 27 10 11 10 25 14 12 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 16 26 27 26 24 11 24 16 27 16 23 25 23 12 26 27 10 + 24 10 16 16 18 14 24 14 27 24 24 12 10 25 10 12 24 + 16 25 26 25 15 24 25 24 27 12 18 25 27 21 23 18 10 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 0 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 23 23 21 31 10 31 26 21 23 24 27 25 24 24 15 27 15 + 31 24 24 30 24 28 31 12 23 31 31 29 31 24 18 16 31 + 31 31 23 31 31 23 31 31 31 30 31 20 27 31 15 23 27 + 24 16 24 26 15 31 28 27 31 31 26 30 11 31 16 12 30 + 31 31 24 21 31 31 23 25 31 26 31 15 31 11 31 31 31 + 31 31 31 31 31 23 31 30 23 31 31 31 23 26 31 21 25 + 27 31 23 24 23 24 23 16 31 31 31 31 31 31 31 31 24 + 31 31 12 31 31 31 31 23 15 27 27 12 25 31 25 15 23 + 11 15 16 18 24 14 14 31 24 28 31 30 28 23 31 31 23 + 21 21 23 15 11 16 15 15 30 0 0 15 15 15 23 15 15 + 23 10 15 31 27 15 15 15 28 23 29 30 18 27 12 27 10 + 23 29 28 18 15 23 23 31 30 16 21 15 23 15 31 14 23 + 23 23 20 15 10 30 25 24 15 23 15 23 16 11 31 24 25 + 20 23 29 25 28 14 24 15 25 29 16 27 15 20 14 16 24 + 31 16 18 16 29 23 15 11 29 11 30 20 24 23 9 23 27 + 0 10 15 24 24 26 30 21 21 15 31 27 21 15 28 24 28 + 12 30 31 30 28 15 27 12 31 14 26 28 25 21 30 31 15 + 28 16 18 15 24 23 27 23 31 28 27 21 16 29 15 16 27 + 15 29 30 29 0 27 29 27 31 12 24 29 31 24 25 11 14 + + 21 21 20 31 15 31 25 20 24 23 27 25 23 23 14 26 11 + 30 24 24 29 24 28 30 11 21 31 31 28 31 23 16 15 31 + 31 31 21 31 31 23 31 31 31 29 31 18 27 31 12 23 27 + 24 15 24 25 11 30 27 27 31 31 25 29 12 30 15 15 29 + 31 31 23 20 31 31 24 25 31 25 31 11 31 10 31 31 31 + 31 31 31 31 31 21 31 29 21 31 31 31 23 25 31 20 24 + 26 30 23 24 23 24 23 15 31 31 31 31 31 31 31 31 24 + 31 31 12 31 31 31 31 21 12 26 26 19 24 30 24 11 21 + 15 14 15 16 23 15 19 30 24 27 30 29 27 21 30 30 21 + 20 20 21 11 12 15 14 14 29 0 0 14 14 14 22 12 11 + 21 5 14 30 26 11 14 11 28 23 28 29 16 26 19 27 19 + 23 28 28 16 11 21 23 31 29 15 20 14 23 11 30 12 21 + 23 21 18 11 15 29 24 24 0 21 11 23 15 15 30 24 25 + 18 21 28 24 28 15 24 11 24 28 15 26 14 18 15 15 24 + 31 15 16 15 28 21 15 12 28 12 29 18 24 23 10 21 26 + 15 11 12 24 23 25 29 20 20 12 30 27 20 11 27 24 28 + 19 29 30 29 27 12 27 19 30 19 25 28 24 20 29 30 12 + 27 15 19 11 23 21 27 21 30 27 26 20 15 28 12 15 27 + 11 28 29 28 15 26 28 26 30 15 23 28 30 24 25 15 12 + + 14 14 12 27 16 27 23 12 21 18 24 23 18 18 3 24 12 + 27 21 21 26 20 25 27 12 16 27 27 25 27 18 11 10 27 + 27 27 18 27 27 20 27 27 27 26 27 12 24 27 10 20 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 12 12 26 + 27 27 18 12 27 27 21 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 16 23 27 23 16 14 + 12 3 10 11 18 12 16 27 21 24 27 26 24 14 27 27 14 + 12 12 14 16 18 10 7 7 26 14 15 0 7 3 19 11 16 + 14 14 2 27 24 16 9 16 25 16 25 26 11 24 16 24 16 + 16 25 25 11 16 14 15 27 26 10 12 3 15 16 27 10 14 + 20 14 12 16 16 26 23 20 14 14 12 16 10 12 27 20 23 + 12 16 25 23 25 12 21 16 23 25 12 24 7 12 12 10 20 + 27 10 11 10 25 14 12 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 16 26 27 26 24 11 24 16 27 16 23 25 23 12 26 27 10 + 24 10 16 16 18 14 24 14 27 24 24 12 10 25 10 12 24 + 16 25 26 25 15 24 25 24 27 12 18 25 27 21 23 18 10 + + 15 14 12 27 16 27 23 12 22 18 24 23 18 18 1 24 12 + 27 21 21 26 20 25 27 12 18 27 27 25 27 18 11 10 27 + 27 27 19 27 27 21 27 27 27 26 27 12 24 27 10 21 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 13 13 26 + 27 27 18 12 27 27 22 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 18 23 27 23 16 14 + 13 1 10 11 18 13 18 27 21 24 27 26 24 14 27 27 14 + 12 12 15 16 18 10 9 9 26 14 15 11 0 1 20 11 16 + 14 14 4 27 24 16 11 16 25 18 25 26 11 24 18 24 18 + 16 25 25 11 16 14 15 27 26 10 12 1 15 16 27 10 14 + 21 14 12 16 16 26 23 20 14 14 12 16 10 13 27 20 23 + 12 18 25 23 25 13 21 16 23 25 13 24 8 12 13 10 20 + 27 10 11 10 25 15 13 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 18 26 27 26 24 11 24 18 27 18 23 25 23 12 26 27 10 + 24 10 18 16 18 14 24 14 27 24 24 12 10 25 10 13 24 + 16 25 26 25 15 24 25 24 27 13 18 25 27 21 23 18 10 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 0 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 17 10 11 25 23 25 20 12 24 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 19 25 25 24 25 12 11 12 25 + 25 25 21 25 25 23 25 25 25 24 25 10 23 25 14 23 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 15 16 24 + 25 25 15 10 25 25 24 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 10 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 19 16 24 16 23 10 + 18 12 12 11 12 15 19 24 15 23 24 24 23 16 24 24 10 + 5 9 17 23 23 12 12 12 24 20 21 12 12 12 0 15 23 + 10 20 12 24 21 23 12 23 23 19 24 24 11 21 19 23 23 + 12 24 23 11 23 10 15 25 24 12 10 12 11 23 24 14 12 + 23 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 19 + 10 19 24 16 23 15 15 23 16 24 15 21 12 10 15 12 15 + 25 12 11 12 24 17 15 23 24 23 24 10 19 11 21 15 21 + 21 23 14 14 12 20 24 9 6 15 24 23 5 23 23 19 23 + 19 24 24 24 23 15 23 19 24 19 20 23 19 8 24 24 14 + 23 12 19 23 14 10 23 10 24 23 21 9 12 24 14 15 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 0 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 0 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 0 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 21 21 20 31 13 31 25 20 22 23 27 25 23 23 14 26 11 + 30 24 24 29 24 28 30 11 21 31 31 28 31 23 16 15 31 + 31 31 21 31 31 21 31 31 31 29 31 18 27 31 12 21 27 + 24 15 24 25 11 30 27 27 31 31 25 29 12 30 15 13 29 + 31 31 23 20 31 31 22 25 31 25 31 11 31 10 31 31 31 + 31 31 31 31 31 21 31 29 21 31 31 31 23 25 31 20 24 + 26 30 23 24 23 24 23 15 31 31 31 31 31 31 31 31 24 + 31 31 12 31 31 31 31 21 12 26 26 18 24 30 24 11 21 + 13 14 15 16 23 13 18 30 24 27 30 29 27 21 30 30 21 + 20 20 21 11 12 15 14 14 29 1 13 14 14 14 21 12 11 + 21 0 14 30 26 11 14 11 28 23 28 29 16 26 18 27 18 + 23 28 28 16 11 21 23 31 29 15 20 14 23 11 30 12 21 + 21 21 18 11 13 29 24 24 1 21 11 23 15 13 30 24 25 + 18 21 28 24 28 13 24 11 24 28 15 26 14 18 13 15 24 + 31 15 16 15 28 21 14 12 28 12 29 18 24 23 10 21 26 + 13 11 12 24 23 25 29 20 20 12 30 27 20 11 27 24 28 + 18 29 30 29 27 12 27 18 30 18 25 28 24 20 29 30 12 + 27 15 18 11 23 21 27 21 30 27 26 20 15 28 12 15 27 + 11 28 29 28 13 26 28 26 30 13 23 28 30 24 25 13 12 + + 14 14 12 27 16 27 23 12 21 18 24 23 18 18 3 24 12 + 27 21 21 26 20 25 27 12 16 27 27 25 27 18 11 10 27 + 27 27 18 27 27 20 27 27 27 26 27 12 24 27 10 20 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 12 12 26 + 27 27 18 12 27 27 21 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 16 23 27 23 16 14 + 12 3 10 11 18 12 16 27 21 24 27 26 24 14 27 27 14 + 12 12 14 16 18 10 7 7 26 14 15 9 7 3 19 11 16 + 14 14 0 27 24 16 9 16 25 16 25 26 11 24 16 24 16 + 16 25 25 11 16 14 15 27 26 10 12 3 15 16 27 10 14 + 20 14 12 16 16 26 23 20 14 14 12 16 10 12 27 20 23 + 12 16 25 23 25 12 21 16 23 25 12 24 7 12 12 10 20 + 27 10 11 10 25 14 12 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 16 26 27 26 24 11 24 16 27 16 23 25 23 12 26 27 10 + 24 10 16 16 18 14 24 14 27 24 24 12 10 25 10 12 24 + 16 25 26 25 15 24 25 24 27 12 18 25 27 21 23 18 10 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 0 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 15 12 11 26 20 26 23 11 22 15 23 21 15 15 11 23 14 + 25 18 18 25 16 24 25 14 18 26 26 24 26 15 1 10 26 + 26 26 19 26 26 21 26 26 26 25 26 10 23 26 12 21 23 + 16 10 18 23 20 25 24 23 26 26 23 25 21 25 13 14 25 + 26 26 15 11 26 26 22 21 26 23 26 20 26 15 26 26 26 + 26 26 26 26 26 12 26 25 12 26 26 26 12 23 26 11 20 + 23 25 12 18 12 18 14 10 26 26 26 26 26 26 26 26 18 + 26 26 12 26 26 26 26 12 12 23 23 18 20 25 20 20 12 + 15 11 10 1 15 13 18 25 18 24 25 25 24 14 25 25 12 + 11 11 15 20 21 10 11 11 25 16 18 11 11 11 20 12 20 + 12 16 11 25 0 20 11 20 24 18 24 25 8 23 18 23 20 + 14 24 24 1 20 12 13 26 25 10 11 11 12 20 25 12 12 + 21 12 10 20 20 25 20 16 16 12 14 14 10 15 25 16 21 + 10 18 24 20 24 13 18 20 20 24 13 23 11 10 13 10 16 + 26 10 1 10 24 15 13 21 24 21 25 10 18 12 18 13 23 + 18 20 12 16 15 23 25 11 11 12 25 23 11 20 24 18 24 + 18 25 25 25 24 12 23 18 25 18 23 24 20 11 25 25 12 + 24 10 18 20 15 12 23 12 25 24 23 11 10 24 12 13 23 + 20 24 25 24 18 23 24 23 25 14 15 24 25 18 21 21 12 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 0 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 15 14 12 27 16 27 23 12 22 18 24 23 18 18 1 24 12 + 27 21 21 26 20 25 27 12 18 27 27 25 27 18 11 10 27 + 27 27 19 27 27 21 27 27 27 26 27 12 24 27 10 21 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 13 13 26 + 27 27 18 12 27 27 22 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 18 23 27 23 16 14 + 13 1 10 11 18 13 18 27 21 24 27 26 24 14 27 27 14 + 12 12 15 16 18 10 9 9 26 14 15 11 9 1 20 11 16 + 14 14 4 27 24 16 0 16 25 18 25 26 11 24 18 24 18 + 16 25 25 11 16 14 15 27 26 10 12 1 15 16 27 10 14 + 21 14 12 16 16 26 23 20 14 14 12 16 10 13 27 20 23 + 12 18 25 23 25 13 21 16 23 25 13 24 8 12 13 10 20 + 27 10 11 10 25 15 13 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 18 26 27 26 24 11 24 18 27 18 23 25 23 12 26 27 10 + 24 10 18 16 18 14 24 14 27 24 24 12 10 25 10 13 24 + 16 25 26 25 15 24 25 24 27 13 18 25 27 21 23 18 10 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 0 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 23 23 23 14 28 14 12 23 24 18 11 12 18 18 24 11 26 + 12 15 15 12 16 10 15 26 23 14 14 11 14 18 24 24 14 + 14 14 23 14 14 23 14 14 14 12 14 23 10 14 25 23 10 + 16 24 15 12 28 12 19 10 14 14 12 12 29 15 24 26 12 + 14 14 18 23 14 14 24 12 14 12 14 28 14 27 14 14 14 + 14 14 14 14 14 23 14 12 23 14 14 14 21 12 14 23 14 + 11 12 21 15 21 15 20 24 14 14 14 14 14 14 14 14 15 + 14 14 25 14 14 14 14 23 25 11 11 25 14 12 14 28 23 + 27 24 24 24 18 25 25 12 15 0 12 12 15 23 12 12 23 + 23 23 23 28 29 24 24 24 12 27 28 24 24 24 23 25 28 + 23 27 24 12 12 28 24 28 0 20 11 19 24 11 25 10 28 + 20 15 19 24 28 23 21 19 12 24 23 24 21 28 12 25 23 + 23 23 23 28 28 12 14 16 27 23 26 20 24 27 12 16 19 + 23 23 11 14 10 25 15 28 14 19 24 11 24 23 25 24 16 + 19 24 24 24 11 23 24 29 15 29 19 23 19 21 28 23 11 + 28 28 25 16 18 12 12 23 23 25 12 10 23 28 10 19 15 + 26 12 12 12 15 25 15 26 12 25 12 10 19 23 12 15 25 + 6 24 24 28 18 23 10 23 12 15 11 23 24 11 25 24 10 + 28 19 15 11 28 11 11 11 12 26 18 19 12 15 12 29 25 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 0 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 17 12 12 27 18 27 23 12 24 16 24 23 16 16 10 23 12 + 26 20 20 25 18 24 26 12 19 27 27 25 27 16 10 6 27 + 27 27 21 27 27 23 27 27 27 25 27 11 24 27 11 23 24 + 18 6 20 23 18 26 24 24 27 27 23 25 20 26 15 15 25 + 27 27 16 12 27 27 24 23 27 23 27 18 27 14 27 27 27 + 27 27 27 27 27 12 27 25 12 27 27 27 14 23 27 12 21 + 23 26 14 20 14 20 15 6 27 27 27 27 27 27 27 27 20 + 27 27 12 27 27 27 27 12 12 23 23 19 21 26 21 18 12 + 15 10 0 10 16 15 19 26 20 24 26 25 24 16 26 26 12 + 12 12 17 18 20 0 10 10 25 15 16 12 10 10 22 12 18 + 12 15 10 26 23 18 12 18 24 19 0 25 10 23 19 24 19 + 15 25 24 10 18 12 15 27 25 0 12 10 14 18 26 11 12 + 23 12 11 18 18 25 21 18 15 12 12 15 0 15 26 18 23 + 11 19 25 21 24 15 20 18 21 25 15 23 10 11 15 6 18 + 27 0 10 6 25 17 15 20 25 20 25 11 20 14 16 15 23 + 16 18 11 18 16 23 25 12 12 12 26 24 12 18 24 19 24 + 19 25 26 25 24 12 24 19 26 19 23 24 21 12 25 26 11 + 24 0 19 18 16 12 24 12 26 24 23 12 0 25 11 15 24 + 18 25 25 25 16 23 25 23 26 15 16 25 26 20 23 20 11 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 0 21 11 15 28 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 0 11 24 12 11 27 24 12 + 21 25 20 15 31 10 19 12 11 11 15 0 31 15 25 28 6 + 11 11 23 24 11 11 24 16 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 0 24 11 11 11 23 15 11 24 18 + 14 10 23 20 23 20 23 25 11 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 0 15 24 10 10 24 + 24 24 24 31 31 25 26 26 0 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 15 23 10 0 25 14 27 12 31 + 23 15 19 25 31 24 23 19 0 25 24 26 23 31 10 27 24 + 24 24 24 31 31 0 18 21 29 24 28 23 25 28 10 21 19 + 24 24 10 18 11 27 20 31 18 19 25 14 26 24 27 25 21 + 19 25 25 25 10 24 26 31 15 31 19 24 20 23 30 24 14 + 30 31 27 21 23 15 0 24 24 27 10 12 24 31 12 21 15 + 28 10 10 0 15 27 15 28 10 27 15 11 19 24 0 15 27 + 12 25 25 31 23 24 12 24 10 15 14 24 25 10 27 25 12 + 31 19 15 10 30 14 10 14 10 28 23 19 10 20 16 31 27 + + 17 14 12 27 16 27 23 12 24 18 24 23 18 18 0 24 12 + 27 21 21 26 20 25 27 12 19 27 27 25 27 18 11 10 27 + 27 27 21 27 27 23 27 27 27 26 27 12 24 27 10 23 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 15 15 26 + 27 27 18 12 27 27 24 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 19 23 27 23 16 14 + 15 0 10 11 18 15 19 27 21 24 27 26 24 16 27 27 14 + 12 12 17 16 18 10 10 10 26 14 15 12 10 0 22 11 16 + 14 14 5 27 24 16 12 16 25 19 25 26 0 24 19 24 19 + 16 25 25 11 16 14 15 27 26 10 12 0 15 16 27 10 14 + 23 14 12 16 16 26 23 20 14 14 12 16 10 15 27 20 23 + 12 19 25 23 25 15 21 16 23 25 15 24 10 12 15 10 20 + 27 10 11 10 25 17 15 18 25 18 26 12 21 15 15 15 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 19 26 27 26 24 11 24 19 27 19 23 25 23 12 26 27 10 + 24 10 19 16 18 14 24 14 27 24 24 12 10 25 10 15 24 + 16 25 26 25 15 24 25 24 27 15 18 25 27 21 23 18 10 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 0 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 17 16 15 28 15 28 24 15 24 21 25 24 21 21 11 24 10 + 28 23 23 27 23 26 28 10 19 28 28 27 28 21 12 12 28 + 28 28 21 28 28 23 28 28 28 27 28 14 25 28 10 23 25 + 23 12 23 24 14 28 25 25 28 28 24 27 15 28 15 15 27 + 28 28 21 15 28 28 24 24 28 24 28 14 28 11 28 28 28 + 28 28 28 28 28 16 28 27 16 28 28 28 18 24 28 15 23 + 24 28 18 23 18 23 20 12 28 28 28 28 28 28 28 28 23 + 28 28 6 28 28 28 28 16 0 24 24 19 23 28 23 14 16 + 15 11 12 12 21 15 19 28 23 25 28 27 25 16 28 28 16 + 15 15 17 14 15 12 11 11 27 12 15 12 11 11 22 0 14 + 16 12 11 28 24 14 12 14 26 20 27 27 12 24 0 25 19 + 20 27 26 12 14 16 18 28 27 12 15 11 18 14 28 10 16 + 23 16 14 14 15 27 23 23 12 16 10 20 12 15 28 23 24 + 14 19 27 23 26 15 23 14 23 27 15 24 11 14 15 12 23 + 28 12 12 12 27 17 15 15 27 15 27 14 23 18 12 16 24 + 15 14 10 23 21 24 27 15 15 0 28 25 15 14 25 23 26 + 19 27 28 27 25 0 25 19 28 19 24 26 23 15 27 28 10 + 25 12 19 14 21 16 25 16 28 25 24 15 12 27 10 15 25 + 14 27 27 27 15 24 27 24 28 15 21 27 28 23 24 15 10 + + 20 20 21 16 27 16 10 21 24 15 11 11 15 15 24 0 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 21 16 16 23 16 16 16 14 16 23 10 16 24 23 10 + 14 23 12 10 27 15 19 10 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 24 11 16 11 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 20 16 16 16 18 10 16 21 12 + 6 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 5 9 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 14 11 15 14 15 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 22 24 27 + 20 26 24 15 12 27 24 27 15 19 12 19 23 0 24 0 27 + 16 15 19 23 27 20 18 19 14 23 21 24 18 27 15 24 20 + 23 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 19 + 23 20 12 12 12 24 12 27 14 19 23 6 24 23 24 23 15 + 19 23 23 23 12 20 24 28 15 28 19 23 19 18 27 20 10 + 27 27 24 14 15 10 14 21 21 24 15 10 21 27 11 19 15 + 25 14 15 14 15 24 15 25 15 24 10 12 19 21 14 15 24 + 11 23 23 27 15 20 10 20 15 15 9 21 23 12 24 23 10 + 27 19 15 12 27 8 12 6 15 25 15 19 15 12 11 28 24 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 0 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 17 5 11 24 23 24 18 12 24 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 19 24 24 23 24 12 12 12 24 + 24 24 21 24 24 23 24 24 24 24 24 11 21 24 15 23 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 15 18 24 + 24 24 15 10 24 24 24 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 6 24 24 10 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 5 16 20 20 19 15 24 15 23 9 + 20 14 12 12 12 15 19 24 14 23 24 24 23 16 24 24 5 + 10 10 17 23 23 12 14 14 24 21 23 14 14 14 22 16 23 + 0 21 14 24 20 23 14 23 23 19 23 24 12 20 19 21 23 + 0 23 23 12 23 10 15 24 24 12 10 14 10 23 24 15 12 + 23 0 11 23 23 24 15 12 21 0 18 11 12 20 24 12 19 + 11 19 23 15 23 15 14 23 15 23 15 20 14 11 15 12 15 + 24 12 12 12 23 17 15 23 23 23 24 11 19 10 23 15 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 19 23 + 19 24 24 24 23 16 21 19 24 19 18 23 19 10 24 24 15 + 23 12 19 23 14 9 21 6 24 23 20 10 12 23 15 15 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 0 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 0 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 0 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 0 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 15 4 10 24 23 24 18 11 22 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 18 24 24 23 24 12 12 12 24 + 24 24 19 24 24 21 24 24 24 24 24 11 21 24 15 21 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 13 18 24 + 24 24 13 10 24 24 22 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 5 24 24 9 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 4 16 20 20 18 15 24 15 23 7 + 20 14 12 12 12 15 18 24 14 23 24 24 23 14 24 24 4 + 10 10 15 23 23 12 14 14 24 21 23 14 14 14 20 16 23 + 1 21 14 24 20 23 14 23 23 18 23 24 12 20 18 21 23 + 11 23 23 12 23 0 13 24 24 12 10 14 10 23 24 15 11 + 21 1 11 23 23 24 15 12 21 1 18 11 12 20 24 12 18 + 11 18 23 15 23 15 14 23 15 23 13 20 14 11 15 12 13 + 24 12 12 12 23 15 14 23 23 23 24 11 18 10 23 13 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 18 23 + 18 24 24 24 23 16 21 18 24 18 18 23 18 10 24 24 15 + 23 12 18 23 12 7 21 5 24 23 20 10 12 23 15 13 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 23 23 23 33 15 33 27 23 24 24 28 27 24 24 18 28 14 + 31 25 25 31 25 30 31 14 23 33 33 31 33 24 21 20 33 + 33 33 23 33 33 23 33 33 33 31 33 23 28 33 16 23 28 + 25 20 25 27 10 31 29 28 33 33 27 31 6 31 20 15 31 + 33 33 24 23 33 33 24 27 33 27 33 10 33 12 33 33 33 + 33 33 33 33 33 23 33 31 23 33 33 33 24 27 33 23 26 + 28 31 24 25 24 25 24 20 33 33 33 33 33 33 33 33 25 + 33 33 15 33 33 33 33 23 15 28 28 19 26 31 26 10 23 + 15 18 20 21 24 16 19 31 25 29 31 31 29 23 31 31 23 + 23 23 23 10 6 20 18 18 31 12 15 18 18 18 23 15 10 + 23 12 18 31 28 10 18 10 30 24 31 31 21 28 19 28 19 + 24 31 30 21 10 23 0 33 31 20 23 18 24 10 31 16 23 + 23 23 23 10 15 31 26 25 12 23 14 24 20 15 31 25 27 + 23 23 31 26 30 16 25 10 26 31 20 28 18 23 16 20 25 + 33 20 21 20 31 23 18 10 31 10 31 23 25 24 11 23 28 + 15 10 16 25 24 27 31 23 23 15 31 28 23 10 29 25 30 + 19 31 31 31 29 15 28 19 31 19 27 30 26 23 31 31 16 + 29 20 21 10 24 23 28 23 31 29 28 23 20 31 16 20 28 + 10 31 31 31 15 28 31 28 31 15 24 31 31 25 27 15 16 + + 23 23 23 33 15 33 27 23 24 24 28 27 24 24 18 28 14 + 31 25 25 31 25 30 31 14 23 33 33 31 33 24 21 20 33 + 33 33 23 33 33 23 33 33 33 31 33 23 28 33 16 23 28 + 25 20 25 27 10 31 29 28 33 33 27 31 6 31 20 15 31 + 33 33 24 23 33 33 24 27 33 27 33 10 33 12 33 33 33 + 33 33 33 33 33 23 33 31 23 33 33 33 24 27 33 23 26 + 28 31 24 25 24 25 24 20 33 33 33 33 33 33 33 33 25 + 33 33 15 33 33 33 33 23 15 28 28 19 26 31 26 10 23 + 15 18 20 21 24 16 19 31 25 29 31 31 29 23 31 31 23 + 23 23 23 10 6 20 18 18 31 12 15 18 18 18 23 15 10 + 23 12 18 31 28 10 18 10 30 24 31 31 21 28 19 28 19 + 24 31 30 21 10 23 24 0 31 20 23 18 24 10 31 16 23 + 23 23 23 10 15 31 26 25 12 23 14 24 20 15 31 25 27 + 23 23 31 26 30 16 25 10 26 31 20 28 18 23 16 20 25 + 33 20 21 20 31 23 18 10 31 10 31 23 25 24 11 23 28 + 15 10 16 25 24 27 31 23 23 15 31 28 23 10 29 25 30 + 19 31 31 31 29 15 28 19 31 19 27 30 26 23 31 31 16 + 29 20 21 10 24 23 28 23 31 29 28 23 20 31 16 20 28 + 10 31 31 31 15 28 31 28 31 15 24 31 31 25 27 15 16 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 0 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 0 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 14 10 8 25 23 25 20 9 21 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 16 25 25 24 25 12 11 12 25 + 25 25 18 25 25 20 25 25 25 24 25 10 23 25 14 20 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 12 16 24 + 25 25 12 7 25 25 21 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 7 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 16 16 24 16 23 10 + 18 12 12 11 12 14 16 24 15 23 24 24 23 13 24 24 10 + 2 6 14 23 23 12 12 12 24 20 21 12 12 12 19 15 23 + 10 20 12 24 21 23 12 23 23 16 24 24 11 21 16 23 23 + 12 24 23 11 23 10 12 25 24 12 0 12 11 23 24 14 10 + 20 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 16 24 16 23 14 15 23 16 24 12 21 12 10 14 12 14 + 25 12 11 12 24 14 12 23 24 23 24 10 16 11 21 12 21 + 21 23 14 14 12 20 24 6 3 15 24 23 2 23 23 16 23 + 16 24 24 24 23 15 23 16 24 16 20 23 16 5 24 24 14 + 23 12 16 23 12 10 23 10 24 23 21 6 12 24 14 12 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 0 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 0 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 0 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 0 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 15 14 12 27 16 27 23 12 22 18 24 23 18 18 1 24 12 + 27 21 21 26 20 25 27 12 18 27 27 25 27 18 11 10 27 + 27 27 19 27 27 21 27 27 27 26 27 12 24 27 10 21 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 13 13 26 + 27 27 18 12 27 27 22 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 18 23 27 23 16 14 + 13 1 10 11 18 13 18 27 21 24 27 26 24 14 27 27 14 + 12 12 15 16 18 10 9 9 26 14 15 11 9 1 20 11 16 + 14 14 4 27 24 16 11 16 25 18 25 26 11 24 18 24 18 + 16 25 25 11 16 14 15 27 26 10 12 1 15 16 27 0 14 + 21 14 12 16 16 26 23 20 14 14 12 16 10 13 27 20 23 + 12 18 25 23 25 13 21 16 23 25 13 24 8 12 13 10 20 + 27 10 11 10 25 15 13 18 25 18 26 12 21 15 15 14 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 18 26 27 26 24 11 24 18 27 18 23 25 23 12 26 27 10 + 24 10 18 16 18 14 24 14 27 24 24 12 10 25 10 13 24 + 16 25 26 25 15 24 25 24 27 13 18 25 27 21 23 18 10 + + 14 14 15 23 25 23 12 15 21 11 14 11 11 11 21 12 23 + 21 3 8 20 10 16 21 23 16 23 23 18 23 11 18 20 23 + 23 23 18 23 23 20 23 23 23 20 23 16 14 23 23 20 14 + 10 20 5 12 25 21 16 14 23 23 12 20 25 21 20 23 20 + 23 23 12 15 23 23 21 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 5 12 2 12 20 23 23 23 23 23 23 23 23 8 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 11 15 21 20 15 14 21 21 14 + 15 15 14 25 25 20 21 21 20 24 24 21 21 21 19 23 25 + 14 24 21 21 12 25 21 25 16 16 18 20 18 12 23 14 25 + 12 18 16 18 25 14 12 23 20 20 15 21 12 25 21 23 0 + 20 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 16 + 16 16 18 10 16 23 8 25 11 18 20 12 21 16 23 20 12 + 23 20 18 20 18 14 21 25 18 25 20 16 16 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 16 16 + 23 20 21 20 15 23 14 23 21 23 12 16 16 15 20 21 23 + 15 20 18 25 11 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 3 11 25 23 + + 18 18 20 18 27 18 7 20 22 14 11 10 14 14 23 10 24 + 16 12 12 15 12 12 16 24 18 18 18 14 18 14 23 23 18 + 18 18 19 18 18 21 18 18 18 15 18 21 11 18 24 21 11 + 12 23 12 5 27 16 18 11 18 18 4 15 27 16 23 24 15 + 18 18 14 20 18 18 22 10 18 10 18 27 18 25 18 18 18 + 18 18 18 18 18 18 18 15 18 18 18 18 16 7 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 18 18 18 12 + 18 18 24 18 18 18 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 12 12 16 15 13 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 20 24 27 + 18 25 23 16 11 27 23 27 13 18 14 18 23 10 24 11 27 + 15 14 18 23 27 18 16 18 15 23 20 23 16 27 16 24 18 + 0 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 18 + 21 18 14 11 12 24 12 27 12 18 23 10 23 21 24 23 13 + 18 23 23 23 14 18 23 27 14 27 18 21 18 16 26 18 10 + 26 27 24 12 14 9 15 20 20 24 16 11 20 27 12 18 13 + 24 15 16 15 13 24 13 24 16 24 7 12 18 20 15 16 24 + 12 23 23 27 14 18 11 18 16 13 10 20 23 14 24 23 11 + 27 18 15 14 26 10 14 10 16 24 14 18 16 12 10 27 24 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 0 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 0 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 15 15 14 28 15 28 24 14 15 20 24 23 20 20 15 24 15 + 27 23 23 27 21 25 27 11 15 28 28 26 28 20 15 11 28 + 28 28 15 28 28 15 28 28 28 27 28 15 24 28 15 15 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 11 11 27 + 28 28 20 14 28 28 15 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 28 27 15 28 28 28 16 24 28 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 15 24 24 10 23 27 23 15 15 + 12 15 15 15 20 0 4 27 23 25 27 27 25 15 27 27 15 + 14 14 15 15 16 15 10 10 27 15 14 10 10 15 15 15 15 + 15 12 10 27 24 15 10 15 25 18 26 27 12 24 10 24 15 + 18 26 25 15 15 15 16 28 27 15 14 15 16 15 27 9 15 + 15 15 15 0 15 27 23 21 15 15 15 18 15 12 27 21 23 + 15 15 26 23 25 0 23 15 23 26 11 24 10 12 0 11 21 + 28 15 15 11 26 15 10 16 26 16 27 12 23 16 14 15 24 + 14 15 15 21 20 24 27 14 14 15 27 24 14 15 25 21 25 + 11 27 27 27 25 15 24 11 27 4 24 25 23 14 27 27 15 + 25 15 12 15 20 15 24 15 27 25 24 14 15 26 15 11 24 + 15 26 27 26 14 24 26 24 27 11 20 26 27 23 23 16 4 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 0 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 12 12 14 23 24 23 12 14 12 10 15 15 10 10 20 15 23 + 23 10 10 21 4 18 23 23 12 23 23 20 23 10 16 18 23 + 23 23 12 23 23 12 23 23 23 21 23 15 15 23 21 12 15 + 9 18 10 12 24 23 16 15 23 23 12 21 25 23 18 23 21 + 23 23 10 14 23 23 12 12 23 12 23 24 23 23 23 23 23 + 23 23 23 23 23 12 23 21 12 23 23 23 15 12 23 14 11 + 14 23 12 10 12 10 15 18 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 12 23 14 14 23 11 23 11 24 12 + 23 20 18 16 10 21 21 23 10 16 23 21 16 12 23 23 12 + 14 14 12 24 25 18 20 20 21 24 24 20 20 20 12 23 24 + 15 24 20 23 14 24 20 24 18 11 20 21 16 15 23 15 24 + 11 20 18 16 24 12 12 23 21 18 14 20 15 24 23 21 12 + 12 15 15 24 24 0 11 8 24 15 23 15 18 23 23 15 12 + 15 12 20 11 18 21 10 24 11 20 18 14 20 15 21 18 0 + 23 18 16 18 20 12 20 25 20 25 21 15 10 12 24 12 14 + 24 24 21 15 10 12 21 14 14 23 23 15 14 24 16 4 18 + 23 21 23 21 16 23 15 23 23 21 12 18 11 14 21 23 21 + 16 18 16 24 10 12 15 12 23 16 14 14 18 20 21 18 15 + 24 20 21 20 24 14 20 14 23 23 15 20 23 15 15 25 21 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 0 21 11 15 28 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 0 11 24 12 11 27 24 12 + 21 25 20 15 31 10 19 12 11 11 15 0 31 15 25 28 6 + 11 11 23 24 11 11 24 16 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 0 24 11 11 11 23 15 11 24 18 + 14 10 23 20 23 20 23 25 11 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 0 15 24 10 10 24 + 24 24 24 31 31 25 26 26 0 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 15 23 10 19 25 14 27 12 31 + 23 15 19 25 31 24 23 19 0 25 24 26 23 31 10 27 24 + 24 24 24 31 31 0 0 21 29 24 28 23 25 28 10 21 19 + 24 24 10 18 11 27 20 31 18 19 25 14 26 24 27 25 21 + 19 25 25 25 10 24 26 31 15 31 19 24 20 23 30 24 14 + 30 31 27 21 23 15 0 24 24 27 10 12 24 31 12 21 15 + 28 10 10 0 15 27 15 28 10 27 15 11 19 24 0 15 27 + 12 25 25 31 23 24 12 24 10 15 14 24 25 10 27 25 12 + 31 19 15 10 30 14 10 14 10 28 23 19 10 20 16 31 27 + + 14 14 15 23 25 23 12 15 21 11 14 11 11 11 21 12 23 + 21 3 8 20 10 16 21 23 16 23 23 18 23 11 18 20 23 + 23 23 18 23 23 20 23 23 23 20 23 16 14 23 23 20 14 + 10 20 5 12 25 21 16 14 23 23 12 20 25 21 20 23 20 + 23 23 12 15 23 23 21 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 5 12 2 12 20 23 23 23 23 23 23 23 23 8 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 11 15 21 20 15 14 21 21 14 + 15 15 14 25 25 20 21 21 20 24 24 21 21 21 19 23 25 + 14 24 21 21 12 25 21 25 16 16 18 20 18 12 23 14 25 + 12 18 16 18 25 14 12 23 20 20 15 21 12 25 21 23 14 + 20 14 16 25 25 20 10 0 24 14 23 12 20 24 21 10 16 + 16 16 18 10 16 23 8 25 11 18 20 12 21 16 23 20 12 + 23 20 18 20 18 14 21 25 18 25 20 16 16 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 16 16 + 23 20 21 20 15 23 14 23 21 23 12 16 16 15 20 21 23 + 15 20 18 25 11 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 3 11 25 23 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 0 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 0 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 0 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 0 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 12 12 12 27 18 27 23 12 18 16 24 23 16 16 10 23 12 + 26 20 20 25 18 24 26 12 13 27 27 25 27 16 10 0 27 + 27 27 15 27 27 17 27 27 27 25 27 11 24 27 11 17 24 + 18 0 20 23 18 26 24 24 27 27 23 25 20 26 9 12 25 + 27 27 16 12 27 27 18 23 27 23 27 18 27 14 27 27 27 + 27 27 27 27 27 12 27 25 12 27 27 27 14 23 27 12 21 + 23 26 14 20 14 20 15 0 27 27 27 27 27 27 27 27 20 + 27 27 12 27 27 27 27 12 12 23 23 13 21 26 21 18 12 + 14 10 6 10 16 11 13 26 20 24 26 25 24 12 26 26 12 + 12 12 12 18 20 6 10 10 25 15 16 10 10 10 16 12 18 + 12 15 10 26 23 18 10 18 24 15 25 25 10 23 13 24 18 + 15 25 24 10 18 12 14 27 25 6 12 10 14 18 26 11 12 + 17 12 11 18 18 25 21 18 15 12 12 15 0 14 26 18 23 + 11 13 25 21 24 11 20 18 21 25 9 23 10 11 11 0 18 + 27 6 10 0 25 12 10 20 25 20 25 11 20 14 16 12 23 + 16 18 11 18 16 23 25 12 12 12 26 24 12 18 24 18 24 + 13 25 26 25 24 12 24 13 26 13 23 24 21 12 25 26 11 + 24 6 13 18 16 12 24 12 26 24 23 12 6 25 11 9 24 + 18 25 25 25 16 23 25 23 26 12 16 25 26 20 23 20 11 + + 17 12 12 27 18 27 23 12 24 16 24 23 16 16 10 23 12 + 26 20 20 25 18 24 26 12 19 27 27 25 27 16 10 6 27 + 27 27 21 27 27 23 27 27 27 25 27 11 24 27 11 23 24 + 18 6 20 23 18 26 24 24 27 27 23 25 20 26 15 15 25 + 27 27 16 12 27 27 24 23 27 23 27 18 27 14 27 27 27 + 27 27 27 27 27 12 27 25 12 27 27 27 14 23 27 12 21 + 23 26 14 20 14 20 15 6 27 27 27 27 27 27 27 27 20 + 27 27 12 27 27 27 27 12 12 23 23 19 21 26 21 18 12 + 15 10 0 10 16 15 19 26 20 24 26 25 24 16 26 26 12 + 12 12 17 18 20 0 10 10 25 15 16 12 10 10 22 12 18 + 12 15 10 26 23 18 12 18 24 19 25 25 10 23 19 24 19 + 15 25 24 10 18 12 15 27 25 0 12 10 14 18 26 11 12 + 23 12 11 18 18 25 21 18 15 12 12 15 0 0 26 18 23 + 11 19 25 21 24 15 20 18 21 25 15 23 10 11 15 6 18 + 27 0 10 6 25 17 15 20 25 20 25 11 20 14 16 15 23 + 16 18 11 18 16 23 25 12 12 12 26 24 12 18 24 19 24 + 19 25 26 25 24 12 24 19 26 19 23 24 21 12 25 26 11 + 24 0 19 18 16 12 24 12 26 24 23 12 0 25 11 15 24 + 18 25 25 25 16 23 25 23 26 15 16 25 26 20 23 20 11 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 0 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 0 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 0 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 0 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 15 10 10 25 23 25 20 11 22 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 18 25 25 24 25 12 11 12 25 + 25 25 19 25 25 21 25 25 25 24 25 10 23 25 14 21 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 13 16 24 + 25 25 13 9 25 25 22 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 9 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 18 16 24 16 23 10 + 18 12 12 11 12 14 18 24 15 23 24 24 23 14 24 24 10 + 4 7 15 23 23 12 12 12 24 20 21 12 12 12 20 15 23 + 10 20 12 24 21 23 12 23 23 18 24 24 11 21 18 23 23 + 12 24 23 11 23 10 13 25 24 12 9 12 11 23 24 14 11 + 21 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 0 24 16 23 14 15 23 16 24 13 21 12 10 14 12 14 + 25 12 11 12 24 15 13 23 24 23 24 10 18 11 21 13 21 + 21 23 14 14 12 20 24 7 5 15 24 23 4 23 23 18 23 + 18 24 24 24 23 15 23 18 24 18 20 23 18 6 24 24 14 + 23 12 18 23 12 10 23 10 24 23 21 7 12 24 14 13 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 0 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 17 15 16 21 25 21 11 16 24 12 12 10 12 12 23 12 24 + 20 10 11 18 11 15 20 24 19 21 21 16 21 12 20 21 21 + 21 21 21 21 21 23 21 21 21 18 21 18 12 21 23 23 12 + 11 21 10 11 25 20 19 12 21 21 11 18 26 20 21 24 18 + 21 21 15 16 21 21 24 10 21 11 21 25 21 24 21 21 21 + 21 21 21 21 21 15 21 18 15 21 21 21 14 11 21 16 6 + 12 20 14 10 14 10 12 21 21 21 21 21 21 21 21 21 11 + 21 21 23 21 21 21 21 15 23 12 12 23 6 20 8 25 15 + 24 23 21 20 12 23 23 20 14 14 20 18 15 16 20 20 15 + 16 16 17 25 26 21 23 23 18 24 25 23 23 23 22 23 25 + 15 24 23 20 12 25 23 25 15 19 16 19 20 12 23 12 25 + 12 16 19 20 25 15 15 21 18 21 16 23 14 25 20 23 15 + 23 15 18 25 25 18 8 11 24 15 24 12 21 24 20 11 19 + 18 19 16 0 15 23 11 25 14 19 21 12 23 18 23 21 15 + 21 21 20 21 16 17 23 26 16 26 19 18 19 14 25 15 12 + 25 25 23 11 12 11 18 16 16 23 20 12 16 25 14 19 15 + 24 18 20 18 15 23 15 24 20 23 11 15 19 16 18 20 23 + 14 21 20 25 14 15 12 15 20 15 12 16 21 16 23 21 12 + 25 19 18 16 25 12 16 12 20 24 12 19 20 10 10 26 23 + + 11 10 11 24 23 24 16 11 18 11 20 15 11 11 15 18 20 + 24 12 12 23 12 23 24 20 13 24 24 23 24 11 12 14 24 + 24 24 15 24 24 17 24 24 24 23 24 12 20 24 16 17 20 + 12 14 12 16 23 24 21 20 24 24 16 23 24 24 14 20 23 + 24 24 11 11 24 24 18 15 24 16 24 23 24 21 24 24 24 + 24 24 24 24 24 10 24 23 10 24 24 24 6 16 24 11 14 + 18 24 4 12 4 12 10 14 24 24 24 24 24 24 24 24 12 + 24 24 18 24 24 24 24 10 18 18 18 18 14 24 14 23 10 + 21 15 14 12 11 16 16 24 12 21 24 23 21 10 24 24 10 + 11 11 11 23 24 14 15 15 23 23 23 15 15 15 16 18 23 + 10 23 15 24 18 23 15 23 23 13 23 23 12 18 18 20 23 + 10 23 23 12 23 10 9 24 23 14 11 15 6 23 24 16 10 + 17 10 12 23 23 23 14 12 23 10 20 10 14 21 24 12 15 + 12 13 23 14 0 16 12 23 14 23 14 18 15 12 16 14 12 + 24 14 12 14 23 11 15 24 23 24 23 12 13 0 23 10 18 + 23 23 16 12 11 16 23 11 11 18 24 20 11 23 21 13 23 + 20 23 24 23 21 18 20 20 24 16 16 23 14 11 23 24 16 + 21 14 13 23 11 10 20 10 24 21 18 11 14 23 16 14 20 + 23 23 23 23 23 18 23 18 24 20 11 23 24 12 15 24 16 + + 23 23 23 12 29 12 12 23 24 20 11 14 20 20 25 12 27 + 12 16 16 11 18 10 15 27 23 12 12 10 12 20 24 24 12 + 12 12 23 12 12 23 12 12 12 11 12 24 11 12 25 23 11 + 18 24 16 12 29 12 19 11 12 12 12 11 30 15 24 27 11 + 12 12 20 23 12 12 24 14 12 12 12 29 12 27 12 12 12 + 12 12 12 12 12 23 12 11 23 12 12 12 23 12 12 23 15 + 12 12 23 16 23 16 21 24 12 12 12 12 12 12 12 12 16 + 12 12 26 12 12 12 12 23 26 12 12 26 15 12 15 29 23 + 27 25 24 24 20 25 25 12 16 10 12 11 15 23 12 12 23 + 23 23 23 29 30 24 25 25 11 28 28 25 25 25 23 26 29 + 23 28 25 12 12 29 25 29 15 21 10 19 24 12 26 11 29 + 21 15 19 24 29 23 23 19 11 24 23 25 23 29 12 25 23 + 23 23 24 29 29 11 15 18 28 23 27 21 24 27 12 18 19 + 24 23 10 15 0 0 16 29 15 19 24 12 25 24 25 24 18 + 19 24 24 24 10 23 25 30 15 30 19 24 19 23 28 23 12 + 28 29 25 18 20 12 11 23 23 26 12 11 23 29 10 19 15 + 27 11 12 11 15 26 15 27 12 25 12 0 19 23 11 15 25 + 10 24 24 29 20 23 11 23 12 15 12 23 24 10 25 24 11 + 29 19 15 10 28 12 10 12 12 27 20 19 12 16 14 30 25 + + 17 15 16 21 25 21 11 16 24 12 12 10 12 12 23 12 24 + 20 10 11 18 11 15 20 24 19 21 21 16 21 12 20 21 21 + 21 21 21 21 21 23 21 21 21 18 21 18 12 21 23 23 12 + 11 21 10 11 25 20 19 12 21 21 11 18 26 20 21 24 18 + 21 21 15 16 21 21 24 10 21 11 21 25 21 24 21 21 21 + 21 21 21 21 21 15 21 18 15 21 21 21 14 11 21 16 6 + 12 20 14 10 14 10 12 21 21 21 21 21 21 21 21 21 11 + 21 21 23 21 21 21 21 15 23 12 12 23 6 20 8 25 15 + 24 23 21 20 12 23 23 20 14 14 20 18 15 16 20 20 15 + 16 16 17 25 26 21 23 23 18 24 25 23 23 23 22 23 25 + 15 24 23 20 12 25 23 25 15 19 16 19 20 12 23 12 25 + 12 16 19 20 25 15 15 21 18 21 16 23 14 25 20 23 15 + 23 15 18 25 25 18 8 11 24 15 24 12 21 24 20 11 19 + 18 19 16 5 15 23 0 25 14 19 21 12 23 18 23 21 15 + 21 21 20 21 16 17 23 26 16 26 19 18 19 14 25 15 12 + 25 25 23 11 12 11 18 16 16 23 20 12 16 25 14 19 15 + 24 18 20 18 15 23 15 24 20 23 11 15 19 16 18 20 23 + 14 21 20 25 14 15 12 15 20 15 12 16 21 16 23 21 12 + 25 19 18 16 25 12 16 12 20 24 12 19 20 10 10 26 23 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 0 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 0 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 20 20 21 16 27 16 10 21 24 15 11 11 15 15 24 0 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 21 16 16 23 16 16 16 14 16 23 10 16 24 23 10 + 14 23 12 10 27 15 19 10 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 24 11 16 11 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 20 16 16 16 18 10 16 21 12 + 6 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 5 9 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 14 11 15 14 15 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 22 24 27 + 20 26 24 15 12 27 24 27 15 19 12 19 23 0 24 10 27 + 16 15 19 23 27 20 18 19 14 23 21 24 18 27 15 24 20 + 23 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 19 + 23 20 12 12 12 24 12 27 14 0 23 6 24 23 24 23 15 + 19 23 23 23 12 20 24 28 15 28 19 23 19 18 27 20 10 + 27 27 24 14 15 10 14 21 21 24 15 10 21 27 11 19 15 + 25 14 15 14 15 24 15 25 15 24 10 12 19 21 14 15 24 + 11 23 23 27 15 20 10 20 15 15 9 21 23 12 24 23 10 + 27 19 15 12 27 8 12 6 15 25 15 19 15 12 11 28 24 + + 17 12 11 26 20 26 23 12 24 15 23 21 15 15 11 23 14 + 25 18 18 25 16 24 25 14 19 26 26 24 26 15 0 10 26 + 26 26 21 26 26 23 26 26 26 25 26 10 23 26 12 23 23 + 16 10 18 23 20 25 24 23 26 26 23 25 21 25 15 15 25 + 26 26 15 11 26 26 24 21 26 23 26 20 26 15 26 26 26 + 26 26 26 26 26 12 26 25 12 26 26 26 12 23 26 11 20 + 23 25 12 18 12 18 14 10 26 26 26 26 26 26 26 26 18 + 26 26 12 26 26 26 26 12 12 23 23 19 20 25 20 20 12 + 15 11 10 0 15 15 19 25 18 24 25 25 24 16 25 25 12 + 11 11 17 20 21 10 11 11 25 16 18 12 11 11 22 12 20 + 12 16 11 25 23 20 12 20 24 19 24 25 10 23 19 23 20 + 14 24 24 0 20 12 15 26 25 10 11 11 12 20 25 12 12 + 23 12 10 20 20 25 20 16 16 12 14 14 10 15 25 16 21 + 10 19 24 20 24 15 18 20 20 24 0 23 11 10 15 10 16 + 26 10 0 10 24 17 15 21 24 21 25 10 19 12 18 15 23 + 18 20 12 16 15 23 25 11 11 12 25 23 11 20 24 19 24 + 19 25 25 25 24 12 23 19 25 19 23 24 20 11 25 25 12 + 24 10 19 20 15 12 23 12 25 24 23 11 10 24 12 15 23 + 20 24 25 24 18 23 24 23 25 15 15 24 25 18 21 21 12 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 0 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 0 21 11 15 28 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 0 11 24 12 11 27 24 12 + 21 25 20 15 31 10 19 12 11 11 15 0 31 15 25 28 6 + 11 11 23 24 11 11 24 16 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 0 24 11 11 11 23 15 11 24 18 + 14 10 23 20 23 20 23 25 11 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 0 15 24 10 10 24 + 24 24 24 31 31 25 26 26 0 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 15 23 10 19 25 14 27 12 31 + 23 15 19 25 31 24 23 19 0 25 24 26 23 31 10 27 24 + 24 24 24 31 31 0 18 21 29 24 28 23 25 28 10 21 19 + 24 24 10 18 11 27 20 31 18 19 25 14 0 24 27 25 21 + 19 25 25 25 10 24 26 31 15 31 19 24 20 23 30 24 14 + 30 31 27 21 23 15 0 24 24 27 10 12 24 31 12 21 15 + 28 10 10 0 15 27 15 28 10 27 15 11 19 24 0 15 27 + 12 25 25 31 23 24 12 24 10 15 14 24 25 10 27 25 12 + 31 19 15 10 30 14 10 14 10 28 23 19 10 20 16 31 27 + + 17 12 12 27 18 27 23 12 24 16 24 23 16 16 10 23 12 + 26 20 20 25 18 24 26 12 19 27 27 25 27 16 10 6 27 + 27 27 21 27 27 23 27 27 27 25 27 11 24 27 11 23 24 + 18 6 20 23 18 26 24 24 27 27 23 25 20 26 15 15 25 + 27 27 16 12 27 27 24 23 27 23 27 18 27 14 27 27 27 + 27 27 27 27 27 12 27 25 12 27 27 27 14 23 27 12 21 + 23 26 14 20 14 20 15 6 27 27 27 27 27 27 27 27 20 + 27 27 12 27 27 27 27 12 12 23 23 19 21 26 21 18 12 + 15 10 0 10 16 15 19 26 20 24 26 25 24 16 26 26 12 + 12 12 17 18 20 0 10 10 25 15 16 12 10 10 22 12 18 + 12 15 10 26 23 18 12 18 24 19 25 25 10 23 19 24 19 + 15 25 24 10 18 12 15 27 25 0 12 10 14 18 26 11 12 + 23 12 11 18 18 25 21 18 15 12 12 15 0 15 26 18 23 + 11 19 25 21 24 15 20 18 21 25 15 23 10 0 15 6 18 + 27 0 10 6 25 17 15 20 25 20 25 11 20 14 16 15 23 + 16 18 11 18 16 23 25 12 12 12 26 24 12 18 24 19 24 + 19 25 26 25 24 12 24 19 26 19 23 24 21 12 25 26 11 + 24 0 19 18 16 12 24 12 26 24 23 12 0 25 11 15 24 + 18 25 25 25 16 23 25 23 26 15 16 25 26 20 23 20 11 + + 17 14 12 27 16 27 23 12 24 18 24 23 18 18 0 24 12 + 27 21 21 26 20 25 27 12 19 27 27 25 27 18 11 10 27 + 27 27 21 27 27 23 27 27 27 26 27 12 24 27 10 23 24 + 20 10 21 23 16 27 24 24 27 27 23 26 18 27 15 15 26 + 27 27 18 12 27 27 24 23 27 23 27 16 27 12 27 27 27 + 27 27 27 27 27 14 27 26 14 27 27 27 15 23 27 12 23 + 24 27 15 21 15 21 16 10 27 27 27 27 27 27 27 27 21 + 27 27 11 27 27 27 27 14 11 24 24 19 23 27 23 16 14 + 15 0 10 11 18 15 19 27 21 24 27 26 24 16 27 27 14 + 12 12 17 16 18 10 10 10 26 14 15 12 10 0 22 11 16 + 14 14 5 27 24 16 12 16 25 19 25 26 11 24 19 24 19 + 16 25 25 11 16 14 15 27 26 10 12 0 15 16 27 10 14 + 23 14 12 16 16 26 23 20 14 14 12 16 10 15 27 20 23 + 12 19 25 23 25 15 21 16 23 25 15 24 10 12 0 10 20 + 27 10 11 10 25 17 15 18 25 18 26 12 21 15 15 15 24 + 15 16 10 20 18 23 26 12 12 11 27 24 12 16 24 20 25 + 19 26 27 26 24 11 24 19 27 19 23 25 23 12 26 27 10 + 24 10 19 16 18 14 24 14 27 24 24 12 10 25 10 15 24 + 16 25 26 25 15 24 25 24 27 15 18 25 27 21 23 18 10 + + 17 10 11 24 23 24 16 12 24 11 20 15 11 11 15 18 20 + 24 12 12 23 12 23 24 20 19 24 24 23 24 11 12 14 24 + 24 24 21 24 24 23 24 24 24 23 24 12 20 24 16 23 20 + 12 14 12 16 23 24 21 20 24 24 16 23 24 24 15 20 23 + 24 24 15 11 24 24 24 15 24 16 24 23 24 21 24 24 24 + 24 24 24 24 24 10 24 23 10 24 24 24 0 16 24 11 14 + 18 24 10 12 10 12 10 14 24 24 24 24 24 24 24 24 12 + 24 24 18 24 24 24 24 10 18 18 18 19 14 24 14 23 10 + 21 15 14 12 11 16 19 24 14 21 24 23 21 16 24 24 10 + 11 11 17 23 24 14 15 15 23 23 23 15 15 15 22 18 23 + 10 23 15 24 18 23 15 23 23 19 23 23 12 18 19 20 23 + 10 23 23 12 23 10 15 24 23 14 11 15 0 23 24 16 12 + 23 10 12 23 23 23 14 12 23 10 20 10 14 21 24 12 19 + 12 19 23 14 23 16 12 23 14 23 15 18 15 12 16 0 15 + 24 14 12 14 23 17 15 24 23 24 23 12 19 6 23 15 18 + 23 23 16 12 11 16 23 11 11 18 24 20 11 23 21 19 23 + 20 23 24 23 21 18 20 20 24 19 16 23 19 11 23 24 16 + 21 14 19 23 14 10 20 10 24 21 18 11 14 23 16 15 20 + 23 23 23 23 23 18 23 18 24 20 11 23 24 12 15 24 16 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 0 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 0 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 0 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 12 14 11 26 20 26 23 11 12 15 23 21 15 15 19 23 19 + 25 18 18 25 16 24 25 14 12 26 26 24 26 15 19 13 26 + 26 26 12 26 26 12 26 26 26 25 26 19 23 26 19 12 23 + 16 13 18 23 20 25 24 23 26 26 23 25 21 25 10 14 25 + 26 26 15 11 26 26 12 21 26 23 26 20 26 15 26 26 26 + 26 26 26 26 26 12 26 25 12 26 26 26 19 23 26 11 20 + 23 25 12 18 12 18 19 13 26 26 26 26 26 26 26 26 18 + 26 26 13 26 26 26 26 14 19 23 23 12 20 25 20 20 12 + 15 19 19 19 15 12 12 25 18 24 25 25 24 12 25 25 14 + 14 11 12 20 21 19 11 11 25 19 18 11 11 19 12 19 20 + 19 16 14 25 23 20 11 20 24 14 24 25 9 23 12 23 20 + 14 24 24 19 20 12 12 26 25 19 11 19 19 20 25 14 12 + 12 19 19 20 20 25 20 16 19 19 19 19 19 15 25 19 21 + 19 12 24 20 24 12 18 20 20 24 10 23 11 13 12 13 16 + 26 19 0 13 24 12 11 21 24 21 25 10 18 13 18 12 23 + 18 20 19 19 15 23 25 11 12 19 25 23 14 20 24 16 24 + 14 25 25 25 24 19 23 14 25 12 23 24 20 11 25 25 19 + 24 19 0 20 15 12 23 12 25 24 23 11 19 24 19 10 23 + 20 24 25 24 18 23 24 23 25 14 19 24 25 19 21 21 12 + + 17 12 11 26 20 26 23 12 24 15 23 21 15 15 11 23 14 + 25 18 18 25 16 24 25 14 19 26 26 24 26 15 0 10 26 + 26 26 21 26 26 23 26 26 26 25 26 10 23 26 12 23 23 + 16 10 18 23 20 25 24 23 26 26 23 25 21 25 15 15 25 + 26 26 15 11 26 26 24 21 26 23 26 20 26 15 26 26 26 + 26 26 26 26 26 12 26 25 12 26 26 26 12 23 26 11 20 + 23 25 12 18 12 18 14 10 26 26 26 26 26 26 26 26 18 + 26 26 12 26 26 26 26 12 12 23 23 19 20 25 20 20 12 + 15 11 10 0 15 15 19 25 18 24 25 25 24 16 25 25 12 + 11 11 17 20 21 10 11 11 25 16 18 12 11 11 22 12 20 + 12 16 11 25 23 20 12 20 24 19 24 25 10 23 19 23 20 + 14 24 24 0 20 12 15 26 25 10 11 11 12 20 25 12 12 + 23 12 10 20 20 25 20 16 16 12 14 14 10 15 25 16 21 + 10 19 24 20 24 15 18 20 20 24 15 23 11 10 15 10 16 + 26 10 0 0 24 17 15 21 24 21 25 10 19 12 18 15 23 + 18 20 12 16 15 23 25 11 11 12 25 23 11 20 24 19 24 + 19 25 25 25 24 12 23 19 25 19 23 24 20 11 25 25 12 + 24 10 19 20 15 12 23 12 25 24 23 11 10 24 12 15 23 + 20 24 25 24 18 23 24 23 25 15 15 24 25 18 21 21 12 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 0 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 21 21 23 15 28 15 11 23 24 16 11 12 16 16 24 10 25 + 14 14 14 12 15 11 15 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 23 15 15 15 12 15 23 0 15 24 23 9 + 15 24 14 11 28 14 19 10 15 15 11 12 28 15 24 25 12 + 15 15 16 23 15 15 24 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 10 14 12 15 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 22 25 28 + 21 27 24 14 12 28 24 28 15 19 12 19 23 10 25 6 28 + 18 15 19 23 28 21 20 19 12 24 23 24 20 28 14 24 21 + 23 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 19 + 23 21 12 12 11 24 14 28 14 19 24 10 24 23 24 24 15 + 19 24 23 24 12 0 24 28 15 28 19 23 19 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 9 23 28 10 19 15 + 25 12 14 12 15 25 15 25 14 24 11 11 19 23 12 15 24 + 10 24 23 28 16 21 9 21 14 15 10 23 24 12 24 24 0 + 28 19 15 12 27 10 12 10 14 25 16 19 14 14 12 28 24 + + 17 5 11 24 23 24 18 12 24 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 19 24 24 23 24 12 12 12 24 + 24 24 21 24 24 23 24 24 24 24 24 11 21 24 15 23 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 15 18 24 + 24 24 15 10 24 24 24 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 6 24 24 10 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 5 16 20 20 19 15 24 15 23 9 + 20 14 12 12 12 15 19 24 14 23 24 24 23 16 24 24 5 + 10 10 17 23 23 12 14 14 24 21 23 14 14 14 22 16 23 + 0 21 14 24 20 23 14 23 23 19 23 24 12 20 19 21 23 + 11 23 23 12 23 10 15 24 24 12 10 14 10 23 24 15 12 + 23 0 11 23 23 24 15 12 21 0 18 11 12 20 24 12 19 + 11 19 23 15 23 15 14 23 15 23 15 20 14 11 15 12 15 + 24 12 12 12 23 17 0 23 23 23 24 11 19 10 23 15 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 19 23 + 19 24 24 24 23 16 21 19 24 19 18 23 19 10 24 24 15 + 23 12 19 23 14 9 21 6 24 23 20 10 12 23 15 15 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 17 11 11 25 21 25 21 12 24 14 23 20 14 14 12 23 15 + 25 16 16 24 15 24 25 15 19 25 25 24 25 14 10 11 25 + 25 25 21 25 25 23 25 25 25 24 25 0 23 25 12 23 23 + 15 11 16 21 21 25 23 23 25 25 21 24 23 25 15 15 24 + 25 25 15 10 25 25 24 20 25 21 25 21 25 16 25 25 25 + 25 25 25 25 25 11 25 24 11 25 25 25 12 21 25 10 18 + 23 25 12 16 12 16 12 11 25 25 25 25 25 25 25 25 16 + 25 25 14 25 25 25 25 11 14 23 23 19 18 25 18 21 11 + 16 12 11 10 14 15 19 25 16 23 25 24 23 16 25 25 11 + 10 10 17 21 23 11 12 12 24 18 20 12 12 12 22 14 21 + 11 18 12 25 23 21 12 21 24 19 24 24 10 23 19 23 21 + 12 24 24 10 21 11 15 25 24 11 10 12 12 21 25 12 12 + 23 11 0 21 21 24 18 15 18 11 15 12 11 16 25 15 20 + 0 19 24 18 24 15 16 21 18 24 15 23 12 6 15 11 15 + 25 11 10 11 24 17 15 0 24 23 24 10 19 12 20 15 23 + 20 21 12 15 14 21 24 10 10 14 25 23 10 21 23 19 24 + 19 24 25 24 23 14 23 19 25 19 21 24 19 10 24 25 12 + 23 11 19 21 14 11 23 11 25 23 23 10 11 24 12 15 23 + 21 24 24 24 20 23 24 23 25 15 14 24 25 16 20 23 12 + + 21 21 20 31 15 31 25 20 24 23 27 25 23 23 14 26 11 + 30 24 24 29 24 28 30 11 21 31 31 28 31 23 16 15 31 + 31 31 21 31 31 23 31 31 31 29 31 18 27 31 12 23 27 + 24 15 24 25 11 30 27 27 31 31 25 29 12 30 15 15 29 + 31 31 23 20 31 31 24 25 31 25 31 11 31 10 31 31 31 + 31 31 31 31 31 21 31 29 21 31 31 31 23 25 31 20 24 + 26 30 23 24 23 24 23 15 31 31 31 31 31 31 31 31 24 + 31 31 12 31 31 31 31 21 12 26 26 19 24 30 24 11 21 + 15 14 15 16 23 15 19 30 24 27 30 29 27 21 30 30 21 + 20 20 21 11 12 15 14 14 29 0 15 14 14 14 22 12 11 + 21 5 14 30 26 11 14 11 28 23 28 29 16 26 19 27 19 + 23 28 28 16 11 21 23 31 29 15 20 14 23 11 30 12 21 + 23 21 18 11 15 29 24 24 0 21 11 23 15 15 30 24 25 + 18 21 28 24 28 15 24 11 24 28 15 26 14 18 15 15 24 + 31 15 16 15 28 21 15 12 0 12 29 18 24 23 10 21 26 + 15 11 12 24 23 25 29 20 20 12 30 27 20 11 27 24 28 + 19 29 30 29 27 12 27 19 30 19 25 28 24 20 29 30 12 + 27 15 19 11 23 21 27 21 30 27 26 20 15 28 12 15 27 + 11 28 29 28 15 26 28 26 30 15 23 28 30 24 25 15 12 + + 17 5 11 24 23 24 18 12 24 12 21 16 12 12 14 20 18 + 24 14 14 24 12 23 24 18 19 24 24 23 24 12 12 12 24 + 24 24 21 24 24 23 24 24 24 24 24 11 21 24 15 23 21 + 12 12 14 18 23 24 23 21 24 24 18 24 23 24 15 18 24 + 24 24 15 10 24 24 24 16 24 18 24 23 24 20 24 24 24 + 24 24 24 24 24 6 24 24 10 24 24 24 10 18 24 10 15 + 20 24 10 14 10 14 11 12 24 24 24 24 24 24 24 24 14 + 24 24 16 24 24 24 24 5 16 20 20 19 15 24 15 23 9 + 20 14 12 12 12 15 19 24 14 23 24 24 23 16 24 24 5 + 10 10 17 23 23 12 14 14 24 21 23 14 14 14 22 16 23 + 0 21 14 24 20 23 14 23 23 19 23 24 12 20 19 21 23 + 11 23 23 12 23 10 15 24 24 12 10 14 10 23 24 15 12 + 23 0 11 23 23 24 15 12 21 0 18 11 12 20 24 12 19 + 11 19 23 15 23 15 14 23 15 23 15 20 14 11 15 12 15 + 24 12 12 12 23 17 15 23 23 0 24 11 19 10 23 15 20 + 23 23 15 12 12 18 24 10 10 16 24 21 10 23 23 19 23 + 19 24 24 24 23 16 21 19 24 19 18 23 19 10 24 24 15 + 23 12 19 23 14 9 21 6 24 23 20 10 12 23 15 15 21 + 23 23 24 23 23 20 23 20 24 18 12 23 24 14 16 23 15 + + 18 18 16 29 15 29 24 16 24 23 25 24 23 23 12 25 0 + 28 23 23 28 23 27 28 10 19 29 29 27 29 23 14 12 29 + 29 29 21 29 29 23 29 29 29 28 29 15 25 29 11 23 25 + 23 12 23 24 12 28 26 25 29 29 24 28 14 28 15 15 28 + 29 29 23 16 29 29 24 24 29 24 29 12 29 10 29 29 29 + 29 29 29 29 29 18 29 28 18 29 29 29 20 24 29 16 24 + 25 28 20 23 20 23 21 12 29 29 29 29 29 29 29 29 23 + 29 29 10 29 29 29 29 18 10 25 25 19 24 28 24 12 18 + 15 12 12 14 23 15 19 28 23 26 28 28 26 18 28 28 18 + 16 16 18 12 14 12 12 12 28 11 15 12 12 12 22 10 12 + 18 11 12 28 25 12 12 12 27 21 27 28 14 25 19 25 19 + 21 27 27 14 12 18 20 29 28 12 16 12 20 12 28 11 18 + 23 18 15 12 15 28 24 23 11 18 0 21 12 15 28 23 24 + 15 19 27 24 27 15 23 12 24 27 15 25 12 15 15 12 23 + 29 12 14 12 27 18 15 14 27 14 0 15 23 20 12 18 25 + 15 12 11 23 23 24 28 16 16 10 28 25 16 12 26 23 27 + 19 28 28 28 26 10 25 19 28 19 24 27 24 16 28 28 11 + 26 12 19 12 23 18 25 18 28 26 25 16 12 27 11 15 25 + 12 27 28 27 15 25 27 25 28 15 23 27 28 23 24 15 11 + + 17 11 12 24 24 24 15 12 24 10 18 14 10 10 16 16 21 + 23 12 12 23 11 21 23 21 19 24 24 23 24 10 14 15 24 + 24 24 21 24 24 23 24 24 24 23 24 12 18 24 18 23 18 + 11 15 12 15 24 23 20 18 24 24 15 23 24 23 15 21 23 + 24 24 15 12 24 24 24 14 24 15 24 24 24 23 24 24 24 + 24 24 24 24 24 11 24 23 11 24 24 24 10 15 24 12 12 + 16 23 10 12 10 12 0 15 24 24 24 24 24 24 24 24 12 + 24 24 20 24 24 24 24 11 20 16 16 20 12 23 12 24 11 + 23 16 15 14 10 18 19 23 14 20 23 23 20 16 23 23 11 + 12 12 17 24 24 15 16 16 23 23 23 16 16 16 22 20 24 + 11 23 16 23 16 24 16 24 21 19 23 23 14 16 20 18 24 + 10 23 21 14 24 11 15 24 23 15 12 16 10 24 23 18 12 + 23 11 12 24 24 23 12 11 23 11 21 0 15 23 23 11 19 + 12 19 23 12 21 18 12 24 14 23 15 16 16 12 18 15 15 + 24 15 14 15 23 17 16 24 23 24 23 0 19 10 23 15 16 + 23 24 18 11 10 15 23 12 12 20 23 18 12 24 20 19 21 + 21 23 23 23 20 20 18 21 23 19 15 21 19 12 23 23 18 + 20 15 19 24 14 11 18 11 23 20 16 12 15 23 18 15 18 + 24 23 23 23 23 16 23 16 23 21 10 23 23 12 14 24 18 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 0 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 17 12 14 23 24 23 12 14 24 10 15 12 10 10 20 14 23 + 23 10 11 21 10 18 23 23 19 23 23 20 23 10 16 18 23 + 23 23 21 23 23 23 23 23 23 21 23 15 15 23 21 23 15 + 5 18 10 12 24 23 19 15 23 23 12 21 25 23 18 23 21 + 23 23 15 14 23 23 24 12 23 12 23 24 23 23 23 23 23 + 23 23 23 23 23 12 23 21 12 23 23 23 12 12 23 14 11 + 14 23 12 10 12 10 11 18 23 23 23 23 23 23 23 23 11 + 23 23 23 23 23 23 23 12 23 14 14 23 11 23 11 24 12 + 23 20 18 16 10 21 21 23 14 16 23 21 16 16 23 23 12 + 14 14 17 24 25 18 20 20 21 24 24 20 20 20 22 23 24 + 12 24 20 23 14 24 20 24 18 19 20 21 16 14 23 15 24 + 11 20 19 16 24 12 15 23 21 18 14 20 12 24 23 21 12 + 23 12 15 24 24 21 11 6 24 12 23 11 18 23 23 0 19 + 15 19 20 11 18 21 11 24 14 20 18 14 20 15 21 18 15 + 23 18 16 18 20 17 20 25 20 25 21 15 19 0 24 15 14 + 24 24 21 0 10 12 21 14 14 23 23 15 14 24 16 19 18 + 23 21 23 21 16 23 15 23 23 21 12 18 19 14 21 23 21 + 16 18 19 24 14 12 15 12 23 16 14 14 18 20 21 18 15 + 24 20 21 20 24 14 20 14 23 23 10 20 23 10 12 25 21 + + 17 11 11 25 21 25 21 12 24 14 23 20 14 14 12 23 15 + 25 16 16 24 15 24 25 15 19 25 25 24 25 14 10 11 25 + 25 25 21 25 25 23 25 25 25 24 25 0 23 25 12 23 23 + 15 11 16 21 21 25 23 23 25 25 21 24 23 25 15 15 24 + 25 25 15 10 25 25 24 20 25 21 25 21 25 16 25 25 25 + 25 25 25 25 25 11 25 24 11 25 25 25 12 21 25 10 18 + 23 25 12 16 12 16 12 11 25 25 25 25 25 25 25 25 16 + 25 25 14 25 25 25 25 11 14 23 23 19 18 25 18 21 11 + 16 12 11 10 14 15 19 25 16 23 25 24 23 16 25 25 11 + 10 10 17 21 23 11 12 12 24 18 20 12 12 12 22 14 21 + 11 18 12 25 23 21 12 21 24 19 24 24 10 23 19 23 21 + 12 24 24 10 21 11 15 25 24 11 10 12 12 21 25 12 12 + 23 11 0 21 21 24 18 15 18 11 15 12 11 16 25 15 20 + 0 19 24 18 24 15 16 21 18 24 15 23 12 6 15 11 15 + 25 11 10 11 24 17 15 23 24 23 24 10 19 12 0 15 23 + 20 21 12 15 14 21 24 10 10 14 25 23 10 21 23 19 24 + 19 24 25 24 23 14 23 19 25 19 21 24 19 10 24 25 12 + 23 11 19 21 14 11 23 11 25 23 23 10 11 24 12 15 23 + 21 24 24 24 20 23 24 23 25 15 14 24 25 16 20 23 12 + + 23 23 24 12 30 12 14 24 24 21 12 15 21 21 25 12 27 + 11 18 18 10 20 10 15 27 23 12 12 0 12 21 24 25 12 + 12 12 23 12 12 23 12 12 12 10 12 24 12 12 26 23 12 + 20 25 18 14 30 11 19 12 12 12 14 10 31 15 25 27 10 + 12 12 21 24 12 12 24 15 12 14 12 30 12 28 12 12 12 + 12 12 12 12 12 23 12 10 23 12 12 12 23 14 12 24 16 + 12 11 23 18 23 18 23 25 12 12 12 12 12 12 12 12 18 + 12 12 27 12 12 12 12 23 27 12 12 27 16 11 16 30 23 + 28 25 25 24 21 26 26 11 18 11 11 10 15 23 11 11 23 + 24 24 23 30 31 25 25 25 10 28 29 25 25 25 23 27 30 + 23 28 25 11 12 30 25 30 15 23 10 19 24 12 27 12 30 + 23 15 19 24 30 23 23 19 10 25 24 25 23 30 11 26 23 + 23 23 24 30 30 10 16 20 28 23 27 23 25 28 11 20 19 + 24 23 0 16 10 26 18 30 16 19 25 12 25 24 26 25 20 + 19 25 24 25 0 23 25 31 15 31 19 24 19 23 29 0 12 + 29 30 26 20 21 14 10 24 24 27 11 12 24 30 11 20 15 + 27 10 11 10 15 27 15 27 11 26 14 10 19 24 10 15 26 + 11 25 24 30 21 23 12 23 11 15 12 24 25 6 26 25 12 + 30 19 15 0 29 12 0 12 11 27 21 19 11 18 15 31 26 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 0 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 17 12 12 27 18 27 23 12 24 16 24 23 16 16 10 23 12 + 26 20 20 25 18 24 26 12 19 27 27 25 27 16 10 6 27 + 27 27 21 27 27 23 27 27 27 25 27 11 24 27 11 23 24 + 18 6 20 23 18 26 24 24 27 27 23 25 20 26 15 15 25 + 27 27 16 12 27 27 24 23 27 23 27 18 27 14 27 27 27 + 27 27 27 27 27 12 27 25 12 27 27 27 14 23 27 12 21 + 23 26 14 20 14 20 15 6 27 27 27 27 27 27 27 27 20 + 27 27 12 27 27 27 27 12 12 23 23 19 21 26 21 18 12 + 15 10 0 10 16 15 19 26 20 24 26 25 24 16 26 26 12 + 12 12 17 18 20 0 10 10 25 15 16 12 10 10 22 12 18 + 12 15 10 26 23 18 12 18 24 19 25 25 10 23 19 24 19 + 15 25 24 10 18 12 15 27 25 0 12 10 14 18 26 11 12 + 23 12 11 18 18 25 21 18 15 12 12 15 0 15 26 18 23 + 11 19 25 21 24 15 20 18 21 25 15 23 10 11 15 6 18 + 27 0 10 6 25 17 15 20 25 20 25 11 20 14 16 15 23 + 0 18 11 18 16 23 25 12 12 12 26 24 12 18 24 19 24 + 19 25 26 25 24 12 24 19 26 19 23 24 21 12 25 26 11 + 24 0 19 18 16 12 24 12 26 24 23 12 0 25 11 15 24 + 18 25 25 25 16 23 25 23 26 15 16 25 26 20 23 20 11 + + 23 23 24 12 30 12 14 24 24 21 12 15 21 21 25 12 27 + 11 18 18 10 20 10 15 27 23 12 12 0 12 21 24 25 12 + 12 12 23 12 12 23 12 12 12 10 12 24 12 12 26 23 12 + 20 25 18 14 30 11 19 12 12 12 14 10 31 15 25 27 10 + 12 12 21 24 12 12 24 15 12 14 12 30 12 28 12 12 12 + 12 12 12 12 12 23 12 10 23 12 12 12 23 14 12 24 16 + 12 11 23 18 23 18 23 25 12 12 12 12 12 12 12 12 18 + 12 12 27 12 12 12 12 23 27 12 12 27 16 11 16 30 23 + 28 25 25 24 21 26 26 11 18 11 11 10 15 23 11 11 23 + 24 24 23 30 31 25 25 25 10 28 29 25 25 25 23 27 30 + 23 28 25 11 12 30 25 30 15 23 10 19 24 12 27 12 30 + 23 15 19 24 30 23 23 19 10 25 24 25 23 30 11 26 23 + 23 23 24 30 30 10 16 20 28 23 27 23 25 28 11 20 19 + 24 23 0 16 10 26 18 30 16 19 25 12 25 24 26 25 20 + 19 25 24 25 0 23 25 31 15 31 19 24 19 23 29 23 12 + 29 0 26 20 21 14 10 24 24 27 11 12 24 30 11 20 15 + 27 10 11 10 15 27 15 27 11 26 14 10 19 24 10 15 26 + 11 25 24 30 21 23 12 23 11 15 12 24 25 6 26 25 12 + 30 19 15 0 29 12 0 12 11 27 21 19 11 18 15 31 26 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 0 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 0 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 15 14 15 23 25 23 12 15 22 11 14 11 11 11 21 12 23 + 21 5 10 20 10 16 21 23 18 23 23 18 23 11 18 20 23 + 23 23 19 23 23 21 23 23 23 20 23 16 14 23 23 21 14 + 10 20 6 12 25 21 18 14 23 23 12 20 25 21 20 23 20 + 23 23 13 15 23 23 22 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 6 12 4 12 20 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 12 15 21 20 15 14 21 21 14 + 15 15 15 25 25 20 21 21 20 24 24 21 21 21 20 23 25 + 14 24 21 21 12 25 21 25 16 18 18 20 18 12 23 14 25 + 12 18 18 18 25 14 13 23 20 20 15 21 12 25 21 23 14 + 21 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 18 + 16 18 18 10 16 23 10 25 12 18 20 12 21 16 23 20 13 + 23 20 18 20 18 15 21 25 18 25 20 16 18 12 24 14 12 + 24 25 23 10 0 12 20 15 15 23 21 14 15 25 15 18 16 + 23 20 21 20 15 23 14 23 21 23 12 16 18 15 20 21 23 + 15 20 18 25 12 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 1 11 25 23 + + 15 14 15 23 25 23 12 15 22 11 14 11 11 11 21 12 23 + 21 5 10 20 10 16 21 23 18 23 23 18 23 11 18 20 23 + 23 23 19 23 23 21 23 23 23 20 23 16 14 23 23 21 14 + 10 20 6 12 25 21 18 14 23 23 12 20 25 21 20 23 20 + 23 23 13 15 23 23 22 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 6 12 4 12 20 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 12 15 21 20 15 14 21 21 14 + 15 15 15 25 25 20 21 21 20 24 24 21 21 21 20 23 25 + 14 24 21 21 12 25 21 25 16 18 18 20 18 12 23 14 25 + 12 18 18 18 25 14 13 23 20 20 15 21 12 25 21 23 14 + 21 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 18 + 16 18 18 10 16 23 10 25 12 18 20 12 21 16 23 20 13 + 23 20 18 20 18 15 21 25 18 25 20 16 18 12 24 14 12 + 24 25 23 10 11 0 20 15 15 23 21 14 15 25 15 18 16 + 23 20 21 20 15 23 14 23 21 23 12 16 18 15 20 21 23 + 15 20 18 25 12 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 1 11 25 23 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 0 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 15 10 10 25 23 25 20 11 22 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 18 25 25 24 25 12 11 12 25 + 25 25 19 25 25 21 25 25 25 24 25 10 23 25 14 21 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 13 16 24 + 25 25 13 9 25 25 22 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 9 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 18 16 24 16 23 10 + 18 12 12 11 12 14 18 24 15 23 24 24 23 14 24 24 10 + 4 7 15 23 23 12 12 12 24 20 21 12 12 12 20 15 23 + 10 20 12 24 21 23 12 23 23 18 24 24 11 21 18 23 23 + 12 24 23 11 23 10 13 25 24 12 9 12 11 23 24 14 11 + 21 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 18 24 16 23 14 15 23 16 24 13 21 12 10 14 12 14 + 25 12 11 12 24 15 13 23 24 23 24 10 18 11 21 13 21 + 21 23 14 14 12 20 24 0 5 15 24 23 4 23 23 18 23 + 18 24 24 24 23 15 23 18 24 18 20 23 18 6 24 24 14 + 23 12 18 23 12 10 23 10 24 23 21 7 12 24 14 13 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 14 10 8 25 23 25 20 9 21 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 16 25 25 24 25 12 11 12 25 + 25 25 18 25 25 20 25 25 25 24 25 10 23 25 14 20 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 12 16 24 + 25 25 12 7 25 25 21 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 7 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 16 16 24 16 23 10 + 18 12 12 11 12 14 16 24 15 23 24 24 23 13 24 24 10 + 2 6 14 23 23 12 12 12 24 20 21 12 12 12 19 15 23 + 10 20 12 24 21 23 12 23 23 16 24 24 11 21 16 23 23 + 12 24 23 11 23 10 12 25 24 12 7 12 11 23 24 14 10 + 20 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 16 24 16 23 14 15 23 16 24 12 21 12 10 14 12 14 + 25 12 11 12 24 14 12 23 24 23 24 10 16 11 21 12 21 + 21 23 14 14 12 20 24 6 0 15 24 23 2 23 23 16 23 + 16 24 24 24 23 15 23 16 24 16 20 23 16 5 24 24 14 + 23 12 16 23 12 10 23 10 24 23 21 6 12 24 14 12 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 0 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 0 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 20 20 21 16 27 16 10 21 24 15 11 11 15 15 24 0 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 21 16 16 23 16 16 16 14 16 23 10 16 24 23 10 + 14 23 12 10 27 15 19 10 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 24 11 16 11 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 20 16 16 16 18 10 16 21 12 + 6 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 5 9 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 14 11 15 14 15 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 22 24 27 + 20 26 24 15 12 27 24 27 15 19 12 19 23 0 24 10 27 + 16 15 19 23 27 20 18 19 14 23 21 24 18 27 15 24 20 + 23 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 19 + 23 20 12 12 12 24 12 27 14 19 23 6 24 23 24 23 15 + 19 23 23 23 12 20 24 28 15 28 19 23 19 18 27 20 10 + 27 27 24 14 15 10 14 21 21 24 15 0 21 27 11 19 15 + 25 14 15 14 15 24 15 25 15 24 10 12 19 21 14 15 24 + 11 23 23 27 15 20 10 20 15 15 9 21 23 12 24 23 10 + 27 19 15 12 27 8 12 6 15 25 15 19 15 12 11 28 24 + + 15 10 10 25 23 25 20 11 22 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 18 25 25 24 25 12 11 12 25 + 25 25 19 25 25 21 25 25 25 24 25 10 23 25 14 21 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 13 16 24 + 25 25 13 9 25 25 22 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 9 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 18 16 24 16 23 10 + 18 12 12 11 12 14 18 24 15 23 24 24 23 14 24 24 10 + 4 7 15 23 23 12 12 12 24 20 21 12 12 12 20 15 23 + 10 20 12 24 21 23 12 23 23 18 24 24 11 21 18 23 23 + 12 24 23 11 23 10 13 25 24 12 9 12 11 23 24 14 11 + 21 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 18 24 16 23 14 15 23 16 24 13 21 12 10 14 12 14 + 25 12 11 12 24 15 13 23 24 23 24 10 18 11 21 13 21 + 21 23 14 14 12 20 24 7 5 15 24 23 0 23 23 18 23 + 18 24 24 24 23 15 23 18 24 18 20 23 18 6 24 24 14 + 23 12 18 23 12 10 23 10 24 23 21 7 12 24 14 13 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 0 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 17 15 14 28 15 28 24 14 24 20 24 23 20 20 10 24 11 + 27 23 23 27 21 25 27 11 19 28 28 26 28 20 12 11 28 + 28 28 21 28 28 23 28 28 28 27 28 12 24 28 0 23 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 15 15 27 + 28 28 20 14 28 28 24 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 28 27 15 28 28 28 16 24 28 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 10 24 24 19 23 27 23 15 15 + 15 10 11 12 20 15 19 27 23 25 27 27 25 16 27 27 15 + 14 14 17 15 16 11 10 10 27 12 15 12 10 10 22 10 15 + 15 12 10 27 24 15 12 15 25 19 26 27 12 24 19 24 19 + 18 26 25 12 15 15 16 28 27 11 14 10 16 15 27 5 15 + 23 15 12 15 15 27 23 21 12 15 11 18 11 15 27 21 23 + 12 19 26 23 25 15 23 15 23 26 15 24 10 12 15 11 21 + 28 11 12 11 26 17 15 16 26 16 27 12 23 16 14 15 24 + 15 15 0 21 20 24 27 14 14 10 27 24 14 15 0 21 25 + 19 27 27 27 25 10 24 19 27 19 24 25 23 14 27 27 0 + 25 11 19 15 20 15 24 15 27 25 24 14 11 26 0 15 24 + 15 26 27 26 15 24 26 24 27 15 20 26 27 23 23 16 10 + + 17 12 14 23 24 23 12 14 24 10 15 12 10 10 20 14 23 + 23 10 11 21 10 18 23 23 19 23 23 20 23 10 16 18 23 + 23 23 21 23 23 23 23 23 23 21 23 15 15 23 21 23 15 + 5 18 10 12 24 23 19 15 23 23 12 21 25 23 18 23 21 + 23 23 15 14 23 23 24 12 23 12 23 24 23 23 23 23 23 + 23 23 23 23 23 12 23 21 12 23 23 23 12 12 23 14 11 + 14 23 12 10 12 10 11 18 23 23 23 23 23 23 23 23 11 + 23 23 23 23 23 23 23 12 23 14 14 23 11 23 11 24 12 + 23 20 18 16 10 21 21 23 14 16 23 21 16 16 23 23 12 + 14 14 17 24 25 18 20 20 21 24 24 20 20 20 22 23 24 + 12 24 20 23 14 24 20 24 18 19 20 21 16 14 23 15 24 + 11 20 19 16 24 12 15 23 21 18 14 20 12 24 23 21 12 + 23 12 15 24 24 21 11 6 24 12 23 11 18 23 23 0 19 + 15 19 20 11 18 21 11 24 14 20 18 14 20 15 21 18 15 + 23 18 16 18 20 17 20 25 20 25 21 15 19 12 24 15 14 + 24 24 21 0 10 12 21 14 14 23 23 15 14 24 16 0 18 + 23 21 23 21 16 23 15 23 23 21 12 18 19 14 21 23 21 + 16 18 19 24 14 12 15 12 23 16 14 14 18 20 21 18 15 + 24 20 21 20 24 14 20 14 23 23 10 20 23 10 12 25 21 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 0 21 11 15 28 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 0 11 24 12 11 27 24 12 + 21 25 20 15 31 10 19 12 11 11 15 0 31 15 25 28 6 + 11 11 23 24 11 11 24 16 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 0 24 11 11 11 23 15 11 24 18 + 14 10 23 20 23 20 23 25 11 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 0 15 24 10 10 24 + 24 24 24 31 31 25 26 26 0 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 15 23 10 19 25 14 27 12 31 + 23 15 19 25 31 24 23 19 0 25 24 26 23 31 10 27 24 + 24 24 24 31 31 0 18 21 29 24 28 23 25 28 10 21 19 + 24 24 10 18 11 27 20 31 18 19 25 14 26 24 27 25 21 + 19 25 25 25 10 24 26 31 15 31 19 24 20 23 30 24 14 + 30 31 27 21 23 15 0 24 24 27 10 12 24 31 12 21 0 + 28 10 10 0 15 27 15 28 10 27 15 11 19 24 0 15 27 + 12 25 25 31 23 24 12 24 10 15 14 24 25 10 27 25 12 + 31 19 15 10 30 14 10 14 10 28 23 19 10 20 16 31 27 + + 17 16 15 28 15 28 24 15 24 21 25 24 21 21 11 24 10 + 28 23 23 27 23 26 28 10 19 28 28 27 28 21 12 12 28 + 28 28 21 28 28 23 28 28 28 27 28 14 25 28 10 23 25 + 23 12 23 24 14 28 25 25 28 28 24 27 15 28 15 15 27 + 28 28 21 15 28 28 24 24 28 24 28 14 28 11 28 28 28 + 28 28 28 28 28 16 28 27 16 28 28 28 18 24 28 15 23 + 24 28 18 23 18 23 20 12 28 28 28 28 28 28 28 28 23 + 28 28 6 28 28 28 28 16 0 24 24 19 23 28 23 14 16 + 15 11 12 12 21 15 19 28 23 25 28 27 25 16 28 28 16 + 15 15 17 14 15 12 11 11 27 12 15 12 11 11 22 0 14 + 16 12 11 28 24 14 12 14 26 20 27 27 12 24 19 25 19 + 20 27 26 12 14 16 18 28 27 12 15 11 18 14 28 10 16 + 23 16 14 14 15 27 23 23 12 16 10 20 12 15 28 23 24 + 14 19 27 23 26 15 23 14 23 27 15 24 11 14 15 12 23 + 28 12 12 12 27 17 15 15 27 15 27 14 23 18 12 16 24 + 15 14 10 23 21 24 27 15 15 0 28 25 15 14 25 23 26 + 0 27 28 27 25 0 25 19 28 19 24 26 23 15 27 28 10 + 25 12 19 14 21 16 25 16 28 25 24 15 12 27 10 15 25 + 14 27 27 27 15 24 27 24 28 15 21 27 28 23 24 15 10 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 0 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 0 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 6 21 21 10 23 12 9 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 6 13 14 10 10 16 10 31 9 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 6 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 6 20 31 24 + 29 27 26 25 23 27 27 6 21 12 6 10 12 24 6 0 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 6 15 31 27 31 12 23 11 13 25 15 28 14 31 + 23 11 13 25 31 24 24 13 10 26 24 27 24 31 6 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 6 23 18 + 25 24 11 20 12 27 21 31 20 13 26 15 27 25 27 26 23 + 13 26 25 26 11 24 27 31 11 31 13 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 6 14 24 31 12 23 12 + 28 10 0 0 12 28 14 28 6 27 16 12 20 24 10 9 27 + 12 26 25 31 23 24 14 24 6 12 15 24 26 11 27 26 14 + 31 13 10 11 31 15 11 15 6 28 23 13 6 21 18 31 27 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 0 21 11 15 28 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 0 11 24 12 11 27 24 12 + 21 25 20 15 31 10 19 12 11 11 15 0 31 15 25 28 6 + 11 11 23 24 11 11 24 16 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 0 24 11 11 11 23 15 11 24 18 + 14 10 23 20 23 20 23 25 11 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 0 15 24 10 10 24 + 24 24 24 31 31 25 26 26 0 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 15 23 10 19 25 14 27 12 31 + 23 15 19 25 31 24 23 19 0 25 24 26 23 31 10 27 24 + 24 24 24 31 31 0 18 21 29 24 28 23 25 28 10 21 19 + 24 24 10 18 11 27 20 31 18 19 25 14 26 24 27 25 21 + 19 25 25 25 10 24 26 31 15 31 19 24 20 23 30 24 14 + 30 31 27 21 23 15 0 24 24 27 10 12 24 31 12 21 15 + 28 10 10 0 0 27 15 28 10 27 15 11 19 24 0 15 27 + 12 25 25 31 23 24 12 24 10 15 14 24 25 10 27 25 12 + 31 19 15 10 30 14 10 14 10 28 23 19 10 20 16 31 27 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 0 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 20 20 21 16 27 16 10 21 24 15 11 11 15 15 24 0 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 21 16 16 23 16 16 16 14 16 23 10 16 24 23 10 + 14 23 12 10 27 15 19 10 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 24 11 16 11 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 20 16 16 16 18 10 16 21 12 + 6 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 5 9 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 14 11 15 14 15 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 22 24 27 + 20 26 24 15 12 27 24 27 15 19 12 19 23 0 24 10 27 + 16 15 19 23 27 20 18 19 14 23 21 24 18 27 15 24 20 + 23 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 19 + 23 20 12 12 12 24 12 27 14 19 23 6 24 23 24 23 15 + 19 23 23 23 12 20 24 28 15 28 19 23 19 18 27 20 10 + 27 27 24 14 15 10 14 21 21 24 15 10 21 27 11 19 15 + 25 14 15 14 15 24 0 25 15 24 10 12 19 21 14 15 24 + 11 23 23 27 15 20 10 20 15 15 9 21 23 12 24 23 10 + 27 19 15 12 27 8 12 6 15 25 15 19 15 12 11 28 24 + + 17 16 15 28 15 28 24 15 24 21 25 24 21 21 11 24 10 + 28 23 23 27 23 26 28 10 19 28 28 27 28 21 12 12 28 + 28 28 21 28 28 23 28 28 28 27 28 14 25 28 10 23 25 + 23 12 23 24 14 28 25 25 28 28 24 27 15 28 15 15 27 + 28 28 21 15 28 28 24 24 28 24 28 14 28 11 28 28 28 + 28 28 28 28 28 16 28 27 16 28 28 28 18 24 28 15 23 + 24 28 18 23 18 23 20 12 28 28 28 28 28 28 28 28 23 + 28 28 6 28 28 28 28 16 0 24 24 19 23 28 23 14 16 + 15 11 12 12 21 15 19 28 23 25 28 27 25 16 28 28 16 + 15 15 17 14 15 12 11 11 27 12 15 12 11 11 22 0 14 + 16 12 11 28 24 14 12 14 26 20 27 27 12 24 19 25 19 + 20 27 26 12 14 16 18 28 27 12 15 11 18 14 28 10 16 + 23 16 14 14 15 27 23 23 12 16 10 20 12 15 28 23 24 + 14 19 27 23 26 15 23 14 23 27 15 24 11 14 15 12 23 + 28 12 12 12 27 17 15 15 27 15 27 14 23 18 12 16 24 + 15 14 10 23 21 24 27 15 15 0 28 25 15 14 25 23 26 + 19 27 28 27 25 0 25 0 28 19 24 26 23 15 27 28 10 + 25 12 19 14 21 16 25 16 28 25 24 15 12 27 10 15 25 + 14 27 27 27 15 24 27 24 28 15 21 27 28 23 24 15 10 + + 14 14 15 23 25 23 12 15 14 14 14 19 12 12 21 19 23 + 21 12 8 20 10 16 21 23 14 23 23 19 23 11 19 20 23 + 23 23 14 23 23 14 23 23 23 20 23 19 19 23 23 14 14 + 14 20 11 12 25 21 15 14 23 23 14 20 25 21 20 23 20 + 23 23 11 15 23 23 14 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 19 12 23 15 12 + 12 21 12 11 12 14 19 20 23 23 23 23 23 23 23 23 8 + 23 23 23 23 23 23 23 14 23 14 12 23 12 21 11 25 14 + 24 21 20 19 11 23 23 21 5 19 21 20 15 14 21 21 14 + 15 15 14 25 25 20 21 21 20 24 24 21 21 21 14 23 25 + 19 24 21 21 12 25 21 25 16 12 18 20 18 19 23 14 25 + 12 18 16 19 25 14 12 23 20 20 15 21 19 25 21 23 14 + 14 19 19 25 25 20 11 12 24 19 23 19 20 24 21 19 11 + 19 14 19 14 19 23 8 25 10 18 20 13 21 16 23 20 10 + 23 20 19 20 19 14 21 25 18 25 20 16 0 13 24 14 12 + 24 25 23 19 14 12 20 15 15 23 21 14 15 25 15 10 16 + 23 20 21 20 15 23 14 23 0 23 12 19 10 15 20 21 23 + 15 20 18 25 11 14 14 14 21 15 12 15 20 18 23 20 19 + 25 18 20 19 24 12 19 13 21 23 19 18 21 19 19 25 23 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 0 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 15 14 15 23 25 23 12 15 22 11 14 11 11 11 21 12 23 + 21 5 10 20 10 16 21 23 18 23 23 18 23 11 18 20 23 + 23 23 19 23 23 21 23 23 23 20 23 16 14 23 23 21 14 + 10 20 6 12 25 21 18 14 23 23 12 20 25 21 20 23 20 + 23 23 13 15 23 23 22 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 6 12 4 12 20 23 23 23 23 23 23 23 23 10 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 12 15 21 20 15 14 21 21 14 + 15 15 15 25 25 20 21 21 20 24 24 21 21 21 20 23 25 + 14 24 21 21 12 25 21 25 16 18 18 20 18 12 23 14 25 + 12 18 18 18 25 14 13 23 20 20 15 21 12 25 21 23 14 + 21 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 18 + 16 18 18 10 16 23 10 25 12 18 20 12 21 16 23 20 13 + 23 20 18 20 18 15 21 25 18 25 20 16 18 12 24 14 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 18 16 + 23 20 21 20 15 23 14 23 21 23 0 16 18 15 20 21 23 + 15 20 18 25 12 14 14 14 21 15 12 15 20 18 23 20 14 + 25 18 20 18 24 12 18 12 21 23 11 18 21 1 11 25 23 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 0 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 23 23 23 12 29 12 12 23 24 20 11 14 20 20 25 12 27 + 12 16 16 11 18 10 15 27 23 12 12 10 12 20 24 24 12 + 12 12 23 12 12 23 12 12 12 11 12 24 11 12 25 23 11 + 18 24 16 12 29 12 19 11 12 12 12 11 30 15 24 27 11 + 12 12 20 23 12 12 24 14 12 12 12 29 12 27 12 12 12 + 12 12 12 12 12 23 12 11 23 12 12 12 23 12 12 23 15 + 12 12 23 16 23 16 21 24 12 12 12 12 12 12 12 12 16 + 12 12 26 12 12 12 12 23 26 12 12 26 15 12 15 29 23 + 27 25 24 24 20 25 25 12 16 10 12 11 15 23 12 12 23 + 23 23 23 29 30 24 25 25 11 28 28 25 25 25 23 26 29 + 23 28 25 12 12 29 25 29 15 21 10 19 24 12 26 11 29 + 21 15 19 24 29 23 23 19 11 24 23 25 23 29 12 25 23 + 23 23 24 29 29 11 15 18 28 23 27 21 24 27 12 18 19 + 24 23 10 15 0 25 16 29 15 19 24 12 25 24 25 24 18 + 19 24 24 24 10 23 25 30 15 30 19 24 19 23 28 23 12 + 28 29 25 18 20 12 11 23 23 26 12 11 23 29 10 19 15 + 27 11 12 11 15 26 15 27 12 25 12 0 0 23 11 15 25 + 10 24 24 29 20 23 11 23 12 15 12 23 24 10 25 24 11 + 29 19 15 10 28 12 10 12 12 27 20 19 12 16 14 30 25 + + 14 10 8 25 23 25 20 9 21 12 23 18 12 12 12 21 16 + 24 15 15 24 14 23 24 16 16 25 25 24 25 12 11 12 25 + 25 25 18 25 25 20 25 25 25 24 25 10 23 25 14 20 23 + 14 12 15 20 23 24 23 23 25 25 20 24 23 24 12 16 24 + 25 25 12 7 25 25 21 18 25 20 25 23 25 18 25 25 25 + 25 25 25 25 25 10 25 24 10 25 25 25 11 20 25 7 16 + 21 24 11 15 11 15 12 12 25 25 25 25 25 25 25 25 15 + 25 25 15 25 25 25 25 10 15 21 21 16 16 24 16 23 10 + 18 12 12 11 12 14 16 24 15 23 24 24 23 13 24 24 10 + 2 6 14 23 23 12 12 12 24 20 21 12 12 12 19 15 23 + 10 20 12 24 21 23 12 23 23 16 24 24 11 21 16 23 23 + 12 24 23 11 23 10 12 25 24 12 7 12 11 23 24 14 10 + 20 10 10 23 23 24 16 14 20 10 16 12 12 18 24 14 18 + 10 16 24 16 23 14 15 23 16 24 12 21 12 10 14 12 14 + 25 12 11 12 24 14 12 23 24 23 24 10 16 11 21 12 21 + 21 23 14 14 12 20 24 6 3 15 24 23 2 23 23 16 23 + 16 24 24 24 23 15 23 16 24 16 20 23 16 0 24 24 14 + 23 12 16 23 12 10 23 10 24 23 21 6 12 24 14 12 23 + 23 24 24 24 21 21 24 21 24 16 12 24 24 15 18 23 14 + + 23 23 23 14 28 14 12 23 23 18 10 15 18 18 24 15 26 + 15 15 15 15 16 10 12 26 23 14 14 15 14 18 24 24 14 + 14 14 23 14 14 23 14 14 14 15 14 23 15 14 25 23 10 + 16 24 15 12 28 15 4 10 14 14 12 15 29 12 24 26 12 + 14 14 18 23 14 14 23 12 14 12 14 28 14 27 14 14 14 + 14 14 14 14 14 23 14 15 23 14 14 14 21 12 14 23 14 + 11 15 21 15 21 15 20 24 14 14 14 14 14 14 14 14 15 + 14 14 25 14 14 14 14 23 25 11 11 25 14 15 14 28 23 + 27 24 24 24 18 25 25 15 15 15 15 15 0 23 15 12 23 + 23 23 23 28 29 24 24 24 15 27 28 24 24 24 23 25 28 + 23 27 24 15 11 28 24 28 10 20 11 12 24 15 25 10 28 + 20 11 10 24 28 23 21 14 15 24 23 24 21 28 15 25 23 + 23 23 23 28 28 15 14 16 27 23 26 20 24 27 15 16 12 + 23 23 15 14 15 25 15 28 14 11 24 11 24 23 25 24 16 + 14 24 24 24 15 23 24 29 11 29 12 23 15 21 28 23 11 + 28 28 25 16 18 12 15 23 23 25 15 10 23 28 4 16 10 + 26 12 12 15 0 25 10 26 15 25 12 15 14 23 0 12 25 + 9 24 24 28 18 23 10 23 15 0 11 23 24 11 25 24 15 + 28 11 12 15 28 11 15 11 15 26 18 11 15 15 15 29 25 + + 24 24 24 11 31 11 15 24 24 23 12 16 23 23 26 14 28 + 10 20 20 0 21 11 15 28 24 11 11 10 11 23 25 25 11 + 11 11 24 11 11 24 11 11 11 0 11 24 12 11 27 24 12 + 21 25 20 15 31 10 19 12 11 11 15 0 31 15 25 28 6 + 11 11 23 24 11 11 24 16 11 15 11 31 11 28 11 11 11 + 11 11 11 11 11 24 11 0 24 11 11 11 23 15 11 24 18 + 14 10 23 20 23 20 23 25 11 11 11 11 11 11 11 11 20 + 11 11 27 11 11 11 11 24 27 14 14 27 18 10 18 31 24 + 28 26 25 25 23 27 27 10 20 12 10 0 15 24 10 10 24 + 24 24 24 31 31 25 26 26 0 29 30 26 26 26 24 27 31 + 24 29 26 10 14 31 26 31 15 23 10 19 25 14 27 12 31 + 23 15 19 25 31 24 23 19 0 25 24 26 23 31 10 27 24 + 24 24 24 31 31 0 18 21 29 24 28 23 25 28 10 21 19 + 24 24 10 18 11 27 20 31 18 19 25 14 26 24 27 25 21 + 19 25 25 25 10 24 26 31 15 31 19 24 20 23 30 24 14 + 30 31 27 21 23 15 0 24 24 27 10 12 24 31 12 21 15 + 28 10 10 0 15 27 15 28 10 27 15 11 19 24 0 0 27 + 12 25 25 31 23 24 12 24 10 15 14 24 25 10 27 25 12 + 31 19 15 10 30 14 10 14 10 28 23 19 10 20 16 31 27 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 0 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 17 15 14 28 15 28 24 14 24 20 24 23 20 20 10 24 11 + 27 23 23 27 21 25 27 11 19 28 28 26 28 20 12 11 28 + 28 28 21 28 28 23 28 28 28 27 28 12 24 28 0 23 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 15 15 27 + 28 28 20 14 28 28 24 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 28 27 15 28 28 28 16 24 28 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 10 24 24 19 23 27 23 15 15 + 15 10 11 12 20 15 19 27 23 25 27 27 25 16 27 27 15 + 14 14 17 15 16 11 10 10 27 12 15 12 10 10 22 10 15 + 15 12 10 27 24 15 12 15 25 19 26 27 12 24 19 24 19 + 18 26 25 12 15 15 16 28 27 11 14 10 16 15 27 5 15 + 23 15 12 15 15 27 23 21 12 15 11 18 11 15 27 21 23 + 12 19 26 23 25 15 23 15 23 26 15 24 10 12 15 11 21 + 28 11 12 11 26 17 15 16 26 16 27 12 23 16 14 15 24 + 15 15 0 21 20 24 27 14 14 10 27 24 14 15 25 21 25 + 19 27 27 27 25 10 24 19 27 19 24 25 23 14 27 27 0 + 0 11 19 15 20 15 24 15 27 25 24 14 11 26 0 15 24 + 15 26 27 26 15 24 26 24 27 15 20 26 27 23 23 16 10 + + 15 15 14 28 15 28 24 14 15 20 24 23 20 20 15 24 15 + 27 23 23 27 21 25 27 11 15 28 28 26 28 20 15 11 28 + 28 28 15 28 28 15 28 28 28 27 28 15 24 28 15 15 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 11 11 27 + 28 28 20 14 28 28 15 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 28 27 15 28 28 28 16 24 28 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 15 24 24 10 23 27 23 15 15 + 12 15 15 15 20 0 4 27 23 25 27 27 25 15 27 27 15 + 14 14 15 15 16 15 10 10 27 15 14 10 10 15 15 15 15 + 15 12 10 27 24 15 10 15 25 18 26 27 12 24 10 24 15 + 18 26 25 15 15 15 16 28 27 15 14 15 16 15 27 9 15 + 15 15 15 15 15 27 23 21 15 15 15 18 15 12 27 21 23 + 15 15 26 23 25 0 23 15 23 26 11 24 10 12 0 11 21 + 28 15 15 11 26 15 10 16 26 16 27 12 23 16 14 15 24 + 14 15 15 21 20 24 27 14 14 15 27 24 14 15 25 21 25 + 11 27 27 27 25 15 24 11 27 4 24 25 23 14 27 27 15 + 25 0 12 15 20 15 24 15 27 25 24 14 15 26 15 11 24 + 15 26 27 26 14 24 26 24 27 11 20 26 27 23 23 16 4 + + 17 12 12 27 18 27 23 12 24 16 24 23 16 16 10 23 12 + 26 20 20 25 18 24 26 12 19 27 27 25 27 16 10 6 27 + 27 27 21 27 27 23 27 27 27 25 27 11 24 27 11 23 24 + 18 6 20 23 18 26 24 24 27 27 23 25 20 26 15 15 25 + 27 27 16 12 27 27 24 23 27 23 27 18 27 14 27 27 27 + 27 27 27 27 27 12 27 25 12 27 27 27 14 23 27 12 21 + 23 26 14 20 14 20 15 6 27 27 27 27 27 27 27 27 20 + 27 27 12 27 27 27 27 12 12 23 23 19 21 26 21 18 12 + 15 10 0 10 16 15 19 26 20 24 26 25 24 16 26 26 12 + 12 12 17 18 20 0 10 10 25 15 16 12 10 10 22 12 18 + 12 15 10 26 23 18 12 18 24 19 25 25 10 23 19 24 19 + 15 25 24 10 18 12 15 27 25 0 12 10 14 18 26 11 12 + 23 12 11 18 18 25 21 18 15 12 12 15 0 15 26 18 23 + 11 19 25 21 24 15 20 18 21 25 15 23 10 11 15 6 18 + 27 0 10 6 25 17 15 20 25 20 25 11 20 14 16 15 23 + 16 18 11 18 16 23 25 12 12 12 26 24 12 18 24 19 24 + 19 25 26 25 24 12 24 19 26 19 23 24 21 12 25 26 11 + 24 0 0 18 16 12 24 12 26 24 23 12 0 25 11 15 24 + 18 25 25 25 16 23 25 23 26 15 16 25 26 20 23 20 11 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 0 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 0 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 31 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 20 20 21 16 27 16 10 21 21 15 10 11 15 15 24 3 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 20 16 16 20 16 16 16 14 16 23 10 16 24 20 10 + 14 23 12 10 27 15 16 10 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 21 11 16 10 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 20 16 16 16 18 10 16 21 12 + 3 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 2 6 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 12 11 15 14 12 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 20 24 27 + 20 26 24 15 9 27 24 27 12 16 12 16 23 3 24 10 27 + 16 12 16 23 27 20 18 16 14 23 21 24 18 27 15 24 20 + 20 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 16 + 23 20 12 12 12 24 12 27 12 16 23 3 24 23 24 23 14 + 16 23 23 23 12 20 24 28 12 28 16 23 16 18 27 20 7 + 27 27 24 14 15 10 14 21 21 24 15 10 21 27 11 16 12 + 25 14 15 14 12 24 12 25 15 24 10 12 16 21 14 15 24 + 11 23 23 27 15 0 10 20 15 12 6 21 23 12 24 23 10 + 27 16 14 12 27 5 12 3 15 25 15 16 15 12 11 28 24 + + 20 20 21 16 27 16 10 21 22 15 10 11 15 15 24 1 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 20 16 16 21 16 16 16 14 16 23 10 16 24 21 10 + 14 23 12 10 27 15 18 10 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 22 11 16 10 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 20 16 16 16 18 10 16 21 12 + 5 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 4 7 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 12 11 15 14 13 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 20 24 27 + 20 26 24 15 11 27 24 27 13 18 12 18 23 1 24 10 27 + 16 13 18 23 27 20 18 18 14 23 21 24 18 27 15 24 20 + 21 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 18 + 23 20 12 12 12 24 12 27 12 18 23 4 24 23 24 23 14 + 18 23 23 23 12 20 24 28 13 28 18 23 18 18 27 20 8 + 27 27 24 14 15 10 14 21 21 24 15 10 21 27 11 18 13 + 25 14 15 14 13 24 13 25 15 24 10 12 18 21 14 15 24 + 11 23 23 27 15 20 0 20 15 13 7 21 23 12 24 23 10 + 27 18 14 12 27 6 12 4 15 25 15 18 15 12 11 28 24 + + 20 20 21 16 27 16 10 21 21 15 10 11 15 15 24 3 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 20 16 16 20 16 16 16 14 16 23 10 16 24 20 10 + 14 23 12 10 27 15 16 10 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 21 11 16 10 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 20 16 16 16 18 10 16 21 12 + 3 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 2 6 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 12 11 15 14 12 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 20 24 27 + 20 26 24 15 9 27 24 27 12 16 12 16 23 3 24 10 27 + 16 12 16 23 27 20 18 16 14 23 21 24 18 27 15 24 20 + 20 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 16 + 23 20 12 12 12 24 12 27 12 16 23 3 24 23 24 23 14 + 16 23 23 23 12 20 24 28 12 28 16 23 16 18 27 20 7 + 27 27 24 14 15 10 14 21 21 24 15 10 21 27 11 16 12 + 25 14 15 14 12 24 12 25 15 24 10 12 16 21 14 15 24 + 11 23 23 27 15 20 10 0 15 12 6 21 23 12 24 23 10 + 27 16 14 12 27 5 12 3 15 25 15 16 15 12 11 28 24 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 0 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 0 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 28 23 19 0 21 18 31 27 + + 20 20 21 16 27 16 10 21 21 15 10 11 15 15 24 3 25 + 15 12 12 14 14 12 15 25 20 16 16 12 16 15 23 23 16 + 16 16 20 16 16 20 16 16 16 14 16 23 10 16 24 20 10 + 14 23 12 10 27 15 16 10 16 16 10 14 28 15 23 25 14 + 16 16 15 21 16 16 21 11 16 10 16 27 16 25 16 16 16 + 16 16 16 16 16 20 16 14 20 16 16 16 18 10 16 21 12 + 3 15 18 12 18 12 16 23 16 16 16 16 16 16 16 16 12 + 16 16 24 16 16 16 16 20 24 2 6 24 12 15 12 27 20 + 25 24 23 23 15 24 24 15 12 11 15 14 12 20 15 15 20 + 21 21 20 27 28 23 24 24 14 26 27 24 24 24 20 24 27 + 20 26 24 15 9 27 24 27 12 16 12 16 23 3 24 10 27 + 16 12 16 23 27 20 18 16 14 23 21 24 18 27 15 24 20 + 20 20 23 27 27 14 12 14 26 20 25 16 23 25 15 14 16 + 23 20 12 12 12 24 12 27 12 16 23 3 24 23 24 23 14 + 16 23 23 23 12 20 24 28 12 28 16 23 16 18 27 20 7 + 27 27 24 14 15 10 14 21 21 24 15 10 21 27 11 16 12 + 25 14 15 14 12 24 12 25 15 24 10 12 16 21 14 15 24 + 11 23 23 27 15 20 10 20 15 12 0 21 23 12 24 23 10 + 27 16 14 12 27 5 12 3 15 25 15 16 15 12 11 28 24 + + 18 18 20 18 27 18 9 20 24 14 11 10 14 14 23 10 24 + 16 12 12 15 12 12 16 24 19 18 18 14 18 14 23 23 18 + 18 18 21 18 18 23 18 18 18 15 18 21 11 18 24 23 11 + 12 23 12 6 27 16 19 11 18 18 5 15 27 16 23 24 15 + 18 18 15 20 18 18 24 10 18 11 18 27 18 25 18 18 18 + 18 18 18 18 18 18 18 15 18 18 18 18 16 9 18 20 11 + 10 16 16 12 16 12 15 23 18 18 18 18 18 18 18 18 12 + 18 18 24 18 18 18 18 18 24 10 10 24 11 16 11 27 18 + 25 23 23 23 14 24 24 16 14 12 16 15 15 18 16 16 18 + 20 20 18 27 27 23 23 23 15 25 26 23 23 23 22 24 27 + 18 25 23 16 12 27 23 27 15 19 14 19 23 10 24 11 27 + 15 15 19 23 27 18 16 19 15 23 20 23 16 27 16 24 18 + 23 18 21 27 27 15 11 12 25 18 24 15 23 25 16 12 19 + 21 19 14 11 12 24 12 27 14 19 23 10 23 21 24 23 15 + 19 23 23 23 14 18 23 27 15 27 19 21 19 16 26 18 10 + 26 27 24 12 14 10 15 20 20 24 16 11 20 27 12 19 15 + 24 15 16 15 15 24 15 24 16 24 9 12 19 20 15 16 24 + 12 23 23 27 14 18 11 18 16 15 10 0 23 14 24 23 11 + 27 19 15 14 26 10 14 10 16 24 14 19 16 12 10 27 24 + + 20 20 18 30 12 30 25 18 20 23 26 24 23 23 15 25 15 + 29 24 24 28 23 27 29 10 20 30 30 28 30 23 15 14 30 + 30 30 20 30 30 20 30 30 30 28 30 16 26 30 15 20 26 + 23 14 24 25 15 29 27 26 30 30 25 28 12 29 14 10 28 + 30 30 23 18 30 30 20 24 30 25 30 15 30 4 30 30 30 + 30 30 30 30 30 20 30 28 20 30 30 30 21 25 30 18 24 + 25 29 21 24 21 24 23 14 30 30 30 30 30 30 30 30 24 + 30 30 11 30 30 30 30 20 15 25 25 11 24 29 24 15 20 + 0 15 15 15 23 12 12 29 24 27 29 28 27 20 29 29 20 + 18 18 20 15 12 15 12 12 28 15 11 12 12 15 20 15 15 + 20 10 12 29 25 15 12 15 27 23 28 28 15 25 11 26 12 + 23 28 27 15 15 20 21 30 28 15 18 15 21 15 29 12 20 + 20 20 16 15 12 28 24 23 15 20 15 23 15 0 29 23 24 + 16 20 28 24 27 12 24 15 24 28 14 25 12 16 12 14 23 + 30 15 15 14 28 20 12 12 28 12 28 16 24 21 11 20 25 + 11 12 15 23 23 25 28 18 18 15 29 26 18 15 27 23 27 + 10 28 29 28 27 15 26 10 29 12 25 27 24 18 28 29 15 + 27 15 15 15 23 20 26 20 29 27 25 18 0 28 15 14 26 + 15 28 28 28 11 25 28 25 29 10 23 28 29 24 24 12 12 + + 17 12 12 27 18 27 23 12 24 16 24 23 16 16 10 23 12 + 26 20 20 25 18 24 26 12 19 27 27 25 27 16 10 6 27 + 27 27 21 27 27 23 27 27 27 25 27 11 24 27 11 23 24 + 18 6 20 23 18 26 24 24 27 27 23 25 20 26 15 15 25 + 27 27 16 12 27 27 24 23 27 23 27 18 27 14 27 27 27 + 27 27 27 27 27 12 27 25 12 27 27 27 14 23 27 12 21 + 23 26 14 20 14 20 15 6 27 27 27 27 27 27 27 27 20 + 27 27 12 27 27 27 27 12 12 23 23 19 21 26 21 18 12 + 15 10 0 10 16 15 19 26 20 24 26 25 24 16 26 26 12 + 12 12 17 18 20 0 10 10 25 15 16 12 10 10 22 12 18 + 12 15 10 26 23 18 12 18 24 19 25 25 10 23 19 24 19 + 15 25 24 10 18 12 15 27 25 0 12 10 14 18 26 11 12 + 23 12 11 18 18 25 21 18 15 12 12 15 0 15 26 18 23 + 11 19 25 21 24 15 20 18 21 25 15 23 10 11 15 6 18 + 27 0 10 6 25 17 15 20 25 20 25 11 20 14 16 15 23 + 16 18 11 18 16 23 25 12 12 12 26 24 12 18 24 19 24 + 19 25 26 25 24 12 24 19 26 19 23 24 21 12 25 26 11 + 24 0 19 18 16 12 24 12 26 24 23 12 0 0 11 15 24 + 18 25 25 25 16 23 25 23 26 15 16 25 26 20 23 20 11 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 0 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 17 15 14 28 15 28 24 14 24 20 24 23 20 20 10 24 11 + 27 23 23 27 21 25 27 11 19 28 28 26 28 20 12 11 28 + 28 28 21 28 28 23 28 28 28 27 28 12 24 28 0 23 24 + 21 11 23 24 15 27 25 24 28 28 24 27 16 27 15 15 27 + 28 28 20 14 28 28 24 23 28 24 28 15 28 12 28 28 28 + 28 28 28 28 28 15 28 27 15 28 28 28 16 24 28 14 23 + 24 27 16 23 16 23 18 11 28 28 28 28 28 28 28 28 23 + 28 28 10 28 28 28 28 15 10 24 24 19 23 27 23 15 15 + 15 10 11 12 20 15 19 27 23 25 27 27 25 16 27 27 15 + 14 14 17 15 16 11 10 10 27 12 15 12 10 10 22 10 15 + 15 12 10 27 24 15 12 15 25 19 26 27 12 24 19 24 19 + 18 26 25 12 15 15 16 28 27 11 14 10 16 15 27 5 15 + 23 15 12 15 15 27 23 21 12 15 11 18 11 15 27 21 23 + 12 19 26 23 25 15 23 15 23 26 15 24 10 12 15 11 21 + 28 11 12 11 26 17 15 16 26 16 27 12 23 16 14 15 24 + 15 15 0 21 20 24 27 14 14 10 27 24 14 15 25 21 25 + 19 27 27 27 25 10 24 19 27 19 24 25 23 14 27 27 0 + 25 11 19 15 20 15 24 15 27 25 24 14 11 26 0 0 24 + 15 26 27 26 15 24 26 24 27 15 20 26 27 23 23 16 10 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 0 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 0 18 14 12 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 21 21 23 15 28 15 11 23 24 16 11 12 16 16 24 10 25 + 14 14 14 12 15 11 15 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 23 15 15 15 12 15 23 0 15 24 23 9 + 15 24 14 11 28 14 19 10 15 15 11 12 28 15 24 25 12 + 15 15 16 23 15 15 24 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 10 14 12 15 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 22 25 28 + 21 27 24 14 12 28 24 28 15 19 12 19 23 10 25 6 28 + 18 15 19 23 28 21 20 19 12 24 23 24 20 28 14 24 21 + 23 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 19 + 23 21 12 12 11 24 14 28 14 19 24 10 24 23 24 24 15 + 19 24 23 24 12 21 24 28 15 28 19 23 19 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 9 23 28 10 19 15 + 25 12 14 12 15 25 15 25 14 24 11 11 19 23 12 15 24 + 10 24 23 28 16 21 9 21 14 15 10 23 24 12 24 24 0 + 28 0 15 12 27 10 12 10 14 25 16 19 14 14 12 28 24 + + 23 23 23 31 15 31 27 23 24 24 28 26 24 24 16 27 12 + 31 25 25 31 24 29 31 12 23 31 31 30 31 24 20 18 31 + 31 31 23 31 31 23 31 31 31 31 31 21 28 31 15 23 28 + 24 18 25 27 0 31 28 28 31 31 27 31 10 31 18 15 31 + 31 31 24 23 31 31 24 26 31 27 31 0 31 12 31 31 31 + 31 31 31 31 31 23 31 31 23 31 31 31 23 27 31 23 25 + 27 31 23 25 23 25 24 18 31 31 31 31 31 31 31 31 25 + 31 31 14 31 31 31 31 23 14 27 27 19 25 31 25 0 23 + 15 16 18 20 24 15 19 31 25 28 31 31 28 23 31 31 23 + 23 23 23 0 10 18 16 16 31 11 15 16 16 16 23 14 0 + 23 11 16 31 27 0 16 0 29 24 30 31 20 27 19 28 19 + 24 30 29 20 0 23 23 31 31 18 23 16 23 0 31 15 23 + 23 23 21 0 15 31 25 24 11 23 12 24 18 15 31 24 26 + 21 23 30 25 29 15 25 0 25 30 18 27 16 21 15 18 24 + 31 18 20 18 30 23 16 10 30 10 31 21 25 23 10 23 27 + 15 6 15 24 24 27 31 23 23 14 31 28 23 0 28 24 29 + 19 31 31 31 28 14 28 19 31 19 27 29 25 23 31 31 15 + 28 18 20 0 24 23 28 23 31 28 27 23 18 30 15 18 28 + 0 30 0 30 15 27 30 27 31 15 24 30 31 25 26 15 15 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 0 31 16 12 16 10 29 23 18 10 23 20 33 28 + + 23 23 24 12 30 12 14 24 24 21 12 15 21 21 25 12 27 + 11 18 18 10 20 10 15 27 23 12 12 0 12 21 24 25 12 + 12 12 23 12 12 23 12 12 12 10 12 24 12 12 26 23 12 + 20 25 18 14 30 11 19 12 12 12 14 10 31 15 25 27 10 + 12 12 21 24 12 12 24 15 12 14 12 30 12 28 12 12 12 + 12 12 12 12 12 23 12 10 23 12 12 12 23 14 12 24 16 + 12 11 23 18 23 18 23 25 12 12 12 12 12 12 12 12 18 + 12 12 27 12 12 12 12 23 27 12 12 27 16 11 16 30 23 + 28 25 25 24 21 26 26 11 18 11 11 10 15 23 11 11 23 + 24 24 23 30 31 25 25 25 10 28 29 25 25 25 23 27 30 + 23 28 25 11 12 30 25 30 15 23 10 19 24 12 27 12 30 + 23 15 19 24 30 23 23 19 10 25 24 25 23 30 11 26 23 + 23 23 24 30 30 10 16 20 28 23 27 23 25 28 11 20 19 + 24 23 0 16 10 26 18 30 16 19 25 12 25 24 26 25 20 + 19 25 24 25 0 23 25 31 15 31 19 24 19 23 29 23 12 + 29 30 26 20 21 14 10 24 24 27 11 12 24 30 11 20 15 + 27 10 11 10 15 27 15 27 11 26 14 10 19 24 10 15 26 + 11 25 24 30 21 23 12 23 11 15 12 24 25 6 26 25 12 + 30 19 15 0 0 12 0 12 11 27 21 19 11 18 15 31 26 + + 21 21 23 15 28 15 11 23 24 16 11 12 16 16 24 10 25 + 14 14 14 12 15 11 15 25 21 15 15 12 15 16 23 24 15 + 15 15 21 15 15 23 15 15 15 12 15 23 0 15 24 23 9 + 15 24 14 11 28 14 19 10 15 15 11 12 28 15 24 25 12 + 15 15 16 23 15 15 24 12 15 11 15 28 15 26 15 15 15 + 15 15 15 15 15 21 15 12 21 15 15 15 20 11 15 23 12 + 10 14 20 14 20 14 18 24 15 15 15 15 15 15 15 15 14 + 15 15 25 15 15 15 15 21 25 10 10 25 12 14 12 28 21 + 26 24 24 23 16 24 24 14 14 10 14 12 15 21 14 14 21 + 23 23 21 28 28 24 24 24 12 27 27 24 24 24 22 25 28 + 21 27 24 14 12 28 24 28 15 19 12 19 23 10 25 6 28 + 18 15 19 23 28 21 20 19 12 24 23 24 20 28 14 24 21 + 23 21 23 28 28 12 12 15 27 21 25 18 24 26 14 15 19 + 23 21 12 12 11 24 14 28 14 19 24 10 24 23 24 24 15 + 19 24 23 24 12 21 24 28 15 28 19 23 19 20 27 21 10 + 27 28 24 15 16 11 12 23 23 25 14 9 23 28 10 19 15 + 25 12 14 12 15 25 15 25 14 24 11 11 19 23 12 15 24 + 10 24 23 28 16 21 9 21 14 15 10 23 24 12 24 24 0 + 28 19 15 12 27 0 12 10 14 25 16 19 14 14 12 28 24 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 0 16 10 29 23 18 10 23 20 33 28 + + 23 23 24 12 30 12 14 24 24 21 12 15 21 21 25 12 27 + 11 18 18 10 20 10 15 27 23 12 12 0 12 21 24 25 12 + 12 12 23 12 12 23 12 12 12 10 12 24 12 12 26 23 12 + 20 25 18 14 30 11 19 12 12 12 14 10 31 15 25 27 10 + 12 12 21 24 12 12 24 15 12 14 12 30 12 28 12 12 12 + 12 12 12 12 12 23 12 10 23 12 12 12 23 14 12 24 16 + 12 11 23 18 23 18 23 25 12 12 12 12 12 12 12 12 18 + 12 12 27 12 12 12 12 23 27 12 12 27 16 11 16 30 23 + 28 25 25 24 21 26 26 11 18 11 11 10 15 23 11 11 23 + 24 24 23 30 31 25 25 25 10 28 29 25 25 25 23 27 30 + 23 28 25 11 12 30 25 30 15 23 10 19 24 12 27 12 30 + 23 15 19 24 30 23 23 19 10 25 24 25 23 30 11 26 23 + 23 23 24 30 30 10 16 20 28 23 27 23 25 28 11 20 19 + 24 23 0 16 10 26 18 30 16 19 25 12 25 24 26 25 20 + 19 25 24 25 0 23 25 31 15 31 19 24 19 23 29 23 12 + 29 30 26 20 21 14 10 24 24 27 11 12 24 30 11 20 15 + 27 10 11 10 15 27 15 27 11 26 14 10 19 24 10 15 26 + 11 25 24 30 21 23 12 23 11 15 12 24 25 6 26 25 12 + 30 19 15 0 29 12 0 0 11 27 21 19 11 18 15 31 26 + + 24 24 24 14 31 14 15 24 24 23 12 16 23 23 26 15 28 + 15 20 20 15 21 11 10 28 24 14 14 15 14 23 25 25 14 + 14 14 24 14 14 24 14 14 14 15 14 24 15 14 27 24 12 + 21 25 20 15 31 15 12 12 14 14 15 15 31 10 25 28 9 + 14 14 23 24 14 14 24 16 14 15 14 31 14 28 14 14 14 + 14 14 14 14 14 24 14 15 24 14 14 14 23 15 14 24 18 + 14 15 23 20 23 20 23 25 14 14 14 14 14 14 14 14 20 + 14 14 27 14 14 14 14 24 27 14 14 27 18 15 18 31 24 + 28 26 25 25 23 27 27 15 20 15 15 15 12 24 15 10 24 + 24 24 24 31 31 25 26 26 15 29 30 26 26 26 24 27 31 + 24 29 26 15 14 31 26 31 11 23 10 4 25 15 27 12 31 + 23 10 11 25 31 24 23 11 15 25 24 26 23 31 15 27 24 + 24 24 24 31 31 15 18 21 29 24 28 23 25 28 15 21 16 + 24 24 15 18 15 27 20 31 18 10 25 14 26 24 27 25 21 + 11 25 25 25 15 24 26 31 10 31 4 24 20 23 30 24 14 + 30 31 27 21 23 15 15 24 24 27 15 12 24 31 12 21 11 + 28 4 10 15 12 27 12 28 15 27 15 15 18 24 15 10 27 + 12 25 25 31 23 24 12 24 15 12 14 24 25 10 27 25 15 + 31 10 0 15 30 14 15 14 0 28 23 10 15 20 16 31 27 + + 24 24 24 10 31 10 16 24 24 23 14 18 23 23 27 15 28 + 0 21 21 10 23 12 15 28 24 10 10 11 10 23 25 26 10 + 10 10 24 10 10 24 10 10 10 10 10 25 14 10 27 24 14 + 23 26 21 16 31 0 19 14 10 10 16 10 31 15 26 28 10 + 10 10 23 24 10 10 24 18 10 16 10 31 10 29 10 10 10 + 10 10 10 10 10 24 10 10 24 10 10 10 24 16 10 24 20 + 15 0 24 21 24 21 23 26 10 10 10 10 10 10 10 10 21 + 10 10 28 10 10 10 10 24 28 15 15 28 20 0 20 31 24 + 29 27 26 25 23 27 27 0 21 12 0 10 15 24 0 6 24 + 24 24 24 31 31 26 27 27 10 30 31 27 27 27 24 28 31 + 24 30 27 0 15 31 27 31 15 23 11 19 25 15 28 14 31 + 23 15 19 25 31 24 24 19 10 26 24 27 24 31 0 27 24 + 24 24 25 31 31 10 20 23 30 24 28 23 26 29 0 23 19 + 25 24 11 20 12 27 21 31 20 19 26 15 27 25 27 26 23 + 19 26 25 26 11 24 27 31 15 31 19 25 21 24 31 24 15 + 31 31 27 23 23 16 10 24 24 28 0 14 24 31 12 23 15 + 28 10 6 10 15 28 15 28 0 27 16 12 20 24 10 15 27 + 12 26 25 31 23 24 14 24 0 15 15 24 26 11 27 26 14 + 31 19 15 11 31 15 11 15 0 0 23 19 0 21 18 31 27 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 0 18 10 23 20 33 28 + + 17 12 12 23 24 23 14 12 24 5 16 12 6 6 18 15 23 + 23 11 11 23 10 20 23 23 19 23 23 21 23 10 15 16 23 + 23 23 21 23 23 23 23 23 23 23 23 14 16 23 20 23 16 + 10 16 11 14 24 23 19 16 23 23 14 23 24 23 16 23 23 + 23 23 15 12 23 23 24 12 23 14 23 24 23 23 23 23 23 + 23 23 23 23 23 12 23 23 12 23 23 23 11 14 23 12 12 + 15 23 11 11 11 11 10 16 23 23 23 23 23 23 23 23 11 + 23 23 21 23 23 23 23 12 21 15 15 21 12 23 12 24 12 + 23 18 16 15 10 20 20 23 14 18 23 23 18 16 23 23 12 + 12 12 17 24 24 16 18 18 23 23 24 18 18 18 22 21 24 + 12 23 18 23 15 24 18 24 20 19 21 23 15 15 21 16 24 + 10 21 20 15 24 12 15 23 23 16 12 18 11 24 23 20 12 + 23 12 14 24 24 23 12 10 23 12 23 10 16 23 23 10 19 + 14 19 21 12 20 20 11 24 14 21 16 15 18 14 20 16 15 + 23 16 15 16 21 17 18 24 21 24 23 14 19 11 24 15 15 + 24 24 20 10 5 14 23 12 12 21 23 16 12 24 18 19 20 + 23 23 23 23 18 21 16 23 23 20 14 20 19 12 23 23 20 + 18 16 19 24 14 12 16 12 23 18 15 12 16 21 20 16 16 + 24 21 23 21 24 15 21 15 23 23 0 0 23 11 12 24 20 + + 23 23 23 14 28 14 12 23 23 18 10 15 18 18 24 15 26 + 15 15 15 15 16 10 12 26 23 14 14 15 14 18 24 24 14 + 14 14 23 14 14 23 14 14 14 15 14 23 15 14 25 23 10 + 16 24 15 12 28 15 4 10 14 14 12 15 29 12 24 26 12 + 14 14 18 23 14 14 23 12 14 12 14 28 14 27 14 14 14 + 14 14 14 14 14 23 14 15 23 14 14 14 21 12 14 23 14 + 11 15 21 15 21 15 20 24 14 14 14 14 14 14 14 14 15 + 14 14 25 14 14 14 14 23 25 11 11 25 14 15 14 28 23 + 27 24 24 24 18 25 25 15 15 15 15 15 0 23 15 12 23 + 23 23 23 28 29 24 24 24 15 27 28 24 24 24 23 25 28 + 23 27 24 15 11 28 24 28 10 20 11 12 24 15 25 10 28 + 20 11 10 24 28 23 21 14 15 24 23 24 21 28 15 25 23 + 23 23 23 28 28 15 14 16 27 23 26 20 24 27 15 16 12 + 23 23 15 14 15 25 15 28 14 11 24 11 24 23 25 24 16 + 14 24 24 24 15 23 24 29 11 29 12 23 15 21 28 23 11 + 28 28 25 16 18 12 15 23 23 25 15 10 23 28 4 16 10 + 26 12 12 15 0 25 10 26 15 25 12 15 14 23 15 12 25 + 9 24 24 28 18 23 10 23 15 0 11 23 24 11 25 24 15 + 28 11 12 15 28 11 15 11 15 26 18 11 0 15 15 29 25 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 0 20 33 28 + + 24 24 25 0 31 0 18 25 24 23 15 20 23 23 27 16 29 + 10 23 23 11 23 12 14 29 24 0 0 12 0 23 26 27 0 + 0 0 24 0 0 24 0 0 0 11 0 25 15 0 28 24 15 + 23 27 23 18 31 10 18 15 0 0 18 11 33 14 27 29 11 + 0 0 23 25 0 0 24 20 0 18 0 31 0 30 0 0 0 + 0 0 0 0 0 24 0 11 24 0 0 0 24 18 0 25 21 + 16 10 24 23 24 23 24 27 0 0 0 0 0 0 0 0 23 + 0 0 28 0 0 0 0 24 28 16 16 28 21 10 21 31 24 + 30 27 27 26 23 28 28 10 23 14 10 11 14 24 10 10 24 + 25 25 24 31 33 27 27 27 11 31 31 27 27 27 24 28 31 + 24 31 27 10 16 31 27 31 14 24 12 18 26 16 28 15 31 + 24 14 18 26 31 24 24 18 11 27 25 27 24 31 10 28 24 + 24 24 25 31 31 11 21 23 31 24 29 24 27 30 10 23 20 + 25 24 12 21 12 28 23 31 21 18 27 16 27 25 28 27 23 + 18 27 26 27 12 24 27 33 14 33 18 25 23 24 31 24 16 + 31 31 28 23 23 18 11 25 25 28 10 15 25 31 14 23 14 + 29 11 10 11 14 28 15 29 10 28 18 12 21 25 11 14 28 + 14 27 26 31 23 24 15 24 10 14 16 25 27 12 28 27 15 + 31 18 14 12 31 16 12 16 10 29 23 18 10 23 0 33 28 + + 17 14 15 23 25 23 12 15 24 11 14 11 11 11 21 12 23 + 21 6 11 20 10 16 21 23 19 23 23 18 23 11 18 20 23 + 23 23 21 23 23 23 23 23 23 20 23 16 14 23 23 23 14 + 10 20 8 12 25 21 19 14 23 23 12 20 25 21 20 23 20 + 23 23 15 15 23 23 24 11 23 12 23 25 23 24 23 23 23 + 23 23 23 23 23 14 23 20 14 23 23 23 12 12 23 15 10 + 12 21 12 8 12 5 12 20 23 23 23 23 23 23 23 23 11 + 23 23 23 23 23 23 23 14 23 12 12 23 10 21 10 25 14 + 24 21 20 18 11 23 23 21 14 15 21 20 15 16 21 21 14 + 15 15 17 25 25 20 21 21 20 24 24 21 21 21 22 23 25 + 14 24 21 21 12 25 21 25 16 19 18 20 18 12 23 14 25 + 12 18 19 18 25 14 15 23 20 20 15 21 12 25 21 23 14 + 23 14 16 25 25 20 10 10 24 14 23 12 20 24 21 10 19 + 16 19 18 10 16 23 11 25 14 19 20 12 21 16 23 20 15 + 23 20 18 20 18 17 21 25 18 25 20 16 19 12 24 15 12 + 24 25 23 10 11 12 20 15 15 23 21 14 15 25 15 19 16 + 23 20 21 20 15 23 15 23 21 23 12 16 19 15 20 21 23 + 15 20 19 25 14 14 14 14 21 15 12 15 20 18 23 20 14 + 25 19 20 18 24 12 18 12 21 23 11 19 21 0 11 0 23 + + 17 16 18 20 26 20 10 18 24 12 12 0 12 12 23 11 24 + 18 11 11 16 12 14 18 24 19 20 20 15 20 12 21 23 20 + 20 20 21 20 20 23 20 20 20 16 20 20 12 20 23 23 12 + 12 23 11 10 26 18 19 12 20 20 10 16 27 18 23 24 16 + 20 20 15 18 20 20 24 8 20 11 20 26 20 24 20 20 20 + 20 20 20 20 20 16 20 16 16 20 20 20 15 10 20 18 10 + 11 18 15 11 15 11 14 23 20 20 20 20 20 20 20 20 11 + 20 20 24 20 20 20 20 16 24 11 11 24 10 18 10 26 16 + 24 23 23 21 12 23 23 18 14 12 18 16 15 16 18 18 16 + 18 18 17 26 27 23 23 23 16 25 25 23 23 23 22 24 26 + 16 25 23 18 12 26 23 26 15 19 15 19 21 11 24 12 26 + 14 15 19 21 26 16 15 20 16 23 18 23 15 26 18 23 16 + 23 16 20 26 26 16 10 12 25 16 24 14 23 24 18 12 19 + 20 19 15 10 14 23 11 26 14 19 23 11 23 20 23 23 15 + 20 23 21 23 15 17 23 27 15 27 19 20 19 15 25 16 11 + 25 26 23 12 12 10 16 18 18 24 18 12 18 26 12 19 15 + 24 16 18 16 15 24 15 24 18 23 10 14 19 18 16 18 23 + 12 23 21 26 14 16 12 16 18 15 11 18 23 15 23 23 12 + 26 19 16 15 25 11 15 11 18 24 12 19 18 11 0 27 0 +EOF diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/ATSP-instances/ry48p.atsp b/ProyectoFinal/CHC/malva/ProblemInstances/ATSP-instances/ry48p.atsp new file mode 100644 index 0000000000000000000000000000000000000000..b02a98c289107d68e881a985a4cf2c8a1c6ff4e2 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/ATSP-instances/ry48p.atsp @@ -0,0 +1,200 @@ +NAME: ry48p +TYPE: ATSP +COMMENT: Asymmetric TSP (Fischetti) +DIMENSION: 48 +EDGE_WEIGHT_TYPE: EXPLICIT +EDGE_WEIGHT_FORMAT: FULL_MATRIX +EDGE_WEIGHT_SECTION + 9999999 1593 569 2056 1327 1009 947 301 234 1800 625 700 754 790 529 + 395 1385 856 1179 821 1085 385 730 1808 915 2076 1120 1002 1297 1026 + 592 1448 694 743 2254 880 1137 330 1121 449 786 1594 1264 755 2354 + 593 849 1216 + 1619 9999999 1191 656 595 2304 2128 1797 1674 834 1348 1620 1183 1050 1629 + 1339 2444 2039 2350 1646 1334 1322 1167 1079 1182 624 2307 2171 478 2272 + 1923 1192 1837 982 1060 2132 2312 1884 1047 1513 1051 550 2287 2125 1123 + 1765 1388 718 + 528 1297 9999999 1682 809 1309 1170 624 506 1445 526 488 561 402 610 + 429 1510 1072 1419 882 801 250 401 1351 485 1579 1436 1194 898 1194 + 816 1054 728 471 1828 1000 1276 837 898 465 459 1183 1314 989 1876 + 708 620 968 + 2097 723 1781 9999999 996 2674 2595 2360 2236 501 1846 2061 1616 1580 2108 + 1884 2678 2590 2635 2068 1584 1847 1638 930 1328 187 2635 2582 948 2669 + 2421 1197 2183 1506 620 2438 2782 2337 1328 1959 1513 680 2603 2497 648 + 2142 1827 1058 + 1310 680 780 1023 9999999 1690 1754 1424 1279 787 900 1153 759 612 1201 + 1098 1918 1682 1858 1148 876 975 761 759 639 820 1759 1651 417 1694 + 1459 718 1292 566 1005 1632 1870 1540 493 1131 954 496 1760 1629 1144 + 1306 886 295 + 1156 2218 1336 2687 1745 9999999 358 1020 964 2253 998 774 1089 1369 692 + 1349 364 339 249 801 1187 1286 1135 2157 1442 2473 276 303 1881 258 + 681 1588 708 1488 2624 391 254 704 1508 879 1636 2165 300 429 2588 + 668 1014 1735 + 827 2103 1085 2504 1692 258 9999999 972 759 2236 834 724 970 1102 604 + 1227 535 54 493 551 1165 1066 974 1908 1239 2379 508 124 1677 311 + 386 1483 590 1382 2444 204 391 614 1437 820 1410 2049 471 245 2595 + 386 858 1615 + 190 1684 698 2274 1395 1116 792 9999999 387 2016 797 691 984 1055 677 + 445 1348 868 1148 936 1246 404 816 1965 1191 2206 1272 1050 1323 1057 + 505 1607 839 890 2379 972 1098 327 1471 545 973 1756 1200 786 2415 + 616 920 1552 + 217 1673 526 2144 1366 1009 796 413 9999999 1941 696 570 899 793 452 + 515 1094 619 1003 758 937 524 615 1760 1020 2103 1133 749 1323 900 + 465 1379 477 762 2222 632 1020 317 1178 247 908 1609 1140 473 2205 + 392 824 1237 + 1892 856 1591 636 780 2323 2205 2133 2014 9999999 1544 1649 1258 1170 1709 + 1716 2377 2141 2443 1629 1320 1686 1395 378 1015 383 2367 2191 833 2283 + 2062 800 1897 1257 448 2138 2287 2109 803 1810 1520 415 2270 2119 478 + 1932 1486 706 + 660 1316 535 1817 893 1084 780 764 592 1407 9999999 323 304 464 344 + 787 1129 839 1180 507 450 669 189 1400 416 1760 992 905 963 975 + 745 890 503 643 1901 829 1118 775 749 403 986 1343 1039 813 1921 + 564 418 853 + 673 1626 580 1892 1168 829 719 745 438 1582 366 9999999 537 648 217 + 787 1031 541 896 370 568 609 434 1536 589 1928 807 792 1282 790 + 677 930 214 705 1993 690 926 561 936 442 987 1422 772 547 1895 + 410 343 1015 + 786 1289 570 1603 682 1203 1059 956 885 1353 297 547 9999999 328 632 + 937 1377 1023 1316 495 332 849 227 1130 254 1474 1322 1106 933 1097 + 955 530 617 535 1634 949 1254 884 521 702 891 1051 1127 1096 1568 + 844 326 758 + 776 1066 499 1584 536 1245 1106 1016 913 1157 331 690 236 9999999 746 + 720 1414 1137 1420 747 457 711 234 1016 211 1370 1479 1144 617 1341 + 1115 761 697 443 1549 1172 1452 939 461 555 768 949 1319 1135 1589 + 791 555 566 + 434 1750 629 2111 1152 812 635 592 499 1693 299 220 686 769 9999999 + 837 1005 609 839 473 664 664 440 1510 773 2009 952 567 1243 788 + 531 1137 228 918 2134 466 902 500 1012 333 916 1638 889 435 2012 + 373 519 1160 + 430 1369 449 1956 1178 1364 1169 534 490 1736 747 829 850 721 832 + 9999999 1524 1019 1405 1055 1018 221 649 1586 854 1849 1420 1180 1082 1460 + 920 1405 886 659 2137 1144 1366 685 1164 621 512 1489 1507 1040 2047 + 848 988 1247 + 1295 2527 1426 2755 1976 340 497 1247 1189 2385 1187 918 1228 1425 1065 + 1531 9999999 659 233 866 1323 1565 1347 2089 1544 2637 126 545 2079 346 + 772 1567 751 1683 2693 613 274 1026 1535 1207 1826 2313 171 795 2715 + 822 1033 1946 + 851 2101 1064 2399 1615 452 196 834 668 2196 775 586 1078 1175 512 + 1028 645 9999999 513 509 1136 909 1009 1929 1194 2379 419 165 1787 323 + 377 1412 467 1184 2407 118 370 608 1422 609 1362 2042 507 269 2516 + 311 838 1685 + 1210 2372 1385 2679 1919 125 516 1170 1001 2442 1102 873 1280 1418 955 + 1398 269 524 9999999 759 1146 1399 1311 2170 1428 2617 79 287 2039 310 + 680 1564 664 1553 2738 407 99 894 1569 1003 1787 2101 329 655 2629 + 808 934 1871 + 723 1779 819 2056 1170 726 592 967 815 1664 406 377 543 649 370 + 1104 750 631 866 9999999 499 841 652 1371 782 1895 694 658 1243 682 + 724 937 213 1047 2019 544 735 791 814 500 1189 1511 799 550 1948 + 438 262 1047 + 1005 1475 840 1600 715 1188 1122 1256 970 1208 508 618 304 615 716 + 999 1175 1107 1206 542 9999999 984 461 1106 460 1480 1125 1128 1115 1054 + 1132 571 755 708 1546 1033 1198 987 545 798 1228 1161 1075 1037 1506 + 876 346 791 + 404 1421 317 1918 1059 1275 1025 420 534 1663 616 660 745 742 683 + 328 1491 904 1452 882 921 9999999 559 1624 718 1903 1280 1053 978 1282 + 710 1140 809 557 2124 984 1278 702 1022 491 558 1414 1335 949 2111 + 695 791 1189 + 546 1189 345 1638 718 1246 1034 781 682 1314 251 504 225 264 593 + 685 1412 863 1312 570 521 614 9999999 1221 414 1559 1246 970 860 1134 + 868 724 662 436 1807 986 1162 706 620 469 665 1181 1090 930 1741 + 586 412 770 + 1695 962 1414 866 621 1982 1923 1990 1749 352 1256 1480 1015 1106 1502 + 1646 2199 1954 2105 1419 1063 1542 1227 9999999 875 798 2153 1991 950 1929 + 1892 683 1620 1115 725 1886 2083 1857 766 1520 1554 459 2052 2040 646 + 1834 1330 537 + 952 1029 537 1441 451 1411 1250 1051 833 1110 524 581 184 228 691 + 923 1568 1237 1419 765 423 873 429 1023 9999999 1310 1350 1283 719 1235 + 1158 538 901 518 1452 1060 1373 1166 461 645 851 966 1332 1218 1365 + 945 553 568 + 2061 722 1713 298 813 2633 2414 2254 2162 487 1606 1867 1419 1350 1900 + 1728 2730 2455 2548 1965 1542 1732 1654 755 1299 9999999 2571 2564 831 2422 + 2357 1210 2057 1254 464 2359 2669 2163 1071 1856 1577 497 2540 2371 714 + 2232 1643 952 + 1173 2364 1322 2759 1912 246 530 1243 1011 2335 1125 907 1166 1454 860 + 1547 298 463 75 661 1197 1362 1227 2108 1302 2550 9999999 381 2018 248 + 661 1602 780 1547 2606 420 191 880 1573 1000 1781 2079 174 619 2648 + 753 963 1735 + 872 2158 1106 2574 1739 273 278 943 833 2234 799 677 1120 1245 559 + 1161 484 163 337 574 1169 1163 970 2001 1196 2375 300 9999999 1849 265 + 508 1383 470 1421 2587 298 224 586 1380 880 1471 2064 358 421 2425 + 553 898 1601 + 1284 503 875 979 375 1874 1736 1429 1243 911 1052 1170 836 658 1334 + 1037 1998 1731 2002 1427 1041 1120 857 969 674 971 1966 1800 9999999 1785 + 1630 936 1323 562 1243 1670 2000 1464 791 1188 747 482 2009 1704 1232 + 1380 1060 565 + 1099 2354 1305 2528 1734 138 418 1078 934 2189 1030 752 1046 1218 717 + 1360 411 417 261 556 1122 1145 1085 1986 1225 2534 255 247 1956 9999999 + 596 1445 581 1540 2501 244 146 896 1491 946 1677 2102 263 483 2439 + 674 965 1749 + 672 1921 948 2388 1537 594 394 495 425 2053 849 589 973 1137 388 + 847 886 350 613 693 1076 778 791 1943 1066 2367 690 390 1561 612 + 9999999 1467 530 1124 2558 369 690 287 1441 455 1363 1989 709 283 2489 + 373 800 1504 + 1387 1277 1020 1219 545 1467 1455 1553 1281 883 765 950 675 770 1139 + 1245 1543 1437 1541 853 570 1325 824 534 657 1287 1625 1490 863 1468 + 1542 9999999 1015 891 1183 1448 1554 1406 266 1142 1162 765 1435 1465 1175 + 1278 700 632 + 747 1668 719 2159 1183 633 500 722 525 1896 400 251 636 742 322 + 812 931 385 692 236 727 855 678 1643 847 1988 774 490 1324 685 + 411 1093 9999999 1028 2141 469 655 532 1049 427 1228 1649 725 424 2064 + 190 462 1251 + 702 1023 383 1383 644 1420 1272 914 824 1280 575 723 604 352 820 + 695 1665 1366 1642 867 806 648 542 1173 567 1316 1504 1408 601 1556 + 1093 826 937 9999999 1521 1187 1466 964 764 617 399 1000 1492 1147 1647 + 980 701 554 + 2318 1080 1876 516 1131 2587 2633 2328 2298 516 1836 2047 1595 1561 2094 + 2137 2690 2509 2644 1942 1545 1967 1716 700 1385 594 2612 2552 1137 2467 + 2474 1260 2162 1513 9999999 2468 2699 2387 1201 2007 1886 661 2545 2527 285 + 2358 1796 954 + 789 2177 966 2481 1629 411 179 930 754 2061 841 687 957 1116 621 + 1236 636 263 374 506 985 1055 927 1804 1104 2429 390 232 1693 296 + 499 1359 448 1361 2370 9999999 353 488 1394 800 1428 1896 532 217 2479 + 423 825 1536 + 1154 2403 1241 2712 1817 176 340 1199 1014 2320 1146 874 1232 1392 791 + 1398 350 419 151 739 1116 1282 1204 2209 1436 2570 289 240 1959 237 + 591 1666 726 1490 2732 312 9999999 855 1610 1063 1665 2126 207 600 2664 + 754 1054 1852 + 514 1895 655 2265 1531 739 492 329 290 2007 671 615 962 939 389 + 708 1052 549 850 682 1173 592 708 1878 1139 2305 1015 636 1528 843 + 313 1391 469 1078 2343 529 887 9999999 1286 361 1114 1923 979 340 2437 + 474 928 1576 + 1232 1141 943 1222 534 1485 1372 1439 1153 879 678 862 390 611 949 + 1157 1610 1385 1532 829 382 1057 770 734 483 1183 1580 1504 754 1350 + 1357 255 1001 641 1214 1312 1653 1420 9999999 1030 1168 709 1451 1329 1247 + 1090 653 364 + 262 1623 397 1915 1050 898 682 573 237 1775 342 439 636 698 196 + 638 1092 683 1125 578 695 364 487 1644 667 1815 1011 842 1238 1022 + 543 1179 456 771 2058 795 910 449 1058 9999999 812 1411 1112 610 2066 + 417 574 1033 + 798 1070 476 1489 790 1729 1582 940 954 1562 957 922 957 695 1068 + 567 1847 1458 1743 1210 1096 627 846 1502 838 1554 1835 1462 709 1766 + 1195 1150 1063 496 1727 1452 1803 1194 997 833 9999999 1159 1857 1385 1819 + 1098 1074 907 + 1536 598 1201 631 449 2195 2058 1776 1767 494 1261 1519 1138 900 1547 + 1459 2231 1924 2156 1470 993 1388 1175 407 955 569 2225 2090 501 2123 + 2002 841 1592 988 699 1868 2137 1899 658 1530 1127 9999999 2060 1916 745 + 1667 1272 510 + 1176 2389 1379 2717 1694 332 408 1260 1022 2321 1004 879 1079 1384 814 + 1588 250 496 217 685 1100 1308 1175 1985 1293 2589 236 498 1912 170 + 709 1428 781 1574 2471 530 212 851 1544 1096 1675 2133 9999999 708 2454 + 706 907 1672 + 619 2085 990 2459 1541 520 280 793 507 2204 821 644 1092 1176 420 + 948 636 231 605 629 1046 945 831 1990 1162 2387 600 416 1766 494 + 197 1483 420 1173 2410 250 615 445 1441 539 1294 1902 590 9999999 2434 + 423 757 1531 + 2281 1127 1889 727 1131 2498 2445 2443 2350 594 1874 2030 1591 1659 2192 + 2056 2593 2501 2532 1979 1553 2056 1761 577 1529 595 2553 2613 1292 2555 + 2474 1123 2106 1632 324 2448 2712 2465 1183 2151 1793 795 2542 2526 9999999 + 2196 1783 1001 + 584 1919 727 2331 1424 610 491 761 514 1839 455 427 733 833 282 + 933 769 376 712 433 886 636 694 1782 964 2210 748 583 1400 675 + 375 1234 152 1078 2279 377 665 332 1160 485 1090 1641 631 415 2342 + 9999999 645 1281 + 856 1456 670 1757 900 860 842 1110 831 1365 324 480 335 625 525 + 981 1008 896 1082 250 274 802 470 1140 486 1609 1062 832 1051 937 + 914 615 426 857 1856 786 1087 955 560 646 1048 1351 1035 809 1752 + 679 9999999 811 + 1209 724 957 1012 248 1750 1558 1373 1393 683 957 1018 588 633 1190 + 1169 1840 1656 1912 1112 811 1188 873 590 428 984 1759 1682 509 1743 + 1590 480 1202 703 1134 1594 1913 1515 346 1227 968 537 1714 1616 1145 + 1371 902 9999999 +EOF diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/DNAFA-instances/pbm.txt b/ProyectoFinal/CHC/malva/ProblemInstances/DNAFA-instances/pbm.txt new file mode 100644 index 0000000000000000000000000000000000000000..38c5037087b666772205bd1b5b3df10869fdf485 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/DNAFA-instances/pbm.txt @@ -0,0 +1,2 @@ +30 +/Mallba/ProblemInstances/DNAFA-instances/x60189_4.dat diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/DNAFA-instances/score.txt b/ProyectoFinal/CHC/malva/ProblemInstances/DNAFA-instances/score.txt new file mode 100644 index 0000000000000000000000000000000000000000..ff26d92ffee9db43bb3000c7413d23c456eb2822 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/DNAFA-instances/score.txt @@ -0,0 +1,39 @@ + 0 1 0 304 1 1 1 0 7 -163 247 1 2 1 1 0 0 2 0 1 1 1 2 1 1 107 0 1 3 1 1 0 1 286 1 3 0 1 1 + 1 0 1 1 -3 3 -1 331 -302 2 5 0 1 0 0 -1 -2 -2 2 281 0 -413 1 0 168 -2 2 0 -3 39 412 2 155 1 4 247 274 0 53 + 0 1 0 -2 225 0 2 1 0 -1 1 178 1 2 -2 -1 -2 -149 -3 -1 -2 2 1 366 -2 4 2 -2 -7 -2 -3 -363 -2 -2 -327 -1 -1 -353 -3 + 304 1 -2 0 -1 -27 -1 0 -1 -160 327 -3 43 -1 1 4 1 2 1 -1 1 -4 2 1 1 200 -1 1 1 1 1 2 1 283 -1 3 3 1 1 + 1 -3 225 -1 0 -2 -3 -3 -2 -1 0 1 0 -1 1 -1 -1 -279 -2 -2 2 0 -106 104 -2 1 2 -2 2 -1 -1 -252 0 -1 -65 0 -1 -250 -1 + 1 3 0 -27 -2 0 1 0 -2 -1 -14 -1 -346 1 -1 6 -88 -1 -241 -2 -1 1 0 1 -2 -276 1 -2 2 -2 -2 1 1 -1 -3 -1 0 3 3 + 1 -1 2 -1 -3 1 0 0 1 -1 -3 -1 2 -6 -414 0 -1 -2 -1 1 -301 2 99 1 1 1 271 6 1 -1 -1 -2 1 -1 1 -3 -2 -1 -1 + 0 331 1 0 -3 0 0 0 -302 0 1 0 1 0 0 1 2 2 3 185 0 -317 1 0 72 -4 2 0 0 2 316 2 155 0 0 247 178 0 3 + 7 -302 0 -1 -2 -2 1 -302 0 -26 2 -1 2 -4 -1 0 -1 -2 -1 -156 -1 288 -2 1 -43 1 1 -2 3 -1 -287 1 -306 -1 1 -377 -149 -1 -1 + -163 2 -1 -160 -1 -1 -1 0 -26 0 -103 2 1 -1 2 1 0 -1 0 -2 1 -1 -1 1 1 0 0 1 1 2 2 1 76 -289 -2 5 -2 2 2 + 247 5 1 327 0 -14 -3 1 2 -103 0 1 30 1 1 1 1 0 -2 1 2 0 1 0 -4 187 2 0 0 0 0 0 0 226 1 0 1 2 5 + 1 0 178 -3 1 -1 -1 0 -1 2 1 0 1 0 -2 -1 1 1 1 2 0 1 2 271 0 1 -1 -4 -309 161 1 -54 0 1 -316 -1 2 -44 23 + 2 1 1 43 0 -346 2 1 2 1 30 1 0 1 1 1 150 0 303 1 1 0 1 0 0 292 1 0 0 0 0 0 0 -2 1 0 1 1 0 + 1 0 2 -1 -1 1 -6 0 -4 -1 1 0 1 0 6 260 -251 2 -123 0 6 2 -1 0 0 1 -2 -300 0 2 -1 -2 0 -1 0 -3 -2 0 -1 + 1 0 -2 1 1 -1 -414 0 -1 2 1 -2 1 6 0 -1 1 1 3 2 301 -2 -79 0 0 1 -251 -6 0 1 1 2 0 1 2 3 2 0 1 + 0 -1 -1 4 -1 6 0 1 0 1 1 -1 1 260 -1 0 -306 2 -178 1 -2 -1 -1 0 0 -4 -2 -100 0 2 3 -2 0 0 1 1 1 -3 3 + 0 -2 -2 1 -1 -88 -1 2 -1 0 1 1 150 -251 1 -306 0 2 339 -1 1 -1 -1 1 1 18 -2 91 1 2 3 -2 1 1 -1 1 1 1 3 + 2 -2 -149 2 -279 -1 -2 2 -2 -1 0 1 0 2 1 2 2 0 -1 -1 1 -1 252 -28 1 2 115 3 1 1 1 176 1 2 -1 1 -1 174 1 + 0 2 -3 1 -2 -241 -1 3 -1 0 -2 1 303 -123 3 -178 339 -1 0 -1 1 -1 -1 1 1 171 0 1 1 2 2 1 1 1 -2 2 1 2 2 + 1 281 -1 -1 -2 -2 1 185 -156 -2 1 2 1 0 2 1 -1 -1 -1 0 0 -312 -1 0 324 1 1 -2 2 214 313 1 9 -1 -3 101 310 3 228 + 1 0 -2 1 2 -1 -301 0 -1 1 2 0 1 6 301 -2 1 1 1 0 0 -2 1 0 0 1 -138 -6 0 1 1 3 0 1 0 3 2 0 1 + 1 -413 2 -4 0 1 2 -317 288 -1 0 1 0 2 -2 -1 -1 -1 -1 -312 -2 0 1 -2 -199 1 1 -2 0 -70 -443 -2 -141 -2 3 -233 -305 1 -84 + 2 1 1 2 -106 0 99 1 -2 -1 1 2 1 -1 -79 -1 -1 252 -1 -1 1 1 0 -2 0 2 228 0 -2 0 0 3 -2 2 -1 2 -1 1 0 + 1 0 366 1 104 1 1 0 1 1 0 271 0 0 0 0 1 -28 1 0 0 -2 -2 0 0 1 -3 0 -100 1 1 -242 0 3 -420 0 2 -232 1 + 1 168 -2 1 -2 -2 1 72 -43 1 -4 0 0 0 0 0 1 1 1 324 0 -199 0 0 0 1 -3 -2 2 195 200 2 0 1 -3 0 204 3 209 + 107 -2 4 200 1 -276 1 -4 1 0 187 1 292 1 1 -4 18 2 171 1 1 1 2 1 1 0 0 1 -3 -2 -2 0 1 86 2 3 0 -2 -2 + 0 2 2 -1 2 1 271 2 1 0 2 -1 1 -2 -251 -2 -2 115 0 1 -138 1 228 -3 -3 0 0 1 1 -1 -1 -1 -3 -1 1 -2 -1 -1 -1 + 1 0 -2 1 -2 -2 6 0 -2 1 0 -4 0 -300 -6 -100 91 3 1 -2 -6 -2 0 0 -2 1 1 0 2 1 1 2 0 1 0 3 2 0 1 + 3 -3 -7 1 2 2 1 0 3 1 0 -309 0 0 0 0 1 1 1 2 0 0 -2 -100 2 -3 1 2 0 -141 1 1 0 -3 145 0 0 -3 -3 + 1 39 -2 1 -1 -2 -1 2 -1 2 0 161 0 2 1 2 2 1 2 214 1 -70 0 1 195 -2 -1 1 -141 0 71 -1 1 1 -1 1 75 1 291 + 1 412 -3 1 -1 -2 -1 316 -287 2 0 1 0 -1 1 3 3 1 2 313 1 -443 0 1 200 -2 -1 1 1 71 0 -1 140 1 -2 232 306 2 85 + 0 2 -363 2 -252 1 -2 2 1 1 0 -54 0 -2 2 -2 -2 176 1 1 3 -2 3 -242 2 0 -1 2 1 -1 -1 0 2 2 203 -1 1 378 -1 + 1 155 -2 1 0 1 1 155 -306 76 0 0 0 0 0 0 1 1 1 9 0 -141 -2 0 0 1 -3 0 0 1 140 2 0 3 0 285 2 0 1 + 286 1 -2 283 -1 -1 -1 0 -1 -289 226 1 -2 -1 1 0 1 2 1 -1 1 -2 2 3 1 86 -1 1 -3 1 1 2 3 0 -1 3 2 1 1 + 1 4 -327 -1 -65 -3 1 0 1 -2 1 -316 1 0 2 1 -1 -1 -2 -3 0 3 -1 -420 -3 2 1 0 145 -1 -2 203 0 -1 0 1 -2 193 4 + 3 247 -1 3 0 -1 -3 247 -377 5 0 -1 0 -3 3 1 1 1 2 101 3 -233 2 0 0 3 -2 3 0 1 232 -1 285 3 1 0 94 -2 1 + 0 274 -1 3 -1 0 -2 178 -149 -2 1 2 1 -2 2 1 1 -1 1 310 2 -305 -1 2 204 0 -1 2 0 75 306 1 2 2 -2 94 0 -1 89 + 1 0 -353 1 -250 3 -1 0 -1 2 2 -44 1 0 0 -3 1 174 2 3 0 1 1 -232 3 -2 -1 0 -3 1 2 378 0 1 193 -2 -1 0 2 + 1 53 -3 1 -1 3 -1 3 -1 2 5 23 0 -1 1 3 3 1 2 228 1 -84 0 1 209 -2 -1 1 -3 291 85 -1 1 1 4 1 89 2 0 diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/DNAFA-instances/x60189_4.dat b/ProyectoFinal/CHC/malva/ProblemInstances/DNAFA-instances/x60189_4.dat new file mode 100644 index 0000000000000000000000000000000000000000..2420540d8e2ec36ca87aa056d31adcdf8a1d7feb --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/DNAFA-instances/x60189_4.dat @@ -0,0 +1,78 @@ +>frag0000 +caccatctcaggcctggagccagaccataaatacaagatgaacctgtacggcttccacggtggccagcgcgtgggccccatctctgtcattggggtgacgggtgagtggatgatggcagccccagggtgggagccgtgggagggtcaccctcttgctctttggtgatgactggtggggaatgggccaggggtccggtcagcaccacagacctgcttgtggctggggctccccttggccttcctctgaggctgacccctggctcctcctgagcagggaggggccgtcaggagctctgctgtgctggtg +>frag0001 +agcacagctcttcatcctctcctctcctgtggcctttcctatccctcaccctgaccctcctgccctcagcccccacctcacccccacctcccaacacccaggccacctctccctgtccctccagcaccgcctctcttttgagcacagccccactcggcctctgcacccctggcctcccagcactggggtctcttcgccatcttttgttcactgggcttctgtctttgctccgcaacaagctcagcacactcctcccgaggccagagcctggggtgtgttcctggatccagctcctcaccagctgccagcagcctcagagcatctttaccctgaattcccctggataccttcctaccccacctccagtccccgatcctagtttgagccactgtcacctctcaccagggccaccaactgcctactggcc +>frag0002 +agggcacattttctagggctgtcttccaaccctgccccacccacactcactcacctgtgacgcccacggcagacaccgggcccaggcgccgcccctcgtggaggccgtacaggtgcatcttgtacttgcgcccaggctccaggcccctcacagtgaccttgctctcctggcccccaacacgcaccgcctggggccgcccgtccctgtccttgtactgcacggtgaaggagtcaaagcggccctgggggacggtccaggaaaggctcagcgagtcaggggaggatcctgtcactgtcagctcccccaggagaggctcctcggggggccctggggctctgtgcctggttctgtagggctgggggtctcgtccacatcctcttgtggggctgaaaggtaatatagggggatacagagtttaagggtttaagggcaacttgctttgctggtgctgtcaacagaggtcatacatcaaatgcgcccctccaga +>frag0003 +catctcaggcctggagccagaccataaatacaagatgaacctgtacggcttccacggtggccagcgcgtgggccccatctctgtcattggggtgacgggtgagtggatgatggcagccccagggtgggagccgtgggagggtcaccctcttgctctttggtgatgactggtggggaatgggccaggggtccggtcagcaccacagacctgcttgtggctggggctccccttggccttcctctgaggctgacccctggctcctcctgagcagggaggggccgtcaggagctctgctgtgctggtggctgtcccagacccccacagctgaccctggaacttgtcatgtgtgttagctgtcagttgagcaggaccacccagccccaagaatgggcttttc +>frag0004 +gctcagcgagtcaggggaggatcctgtcactgtcagctcccccaggagaggctcctcggggggccctggggctctgtgcctggttctgtagggctgggggtctcgtccacatcctcttgtggggctgaaaggtaatatagggggatacagagtttaagggtttaagggcaacttgctttgctggtgctgtcaacagaggtcatacatcaaatgcgcccctccagagcaggctgagggctggggcagctttgagttcgccgttcagtgactcttggaataagagccggtgaggtatccccgagcccccgactgtactgctggcagagctgcactgttagaaacctccagaaggcaa +>frag0005 +gcccctgacacgcatcacctggggccgcccgtccctgtccttgtactgcacggtgaaggagtcgaagtggccctgggggatggtccaggagaggctcagcgagtcaggggaggatcctgtcactgtcagctcccccaggagcggctcctcagggggctccggggcctcagtgctgagttccgtggggctgggggtctcttcctctgcagctgagaaaaggagatatagagaggatgccaggtgcctgggggatgtgctcaggtcttcaagggaaggagggagaaaccatggccactactgggtatgtgaggtcatttcagaaaagcccattcttggggctgggtgg +>frag0006 +gaattcccaacctcaggtgatccacccgcctcggcctcccaaaatgctaggattacaggcgtgaaccactgctcccagcccagaatttcttttttagcccacgtttttctagtgaaaataatacagcaacattatgtggaaagcttgaaaaacagaaaacaagaatctcatagtcctactttctcccccagctgccggcattaataacaatgtgtgtagtgcacattcccttcctgtattttgcatgcagaggctgttttaaagttgcaatcagtgttcataaagttcttggcacttccttttttgtacacaagtacattgtaatcattcacctcacggctacacaaccagcattcatcatcgtttcaatggttatttgatgcgttgcggtgaaagcactataacaaaattaatcatcttctacgggtcatttg +>frag0007 +agcacagctcttcatcctctcctctcctgtggcctttcctatccctcaccctgaccctcctgccctcagcccccacctcacccccacctcccaacacccaggccacctctccctgtccctccagcaccgcctctcttttgagcacagccccactcggcctctgcacccctggcctcccagcactggggtctcttcgccatcttttgttcactgggcttctgtctttgctccgcaacaagctcagcacactcctcccgaggccagagcctggggtgtgttcctggatccagctcctcaccagctgccagcagcctcagagcatctttaccct +>frag0008 +gctggtgaggagctggatccaggaacacaccccaggctctggcctcgggaggagtgtgctgagcttgttgcggagcaaagacagaagcccagtgaacaaaagatggcgaagagaccccagtgctgggaggccaggggtgcagaggccgagtggggctgtgctcaaaagagaggcggtgctggagggacagggagaggtggcctgggtgttgggaggtgggggtgaggtgggggctgagggcaggagggtcagggtgagggataggaaaggccacaggagaggagaggatgaagagctgtgctggaggggctgtgggcagcatcgtcctgctcttgggcactttgtgttttgtgacacatcctttctatgctgaactgaggagccagggacctcactgtccccacacgtgtctgtccaactccagaggatgaagccgagaccacccaagcagtg +>frag0009 +ccaaagagcaagagggtgaccctcccacggctcccaccctggggctgccatcatccactcacccgtcaccccaatgacagagatggggcccacgcgctggccaccgtggaagccgtacaggttcatcttgtatttatggtctggctccaggcctgagatggtgaccccgtcctcgtgccccggcacccgcaccgccttgggctgcccatccccattcctgtactggaccaggaagtggtcaaactggccctcgggaaccgtccaggacaggctgagggagtcaggggtggcatctgtcatggtcagctcccccaggcgaggcttgatggggggctcaggggtcatggtaggcactgcttgggtggtctcggcttcat +>frag0010 +tggccagcgcgtgggccccatctctgtcattggggtgacgggtgagtggatgatggcagccccagggtgggagccgtgggagggtcaccctcttgctctttggtgatgactggtggggaatgggccaggggtccggtcagcaccacagacctgcttgtggctggggctccccttggccttcctctgaggctgacccctggctcctcctgagcagggaggggccgtcaggagctctgctgtgctggtggctgtcccagacccccacagctgaccctggaacttgtcatgtgtgttagctgtcagttgagcaggaccacccagccccaa +>frag0011 +atgctctttctagcctcctggcctttgcaccagctgtgattatctgacacacttcaccttctctctaaagctgtcaccaagctaaggcatgcctggcctcaggtcctggctgtcccctgggtacccatgggcagggtgacttaggcgtccctgtctggtcctgacctgagccctgggcctccctatcacatgctcacccgcctttgcttcatttgctggattgcagcctgtctctccatgacatgtctttccataatgttgctatattcctttcactgtgagccccatcaagacagaaatatgtataggaaaatggtagagaagggcacattttctagggctgtcttccaaccctgccccacccacactcactcacctgtgacgcccacggcagacaccgggcccaggcgccgcccctcgtggaggccgtacaggtgcatcttgtacttgcgcccaggctccaggcccctcacagtgaccttgctctcctggcccccaac +>frag0012 +tgtcagttgagcaggaccacccagccccaagaatgggcttttctgaaatgacctcacatacccagtagtggccatggtttctccctccttcccttgaagacctgagcacatcccccaggcacctggcatcctctctatatctccttttctcagctgcagaggaagagacccccagccccacggaactcagcactgaggccccggagccccctgaggagccgctcctgggggagctgacagtgacaggatcctcccctgactcgctgagcctctcctggaccatcccccagggccacttcgactccttcaccgtgcagtacaaggacagggacgggcggccccaggtgatgcgtgtcaggggcgaggagagcgaggtcaccgtggggggcctggagcccgggcgcaaatacaagatgcacctgta +>frag0013 +gaattctttgctgaatgaacaaattggcccattggtgagaaaggtctgttcctattcctattccaatagtgggcttccagagtgtgcagtcgacgcgctgcccctcactgccttctgtcttccttcacggcccctagtcaactccacagagaaagcacactaccaggaatcagggacgcagaaaaattctcttcaacagatttcaaaagagggtccaattcctttgtcgtgaagaactttgctactcaaggggcgtgatcatgggccagcagcatccgcatcatttcttgttggaaatgcgagaatctctggccctagcccaaacctgttgaaccccaatctgcctcttagcaagatccccaagcatggaaacgtgcaaaagaagcccggctggtgagaatatttttgttttcatgaagttgcagagaaagcaacatcttctagggccatcttcctcact +>frag0014 +attaattttgttatagtgctttcaccgcaacgcatcaaataaccattgaaacgatgatgaatgctggttgtgtagccgtgaggtgaatgattacaatgtacttgtgtacaaaaaaggaagtgccaagaactttatgaacactgattgcaactttaaaacagcctctgcatgcaaaatacaggaagggaatgtgcactacacacattgttattaatgccggcagctgggggagaaagtaggactatgagattcttgttttctgtttttcaagctttccacataatgttgctgtattattttcactagaaaaacgtgggctaaaaaagaaattctgggctgggagcagtggttcacgcctgtaatcctagcattttgggaggccgaggcgggtggatcacctgaggttgggaattc +>frag0015 +tttcaaaagagggtccaattcctttgtcgtgaagaactttgctactcaaggggcgtgatcatgggccagcagcatccgcatcatttcttgttggaaatgcgagaatctctggccctagcccaaacctgttgaaccccaatctgcctcttagcaagatccccaagcatggaaacgtgcaaaagaagcccggctggtgagaatatttttgttttcatgaagttgcagagaaagcaacatcttctagggccatcttcctcactcacaaacactcacctgtcacacccacggtggacaccgggcccacacgccgcccct +>frag0016 +ctggaccatcccccagggccacttcgactccttcaccgtgcagtacaaggacagggacgggcggccccaggtgatgcgtgtcaggggcgaggagagcgaggtcaccgtggggggcctggagcccgggcgcaaatacaagatgcacctgtacggcctccacgaggggcggcgtgtgggcccggtgtccaccgtgggtgtgacaggtgagtgtttgtgagtgaggaagatggccctagaagatgttgctttctctgcaacttcatgaaaacaaaaatattctcaccagccgggcttcttttgcacgtttccatgcttggggatcttgctaagaggcagattggggttcaacaggtttgggctagggccagagattctcgcatttccaacaagaaatgatgcggatgctgctggcccatgatcacgccccttgagtagcaaagttcttcacgacaaaggaattggaccct +>frag0017 +ctgctgtcatgaataaccccatcgtgagttcttccatgctataactttttcctgctttaataattttcttaggacagatgcccagaactgggattattgggtcaaaggaaatgagaattactttggctcctgacactatgtctcagttgccttctggaggtttctaacagtgcagctctgccagcagtacagtcgggggctcggggatacctcaccggctcttattccaagagtcactgaacggcgaactcaaagctgccccagccctcagcctgctctggaggggcgcatttgatgtatgacctctgttgacagcaccagcaaagcaagttgcccttaaacccttaaactctgtatccccctatattacctttcagccccacaagaggatgtggacgagacccccagccctacagaaccaggca +>frag0018 +cctggcatcctctctatatctccttttctcagctgcagaggaagagacccccagccccacggaactcagcactgaggccccggagccccctgaggagccgctcctgggggagctgacagtgacaggatcctcccctgactcgctgagcctctcctggaccatcccccagggccacttcgactccttcaccgtgcagtacaaggacagggacgggcggccccaggtgatgcgtgtcaggggcgaggagagcgaggtcaccgtggggggcctggagcccgggcgcaaatacaagatgcacctgtacggcctccacgaggggcggcgtgtgggcccggtgtccaccgtgggtgtgacaggtgagtgtttgtgagtgaggaagatggccctagaagatgttgctttctctgcaacttcatgaaaacaaaaatattctcaccagccgggcttcttttgcacgtttccatgcttggggatcttgctaagaggcagatt +>frag0019 +gccccactcggcctctgcacccctggcctcccagcactggggtctcttcgccatcttttgttcactgggcttctgtctttgctccgcaacaagctcagcacactcctcccgaggccagagcctggggtgtgttcctggatccagctcctcaccagctgccagcagcctcagagcatctttaccctgaattcccctggataccttcctaccccacctccagtccccgatcctagtttgagccactgtcacctctcaccagggccaccaactgcctactggcctcgctgcctccaggctccctgccaccccatccccatcttcagcccccacggatgagcttcacacaggcacagctgctggggccatctcagcacagacctaggcaaccacaccctcaaccccgggagaccccaggcctagtgagtggtcccctcctctgctcccacacttcaggat +>frag0020 +aaggaagtgccaagaactttatgaacactgattgcaactttaaaacagcctctgcatgcaaaatacaggaagggaatgtgcactacacacattgttattaatgccggcagctgggggagaaagtaggactatgagattcttgttttctgtttttcaagctttccacataatgttgctgtattattttcactagaaaaacgtgggctaaaaaagaaattctgggctgggagcagtggttcacgcctgtaatcctagcattttgggaggccgaggcgggtggatcacctgaggttgggaattc +>frag0021 +gatggggtggcagggagcctggaggcagcgaggccagtaggcagttggtggccctggtgagaggtgacagtggctcaaactaggatcggggactggaggtggggtaggaaggtatccaggggaattcagggtaaagatgctctgaggctgctggcagctggtgaggagctggatccaggaacacaccccaggctctggcctcgggaggagtgtgctgagcttgttgcggagcaaagacagaagcccagtgaacaaaagatggcgaagagaccccagtgctgggaggccaggggtgcagaggccgagtggggctgtgctcaaaagagaggcggtgctggagggacagggagaggtggcctgggtgttgggaggtgggggtgaggtgggggctgagggcaggagggtcagggtgagggataggaaaggccacaggagaggagagga +>frag0022 +acggctacacaaccagcattcatcatcgtttcaatggttatttgatgcgttgcggtgaaagcactataacaaaattaatcatcttctacgggtcatttgtgttcctgacacatctgctgtcatgaataaccccatcgtgagttcttccatgctataactttttcctgctttaataattttcttaggacagatgcccagaactgggattattgggtcaaaggaaatgagaattactttggctcctgacactatgtctcagttgccttctggaggtttctaacagtgcagctctgccagcagtacagtcgggggctcggggatacctcaccggctcttattccaagagtcactgaacggcgaactca +>frag0023 +gtctctccatgacatgtctttccataatgttgctatattcctttcactgtgagccccatcaagacagaaatatgtataggaaaatggtagagaagggcacattttctagggctgtcttccaaccctgccccacccacactcactcacctgtgacgcccacggcagacaccgggcccaggcgccgcccctcgtggaggccgtacaggtgcatcttgtacttgcgcccaggctccaggcccctcacagtgaccttgctctcctggcccccaacacgcaccgcctggggccgcccgtccctgtccttgtactgcacggtgaaggagtcaaagcggccctgggggacggtccaggaaaggctcagcgagtcaggggaggatcctgtcactgtcagctcccccaggagaggctcctcggggggccctggggctctgtgcctggttctgtagggctgggggtctc +>frag0024 +gccagagcctggggtgtgttcctggatccagctcctcaccagctgccagcagcctcagagcatctttaccctgaattcccctggataccttcctaccccacctccagtccccgatcctagtttgagccactgtcacctctcaccagggccaccaactgcctactggcctcgctgcctccaggctccctgccaccccatccccatcttcagcccccacggatgagcttcacacaggcacagctgctggggccatctcagcacagacctaggcaaccacaccctcaaccccgggagaccccaggcctagtgagtggtcccctcctc +>frag0025 +caccacagacctgcttgtggctggggctccccttggccttcctctgaggctgacccctggctcctcctgagcagggaggggccgtcaggagctctgctgtgctggtggctgtcccagacccccacagctgaccctggaacttgtcatgtgtgttagctgtcagttgagcaggaccacccagccccaagaatgggcttttctgaaatgacctcacatacccagtagtggccatggtttctccctccttcccttgaagacctgagcacatcccccaggcacctggcatcctctctatatctccttttctcagctgcagaggaagagacccccagccccacggaactcagcactgaggccccggagccccctgaggagccgctcctgggggagctgacagtgacaggatcctcccctgactcgctgagcctctcctggaccatcccccaggg +>frag0026 +aatctcatagtcctactttctcccccagctgccggcattaataacaatgtgtgtagtgcacattcccttcctgtattttgcatgcagaggctgttttaaagttgcaatcagtgttcataaagttcttggcacttccttttttgtacacaagtacattgtaatcattcacctcacggctacacaaccagcattcatcatcgtttcaatggttatttgatgcgttgcggtgaaagcactataacaaaattaatcatcttctacgggtcatttgtgttcctgacacatctgctgtcatgaataaccccatcgtgagttcttccatgctataactttttcctgctttaataattttcttaggacagatgcccagaactgggattattgggtcaaaggaaatgag +>frag0027 +gcatttccaacaagaaatgatgcggatgctgctggcccatgatcacgccccttgagtagcaaagttcttcacgacaaaggaattggaccctcttttgaaatctgttgaagagaatttttctgcgtccctgattcctggtagtgtgctttctctgtggagttgactaggggccgtgaaggaagacagaaggcagtgaggggcagcgcgtcgactgcacactctggaagcccactattggaataggaataggaacagacctttctcaccaatgggccaatttgttcattcagcaaagaattc +>frag0028 +gtgcccttctctaccattttcctatacatatttctgtcttgatggggctcacagtgaaaggaatatagcaacattatggaaagacatgtcatggagagacaggctgcaatccagcaaatgaagcaaaggcgggtgagcatgtgatagggaggcccagggctcaggtcaggaccagacagggacgcctaagtcaccctgcccatgggtacccaggggacagccaggacctgaggccaggcatgccttagcttggtgacagctttagagagaaggtgaagtgtgtcagataatcacagctggtgcaaaggc +>frag0029 +ctgtcacctctcaccagggccaccaactgcctactggcctcgctgcctccaggctccctgccaccccatccccatcttcagcccccacggatgagcttcacacaggcacagctgctggggccatctcagcacagacctaggcaaccacaccctcaaccccgggagaccccaggcctagtgagtggtcccctcctctgctcccacacttcaggatgagatactcaccgtaaaggacaccccactcaatcctcagtgcctctcacgtgccatgctctttctagcctcctggcctttgcaccagctgtgattatctgacacacttcaccttctctctaaagctgtcaccaagctaaggcatgcctggcctcaggtcctggctgtcccctgggtacccatgggcagggtgacttaggcgtccctgtctggtcc +>frag0030 +cctctcctctcctgtggcctttcctatccctcaccctgaccctcctgccctcagcccccacctcacccccacctcccaacacccaggccacctctccctgtccctccagcaccgcctctcttttgagcacagccccactcggcctctgcacccctggcctcccagcactggggtctcttcgccatcttttgttcactgggcttctgtctttgctccgcaacaagctcagcacactcctcccgaggccagagcctggggtgtgttcctggatccagctcctcaccagctgccagcagcctcagagcatctttaccctgaattcccctggataccttcctaccccacctccagtccccgatcctagtttgagccactgtcacctctcaccagggccaccaactgcctactggcctcgctgcctccaggctccctgccaccccatcc +>frag0031 +tcaaagctgccccagccctcagcctgctctggaggggcgcatttgatgtatgacctctgttgacagcaccagcaaagcaagttgcccttaaacccttaaactctgtatccccctatattacctttcagccccacaagaggatgtggacgagacccccagccctacagaaccaggcacagagccccagggccccccgaggagcctctcctgggggagctgacagtgacaggatcctcccctgactcgctgagcctttcctggaccgtcccccagggccgctttgactccttcaccgtgcagtacaaggacagggacgggcggccccaggcggtgcgtgttgggggccaggagagcaaggtcactgtgaggggcctggagcctgggcgcaag +>frag0032 +gtcagctcccccaggcgaggcttgatggggggctcaggggtcatggtaggcactgcttgggtggtctcggcttcatcctctggagttggacagacacgtgtggggacagtgaggtccctggctcctcagttcagcatagaaaggatgtgtcacaaaacacaaagtgcccaagagcaggacgatgctgcccacagcccctccagcacagctcttcatcctctcctctcctgtggcctttcctatccctcaccctgaccctcctgccctcagcccccacctcacccccacctcccaacacccaggccacctctccctgtccctccagcaccgcctctcttttgagcacagccccactc +>frag0033 +cacccctgactccctcagcctgtcctggacggttcccgagggccagtttgaccacttcctggtccagtacaggaatggggatgggcagcccaaggcggtgcgggtgccggggcacgaggacggggtcaccatctcaggcctggagccagaccataaatacaagatgaacctgtacggcttccacggtggccagcgcgtgggccccatctctgtcattggggtgacgggtgagtggatgatggcagccccagggtgggagccgtgggagggtcaccctcttgctctttggtgatgactggtggggaatgggccaggggtccggtcagcaccacagacctgcttgtggctggggctccccttggccttcctctgaggctgacccctggctcctcctgagcagggaggggccgtc +>frag0034 +ggccccccgaggagcctctcctgggggagctgacagtgacaggatcctcccctgactcgctgagcctttcctggaccgtcccccagggccgctttgactccttcaccgtgcagtacaaggacagggacgggcggccccaggcggtgcgtgttgggggccaggagagcaaggtcactgtgaggggcctggagcctgggcgcaagtacaagatgcacctgtacggcctccacgaggggcggcgcctgggcccggtgtctgccgtgggcgtcacaggtgagtgagtgtgggtggggcagggttggaagacagccctagaaaatgtgcccttctctaccattttcctatacatatttctgtcttgatggggctcacagtgaaaggaatatagcaacattatggaaagacatgtcatggagagacaggctgcaatccagcaaatgaagcaaaggcgggtgagcatgtgat +>frag0035 +ttcatcctctggagttggacagacacgtgtggggacagtgaggtccctggctcctcagttcagcatagaaaggatgtgtcacaaaacacaaagtgcccaagagcaggacgatgctgcccacagcccctccagcacagctcttcatcctctcctctcctgtggcctttcctatccctcaccctgaccctcctgccctcagcccccacctcacccccacctcccaacacccaggccacctctccctgtccctccagcaccgcctctcttttgagcacagccccactcggcctctgcacccctggcctcccagcactggggtctcttcgccatcttttgttcactgggcttctgtctttgctccgcaacaagctcagcac +>frag0036 +tcggcctctgcacccctggcctcccagcactggggtctcttcgccatcttttgttcactgggcttctgtctttgctccgcaacaagctcagcacactcctcccgaggccagagcctggggtgtgttcctggatccagctcctcaccagctgccagcagcctcagagcatctttaccctgaattcccctggataccttcctaccccacctccagtccccgatcctagtttgagccactgtcacctctcaccagggccaccaactgcctactggcctcgctgcctccaggctccctgccaccccatccccat +>frag0037 +aaagctgccccagccctcagcctgctctggaggggcgcatttgatgtatgacctctgttgacagcaccagcaaagcaagttgcccttaaacccttaaactctgtatccccctatattacctttcagccccacaagaggatgtggacgagacccccagccctacagaaccaggcacagagccccagggccccccgaggagcctctcctgggggagctgacagtgacaggatcctcccctgactcgctgagcctttcctggaccgtcccccagggccgctttgactccttcaccgtgcagtacaaggacagggacgggcggccccaggcggtgcgtgttgggggccaggagagcaaggtcactgtgaggggcctggagcc +>frag0038 +cctagtttgagccactgtcacctctcaccagggccaccaactgcctactggcctcgctgcctccaggctccctgccaccccatccccatcttcagcccccacggatgagcttcacacaggcacagctgctggggccatctcagcacagacctaggcaaccacaccctcaaccccgggagaccccaggcctagtgagtggtcccctcctctgctcccacacttcaggatgagatactcaccgtaaaggacaccccactcaatcctcagtgcctctcacgtgccatgctctttctagcctcctggcc diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/MAXSAT-instances/format.txt b/ProyectoFinal/CHC/malva/ProblemInstances/MAXSAT-instances/format.txt new file mode 100644 index 0000000000000000000000000000000000000000..dc630e19477ddc67cbc6cb78c485461b4cc04dcc --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/MAXSAT-instances/format.txt @@ -0,0 +1,4 @@ +// number of variables, number of clauses and number of literals per clause. +// clause 1 (finalized in 0), if literal < 0 then the literal is negated. + +// clause N (finalized in 0), if literal < 0 then the literal is negated. diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/MAXSAT-instances/sat1.txt b/ProyectoFinal/CHC/malva/ProblemInstances/MAXSAT-instances/sat1.txt new file mode 100644 index 0000000000000000000000000000000000000000..f8aa7feb0eb9664001f550dc4c5f37757f16bc47 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/MAXSAT-instances/sat1.txt @@ -0,0 +1,44 @@ +10 43 3 +-4 -1 5 0 +-1 -9 -10 0 +-5 -3 -8 0 +-4 -8 -5 0 +2 6 7 0 +-9 -1 -10 0 +5 -3 -9 0 +1 -3 -5 0 +7 2 -4 0 +-7 3 4 0 +-2 1 -9 0 +-8 1 3 0 +3 6 7 0 +-1 -3 -2 0 +4 7 -2 0 +-8 -7 -3 0 +4 3 2 0 +-5 -4 1 0 +-9 10 -8 0 +-6 2 8 0 +-7 -8 5 0 +-7 -5 3 0 +7 9 -10 0 +1 -6 -3 0 +1 -9 6 0 +10 9 4 0 +-8 3 7 0 +8 7 -3 0 +-8 4 9 0 +8 -5 4 0 +8 10 1 0 +-1 -7 8 0 +6 2 5 0 +6 2 10 0 +2 -6 4 0 +-3 9 -1 0 +9 1 -10 0 +10 -5 -8 0 +-10 6 1 0 +1 7 2 0 +-6 3 2 0 +-1 -9 8 0 +-5 2 -10 0 diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/MAXSAT-instances/sat2.txt b/ProyectoFinal/CHC/malva/ProblemInstances/MAXSAT-instances/sat2.txt new file mode 100644 index 0000000000000000000000000000000000000000..806241f36dba6858b65c4aac3d5fc5afc2ae7950 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/MAXSAT-instances/sat2.txt @@ -0,0 +1,4301 @@ +1000 4300 3 +881 -647 537 0 +-739 396 282 0 +-43 -487 -52 0 +-643 205 796 0 +939 -885 -829 0 +-361 576 421 0 +-193 904 -238 0 +-940 902 26 0 +-177 -783 257 0 +439 942 675 0 +-794 714 -977 0 +310 -524 523 0 +-762 -494 260 0 +-578 305 502 0 +-805 -630 547 0 +729 855 -76 0 +-168 -754 667 0 +965 -418 93 0 +-668 -824 -495 0 +286 976 339 0 +776 -809 -157 0 +395 -120 838 0 +412 895 703 0 +-472 -479 -19 0 +-65 -918 945 0 +-682 -47 -590 0 +-956 996 316 0 +-969 120 222 0 +809 938 995 0 +-882 131 -976 0 +34 61 -359 0 +475 182 -67 0 +105 -391 986 0 +616 -867 -339 0 +-830 236 752 0 +-415 124 903 0 +-473 585 681 0 +203 -11 380 0 +-874 -126 -568 0 +498 -850 -74 0 +435 -113 -261 0 +-690 542 148 0 +-800 -657 752 0 +-624 269 526 0 +794 177 512 0 +-620 -987 819 0 +292 -87 455 0 +-945 758 946 0 +-723 421 908 0 +131 -977 369 0 +-811 -172 875 0 +971 410 -522 0 +287 474 -157 0 +753 458 491 0 +-265 -653 -269 0 +743 890 -606 0 +-207 555 211 0 +-367 799 403 0 +869 559 -407 0 +33 657 488 0 +834 -663 646 0 +-318 -109 804 0 +-235 572 452 0 +-257 -977 984 0 +386 -388 800 0 +-879 -50 131 0 +91 936 -258 0 +215 -310 -748 0 +911 842 670 0 +-514 442 496 0 +8 -111 35 0 +616 -77 325 0 +266 796 918 0 +-22 -261 -317 0 +-654 827 647 0 +48 -267 -905 0 +-921 418 407 0 +685 930 -196 0 +593 379 212 0 +-407 812 805 0 +-983 -942 919 0 +-138 32 678 0 +-306 764 -898 0 +-752 637 573 0 +916 332 -598 0 +890 350 -859 0 +-216 -821 -218 0 +-497 -981 -276 0 +-681 -893 -12 0 +765 -862 -222 0 +-740 6 666 0 +4 145 -59 0 +825 217 14 0 +135 889 -870 0 +-147 -85 -563 0 +298 -876 929 0 +-341 943 997 0 +329 -258 299 0 +-41 911 -906 0 +439 716 450 0 +-300 709 -704 0 +-363 125 260 0 +-442 776 474 0 +-615 -612 593 0 +233 -271 40 0 +661 248 -981 0 +-549 736 228 0 +565 -795 97 0 +706 -314 881 0 +-513 -476 -125 0 +54 721 822 0 +355 -327 -772 0 +-94 588 284 0 +-977 697 485 0 +-144 560 -671 0 +112 -780 324 0 +649 35 -134 0 +84 912 -265 0 +-705 21 858 0 +-224 -991 491 0 +930 -610 -668 0 +-956 -723 -845 0 +-694 798 527 0 +-208 726 594 0 +-151 311 279 0 +-347 -499 994 0 +679 195 -34 0 +-214 829 -895 0 +771 -106 -532 0 +684 855 942 0 +-323 552 -191 0 +-412 -8 -319 0 +327 -117 702 0 +-752 -663 234 0 +427 -92 846 0 +662 -736 -344 0 +164 774 -856 0 +-303 818 -889 0 +-791 -899 477 0 +-786 626 791 0 +-185 -589 -126 0 +964 314 466 0 +175 -299 -442 0 +-384 -545 -365 0 +-584 -719 -906 0 +901 -305 51 0 +-5 671 -804 0 +-895 417 55 0 +579 -693 586 0 +259 863 -872 0 +-176 -933 213 0 +829 437 24 0 +-322 -321 910 0 +-522 -696 641 0 +-682 -538 202 0 +108 450 798 0 +254 505 663 0 +-672 -420 116 0 +-652 -294 759 0 +-196 987 -572 0 +-219 -576 -261 0 +357 -975 -458 0 +164 -44 726 0 +-508 909 286 0 +-201 97 594 0 +-218 -198 776 0 +669 199 -655 0 +-146 822 360 0 +838 -958 372 0 +733 718 412 0 +-445 835 -924 0 +554 -488 155 0 +365 -834 -230 0 +-735 364 348 0 +540 -162 803 0 +-547 113 374 0 +-242 -569 -572 0 +-121 501 -174 0 +213 -815 -942 0 +370 758 492 0 +889 -733 -256 0 +636 -149 273 0 +543 176 -58 0 +92 941 402 0 +-683 -952 924 0 +788 -686 -56 0 +849 -866 155 0 +-121 837 323 0 +-578 866 277 0 +62 -504 857 0 +192 807 -944 0 +647 -350 -468 0 +816 967 -910 0 +-48 -745 285 0 +-894 -521 -397 0 +374 -616 905 0 +-968 -290 -854 0 +-770 747 -777 0 +610 779 -278 0 +-704 -452 964 0 +51 -774 -681 0 +532 -752 -528 0 +-738 433 -319 0 +17 635 -456 0 +-969 709 390 0 +68 317 -980 0 +-502 95 462 0 +-952 -920 -127 0 +280 -820 102 0 +466 635 -896 0 +446 967 -261 0 +-672 -626 396 0 +-609 392 103 0 +826 383 740 0 +-404 218 281 0 +112 -548 941 0 +-463 -408 975 0 +449 245 748 0 +-657 -752 668 0 +395 -915 739 0 +-246 100 -469 0 +975 388 814 0 +-669 -738 -465 0 +-199 203 336 0 +-85 -167 -662 0 +455 -789 475 0 +514 427 -915 0 +806 -825 -635 0 +720 -228 -179 0 +-941 -82 -700 0 +228 -256 -547 0 +374 732 -204 0 +-927 -79 58 0 +-535 -860 -669 0 +391 674 817 0 +-36 -15 -318 0 +-690 -538 -206 0 +-824 418 685 0 +-981 512 -849 0 +-268 -343 952 0 +-914 -720 -827 0 +173 -697 -115 0 +-95 628 -419 0 +-10 521 -459 0 +-539 236 396 0 +-922 -709 740 0 +-248 -746 679 0 +215 511 503 0 +-799 -121 -631 0 +-438 300 -651 0 +-76 287 135 0 +-566 186 706 0 +944 -756 230 0 +-950 264 -581 0 +113 953 821 0 +270 -214 192 0 +-442 145 -143 0 +-951 -931 349 0 +499 903 331 0 +-618 -654 112 0 +-287 -662 -243 0 +440 -691 -429 0 +-374 -370 -707 0 +-559 -883 -214 0 +988 439 471 0 +-239 -13 -732 0 +-997 593 751 0 +287 324 -135 0 +-624 -341 -298 0 +-796 851 -884 0 +198 -191 -81 0 +-71 -647 -421 0 +840 -87 56 0 +-710 465 -8 0 +-465 787 375 0 +573 524 232 0 +-373 -775 28 0 +7 516 -771 0 +-623 -951 770 0 +-152 841 656 0 +741 387 510 0 +49 287 642 0 +-202 -881 -389 0 +-265 -953 -752 0 +-756 -927 -479 0 +-422 227 25 0 +-162 -663 659 0 +-878 935 999 0 +86 982 -458 0 +781 515 510 0 +225 289 890 0 +929 -495 -377 0 +-857 866 -433 0 +436 221 530 0 +-750 8 -24 0 +-413 860 121 0 +609 375 321 0 +850 950 -27 0 +432 -539 -267 0 +-677 242 326 0 +-157 21 -736 0 +-812 -679 726 0 +787 856 -859 0 +-874 50 626 0 +-884 248 127 0 +-716 84 606 0 +825 382 308 0 +-922 -917 250 0 +625 -410 514 0 +144 -975 -311 0 +-570 115 -736 0 +-20 -584 179 0 +373 -515 -166 0 +705 985 226 0 +-707 816 -140 0 +535 -60 441 0 +800 459 -568 0 +50 -180 630 0 +365 715 -819 0 +17 -379 -454 0 +828 178 -957 0 +-383 -741 -258 0 +-740 -336 736 0 +178 -870 417 0 +375 205 216 0 +402 73 -492 0 +-361 63 -409 0 +-996 -741 152 0 +-981 411 808 0 +-875 -71 -26 0 +-448 627 -161 0 +-25 -808 -657 0 +866 -202 -348 0 +-963 -713 671 0 +-464 -642 215 0 +52 -312 -258 0 +96 -466 945 0 +-303 -957 -152 0 +-451 229 530 0 +-695 -547 835 0 +820 -646 294 0 +410 -921 15 0 +-40 520 837 0 +-610 -90 26 0 +-454 576 539 0 +469 -563 -62 0 +477 -897 -272 0 +394 -395 650 0 +551 318 -99 0 +406 -498 361 0 +-219 -348 -116 0 +551 82 -262 0 +-684 487 505 0 +-806 -903 -348 0 +-289 56 587 0 +-780 231 667 0 +-452 -44 68 0 +-586 96 -107 0 +-672 470 242 0 +178 287 46 0 +-648 -366 263 0 +777 126 435 0 +939 -289 -364 0 +830 -176 883 0 +-772 890 803 0 +-68 -429 -616 0 +659 -54 -227 0 +-502 53 999 0 +-430 -909 129 0 +-716 -970 -554 0 +57 -256 242 0 +-152 -255 -478 0 +-347 127 918 0 +127 328 368 0 +731 866 -936 0 +561 331 -525 0 +545 -188 -504 0 +919 765 -243 0 +-724 -864 -492 0 +645 425 -299 0 +949 -38 -968 0 +84 17 202 0 +-884 -28 -736 0 +-1 -410 -464 0 +493 467 -755 0 +642 -759 830 0 +-455 543 -47 0 +-523 885 -72 0 +-761 751 -575 0 +129 9 -836 0 +-621 -59 756 0 +-392 203 -919 0 +200 347 31 0 +-605 -359 525 0 +-869 -339 827 0 +871 -493 79 0 +721 -892 -406 0 +-140 -934 -96 0 +764 -796 -245 0 +365 1000 60 0 +-922 517 -990 0 +893 704 122 0 +819 -586 957 0 +170 184 491 0 +-72 664 381 0 +-1000 295 -918 0 +-868 525 -309 0 +534 -189 210 0 +461 -432 -990 0 +-605 71 -826 0 +527 -317 990 0 +974 -516 -442 0 +-443 -137 -84 0 +-713 -181 -555 0 +626 945 -996 0 +255 685 -306 0 +214 744 -786 0 +-183 -19 -812 0 +-704 472 678 0 +-321 -540 83 0 +277 953 128 0 +-693 -432 -452 0 +-59 -145 41 0 +135 -220 -865 0 +-601 122 -557 0 +-162 -877 238 0 +-373 -649 -579 0 +982 -445 -623 0 +-172 797 687 0 +138 -288 -868 0 +221 668 -570 0 +180 254 -469 0 +39 -766 657 0 +56 -465 773 0 +599 -183 127 0 +-263 81 169 0 +-74 432 -813 0 +-487 -756 -126 0 +-288 -285 -552 0 +-873 52 760 0 +221 631 -550 0 +-812 -310 -242 0 +-328 -141 -278 0 +-792 441 41 0 +51 983 -547 0 +-993 -150 -613 0 +352 564 -483 0 +123 389 -989 0 +-52 830 -364 0 +680 -189 46 0 +-241 634 -130 0 +-720 -401 -297 0 +731 -349 -736 0 +6 -452 8 0 +927 -875 911 0 +309 344 -112 0 +-326 610 -426 0 +843 -699 978 0 +546 118 856 0 +-397 -455 262 0 +653 914 -500 0 +480 848 130 0 +-304 679 672 0 +-765 984 -907 0 +-847 425 -46 0 +199 -727 -716 0 +-350 -281 -804 0 +394 851 -540 0 +-267 -334 -282 0 +339 754 558 0 +-835 -603 155 0 +628 -96 832 0 +-532 899 142 0 +-51 909 -248 0 +-913 20 -577 0 +-688 668 -529 0 +-725 430 198 0 +-887 -454 849 0 +-753 39 177 0 +-584 104 -805 0 +75 296 983 0 +-28 919 -18 0 +68 -848 -550 0 +185 -922 415 0 +-762 873 -367 0 +181 -79 -468 0 +709 -685 410 0 +600 553 -718 0 +-568 -757 309 0 +483 682 -439 0 +-923 847 -668 0 +-513 -668 392 0 +304 -813 880 0 +410 -179 -943 0 +205 -615 -377 0 +354 -131 -917 0 +614 -715 -891 0 +-150 -794 -375 0 +-970 376 325 0 +514 -584 -824 0 +-311 -847 -247 0 +919 -867 433 0 +273 872 -788 0 +958 9 -279 0 +-674 546 -261 0 +-954 678 -774 0 +-739 232 -328 0 +-196 -416 272 0 +338 921 900 0 +-655 -872 -286 0 +-232 -974 399 0 +-772 -199 -428 0 +-553 -778 306 0 +289 -84 151 0 +-483 866 -897 0 +-399 692 844 0 +-35 423 624 0 +-461 -88 -231 0 +-211 -956 -462 0 +-966 -994 40 0 +990 -149 813 0 +-228 853 913 0 +39 -330 -785 0 +-942 -726 -9 0 +-754 -122 -194 0 +539 503 710 0 +-123 461 -815 0 +425 -169 362 0 +3 -954 -383 0 +-538 -374 -8 0 +217 -318 51 0 +299 -499 -919 0 +-452 -121 -674 0 +211 -463 980 0 +-342 563 514 0 +839 691 814 0 +8 646 -632 0 +-487 -231 -401 0 +-479 -206 335 0 +-629 852 354 0 +950 -48 -406 0 +954 -977 415 0 +-315 -858 866 0 +-912 -799 -376 0 +-509 519 964 0 +-550 99 -996 0 +-173 342 483 0 +-677 -525 -828 0 +933 858 23 0 +425 166 -174 0 +-879 -970 -171 0 +618 -303 -364 0 +-76 507 512 0 +762 -604 947 0 +-188 256 -232 0 +730 -854 811 0 +338 -535 606 0 +-24 -772 102 0 +-132 -947 -454 0 +993 -344 476 0 +596 -856 -965 0 +-814 70 -553 0 +229 659 751 0 +38 473 696 0 +928 222 337 0 +-795 -524 -700 0 +-183 281 -516 0 +-169 249 -378 0 +394 -292 941 0 +-200 -806 -739 0 +33 777 358 0 +92 -168 162 0 +-995 -880 -189 0 +181 -495 428 0 +358 45 849 0 +-579 275 -391 0 +116 -466 -982 0 +923 513 -194 0 +-965 -325 -741 0 +-238 -655 643 0 +767 246 257 0 +-199 -826 -318 0 +-728 656 -603 0 +-395 -279 885 0 +259 -342 63 0 +-370 -928 -388 0 +556 544 348 0 +-886 115 788 0 +70 -668 690 0 +-55 -680 -474 0 +814 457 899 0 +-15 239 953 0 +249 184 -6 0 +-608 611 735 0 +-761 468 324 0 +60 -86 -731 0 +363 38 105 0 +-53 -780 953 0 +-140 953 -163 0 +464 -410 438 0 +221 151 438 0 +98 415 698 0 +36 489 -655 0 +998 332 580 0 +-326 -971 105 0 +927 -857 499 0 +-677 -593 -779 0 +-622 -24 457 0 +-22 452 364 0 +-844 -647 194 0 +-101 -348 36 0 +115 -547 970 0 +-202 -261 -878 0 +272 -286 -125 0 +-722 -773 -601 0 +-796 250 273 0 +-834 -265 766 0 +-799 773 -680 0 +-296 841 980 0 +-902 -855 -699 0 +-301 -130 238 0 +799 -916 917 0 +-944 -681 731 0 +606 729 751 0 +649 67 582 0 +-267 -909 -979 0 +816 -889 650 0 +-716 -205 228 0 +530 -161 302 0 +175 823 -319 0 +-344 -944 -701 0 +433 272 -254 0 +94 113 -130 0 +806 -399 -508 0 +-880 897 -456 0 +-288 602 -793 0 +-999 92 362 0 +98 581 698 0 +-994 -428 -524 0 +-565 -967 -848 0 +97 814 -999 0 +842 -904 -899 0 +-61 627 437 0 +340 -977 371 0 +-220 302 336 0 +831 -591 251 0 +107 957 -949 0 +-552 -601 988 0 +-630 348 167 0 +-519 -587 404 0 +783 809 -377 0 +345 -315 -918 0 +-904 346 584 0 +-785 -201 -381 0 +-679 854 -334 0 +-117 367 836 0 +-274 -329 891 0 +-940 429 22 0 +341 -974 768 0 +-972 494 14 0 +-988 -457 -613 0 +997 -391 607 0 +-188 667 -874 0 +-468 814 927 0 +950 -677 -438 0 +-839 -469 691 0 +184 918 401 0 +-236 500 697 0 +-488 -595 -274 0 +390 -536 -162 0 +317 907 -247 0 +928 899 -770 0 +962 872 341 0 +-717 14 1000 0 +-805 -635 535 0 +-950 720 -883 0 +32 -360 390 0 +-176 -541 503 0 +-394 -550 279 0 +-387 -913 228 0 +-125 89 93 0 +329 99 -136 0 +435 -938 39 0 +856 -304 -915 0 +452 -818 129 0 +-18 -532 -493 0 +794 -408 -714 0 +-428 38 983 0 +992 609 -295 0 +-390 -477 574 0 +197 884 -530 0 +-79 -955 -958 0 +142 -455 465 0 +601 953 -622 0 +478 -678 947 0 +-443 -778 2 0 +608 -893 696 0 +421 565 300 0 +-164 140 -726 0 +-299 -320 214 0 +-237 1000 70 0 +136 -886 -613 0 +-145 802 692 0 +822 -641 -939 0 +-631 343 822 0 +554 -679 621 0 +176 432 523 0 +125 181 -41 0 +422 809 845 0 +691 -625 -281 0 +-605 967 -687 0 +809 155 -45 0 +-350 510 -722 0 +747 -816 -758 0 +301 -392 -3 0 +198 -856 -397 0 +-304 965 808 0 +-120 -412 641 0 +95 -903 702 0 +146 -932 776 0 +-231 -163 -696 0 +682 668 -939 0 +-819 460 451 0 +57 -799 -592 0 +-391 453 769 0 +-381 -877 -983 0 +686 595 68 0 +-800 -485 39 0 +396 803 821 0 +-727 -988 -37 0 +-883 66 805 0 +-966 432 -977 0 +-786 468 192 0 +-849 24 -514 0 +-67 690 153 0 +-526 -518 442 0 +27 631 -245 0 +701 211 -58 0 +514 243 904 0 +58 483 956 0 +-815 -870 -158 0 +-296 993 -476 0 +-913 -581 -512 0 +-497 -11 -2 0 +-127 118 767 0 +-655 -302 -514 0 +273 293 395 0 +145 -390 338 0 +-716 117 -563 0 +273 172 256 0 +449 -693 -283 0 +19 -907 -97 0 +-237 -163 -509 0 +99 -813 886 0 +924 3 51 0 +-107 -314 515 0 +-907 184 367 0 +850 539 800 0 +-457 714 420 0 +411 -604 367 0 +643 -791 636 0 +-613 -888 500 0 +526 -605 47 0 +-431 947 930 0 +-660 -860 148 0 +-129 269 753 0 +-488 130 -958 0 +-772 491 422 0 +-910 -339 461 0 +13 -143 504 0 +-414 406 643 0 +-284 182 772 0 +-271 211 -577 0 +946 139 114 0 +-524 -463 108 0 +-424 -688 111 0 +317 780 -384 0 +-3 -50 -678 0 +719 -15 969 0 +-287 -899 -66 0 +-74 187 -865 0 +-346 794 910 0 +869 -166 121 0 +347 -540 224 0 +-26 -281 600 0 +-849 -788 -906 0 +-880 -348 -128 0 +-19 904 -430 0 +715 -377 490 0 +406 230 675 0 +-495 -110 615 0 +474 315 180 0 +-883 672 -444 0 +578 -534 -662 0 +711 -112 -400 0 +-659 642 -144 0 +-693 676 52 0 +-258 716 997 0 +-38 -436 729 0 +-87 -622 -369 0 +516 309 4 0 +-425 657 -965 0 +870 -441 714 0 +-512 822 678 0 +-942 -982 -868 0 +-609 -78 -679 0 +44 -405 -463 0 +-334 -663 -534 0 +413 510 -451 0 +-846 865 475 0 +-559 -765 957 0 +178 222 -276 0 +-437 -645 -369 0 +-936 768 -601 0 +57 -136 554 0 +-374 28 -583 0 +-355 -926 -539 0 +-696 -381 -329 0 +243 720 287 0 +529 811 -790 0 +-961 889 -611 0 +113 542 89 0 +804 -345 532 0 +894 295 508 0 +-606 -894 70 0 +-898 -441 499 0 +-124 -372 -948 0 +223 -909 914 0 +-389 271 782 0 +345 -421 -32 0 +-137 771 -230 0 +587 -689 74 0 +642 351 -523 0 +-255 -297 673 0 +997 656 108 0 +-726 603 442 0 +390 -864 -452 0 +400 -532 -627 0 +215 876 656 0 +945 250 235 0 +651 -754 890 0 +254 -511 516 0 +53 623 -605 0 +500 798 696 0 +170 -84 933 0 +210 -168 150 0 +-765 871 514 0 +532 -793 -440 0 +-320 661 54 0 +422 121 -372 0 +-498 -693 -1 0 +-743 -352 327 0 +-917 -673 -251 0 +-172 -155 -598 0 +-356 -50 627 0 +-512 -498 46 0 +336 181 -852 0 +-585 -393 -178 0 +-849 -222 -478 0 +-677 -471 -645 0 +-729 -432 -517 0 +-147 -571 -730 0 +259 -368 270 0 +-461 524 -696 0 +-316 -700 758 0 +174 -966 -342 0 +-586 -16 114 0 +-208 -123 -490 0 +-864 851 -818 0 +-690 -524 -778 0 +301 -541 855 0 +664 -200 196 0 +-609 -207 452 0 +-991 451 -897 0 +429 168 954 0 +399 343 -962 0 +801 252 -200 0 +-457 -499 -480 0 +726 -1000 83 0 +675 -498 771 0 +282 631 394 0 +666 -595 90 0 +573 -538 121 0 +98 -901 925 0 +781 245 440 0 +-747 680 53 0 +557 -113 -787 0 +666 257 751 0 +-445 -232 251 0 +-582 -754 382 0 +-849 -303 255 0 +-950 -420 -313 0 +181 -5 29 0 +-16 -298 -965 0 +94 -785 -598 0 +618 -326 -549 0 +-337 474 283 0 +-476 -696 -349 0 +658 -423 526 0 +-973 880 943 0 +420 847 794 0 +565 833 -352 0 +254 755 312 0 +27 323 338 0 +709 996 479 0 +-636 851 -680 0 +102 -873 -263 0 +903 982 -37 0 +424 -366 805 0 +-468 755 638 0 +380 48 586 0 +427 212 414 0 +178 354 -673 0 +-156 -558 -192 0 +-670 -106 383 0 +-127 838 857 0 +195 -973 -987 0 +994 -891 112 0 +850 542 -238 0 +-124 -382 772 0 +-177 332 494 0 +-844 -511 818 0 +-843 -108 -721 0 +982 -463 899 0 +298 -810 -232 0 +-147 -17 -774 0 +-383 -592 748 0 +368 -321 882 0 +35 473 -855 0 +-578 927 654 0 +-620 683 694 0 +781 -54 169 0 +742 -256 -115 0 +622 -387 -123 0 +380 364 234 0 +133 659 80 0 +260 632 -265 0 +990 -596 -966 0 +944 694 995 0 +774 -212 -504 0 +-906 168 -75 0 +5 824 886 0 +55 982 34 0 +313 -87 -257 0 +792 575 586 0 +76 439 35 0 +449 542 330 0 +-95 111 971 0 +-433 -726 802 0 +-605 992 596 0 +-655 856 -631 0 +-413 600 -606 0 +165 843 -5 0 +883 -481 -210 0 +-579 -21 -533 0 +-232 -44 125 0 +434 -776 -171 0 +-509 -279 -29 0 +-910 795 -564 0 +-417 915 216 0 +67 983 -871 0 +565 -855 -675 0 +110 -387 461 0 +602 -88 -294 0 +-40 781 -826 0 +-996 612 -440 0 +916 -446 -606 0 +-947 684 -618 0 +48 694 7 0 +-497 866 58 0 +-915 77 710 0 +445 95 594 0 +710 682 -379 0 +581 -551 -419 0 +-873 -536 917 0 +-267 -794 51 0 +-890 -20 521 0 +969 104 529 0 +130 -929 237 0 +-426 216 93 0 +225 301 -589 0 +-825 -461 -918 0 +-426 82 901 0 +-878 185 -992 0 +510 -136 -850 0 +399 288 883 0 +-334 4 -807 0 +610 -512 -685 0 +-550 556 12 0 +-788 -492 8 0 +-473 190 -244 0 +-63 -446 598 0 +-774 -933 -219 0 +928 -311 -600 0 +-466 265 322 0 +817 -869 -57 0 +-887 940 63 0 +-603 862 -109 0 +-711 -845 -143 0 +415 226 192 0 +-275 321 607 0 +-954 312 600 0 +944 -377 -353 0 +320 -404 820 0 +58 -958 -858 0 +225 -289 -278 0 +-185 -797 -914 0 +486 123 895 0 +-863 -769 -812 0 +452 -322 -621 0 +-604 -591 649 0 +473 818 993 0 +265 912 150 0 +540 -107 -3 0 +3 -326 -128 0 +181 814 -41 0 +-646 -606 196 0 +-29 305 -547 0 +-966 -282 -398 0 +905 -994 -465 0 +89 -883 698 0 +724 -706 767 0 +691 -575 81 0 +-835 180 176 0 +-489 -205 585 0 +-718 -198 -28 0 +759 -647 406 0 +-740 -89 187 0 +-231 529 -319 0 +548 -387 406 0 +613 950 538 0 +-719 -331 -520 0 +616 728 871 0 +538 425 865 0 +-504 336 -716 0 +-497 274 133 0 +557 -132 -809 0 +-911 -226 -128 0 +484 -390 609 0 +-191 -396 81 0 +739 444 788 0 +-619 350 107 0 +-298 560 1000 0 +-179 -243 154 0 +476 -979 886 0 +275 -606 -674 0 +-495 220 -340 0 +-38 -653 14 0 +27 -676 832 0 +-121 820 403 0 +815 726 -337 0 +-409 878 -750 0 +-458 -618 129 0 +-619 -294 625 0 +-504 201 526 0 +394 447 974 0 +-774 -371 6 0 +589 -641 -846 0 +-803 257 934 0 +-516 -909 -306 0 +714 521 -782 0 +445 -19 -48 0 +627 -174 -483 0 +-257 -39 -527 0 +-873 762 -609 0 +445 -575 -844 0 +61 580 -816 0 +-86 578 317 0 +-35 -244 -127 0 +312 -836 786 0 +106 600 425 0 +-417 373 724 0 +98 -354 339 0 +482 -465 580 0 +-99 -730 311 0 +300 501 8 0 +-118 -332 -680 0 +-272 351 918 0 +94 798 833 0 +743 693 454 0 +560 656 -842 0 +-18 175 -643 0 +592 -423 830 0 +723 23 -507 0 +155 342 307 0 +-113 -738 454 0 +77 -430 -740 0 +171 283 -262 0 +-907 -866 -853 0 +-370 -881 429 0 +726 522 -817 0 +360 225 -648 0 +-974 47 492 0 +-993 -103 330 0 +-572 592 131 0 +-588 295 193 0 +-240 -954 -787 0 +941 797 417 0 +-263 245 326 0 +-227 -317 -550 0 +114 539 309 0 +204 223 -420 0 +538 400 -602 0 +-630 47 500 0 +-293 -59 189 0 +-599 50 -501 0 +-615 772 928 0 +-1000 343 -494 0 +953 189 -451 0 +-310 349 317 0 +86 427 151 0 +-577 -685 318 0 +-264 732 337 0 +-130 816 -496 0 +-784 -994 -921 0 +-258 128 277 0 +158 -86 -992 0 +-335 -683 -537 0 +720 901 -244 0 +863 -290 163 0 +-501 368 -681 0 +-221 -127 -1 0 +-584 677 -864 0 +981 -370 -623 0 +-114 602 -63 0 +-198 322 -981 0 +907 -533 -124 0 +153 299 -836 0 +-70 -659 -575 0 +-806 694 -823 0 +-333 -628 -151 0 +95 212 46 0 +259 575 -809 0 +228 902 -894 0 +-308 981 448 0 +-153 -341 20 0 +92 616 966 0 +326 -743 -859 0 +328 -843 347 0 +653 -428 -401 0 +212 717 -475 0 +306 -976 -469 0 +462 -974 -653 0 +379 -310 437 0 +712 -698 -483 0 +-989 126 -848 0 +478 -92 -769 0 +515 878 774 0 +-763 494 605 0 +399 314 122 0 +118 759 -195 0 +-61 905 -917 0 +-774 550 -693 0 +-657 -222 263 0 +-923 665 352 0 +655 -267 -936 0 +-297 -442 -448 0 +-347 -866 -174 0 +630 -866 -116 0 +-429 628 -274 0 +-751 -630 -352 0 +-9 666 -468 0 +-544 -140 -594 0 +356 705 506 0 +-645 -248 546 0 +-643 338 -37 0 +148 684 522 0 +475 336 -315 0 +198 302 194 0 +919 -795 921 0 +24 607 145 0 +-316 593 -52 0 +761 -292 -37 0 +456 766 682 0 +-814 -294 348 0 +-940 417 722 0 +712 -131 465 0 +-987 -449 -78 0 +987 -639 824 0 +288 -314 458 0 +686 528 -813 0 +-539 -282 81 0 +32 889 937 0 +579 -161 281 0 +-768 -518 626 0 +-386 -130 866 0 +-721 736 -414 0 +-137 725 -275 0 +140 -157 293 0 +-257 -183 -90 0 +832 -404 -111 0 +-123 -955 -792 0 +-149 999 66 0 +-660 -659 -151 0 +80 243 -258 0 +972 -247 -865 0 +436 961 254 0 +-120 -251 -492 0 +744 618 -748 0 +867 36 -93 0 +-629 -793 345 0 +-443 542 -187 0 +-40 -358 -592 0 +634 806 -122 0 +363 316 -634 0 +-229 338 -451 0 +-452 -798 391 0 +-29 174 -585 0 +15 -609 -136 0 +-751 659 -813 0 +-45 962 -593 0 +-475 439 -271 0 +-949 858 631 0 +931 233 917 0 +-824 74 -274 0 +529 -560 -464 0 +-355 892 -526 0 +193 787 734 0 +-949 583 727 0 +675 -296 -745 0 +652 279 639 0 +314 241 -815 0 +-227 -578 919 0 +653 -278 -718 0 +986 46 -146 0 +974 -651 693 0 +206 781 -523 0 +284 -712 930 0 +-977 458 -497 0 +-80 -825 769 0 +-578 85 -297 0 +202 420 -852 0 +-231 -589 -38 0 +-542 553 -661 0 +-258 -979 36 0 +59 821 159 0 +949 148 -411 0 +-469 383 -200 0 +-466 342 -232 0 +790 211 160 0 +-525 363 -196 0 +695 -77 -2 0 +123 -639 19 0 +-200 636 -671 0 +-898 19 798 0 +-593 -496 -32 0 +267 -125 91 0 +-98 -188 623 0 +602 685 -198 0 +-69 875 -387 0 +825 -289 227 0 +-285 -551 753 0 +875 -178 -57 0 +-682 -686 614 0 +-614 756 -241 0 +-654 -736 235 0 +-743 -845 375 0 +-893 763 246 0 +406 -233 610 0 +468 100 466 0 +-705 293 43 0 +-724 -697 634 0 +-517 -184 -743 0 +327 849 227 0 +694 869 -145 0 +447 222 975 0 +-512 -834 609 0 +258 -423 -681 0 +204 584 925 0 +532 27 -920 0 +-402 -786 938 0 +807 -401 -373 0 +-492 812 526 0 +-988 779 -926 0 +60 -858 -774 0 +340 -277 -547 0 +-747 329 601 0 +610 -826 624 0 +930 -596 -227 0 +395 742 563 0 +-171 970 396 0 +-655 -664 -701 0 +284 103 275 0 +-758 -824 -979 0 +191 868 891 0 +-290 -479 108 0 +410 -576 -176 0 +-473 223 -956 0 +-687 -127 386 0 +145 -189 713 0 +54 49 -507 0 +-700 510 230 0 +993 989 135 0 +843 -454 900 0 +663 478 584 0 +285 -784 288 0 +-199 404 -713 0 +-374 -147 238 0 +-58 21 -893 0 +289 963 -278 0 +-886 642 -185 0 +85 -130 77 0 +-927 210 166 0 +-587 418 145 0 +-652 878 -171 0 +952 207 826 0 +262 -953 -165 0 +-589 -404 174 0 +-878 411 705 0 +549 -187 -469 0 +-332 481 364 0 +155 214 -991 0 +-16 -928 160 0 +849 699 -388 0 +653 831 -22 0 +398 415 768 0 +-805 -288 -201 0 +947 -95 -942 0 +-872 59 553 0 +-386 -223 260 0 +202 82 881 0 +-44 -944 -670 0 +-886 -706 306 0 +-459 -774 -452 0 +-826 -361 -562 0 +-318 -732 512 0 +-716 -791 647 0 +-103 821 153 0 +-858 -938 114 0 +-973 826 870 0 +457 -326 -320 0 +301 808 556 0 +-502 960 146 0 +-456 -88 -144 0 +-915 -856 521 0 +-526 -71 -405 0 +626 24 -395 0 +919 171 191 0 +-122 -60 268 0 +862 -650 -735 0 +117 -511 949 0 +649 797 82 0 +-907 -919 136 0 +644 843 -849 0 +635 213 149 0 +970 204 460 0 +-216 -728 -159 0 +466 -989 693 0 +-106 200 -666 0 +-429 250 -980 0 +967 465 788 0 +-8 -939 803 0 +605 113 -797 0 +-37 -187 -164 0 +-380 -551 -387 0 +-705 758 800 0 +725 -470 267 0 +-909 -123 -996 0 +568 334 -211 0 +-530 608 551 0 +-615 173 444 0 +-592 -617 -158 0 +-793 684 -373 0 +-706 991 177 0 +727 -9 -204 0 +-608 486 174 0 +532 -570 876 0 +970 490 832 0 +232 884 -162 0 +-439 161 -565 0 +-692 235 -767 0 +437 831 -610 0 +-461 -672 878 0 +-371 -303 -258 0 +937 -162 -795 0 +-996 599 -98 0 +813 -466 395 0 +440 -851 469 0 +-64 -432 -555 0 +921 875 752 0 +303 -71 474 0 +-445 666 604 0 +-124 380 -322 0 +770 348 341 0 +-371 194 -14 0 +-668 -689 -275 0 +-800 -539 628 0 +419 -727 -587 0 +925 -376 714 0 +579 371 525 0 +539 216 789 0 +-143 87 -927 0 +-878 -248 -479 0 +459 164 -265 0 +522 783 554 0 +924 281 -484 0 +214 -322 779 0 +806 -425 470 0 +-248 518 349 0 +-210 139 -554 0 +3 -426 577 0 +934 659 548 0 +486 576 -801 0 +390 -402 21 0 +184 -113 927 0 +789 708 35 0 +405 -680 -962 0 +606 -958 -268 0 +-268 647 -56 0 +616 -257 221 0 +880 -310 -627 0 +847 501 -515 0 +-495 -289 178 0 +511 789 135 0 +609 -92 438 0 +-141 -357 -74 0 +-762 -434 305 0 +390 257 574 0 +119 199 -231 0 +935 -303 295 0 +871 -692 596 0 +538 -29 588 0 +-776 -502 553 0 +-711 908 -645 0 +879 224 -108 0 +931 -278 369 0 +849 -926 944 0 +854 395 234 0 +943 -46 -430 0 +-993 -624 -80 0 +-152 -868 252 0 +234 -473 -273 0 +370 984 691 0 +454 -708 -934 0 +720 230 967 0 +-941 -56 782 0 +-793 959 863 0 +286 -380 846 0 +-332 502 -455 0 +-66 865 974 0 +-123 -646 -318 0 +-341 -851 -344 0 +750 -837 915 0 +-341 -18 -318 0 +356 -624 -955 0 +-800 -669 500 0 +-700 204 -60 0 +992 -794 -819 0 +273 -734 -715 0 +579 -101 -436 0 +941 640 -156 0 +-802 182 402 0 +578 -763 -740 0 +-541 875 -13 0 +-27 -706 -7 0 +-43 -704 -442 0 +-853 -642 -420 0 +99 -351 664 0 +-293 22 -296 0 +-412 -847 997 0 +114 -709 413 0 +408 -91 323 0 +-502 868 402 0 +-300 122 689 0 +96 179 -814 0 +-308 -399 -289 0 +376 -656 -122 0 +605 -906 -148 0 +14 -495 909 0 +-646 66 -4 0 +959 833 -12 0 +198 -368 -16 0 +414 850 -363 0 +-982 -842 -365 0 +-524 283 -919 0 +-357 802 -733 0 +-772 391 161 0 +-611 239 494 0 +217 211 135 0 +965 -737 501 0 +499 351 112 0 +746 621 102 0 +-574 689 -533 0 +927 -66 -483 0 +316 715 -389 0 +-117 -336 -861 0 +-482 -365 -492 0 +905 -178 -653 0 +-183 812 -820 0 +-422 -555 -483 0 +550 678 -31 0 +282 778 -14 0 +-964 -549 -730 0 +-589 23 -595 0 +13 -923 691 0 +30 356 912 0 +-884 437 -563 0 +13 -996 931 0 +-243 -452 -74 0 +116 549 -237 0 +-222 285 668 0 +261 -888 -458 0 +216 -937 -525 0 +-14 185 119 0 +-785 272 -276 0 +487 -361 443 0 +987 -28 342 0 +-224 -505 -245 0 +620 655 525 0 +442 -103 128 0 +-248 759 81 0 +-762 22 389 0 +552 -145 262 0 +737 520 -131 0 +95 -295 473 0 +-396 -678 518 0 +-827 -55 -863 0 +-432 132 172 0 +-322 94 -33 0 +-290 665 626 0 +-966 275 -284 0 +-835 -508 174 0 +-940 417 175 0 +369 345 -267 0 +-350 429 201 0 +-489 31 185 0 +857 574 47 0 +204 -573 416 0 +-207 -298 220 0 +780 -991 -452 0 +-287 -775 -523 0 +374 484 -596 0 +449 -289 -755 0 +238 564 -251 0 +134 517 -908 0 +-811 540 66 0 +-237 20 -239 0 +934 222 -769 0 +-927 -23 -716 0 +348 981 260 0 +-595 901 537 0 +623 641 -823 0 +126 -620 782 0 +-566 -383 -658 0 +-717 -345 -164 0 +-22 -808 50 0 +613 42 65 0 +568 -207 -976 0 +-225 52 -836 0 +132 -463 -325 0 +-590 -386 -593 0 +634 -53 722 0 +648 -242 -410 0 +-352 -400 -642 0 +-69 -514 143 0 +181 -760 -465 0 +347 -875 -177 0 +882 -983 14 0 +121 103 -992 0 +-734 380 -322 0 +-986 -920 -926 0 +872 -781 565 0 +-800 903 329 0 +588 234 -960 0 +-411 375 584 0 +503 -210 189 0 +-209 767 610 0 +-992 925 622 0 +394 350 96 0 +-163 851 -778 0 +-852 -221 822 0 +796 -21 148 0 +-423 736 150 0 +696 -795 33 0 +-719 778 195 0 +-19 -625 894 0 +132 -883 -183 0 +-699 9 -923 0 +-956 -249 248 0 +-591 160 -988 0 +564 479 -399 0 +552 463 -840 0 +-422 -349 -200 0 +713 687 36 0 +-541 -817 -915 0 +221 552 -288 0 +-890 -578 143 0 +41 669 -195 0 +-35 107 -411 0 +948 -745 51 0 +581 628 719 0 +814 -304 -456 0 +-271 70 492 0 +115 214 -92 0 +216 -885 -306 0 +-942 804 242 0 +-121 716 577 0 +543 -146 -639 0 +-589 404 -435 0 +-590 120 854 0 +663 900 -211 0 +-337 -47 -359 0 +9 -628 -677 0 +-348 -648 -332 0 +680 475 388 0 +742 254 -732 0 +-521 127 466 0 +778 -310 -969 0 +-367 369 991 0 +95 -87 710 0 +741 -956 585 0 +-405 263 140 0 +580 557 54 0 +-121 -946 617 0 +-971 -99 -509 0 +-151 367 240 0 +-239 -522 464 0 +-545 -534 948 0 +373 -197 559 0 +762 907 -263 0 +684 -261 -537 0 +-134 3 -45 0 +558 -150 -902 0 +-296 356 -865 0 +983 581 -892 0 +714 185 -300 0 +576 -696 -504 0 +150 950 -809 0 +-56 420 -15 0 +-92 59 -925 0 +-670 -483 -284 0 +-762 -702 96 0 +975 759 294 0 +-857 -518 142 0 +937 -486 518 0 +-244 -585 -845 0 +-129 -834 216 0 +-439 385 926 0 +-377 29 -922 0 +-989 -502 -303 0 +892 -472 422 0 +-275 -561 26 0 +-747 887 -791 0 +277 -762 111 0 +-967 -891 286 0 +-470 -164 261 0 +762 527 -558 0 +159 -757 553 0 +944 270 558 0 +-398 -3 151 0 +-9 -715 80 0 +436 -15 -947 0 +872 -60 -213 0 +658 298 -787 0 +2 -784 94 0 +461 398 -696 0 +-550 982 -33 0 +199 -645 -154 0 +732 361 617 0 +-515 -386 -115 0 +-105 73 -165 0 +-145 165 48 0 +751 -977 -39 0 +995 -918 -892 0 +772 651 578 0 +110 311 -640 0 +-388 -139 693 0 +493 96 798 0 +-225 600 -253 0 +-226 -574 -530 0 +-86 156 599 0 +379 -15 299 0 +-953 622 967 0 +690 -454 -764 0 +688 -463 -265 0 +-123 -473 -282 0 +580 451 -242 0 +-642 523 -57 0 +-569 561 898 0 +754 -557 228 0 +121 547 734 0 +-133 -329 -314 0 +357 643 45 0 +-576 247 -677 0 +-819 8 -642 0 +312 496 941 0 +678 -196 46 0 +222 622 -17 0 +318 -303 757 0 +239 -649 219 0 +-944 -516 -448 0 +-336 293 290 0 +368 -868 915 0 +-84 11 -373 0 +40 -699 -964 0 +-202 849 -470 0 +627 -951 71 0 +441 238 354 0 +657 517 32 0 +-694 -306 -77 0 +-236 -977 821 0 +-304 -194 61 0 +236 -921 118 0 +-646 -644 691 0 +625 544 202 0 +785 992 -843 0 +504 -494 -713 0 +44 -556 192 0 +788 168 -891 0 +276 -183 940 0 +899 -163 705 0 +-440 172 -863 0 +-378 775 262 0 +285 670 583 0 +-235 35 414 0 +-106 117 -671 0 +999 -213 -140 0 +362 -775 977 0 +-882 197 -734 0 +-820 -969 -873 0 +335 920 740 0 +-919 350 -312 0 +-271 849 -548 0 +-643 -642 5 0 +-150 52 473 0 +-433 455 692 0 +-365 -631 918 0 +-390 -280 -124 0 +70 -544 -976 0 +-193 -235 -163 0 +-803 58 770 0 +-107 817 -323 0 +-67 954 124 0 +516 291 629 0 +-545 760 361 0 +483 591 -141 0 +650 294 -570 0 +-53 -855 -45 0 +57 -940 449 0 +471 -134 843 0 +-618 -732 -452 0 +-895 674 -939 0 +-970 -550 26 0 +220 493 874 0 +-948 159 602 0 +-777 195 898 0 +346 104 802 0 +-77 90 -923 0 +-441 -648 -480 0 +264 288 939 0 +385 780 267 0 +-195 -861 244 0 +143 713 -836 0 +-542 733 -739 0 +-138 -480 837 0 +527 -480 -38 0 +950 252 48 0 +993 -436 812 0 +563 705 -378 0 +-464 369 838 0 +843 378 571 0 +-391 634 680 0 +-799 -626 113 0 +599 -28 -285 0 +155 -210 981 0 +109 545 206 0 +-56 583 601 0 +969 -436 260 0 +-153 629 969 0 +-419 -514 -99 0 +-802 16 -922 0 +478 -996 778 0 +645 -389 -188 0 +-726 718 635 0 +-467 -116 272 0 +-669 105 -302 0 +763 -372 -778 0 +291 226 885 0 +-790 669 99 0 +889 -995 716 0 +130 777 926 0 +907 -699 268 0 +717 -940 718 0 +271 -425 247 0 +-502 -808 -866 0 +514 -958 709 0 +-984 841 16 0 +556 -188 999 0 +771 954 -758 0 +-182 -990 -919 0 +-44 475 -859 0 +-694 -423 -696 0 +296 -945 -131 0 +48 140 775 0 +365 275 615 0 +604 -950 757 0 +-861 -820 -377 0 +-763 -435 696 0 +-3 130 -493 0 +-567 281 -685 0 +-372 609 -445 0 +597 338 -679 0 +-400 588 68 0 +-909 536 -785 0 +455 -275 -102 0 +-362 -693 -529 0 +-709 -239 -513 0 +894 679 888 0 +-163 -479 -470 0 +459 264 -456 0 +-272 325 773 0 +297 -991 -119 0 +378 502 198 0 +-65 -466 57 0 +-411 -381 95 0 +970 862 699 0 +941 585 -538 0 +-239 41 35 0 +659 -210 826 0 +330 260 804 0 +509 80 -343 0 +-244 243 -134 0 +-338 -620 605 0 +698 -213 -768 0 +298 -923 762 0 +-995 41 -763 0 +309 -285 865 0 +996 104 619 0 +-896 -478 660 0 +-800 -904 -404 0 +546 812 101 0 +487 36 186 0 +-689 -218 -646 0 +482 490 304 0 +-503 -946 -116 0 +-722 52 430 0 +-905 -949 505 0 +776 969 866 0 +292 -613 957 0 +-26 -240 515 0 +429 58 -978 0 +149 86 -175 0 +982 -863 -415 0 +960 -343 717 0 +-836 688 102 0 +-762 609 -496 0 +117 630 -979 0 +-334 916 552 0 +-110 253 828 0 +-165 -873 -905 0 +670 -486 -898 0 +400 -529 -651 0 +-240 -334 -981 0 +-728 -869 -271 0 +957 101 -67 0 +226 -679 363 0 +-228 234 899 0 +-420 -43 965 0 +-535 -974 -97 0 +352 -162 737 0 +-141 -723 -553 0 +-76 -936 567 0 +943 -520 88 0 +683 557 827 0 +-939 49 551 0 +-645 -76 -797 0 +386 -913 -167 0 +694 -615 257 0 +-201 -294 154 0 +-492 -108 66 0 +-653 469 158 0 +717 294 444 0 +-881 -528 754 0 +-750 -23 -880 0 +26 578 -83 0 +933 386 742 0 +-913 910 -846 0 +489 -934 721 0 +-756 -611 -208 0 +155 446 977 0 +162 -899 -406 0 +951 355 290 0 +-810 -301 534 0 +618 846 -264 0 +36 755 -636 0 +-820 -709 736 0 +-442 304 -383 0 +449 66 -764 0 +-323 -635 298 0 +65 -624 254 0 +-43 -257 362 0 +348 -199 940 0 +-5 955 626 0 +-242 -3 651 0 +619 235 -881 0 +-203 -908 466 0 +526 874 -221 0 +-935 799 852 0 +618 -427 243 0 +724 -648 64 0 +576 -164 -662 0 +-772 710 -932 0 +986 578 -872 0 +-409 -920 573 0 +-126 499 335 0 +248 -533 -267 0 +-360 -755 862 0 +-811 1 577 0 +-73 -81 419 0 +-278 -367 600 0 +425 155 -186 0 +726 905 926 0 +798 -478 -415 0 +-134 301 -617 0 +709 12 175 0 +744 326 -578 0 +-114 473 79 0 +833 276 577 0 +26 808 -346 0 +-860 414 -158 0 +329 -731 -61 0 +874 -377 903 0 +223 108 -790 0 +-791 215 898 0 +404 341 -186 0 +996 972 490 0 +-126 -518 256 0 +-513 -754 604 0 +176 267 -31 0 +-196 -819 172 0 +834 -11 986 0 +-82 -849 -931 0 +450 746 -60 0 +159 196 615 0 +530 -75 318 0 +562 -316 112 0 +-206 -404 157 0 +-569 289 -530 0 +-152 -201 2 0 +497 749 -639 0 +314 -368 289 0 +698 -899 935 0 +768 -133 239 0 +991 -934 231 0 +-964 742 141 0 +-969 135 94 0 +232 519 158 0 +-547 939 736 0 +-176 202 -160 0 +-748 -999 -473 0 +219 134 -382 0 +666 989 607 0 +-55 87 -355 0 +-800 673 -722 0 +-38 -973 -751 0 +-373 32 787 0 +423 74 217 0 +-515 529 -444 0 +-426 969 378 0 +649 -218 -389 0 +316 767 -901 0 +417 -753 712 0 +-595 -300 635 0 +403 689 569 0 +-130 536 131 0 +-410 -758 621 0 +654 -826 -928 0 +514 210 217 0 +-417 -570 755 0 +-833 -491 945 0 +439 -381 -1 0 +895 183 18 0 +330 682 -26 0 +201 822 -550 0 +-52 269 -817 0 +877 -274 -264 0 +360 -688 172 0 +-43 152 -209 0 +-632 961 327 0 +361 -923 662 0 +739 952 176 0 +-196 -218 371 0 +752 -160 446 0 +-912 -881 168 0 +383 70 792 0 +110 268 -324 0 +719 988 -837 0 +554 127 290 0 +826 626 300 0 +161 28 471 0 +-934 921 -240 0 +-415 -19 -297 0 +-486 -734 114 0 +-839 890 -299 0 +303 565 833 0 +-679 -632 180 0 +582 -439 66 0 +961 -41 -820 0 +-59 594 -151 0 +-426 -422 -826 0 +-107 8 -235 0 +844 958 -838 0 +-210 -243 193 0 +307 258 418 0 +485 -57 492 0 +-150 110 -460 0 +870 320 219 0 +529 -410 885 0 +762 -967 -506 0 +-288 -458 -211 0 +-583 -974 -330 0 +-825 847 457 0 +-496 -597 -548 0 +931 560 334 0 +-457 -290 291 0 +754 796 555 0 +938 359 -334 0 +668 486 782 0 +-361 -678 840 0 +170 -13 213 0 +-808 156 300 0 +-98 -834 461 0 +-58 417 233 0 +-885 -719 144 0 +-193 -485 -392 0 +826 -876 391 0 +165 972 -472 0 +-317 -920 649 0 +839 -697 893 0 +-529 739 -156 0 +-271 -1 -952 0 +286 -535 452 0 +-555 201 -78 0 +-740 -765 -492 0 +62 778 -924 0 +-46 967 -621 0 +592 984 -29 0 +-310 235 262 0 +473 391 -87 0 +1000 -82 717 0 +344 -62 -844 0 +994 -174 -36 0 +-380 591 -160 0 +469 -781 -968 0 +596 -152 780 0 +-773 -133 493 0 +-240 -354 -26 0 +-701 -869 416 0 +-229 181 -618 0 +735 154 982 0 +-212 -277 -928 0 +-220 217 271 0 +-778 -487 -371 0 +350 -657 505 0 +148 11 746 0 +410 27 999 0 +-476 -998 -405 0 +922 507 606 0 +275 752 -410 0 +-510 842 680 0 +805 -316 -960 0 +672 -765 -771 0 +-200 -470 -162 0 +-232 -334 440 0 +593 -757 -676 0 +-6 -971 779 0 +71 -193 -913 0 +28 -832 230 0 +798 659 843 0 +-196 990 -932 0 +95 -37 600 0 +-137 -175 509 0 +20 778 -620 0 +-341 -644 841 0 +19 -235 -55 0 +-96 -828 905 0 +543 -279 218 0 +-939 341 859 0 +137 558 711 0 +-555 678 453 0 +-84 288 -306 0 +-959 510 592 0 +856 793 -623 0 +767 -821 922 0 +444 -810 -325 0 +-12 175 -942 0 +267 979 358 0 +-977 -660 838 0 +-126 840 -92 0 +-44 241 133 0 +-522 361 325 0 +212 921 -756 0 +399 915 945 0 +581 -631 507 0 +998 641 572 0 +585 -670 849 0 +-959 -846 -32 0 +-13 961 24 0 +-942 -807 -923 0 +-975 139 3 0 +-793 164 -591 0 +-496 -802 -512 0 +969 655 -929 0 +463 576 -823 0 +736 937 485 0 +800 496 -963 0 +799 -263 -445 0 +959 708 534 0 +706 -50 -414 0 +-615 339 -50 0 +973 -85 896 0 +559 510 260 0 +-714 783 689 0 +-581 -110 -257 0 +-429 162 -843 0 +285 -951 718 0 +19 -353 -510 0 +302 532 167 0 +-992 -477 -537 0 +-152 844 -819 0 +134 212 -215 0 +643 9 -709 0 +927 -821 443 0 +-101 -680 782 0 +333 440 100 0 +926 192 -269 0 +124 858 -413 0 +-376 151 938 0 +-605 -700 -461 0 +981 103 -770 0 +-258 -575 323 0 +-405 604 -353 0 +418 -485 709 0 +733 595 -892 0 +-845 289 -619 0 +-181 617 -216 0 +302 706 -102 0 +385 -631 -4 0 +805 492 820 0 +-543 -386 -876 0 +-344 -164 -420 0 +-286 841 -779 0 +426 -502 -9 0 +179 923 850 0 +-437 606 -278 0 +365 527 801 0 +-696 -505 517 0 +114 -324 746 0 +-926 204 919 0 +194 922 217 0 +446 -101 75 0 +-188 -287 -60 0 +-962 -856 -744 0 +587 -578 110 0 +-299 439 -728 0 +681 534 815 0 +-2 525 435 0 +286 154 -72 0 +374 121 -858 0 +-816 731 -479 0 +530 973 125 0 +541 835 -841 0 +-764 125 -742 0 +196 600 60 0 +-599 -312 -811 0 +458 -813 853 0 +430 -394 288 0 +400 81 17 0 +338 303 460 0 +108 652 446 0 +-630 507 566 0 +-981 314 635 0 +-800 -586 156 0 +-365 -246 704 0 +-118 -777 802 0 +352 -190 585 0 +921 -720 992 0 +331 486 891 0 +575 554 -577 0 +330 29 98 0 +-245 961 -111 0 +-510 588 799 0 +474 -321 -565 0 +137 -57 839 0 +843 -508 243 0 +342 -242 -315 0 +48 -370 -193 0 +195 -44 168 0 +-796 619 -913 0 +908 965 408 0 +-935 924 259 0 +-644 -817 -387 0 +840 903 456 0 +-737 656 175 0 +177 -355 651 0 +-446 -660 -34 0 +-726 -333 772 0 +842 900 -545 0 +102 456 -143 0 +126 311 897 0 +14 937 106 0 +833 -951 796 0 +-361 -766 -377 0 +-782 -110 -786 0 +-408 -150 -921 0 +-124 -101 467 0 +749 -433 -126 0 +931 446 -485 0 +4 754 890 0 +277 -509 661 0 +263 -271 550 0 +-36 342 -246 0 +832 29 -235 0 +-877 -603 -265 0 +-543 253 -342 0 +-997 -658 957 0 +572 360 742 0 +-960 350 739 0 +-968 -221 206 0 +-845 -515 746 0 +485 200 -915 0 +-801 835 78 0 +-360 517 -530 0 +-415 40 -545 0 +207 29 619 0 +363 -565 -557 0 +-32 346 24 0 +617 428 -446 0 +594 995 -564 0 +-123 -588 884 0 +-18 -801 -373 0 +-962 814 -526 0 +-289 605 -48 0 +222 -971 578 0 +-867 -551 -856 0 +-6 646 -445 0 +-485 -777 -480 0 +-573 -73 975 0 +-874 -126 -354 0 +-57 -559 501 0 +-188 -304 626 0 +-948 -474 383 0 +-496 -275 213 0 +616 606 -88 0 +228 612 240 0 +268 -482 -502 0 +-461 -403 -41 0 +-170 401 -841 0 +279 -579 435 0 +893 934 -311 0 +931 349 -484 0 +534 -247 308 0 +265 703 -585 0 +198 -570 166 0 +166 483 551 0 +-169 -542 -89 0 +-726 352 754 0 +-991 -951 -768 0 +-571 -133 -810 0 +-588 -976 -62 0 +-388 -840 935 0 +-211 799 -640 0 +-793 -63 -831 0 +682 180 637 0 +675 229 -364 0 +847 -572 -703 0 +800 -760 -56 0 +816 98 -78 0 +696 -679 547 0 +-715 987 -482 0 +-247 242 -972 0 +410 186 -174 0 +-194 61 -325 0 +859 787 836 0 +847 -39 -557 0 +-685 -148 -504 0 +-934 44 54 0 +904 -978 -186 0 +704 24 -276 0 +-59 113 -148 0 +384 491 -896 0 +-708 314 124 0 +220 -277 -229 0 +-74 -607 185 0 +211 -330 954 0 +427 201 562 0 +827 205 -253 0 +495 485 218 0 +-460 999 327 0 +-530 -958 -662 0 +-78 -234 -109 0 +185 -177 236 0 +675 893 -507 0 +-528 -915 510 0 +-972 111 -566 0 +915 -156 528 0 +901 -453 -489 0 +919 -91 -859 0 +-69 255 986 0 +-232 -33 286 0 +859 -99 -11 0 +-291 425 664 0 +-793 588 89 0 +615 -410 -521 0 +-953 -531 817 0 +537 168 -747 0 +808 123 -521 0 +-878 -978 779 0 +465 -986 -861 0 +295 872 -593 0 +190 159 147 0 +-441 -341 986 0 +144 -729 60 0 +559 877 -491 0 +29 -339 434 0 +-85 -297 140 0 +195 -6 115 0 +368 -609 -504 0 +-894 -749 623 0 +102 -366 743 0 +-823 -31 -567 0 +654 84 -148 0 +-130 116 -306 0 +728 -91 -281 0 +-628 -536 81 0 +269 901 920 0 +-695 -65 49 0 +-66 919 -884 0 +-508 88 -847 0 +-607 289 -682 0 +94 657 -131 0 +283 -508 841 0 +70 -479 -492 0 +227 574 -600 0 +690 708 515 0 +-853 -269 575 0 +-615 -717 18 0 +-139 166 -483 0 +720 746 976 0 +-328 320 -370 0 +985 709 637 0 +-499 -494 -589 0 +275 733 -469 0 +-666 877 -96 0 +644 362 653 0 +956 -27 -73 0 +-855 -834 -797 0 +-529 -922 -879 0 +-43 -573 404 0 +840 802 -831 0 +-42 -662 -303 0 +997 -340 -489 0 +-610 323 -901 0 +238 310 44 0 +-507 802 252 0 +839 84 870 0 +-676 -173 -606 0 +720 249 -358 0 +-796 422 139 0 +223 -946 246 0 +513 -700 -506 0 +560 -310 -147 0 +670 520 -652 0 +-146 -910 922 0 +333 -969 -164 0 +936 -814 585 0 +106 -135 979 0 +-48 191 544 0 +-667 -46 916 0 +551 -241 -269 0 +152 -493 231 0 +271 987 523 0 +-584 -751 444 0 +68 -488 661 0 +-490 -774 801 0 +-388 769 -394 0 +-319 -163 -936 0 +213 -978 410 0 +-856 339 -24 0 +590 -526 779 0 +753 -150 376 0 +866 253 -675 0 +-949 -892 -976 0 +260 -174 240 0 +339 351 -198 0 +-944 27 -773 0 +769 557 -149 0 +541 808 -100 0 +-847 601 -406 0 +-248 -786 546 0 +-596 -551 741 0 +537 -593 -253 0 +774 -333 -240 0 +-85 -244 696 0 +-190 -135 -392 0 +-916 141 721 0 +25 223 -354 0 +-966 -976 514 0 +572 -756 697 0 +370 98 -446 0 +585 -812 289 0 +775 -613 -943 0 +-171 -332 600 0 +-127 784 755 0 +-904 498 261 0 +-915 -462 961 0 +-733 -574 880 0 +-1000 -769 804 0 +-723 581 60 0 +-482 911 -884 0 +295 290 -271 0 +1 670 -304 0 +-13 452 772 0 +589 -963 -263 0 +781 132 87 0 +240 902 716 0 +464 636 564 0 +-853 179 297 0 +-359 -811 709 0 +-215 872 -534 0 +921 974 -653 0 +785 -964 -728 0 +108 741 307 0 +-890 21 -654 0 +-177 -236 686 0 +707 716 -998 0 +671 -791 936 0 +172 678 -967 0 +193 -742 800 0 +425 -880 780 0 +114 798 215 0 +964 954 -972 0 +-101 -320 -32 0 +583 812 -424 0 +973 607 -588 0 +-675 949 -544 0 +580 -790 -145 0 +-535 346 -911 0 +-334 388 -809 0 +-634 -25 -39 0 +-209 -148 520 0 +246 767 -669 0 +813 256 -148 0 +712 764 -19 0 +-755 -21 42 0 +-668 518 -187 0 +-711 954 -504 0 +768 753 -260 0 +-811 810 -824 0 +-225 941 -860 0 +751 -969 453 0 +-995 409 592 0 +-85 -582 791 0 +-681 -135 727 0 +-444 715 -286 0 +-303 199 373 0 +628 -966 -433 0 +-140 -186 967 0 +-930 758 850 0 +267 954 73 0 +-467 847 -272 0 +-466 -399 -104 0 +-906 459 -156 0 +465 -685 -412 0 +756 -482 795 0 +-661 -852 -464 0 +5 -615 116 0 +507 -752 607 0 +-184 298 -100 0 +305 104 424 0 +810 -771 -769 0 +-707 328 -936 0 +-506 -707 -899 0 +160 910 -833 0 +492 282 301 0 +633 211 -157 0 +256 231 -575 0 +-652 -794 881 0 +-874 963 880 0 +745 -136 -460 0 +-537 230 88 0 +-576 103 -42 0 +586 280 -862 0 +925 -5 863 0 +814 -567 72 0 +-852 -41 765 0 +410 419 -93 0 +985 654 -377 0 +-355 -171 750 0 +731 673 -576 0 +-240 633 -157 0 +578 959 936 0 +-981 675 -205 0 +690 -393 452 0 +603 -909 251 0 +222 -875 -689 0 +-597 -837 -124 0 +859 -345 -683 0 +123 -938 -452 0 +905 375 -465 0 +-947 -927 672 0 +369 33 -648 0 +-861 -530 -346 0 +740 290 845 0 +-94 559 589 0 +-753 301 -57 0 +-70 -486 -537 0 +-913 -607 -76 0 +703 -826 -202 0 +-192 303 -663 0 +-749 194 274 0 +889 -733 89 0 +-978 551 999 0 +344 -655 251 0 +-288 718 -470 0 +-411 687 36 0 +864 -890 252 0 +497 -431 -15 0 +-620 79 -411 0 +-972 -337 -712 0 +-645 923 -372 0 +-878 -545 747 0 +683 -211 -38 0 +-437 764 -30 0 +413 -40 -740 0 +-526 -392 -574 0 +-330 982 323 0 +649 587 200 0 +232 -586 -256 0 +-324 215 -510 0 +7 249 83 0 +933 767 252 0 +-481 670 -457 0 +-894 322 68 0 +473 -832 552 0 +555 -295 100 0 +-684 946 397 0 +383 417 381 0 +-755 759 634 0 +5 674 -708 0 +154 684 -647 0 +-501 -219 844 0 +-944 154 -949 0 +-353 411 633 0 +561 573 -430 0 +445 -773 -111 0 +445 436 -786 0 +-617 385 -609 0 +50 820 -763 0 +797 -553 -104 0 +719 -557 900 0 +-896 299 -738 0 +-751 232 947 0 +181 -189 -607 0 +768 293 -818 0 +955 -35 -687 0 +28 298 310 0 +688 -761 -269 0 +-937 459 -143 0 +834 807 -11 0 +-601 61 300 0 +-642 -137 -562 0 +-653 -78 536 0 +423 -435 -68 0 +-205 -367 623 0 +-615 -260 266 0 +-280 -685 955 0 +-341 539 504 0 +137 850 538 0 +767 -488 670 0 +-454 -607 457 0 +-75 107 928 0 +-4 324 -894 0 +-817 -272 113 0 +-673 -186 149 0 +-732 -393 -472 0 +865 -102 -551 0 +345 -404 -846 0 +-427 -468 -857 0 +188 466 -698 0 +805 -470 939 0 +-559 -565 42 0 +466 -208 756 0 +795 465 -367 0 +495 -787 -281 0 +-126 921 -222 0 +271 -980 192 0 +823 -767 974 0 +577 827 -822 0 +716 -614 694 0 +472 774 883 0 +-653 -74 -847 0 +376 -448 382 0 +369 689 973 0 +416 880 -869 0 +937 810 -967 0 +677 560 -627 0 +717 994 173 0 +-784 -392 -422 0 +-965 6 -545 0 +-870 1000 296 0 +950 -356 -171 0 +674 380 48 0 +-953 276 377 0 +984 -642 24 0 +-225 968 -25 0 +6 -995 99 0 +-861 686 -907 0 +578 19 74 0 +-307 474 -768 0 +74 109 -774 0 +900 -545 129 0 +754 -403 609 0 +966 -327 -186 0 +314 310 -382 0 +632 622 -227 0 +999 -254 -470 0 +561 481 -768 0 +350 -108 603 0 +-248 742 -527 0 +-368 131 837 0 +-633 479 19 0 +-597 -32 166 0 +-384 349 -253 0 +-211 618 -734 0 +319 591 997 0 +211 60 -687 0 +293 -689 475 0 +-18 -636 -315 0 +-880 -109 -332 0 +256 -172 -82 0 +-591 -788 371 0 +-997 689 960 0 +-624 -428 936 0 +665 181 -385 0 +1 -898 -886 0 +-377 -577 379 0 +-729 235 954 0 +921 173 -635 0 +904 -544 -112 0 +-919 660 875 0 +-548 180 -442 0 +598 -386 -331 0 +176 -843 -339 0 +943 -944 -273 0 +431 -671 -948 0 +-97 841 -688 0 +-10 78 600 0 +714 -595 867 0 +592 -431 -990 0 +-110 672 -765 0 +-70 -33 -508 0 +733 -730 661 0 +-585 -861 763 0 +-363 319 -553 0 +252 -536 209 0 +-656 641 412 0 +453 773 -200 0 +647 541 24 0 +-784 -536 -948 0 +-247 381 -260 0 +800 -626 -405 0 +-204 -1000 639 0 +-241 -799 -536 0 +387 223 2 0 +-930 -129 -441 0 +116 -829 -637 0 +668 -975 977 0 +-636 387 -948 0 +741 188 -410 0 +-106 934 -17 0 +240 675 629 0 +970 68 332 0 +627 -6 -591 0 +374 68 399 0 +-357 853 373 0 +-616 -114 358 0 +701 78 910 0 +-121 679 115 0 +594 -640 81 0 +68 871 981 0 +-34 -765 -800 0 +-503 -582 651 0 +922 -839 -501 0 +-236 757 661 0 +-3 -883 640 0 +174 389 -61 0 +-1 -110 -705 0 +-246 663 -25 0 +485 -968 -47 0 +413 794 80 0 +-339 60 -379 0 +-760 942 -748 0 +782 744 -414 0 +409 747 -691 0 +126 411 -619 0 +-715 -431 -597 0 +-922 -147 -145 0 +-826 252 -996 0 +-651 -296 263 0 +-796 291 882 0 +-790 472 -61 0 +412 -31 -59 0 +523 611 -211 0 +942 -917 -613 0 +-613 -147 -587 0 +-481 -359 -822 0 +769 -26 854 0 +504 -566 -930 0 +728 -211 -559 0 +-331 -84 9 0 +456 872 -158 0 +774 668 272 0 +107 -142 786 0 +85 217 -278 0 +-460 -282 -945 0 +751 -46 -981 0 +-729 522 -433 0 +496 -177 -85 0 +541 -430 -543 0 +987 364 -929 0 +-417 -124 -659 0 +935 13 302 0 +65 -707 117 0 +401 -112 -351 0 +-610 940 366 0 +302 544 -928 0 +898 -417 732 0 +-966 391 124 0 +24 -114 -470 0 +374 -799 741 0 +-160 915 423 0 +-26 -124 132 0 +-239 408 161 0 +-350 88 -389 0 +602 466 261 0 +471 -180 505 0 +881 178 -345 0 +-474 811 77 0 +-366 -62 565 0 +-113 -43 519 0 +-688 380 -435 0 +227 -439 -73 0 +-293 -774 -343 0 +-354 -781 143 0 +-211 510 859 0 +-55 80 -499 0 +-738 -522 -849 0 +-964 -206 761 0 +126 39 -906 0 +863 759 -292 0 +30 -449 995 0 +-768 860 175 0 +-658 -86 -26 0 +762 532 -639 0 +-216 386 554 0 +-443 306 -756 0 +754 747 838 0 +569 -115 340 0 +925 -725 971 0 +-645 665 -603 0 +-421 687 -982 0 +797 508 -485 0 +84 207 -828 0 +409 -943 -432 0 +-920 30 -226 0 +-630 -939 -127 0 +-246 340 -711 0 +-948 366 200 0 +-542 -828 441 0 +-513 -759 78 0 +404 289 -81 0 +-868 -88 803 0 +4 376 -888 0 +273 -31 596 0 +-760 -468 168 0 +-783 98 431 0 +933 159 705 0 +560 334 -437 0 +-60 418 875 0 +-641 267 -419 0 +-456 -280 -201 0 +-229 205 587 0 +695 644 93 0 +-467 14 -714 0 +704 805 883 0 +-113 498 -355 0 +-703 12 -262 0 +-242 -604 -649 0 +702 251 -244 0 +518 640 328 0 +398 -137 476 0 +-374 -504 -709 0 +-898 -186 289 0 +39 752 147 0 +685 53 601 0 +-73 -547 881 0 +-662 808 -52 0 +-232 -493 278 0 +-146 649 -461 0 +-226 776 931 0 +-881 -463 206 0 +728 605 -331 0 +-9 -600 619 0 +815 -592 -730 0 +930 -693 -877 0 +-314 -961 807 0 +-398 316 -733 0 +-897 -81 -539 0 +254 -948 -383 0 +170 -379 -793 0 +183 624 -652 0 +937 686 98 0 +-106 -976 330 0 +-602 1 -127 0 +-22 271 751 0 +87 -466 515 0 +-665 -216 238 0 +970 -802 576 0 +-418 243 968 0 +4 -622 -510 0 +954 -44 -547 0 +-681 -552 579 0 +-495 -525 6 0 +-546 -466 860 0 +883 722 115 0 +-914 558 575 0 +-255 -156 647 0 +-640 -228 -114 0 +747 352 297 0 +354 -627 179 0 +-44 -908 850 0 +-745 838 -243 0 +676 998 893 0 +748 -514 98 0 +-890 -175 -589 0 +111 -873 7 0 +124 803 748 0 +48 -711 139 0 +-641 576 233 0 +-553 163 598 0 +327 -192 -299 0 +-588 -306 796 0 +-341 -926 688 0 +73 -569 -955 0 +320 -958 74 0 +411 2 -210 0 +159 582 -51 0 +-510 163 -378 0 +-935 42 -513 0 +-973 -651 952 0 +-886 -276 884 0 +-343 -295 434 0 +-66 521 -888 0 +90 -599 -176 0 +797 257 68 0 +938 -108 -129 0 +-476 282 231 0 +887 273 -480 0 +-437 674 162 0 +735 911 -334 0 +-543 -316 -422 0 +747 335 39 0 +-599 -236 567 0 +692 499 -589 0 +780 -393 970 0 +879 -318 -633 0 +756 446 541 0 +-84 -770 -606 0 +954 266 934 0 +-316 243 -584 0 +-359 311 817 0 +-807 648 -685 0 +-1 -224 915 0 +-485 -309 346 0 +-961 110 122 0 +371 173 147 0 +-956 -757 -321 0 +749 104 -467 0 +-344 709 765 0 +-521 -278 -297 0 +635 -354 183 0 +678 920 -955 0 +82 -883 -672 0 +643 -38 274 0 +15 -871 -427 0 +-276 607 357 0 +477 -728 394 0 +-910 -84 163 0 +136 908 758 0 +-934 -493 533 0 +70 -290 424 0 +740 -4 960 0 +178 -775 -770 0 +135 598 62 0 +319 38 955 0 +-566 -907 -781 0 +569 99 470 0 +15 -610 977 0 +538 221 119 0 +-227 -477 860 0 +-479 136 -786 0 +305 564 -772 0 +504 -593 63 0 +66 -34 601 0 +423 -576 -305 0 +64 -265 -969 0 +-118 143 369 0 +-486 824 -261 0 +-39 -363 -809 0 +996 -197 -297 0 +-328 -401 -782 0 +-28 -581 806 0 +-397 -474 953 0 +-45 -661 172 0 +870 -213 683 0 +298 -69 492 0 +838 511 -360 0 +-400 514 195 0 +782 884 638 0 +-421 -192 -789 0 +-277 -472 -384 0 +-191 -579 73 0 +-944 -585 -897 0 +1 301 143 0 +404 -815 -342 0 +-136 -857 -183 0 +576 22 -773 0 +-877 548 654 0 +578 -600 93 0 +513 -128 353 0 +688 -325 -652 0 +-631 512 71 0 +74 -15 -638 0 +748 -597 356 0 +-344 366 -575 0 +-153 -835 -117 0 +-274 -332 -997 0 +-835 333 -36 0 +-217 -320 40 0 +-91 240 435 0 +-796 -311 851 0 +506 538 -915 0 +150 -318 -895 0 +-251 -818 631 0 +552 628 63 0 +713 -447 -535 0 +184 -786 386 0 +-458 -422 573 0 +327 191 5 0 +289 291 220 0 +62 222 -208 0 +-463 -970 -52 0 +336 727 612 0 +-753 -464 -596 0 +379 -948 321 0 +593 -880 -698 0 +-366 331 -328 0 +-351 -235 193 0 +871 671 -663 0 +-544 479 147 0 +323 406 -21 0 +172 46 262 0 +-500 -138 715 0 +966 776 491 0 +149 6 338 0 +-477 500 -650 0 +-243 850 580 0 +-768 -76 -232 0 +376 -438 912 0 +310 -674 -3 0 +940 -474 -645 0 +46 -866 142 0 +373 969 -495 0 +-358 801 -758 0 +736 -496 -20 0 +-580 1 479 0 +133 658 -577 0 +899 -580 -558 0 +607 -427 850 0 +991 82 764 0 +14 -514 -434 0 +848 -553 -385 0 +73 791 -509 0 +-277 23 799 0 +821 -961 538 0 +676 -5 706 0 +-864 -257 -941 0 +-124 32 -150 0 +-490 576 -171 0 +-44 -835 -257 0 +-715 -706 341 0 +992 -752 -70 0 +56 -435 -217 0 +348 298 -680 0 +604 325 -30 0 +-529 -881 564 0 +-971 -548 -233 0 +800 -382 -224 0 +343 -173 -587 0 +-189 -368 -319 0 +-901 975 -494 0 +728 627 768 0 +533 224 941 0 +738 240 -871 0 +473 589 -39 0 +-569 -185 706 0 +-817 342 358 0 +145 -956 -549 0 +306 -69 -485 0 +550 842 929 0 +-698 113 -9 0 +-143 -884 -488 0 +-891 -474 -907 0 +-62 -451 793 0 +-836 730 896 0 +382 -755 936 0 +83 366 712 0 +-765 874 -679 0 +840 -541 -382 0 +-784 297 -334 0 +-444 -144 -705 0 +-372 -821 -798 0 +102 -292 577 0 +524 -49 225 0 +-699 -225 420 0 +780 -221 807 0 +832 959 -951 0 +-443 146 -998 0 +-336 312 -425 0 +-724 -2 -490 0 +488 -472 632 0 +606 997 -474 0 +989 -725 163 0 +-30 -484 365 0 +914 -465 908 0 +-896 378 -151 0 +-901 599 23 0 +193 -643 915 0 +738 168 322 0 +-599 -231 -477 0 +599 -163 985 0 +-645 829 713 0 +-751 596 80 0 +147 -171 69 0 +990 737 -961 0 +84 111 951 0 +944 -679 -910 0 +245 371 -771 0 +-337 62 -461 0 +272 -47 -326 0 +418 189 927 0 +867 810 -657 0 +835 856 -649 0 +-628 -360 658 0 +-139 -351 490 0 +177 -373 287 0 +847 -448 98 0 +-108 488 544 0 +-23 578 476 0 +178 -683 611 0 +-656 -309 285 0 +938 -913 632 0 +606 700 -649 0 +27 421 -624 0 +201 -587 822 0 +697 111 -844 0 +-276 -355 -736 0 +953 278 -606 0 +518 609 173 0 +-795 -86 35 0 +212 -146 398 0 +-811 375 -854 0 +-770 807 346 0 +435 983 -403 0 +73 300 94 0 +940 -879 134 0 +78 -307 136 0 +-507 110 -600 0 +655 -264 987 0 +265 150 -29 0 +348 724 -635 0 +238 339 343 0 +-591 91 -949 0 +186 -313 -771 0 +-571 825 -160 0 +-363 -721 -627 0 +-488 726 16 0 +482 -958 976 0 +-407 150 963 0 +835 76 884 0 +456 -354 241 0 +-46 458 561 0 +-772 426 -802 0 +-814 110 -232 0 +8 708 794 0 +-341 -581 66 0 +385 946 77 0 +-294 628 -495 0 +439 131 -593 0 +379 570 -337 0 +-967 -353 137 0 +693 -923 -958 0 +-475 -278 274 0 +856 -308 -527 0 +-204 918 -326 0 +503 328 859 0 +679 -667 -502 0 +-521 415 -495 0 +-968 299 -45 0 +-80 699 349 0 +359 -621 -602 0 +962 136 -982 0 +-868 15 758 0 +-742 -91 -717 0 +-469 733 436 0 +-308 -672 79 0 +-815 605 379 0 +-687 -600 -855 0 +658 -634 517 0 +-419 -624 -216 0 +520 620 -297 0 +502 664 -672 0 +174 -194 -347 0 +642 285 409 0 +-626 856 698 0 +-819 -994 431 0 +624 -349 -308 0 +350 -876 540 0 +126 424 -893 0 +-560 -376 -543 0 +-97 -390 -875 0 +439 -925 -413 0 +-357 -516 832 0 +599 -609 -768 0 +-698 -340 -765 0 +108 421 -964 0 +-856 -7 964 0 +65 -504 -85 0 +694 -57 -224 0 +73 -62 -288 0 +326 946 785 0 +36 853 169 0 +-574 156 538 0 +127 -374 -935 0 +375 -5 -761 0 +817 583 -403 0 +-178 -316 -825 0 +-193 -751 293 0 +526 -522 848 0 +91 -354 -53 0 +363 -168 680 0 +-721 -229 -418 0 +-927 -319 -653 0 +-410 -710 546 0 +391 644 967 0 +-636 -50 225 0 +-445 -635 631 0 +-26 701 340 0 +83 -96 868 0 +-607 -522 865 0 +-620 -519 62 0 +-199 750 -54 0 +959 -533 -492 0 +51 665 -784 0 +209 -654 137 0 +574 -262 622 0 +-41 -567 -415 0 +319 708 -563 0 +-441 -146 -569 0 +-166 354 -661 0 +606 -382 -255 0 +756 -122 109 0 +-354 -577 399 0 +-225 212 -289 0 +761 951 703 0 +-132 828 -690 0 +-389 501 -185 0 +-573 -462 78 0 +272 511 -42 0 +810 358 467 0 +-389 -286 678 0 +-44 -391 -415 0 +987 825 807 0 +73 204 -589 0 +532 937 -434 0 +637 797 410 0 +-227 -840 -889 0 +760 437 839 0 +644 -221 325 0 +-790 -670 -961 0 +-353 -999 445 0 +-625 -135 -52 0 +416 -709 -393 0 +-642 545 -875 0 +-49 -303 297 0 +201 -597 204 0 +420 -150 995 0 +-265 -519 -853 0 +-889 401 737 0 +779 679 186 0 +583 88 -299 0 +561 252 958 0 +884 -23 570 0 +210 -20 266 0 +706 263 -912 0 +-937 648 -521 0 +-601 -176 672 0 +-455 -640 138 0 +-904 -721 -259 0 +-70 -612 872 0 +-678 635 215 0 +-768 526 707 0 +-690 -494 -752 0 +360 625 572 0 +154 -66 512 0 +929 738 -286 0 +963 698 177 0 +449 -713 -212 0 +-292 -539 551 0 +-841 -688 -122 0 +452 817 -256 0 +-426 -312 -263 0 +-463 407 561 0 +-968 373 147 0 +765 -359 303 0 +420 -51 -862 0 +-815 676 237 0 +572 470 -540 0 +-927 -889 -547 0 +-111 -116 649 0 +-981 -546 463 0 +-513 -146 400 0 +708 -102 461 0 +-140 1000 789 0 +-724 615 576 0 +635 -197 -291 0 +263 658 590 0 +182 -966 -289 0 +-865 -74 -447 0 +705 327 -531 0 +954 540 -56 0 +-839 38 -857 0 +-218 -691 736 0 +-660 639 816 0 +-63 -637 519 0 +-49 -819 -336 0 +989 -803 -838 0 +-365 -438 -203 0 +24 -494 -430 0 +791 -550 493 0 +-666 -793 100 0 +-725 -139 -253 0 +-787 -9 -191 0 +-208 -322 -895 0 +997 -371 491 0 +-443 599 -220 0 +-386 -969 -731 0 +261 -648 878 0 +834 -158 730 0 +998 392 276 0 +-939 472 -427 0 +-310 -797 618 0 +881 -785 485 0 +-95 -854 382 0 +541 956 -737 0 +-826 983 -163 0 +-232 -310 306 0 +-149 -355 -706 0 +884 -86 475 0 +-126 782 -631 0 +952 -730 934 0 +-760 -1000 971 0 +-710 125 472 0 +650 948 -457 0 +830 94 -201 0 +429 772 839 0 +-401 953 -25 0 +-402 847 -905 0 +407 -420 235 0 +239 705 519 0 +339 -963 545 0 +-811 -300 -151 0 +163 -913 -107 0 +-46 248 726 0 +982 630 -612 0 +577 381 417 0 +-686 -780 -642 0 +-395 -28 -330 0 +-67 986 -427 0 +717 999 -363 0 +-174 -878 843 0 +376 829 795 0 +779 -322 129 0 +-42 70 752 0 +-33 850 358 0 +690 -527 -923 0 +-761 867 328 0 +-927 117 554 0 +159 -997 -427 0 +316 509 854 0 +373 124 -442 0 +-856 852 -708 0 +638 -720 899 0 +-434 861 -912 0 +824 -402 -795 0 +817 215 704 0 +441 13 439 0 +83 687 -714 0 +-791 -70 69 0 +412 -728 931 0 +-240 122 -961 0 +378 220 450 0 +493 612 228 0 +-189 521 912 0 +-772 536 -436 0 +-380 -578 -859 0 +905 305 -489 0 +430 48 -1000 0 +920 294 -312 0 +-670 -797 47 0 +-423 -86 -169 0 +958 -531 817 0 +-163 -743 -855 0 +-225 956 -769 0 +-852 912 282 0 +952 -276 -978 0 +173 -618 706 0 +769 -823 555 0 +375 -740 577 0 +889 -306 585 0 +-415 258 -163 0 +-121 337 -428 0 +-745 -16 259 0 +192 556 -850 0 +772 617 -606 0 +-598 -260 -180 0 +741 -108 -988 0 +-363 3 967 0 +-590 -941 587 0 +506 -391 817 0 +-102 183 -368 0 +-341 -790 -772 0 +-965 -65 902 0 +245 429 -940 0 +613 365 186 0 +-933 718 -175 0 +615 636 -111 0 +-763 -138 -578 0 +903 -851 -319 0 +196 -702 -289 0 +787 -988 455 0 +688 426 603 0 +206 46 -204 0 +-530 -986 994 0 +979 875 -79 0 +-603 557 -25 0 +62 -358 -811 0 +-231 -96 -457 0 +-72 599 779 0 +300 489 -200 0 +-804 936 433 0 +923 738 -565 0 +919 -879 -563 0 +269 -967 -747 0 +-318 669 -546 0 +-226 173 369 0 +-844 -550 433 0 +809 -514 -354 0 +-911 -932 -844 0 +814 -481 -628 0 +813 497 -61 0 +650 326 -206 0 +478 506 -382 0 +-908 -341 457 0 +-713 -411 140 0 +-384 -276 -805 0 +689 232 -860 0 +727 -337 273 0 +121 534 25 0 +384 -403 -338 0 +-128 299 -615 0 +-363 -714 612 0 +63 -17 767 0 +-522 685 32 0 +-921 -256 -427 0 +393 -748 413 0 +17 -55 -792 0 +-483 559 116 0 +634 -489 453 0 +-458 5 968 0 +-94 246 946 0 +-919 -678 -509 0 +340 -181 513 0 +-668 234 570 0 +-913 521 -393 0 +831 -534 973 0 +928 202 -522 0 +-740 -429 535 0 +-454 118 -895 0 +-91 -402 993 0 +-806 763 994 0 +573 710 -133 0 +258 -455 -9 0 +-481 897 287 0 +692 -650 378 0 +6 103 -151 0 +4 -176 -80 0 +111 -787 -248 0 +-946 782 -954 0 +917 772 165 0 +308 833 224 0 +-439 -156 791 0 +284 -613 912 0 +832 443 -240 0 +945 859 171 0 +284 -326 590 0 +-21 76 193 0 +-659 -315 942 0 +-121 -923 502 0 +-913 328 -578 0 +-149 563 561 0 +-299 -866 -673 0 +-44 528 -576 0 +-385 545 -813 0 +-249 625 694 0 +909 -328 571 0 +-240 237 -86 0 +-624 -164 -449 0 +-687 -494 -319 0 +209 -664 950 0 +997 828 972 0 +-350 -213 -488 0 +-15 -558 85 0 +-717 842 532 0 +-944 -265 -932 0 +-123 -880 211 0 +-530 -857 702 0 +373 548 -883 0 +-773 -930 992 0 +809 -788 -786 0 +996 911 454 0 +129 525 265 0 +-101 -983 -856 0 +550 -806 286 0 +417 -828 -999 0 +551 70 -194 0 +12 -896 191 0 +-935 882 -963 0 +986 -487 -733 0 +319 -1000 -384 0 +140 -920 -703 0 +-347 -10 594 0 +482 -645 906 0 +-982 951 295 0 +926 -499 846 0 +732 -215 -797 0 +923 81 752 0 +-696 791 -978 0 +-130 -636 -666 0 +-298 46 142 0 +-946 -318 -332 0 +520 753 402 0 +242 745 796 0 +-124 878 631 0 +366 312 840 0 +-76 -254 -113 0 +-680 808 565 0 +-721 223 339 0 +939 868 -149 0 +964 31 644 0 +-340 768 -291 0 +246 366 -473 0 +804 182 283 0 +348 56 941 0 +-239 71 104 0 +-365 443 -959 0 +-924 -314 986 0 +-939 -157 -148 0 +48 -344 421 0 +-133 -914 -356 0 +706 -302 200 0 +-261 599 -761 0 +-606 -111 -207 0 +232 661 113 0 +-995 -997 180 0 +179 353 450 0 +39 -343 -540 0 +949 -360 -824 0 +149 -588 -961 0 +-620 -739 -915 0 +376 -801 -152 0 +-301 -278 300 0 +778 -966 -504 0 +947 -915 -325 0 +293 -453 280 0 +-184 -94 507 0 +-920 -360 73 0 +-500 -578 589 0 +-257 -315 835 0 +-396 -501 618 0 +-217 -692 -232 0 +-305 741 522 0 +611 635 -340 0 +336 -199 -739 0 +-61 -218 243 0 +-419 -745 723 0 +-68 846 -67 0 +222 -634 -479 0 +-220 -483 -586 0 +964 -126 368 0 +-927 297 -964 0 +-843 955 708 0 +-100 -895 -734 0 +271 -62 -404 0 +346 111 65 0 +419 -192 781 0 +-952 -404 209 0 +-850 -18 -277 0 +164 -419 671 0 +958 -292 800 0 +636 289 362 0 +-122 -28 837 0 +480 396 954 0 +-888 -508 381 0 +-910 -715 559 0 +-422 104 -331 0 +-736 586 679 0 +-362 733 -34 0 +-330 953 967 0 +127 -215 296 0 +-415 675 -809 0 +-606 753 -599 0 +156 946 70 0 +-355 -73 396 0 +-32 -99 177 0 +100 862 729 0 +-648 -45 125 0 +675 -543 -80 0 +396 669 -338 0 +-370 -607 -89 0 +792 106 -925 0 +352 -396 -430 0 +-129 957 -290 0 +358 -218 54 0 +-917 -995 -668 0 +-221 -140 -347 0 +-334 -722 890 0 +-458 -893 230 0 +-209 987 -175 0 +928 -993 -96 0 +-208 976 -410 0 +576 966 252 0 +-157 460 -914 0 +306 -965 -122 0 +463 -425 -954 0 +105 557 243 0 +270 -914 -517 0 +-352 -579 979 0 +35 -679 -855 0 +-610 51 154 0 +546 -137 -612 0 +396 913 -605 0 +-489 -262 535 0 +51 -959 209 0 +-719 292 764 0 +-759 566 365 0 +-401 331 -118 0 +237 -622 -192 0 +790 447 987 0 +842 -290 857 0 +267 -970 -207 0 +830 -688 215 0 +549 -540 402 0 +-303 -427 446 0 +-987 -655 176 0 +521 -709 806 0 +-602 -805 -178 0 +-743 960 -580 0 +-524 -29 -353 0 +-187 -190 663 0 +-485 -180 5 0 +-380 -1 -871 0 +-186 -405 92 0 +242 -736 832 0 +860 915 -598 0 +64 62 -667 0 +-292 47 -409 0 +362 612 -935 0 +69 -448 882 0 +-291 784 -539 0 +979 -641 407 0 +97 342 769 0 +-366 38 174 0 +-596 -509 777 0 +130 892 261 0 +314 75 -524 0 +256 795 510 0 +380 864 771 0 +-672 -361 -477 0 +776 -219 595 0 +-861 898 234 0 +-371 -187 300 0 +635 -76 156 0 +828 518 490 0 +825 846 -614 0 +453 6 482 0 +-334 -33 -309 0 +-28 546 -757 0 +485 -274 95 0 +-363 -548 877 0 +879 -82 -689 0 +-723 100 674 0 +418 76 -706 0 +908 9 962 0 +-23 510 843 0 +-193 860 171 0 +935 -4 127 0 +350 103 131 0 +464 -459 -515 0 +51 776 734 0 +-448 -342 642 0 +614 -24 694 0 +-51 -721 -994 0 +538 -600 -611 0 +916 88 -287 0 +-488 -939 153 0 +252 677 746 0 +263 71 616 0 +934 -920 -10 0 +605 -252 925 0 +-680 496 -880 0 +648 -640 -4 0 +567 100 -831 0 +196 -712 388 0 +-488 -18 497 0 +886 -267 -637 0 +-504 519 111 0 +-96 277 697 0 +146 -48 453 0 +-305 815 330 0 +-921 -142 715 0 +-110 -43 -948 0 +612 -922 13 0 +799 659 309 0 +-315 369 54 0 +-831 338 352 0 +-515 880 100 0 +-575 -675 -470 0 +-236 -283 -76 0 +-125 -112 -130 0 +431 935 116 0 +-34 953 451 0 +629 -713 640 0 +-96 379 -681 0 +200 402 99 0 +-953 -423 -386 0 +-166 637 -113 0 +563 314 -179 0 +877 264 -993 0 +-337 48 -743 0 +-362 -390 844 0 +-542 -374 -376 0 +305 -468 -939 0 +-801 541 726 0 +-239 802 716 0 +-381 418 -676 0 +593 -656 241 0 +418 -757 125 0 +-823 -485 -303 0 +-459 -747 -345 0 +846 -209 -709 0 +-739 565 655 0 +-945 484 -56 0 +-373 -659 211 0 +-165 -624 -153 0 +395 446 -267 0 +189 -32 137 0 +368 -597 -679 0 +415 270 -503 0 +37 -903 -68 0 +30 753 -203 0 +-760 -520 777 0 +728 196 445 0 +-180 695 823 0 +152 -284 140 0 +-898 409 -862 0 +849 69 -839 0 +225 694 -575 0 +210 45 -18 0 +-691 -297 76 0 +195 -820 -485 0 +-27 -741 -956 0 +-81 -514 -825 0 +831 -72 268 0 +-258 -723 -984 0 +476 351 414 0 +101 76 722 0 +-291 -866 -567 0 +411 268 98 0 +-988 599 -418 0 +991 366 -270 0 +141 478 -744 0 +-787 497 756 0 +535 -388 219 0 +-817 -815 250 0 +-690 544 -749 0 +-937 20 -404 0 +46 693 82 0 +584 -897 -847 0 +939 653 -335 0 +-189 -903 -400 0 +844 519 -652 0 +135 -257 491 0 +52 -312 103 0 +-642 -625 -800 0 +-724 -850 -785 0 +-547 279 -986 0 +-632 -600 -108 0 +62 -735 -204 0 +82 213 -231 0 +364 308 277 0 +-325 -534 504 0 +-755 872 760 0 +910 423 -639 0 +-702 854 -156 0 +213 655 232 0 +753 729 550 0 +-282 -98 232 0 +987 -999 5 0 +784 54 481 0 +947 844 599 0 +-112 1000 295 0 +-663 -235 190 0 +-354 700 -746 0 +233 245 517 0 +596 -415 987 0 +-117 -458 877 0 +228 788 703 0 +285 -9 661 0 +-370 -407 -539 0 +407 -324 92 0 +695 -246 260 0 +-573 -165 -544 0 +35 85 -240 0 +-549 -441 496 0 +-891 631 703 0 +-389 -548 368 0 +-385 -457 807 0 +-650 -691 708 0 +-877 -153 -832 0 +-209 958 292 0 +643 -153 -640 0 +710 45 300 0 +-603 171 -901 0 +401 -984 751 0 +540 372 724 0 +601 995 231 0 +605 -861 211 0 +-61 -89 660 0 +232 411 31 0 +-207 471 632 0 +-886 7 436 0 +248 -137 464 0 +616 -754 29 0 +-684 -645 807 0 +532 -668 -194 0 +477 -541 227 0 +-793 -670 -775 0 +-323 -675 637 0 +325 508 -612 0 +499 -71 -335 0 +482 67 677 0 +-87 905 492 0 +-616 -328 -228 0 +304 964 -228 0 +-308 -359 952 0 +845 -652 794 0 +161 -92 375 0 +670 -872 926 0 +686 6 -576 0 +-732 33 -630 0 +-151 -341 400 0 +937 -890 160 0 +-92 -971 -730 0 +207 -232 107 0 +-810 -597 -213 0 +312 246 -944 0 +503 -504 -473 0 +-448 654 -243 0 +267 367 819 0 +-441 765 270 0 +-582 -189 713 0 +-763 762 419 0 +530 678 -442 0 +-482 599 -495 0 +-469 -535 555 0 +-209 856 -11 0 +-370 569 -165 0 +9 307 654 0 +175 -718 51 0 +530 736 205 0 +-635 972 -848 0 +746 -419 -427 0 +571 -84 181 0 +-248 414 -298 0 +-240 293 664 0 +-196 657 -8 0 +328 -629 623 0 +777 -690 196 0 +155 -330 117 0 +-37 891 -40 0 +-630 222 -926 0 +-389 296 -48 0 +359 666 455 0 +-20 636 300 0 +-122 374 -427 0 +-918 90 -107 0 +217 958 984 0 +973 -656 -134 0 +-753 288 715 0 +206 903 435 0 +874 118 -447 0 +-882 146 -105 0 +-760 -635 -580 0 +-712 -733 140 0 +-50 919 788 0 +87 791 -16 0 +213 506 -42 0 +395 171 -898 0 +687 -829 -91 0 +-325 819 553 0 +-449 169 643 0 +799 -734 -270 0 +324 -305 372 0 +-757 -114 17 0 +71 -969 275 0 +490 544 136 0 +16 -774 745 0 +-578 -736 487 0 +210 -812 428 0 +-255 -412 -159 0 +114 -583 208 0 +778 290 985 0 +171 -466 -797 0 +-35 -254 124 0 +643 979 524 0 +-405 -922 979 0 +177 990 -54 0 +456 -733 371 0 +-369 280 786 0 +527 986 658 0 +173 -291 -613 0 +-176 471 726 0 +234 908 -576 0 +-597 -760 -33 0 +410 340 93 0 +898 457 622 0 +-158 -671 -308 0 +-786 714 -543 0 +-400 846 -507 0 +59 -497 74 0 +912 915 819 0 +464 -798 -938 0 +589 -222 -143 0 +-830 207 731 0 +-285 -472 -748 0 +88 65 125 0 +-948 -11 366 0 +-452 161 420 0 +-395 984 818 0 +619 -508 -358 0 +-644 -49 -923 0 +-273 580 176 0 +-463 540 -724 0 +-666 -337 340 0 +118 161 -282 0 +-506 796 -387 0 +-754 610 190 0 +-434 152 -468 0 +-329 -991 -760 0 +-682 324 -438 0 +-601 -3 -127 0 +-5 -453 254 0 +516 -597 -925 0 +-239 641 -486 0 +-14 795 -113 0 +-251 -145 -810 0 +817 426 854 0 +111 997 -370 0 +-243 -147 965 0 +106 -911 9 0 +-606 -628 623 0 +-6 -259 122 0 +105 -958 658 0 +932 416 24 0 +-158 -56 322 0 +968 -651 -185 0 +-186 -671 346 0 +749 911 717 0 +-816 -912 653 0 +38 221 663 0 +-379 59 313 0 +-164 -414 -295 0 +-34 638 -633 0 +-794 490 457 0 +102 -582 -728 0 +-490 -161 -927 0 +902 677 -322 0 +221 922 746 0 +-869 350 -304 0 +184 145 734 0 +641 192 624 0 +-305 -492 -430 0 +611 786 -841 0 +-13 -949 764 0 +-500 364 -783 0 +277 -155 736 0 +890 -48 603 0 +506 -371 504 0 +456 -452 371 0 +513 -427 -584 0 +198 -820 433 0 +809 -206 -373 0 +710 -731 505 0 +-120 481 656 0 +458 -999 -600 0 +347 610 -56 0 +-361 -753 139 0 +426 -982 641 0 +-820 802 -961 0 +957 701 340 0 +-84 -643 30 0 +963 -464 919 0 +301 -643 472 0 +-354 42 -297 0 +-705 -650 694 0 +-818 714 206 0 +-289 -397 -274 0 +70 711 -516 0 +538 739 -683 0 +-328 159 658 0 +979 12 80 0 +-702 -899 173 0 +-691 746 685 0 +649 720 -628 0 +329 -231 871 0 +884 -361 69 0 +-939 -112 -245 0 +-569 174 -214 0 +-792 833 -579 0 +-521 570 -469 0 +-761 510 808 0 +-32 -901 -894 0 +756 204 293 0 +-202 290 102 0 +-697 -638 -343 0 +874 -533 934 0 +576 -99 965 0 +419 206 -92 0 +111 -777 -827 0 +-936 323 716 0 +-155 -584 291 0 +46 -164 -438 0 +559 759 722 0 +628 -821 -569 0 +-360 -876 555 0 +279 -732 -432 0 +824 -579 348 0 +-363 -283 945 0 +101 423 -56 0 +588 855 -684 0 +757 257 214 0 +-488 29 -775 0 +316 -14 -667 0 +742 -832 954 0 +-591 -694 -859 0 +-147 986 -798 0 +640 -662 437 0 +-828 -462 871 0 +-991 430 153 0 +-719 -303 6 0 +343 73 495 0 +465 592 684 0 +-966 -931 411 0 +-945 355 -104 0 +-288 -771 -328 0 +-715 365 -656 0 +774 277 799 0 +-395 -697 33 0 +782 -426 -732 0 +-673 223 738 0 +-884 -130 -674 0 +408 568 -261 0 +-103 623 207 0 +-823 639 -546 0 +-576 700 -11 0 +-625 -51 440 0 +880 -754 14 0 +708 -743 -327 0 +-4 -371 -11 0 +266 314 -844 0 +897 988 934 0 +189 450 869 0 +420 -541 112 0 +599 288 36 0 +-319 -77 749 0 +-421 -906 -222 0 +-793 259 -141 0 +394 -660 -757 0 +-474 959 -24 0 +-543 950 302 0 +-589 538 299 0 +-297 638 250 0 +735 -584 320 0 +-747 -333 -809 0 +801 -705 942 0 +-341 -622 204 0 +73 832 -237 0 +-705 -53 -995 0 +607 -992 328 0 +401 -513 33 0 +803 483 197 0 +129 -281 387 0 +113 401 -110 0 +39 612 928 0 +348 -539 -9 0 +267 -663 -524 0 +-354 376 326 0 +-180 -451 754 0 +-952 -356 521 0 +-127 -645 36 0 +-312 -965 -697 0 +-975 633 159 0 +-770 -713 983 0 +-612 -105 198 0 +329 533 -860 0 +-91 487 -422 0 +560 -586 -206 0 +-104 -317 402 0 +-582 -94 976 0 +897 575 -211 0 +-640 -813 -992 0 +819 -792 297 0 +-312 -337 -194 0 +349 -692 -933 0 +320 459 -413 0 +911 278 787 0 +704 26 -160 0 +102 -923 -831 0 +776 -930 -623 0 +241 -280 -991 0 +158 722 -270 0 +750 -936 707 0 +916 661 334 0 +-441 770 598 0 +418 -677 888 0 +-944 44 621 0 +820 278 -862 0 +-712 -824 272 0 +209 -375 -400 0 +-715 -788 -82 0 +339 706 239 0 +475 -822 428 0 +-341 -132 215 0 +174 39 604 0 +308 400 -774 0 +719 -862 579 0 +-172 -505 -856 0 +-540 -589 -672 0 +-925 816 684 0 +-52 61 -398 0 +363 -177 735 0 +-763 383 -917 0 +-401 830 -359 0 +-779 114 -643 0 +54 138 902 0 +327 -576 -717 0 +418 635 729 0 +-506 773 -711 0 +-950 213 -814 0 +-103 -7 -225 0 +220 -309 539 0 +-925 59 -757 0 +454 986 591 0 +599 -124 -971 0 +730 -721 -825 0 +128 -84 -157 0 +615 602 57 0 +-132 -658 681 0 +-209 -782 354 0 +805 -540 110 0 +596 -230 -939 0 +-513 -169 -183 0 +-184 848 619 0 +-898 -794 -215 0 +16 613 -370 0 +291 -861 990 0 +409 118 318 0 +863 -839 378 0 +-236 -642 -770 0 +-958 300 451 0 +137 -364 465 0 +-169 -728 -981 0 +-320 77 -645 0 +361 -982 674 0 +315 -29 600 0 +685 -645 563 0 +-5 751 8 0 +-287 -979 -119 0 +-532 692 -113 0 +-192 -772 435 0 +44 -801 998 0 +-254 -960 385 0 +-613 81 -822 0 +725 -470 511 0 +335 713 -770 0 +928 390 57 0 +183 -237 277 0 +367 -855 649 0 +249 302 979 0 +577 349 -841 0 +883 340 978 0 +-153 -931 133 0 +465 897 -186 0 +80 26 885 0 +639 386 -674 0 +37 -663 -421 0 +709 749 14 0 +-173 409 -610 0 +-228 -154 534 0 +242 -585 403 0 +-295 -961 978 0 +-284 -915 -588 0 +-895 478 -595 0 +-166 -905 -538 0 +194 449 -232 0 +-355 331 -188 0 +727 202 246 0 +972 -764 350 0 +417 91 -841 0 +864 315 -239 0 +-610 -189 506 0 +69 -354 -365 0 +441 61 -981 0 +75 193 -883 0 +-918 562 -351 0 +686 304 885 0 +595 -30 -446 0 +-997 -338 -487 0 +355 217 -25 0 +104 -311 420 0 +728 -407 748 0 +784 -972 -554 0 +750 791 421 0 +996 -488 -214 0 +791 -797 -480 0 +-944 -999 401 0 +-505 -46 341 0 +-453 759 -660 0 +598 157 -984 0 +-884 52 766 0 +727 767 -869 0 +-663 575 -382 0 +473 -262 -511 0 +475 -78 325 0 +-948 808 -311 0 +-957 -280 29 0 +-19 -685 150 0 +454 500 718 0 +-646 638 278 0 +-287 -705 392 0 +727 -409 677 0 +936 -134 340 0 +-385 -185 -599 0 +774 305 -223 0 +703 184 628 0 +-20 733 -158 0 +-72 -612 -154 0 +965 512 -627 0 +-820 -887 905 0 +-506 364 -368 0 +-224 -572 -74 0 +-173 -724 -946 0 +-735 -856 422 0 +231 -145 704 0 +-739 126 -503 0 +128 525 -716 0 +-491 -261 -838 0 +-25 -325 -811 0 +-160 185 295 0 +631 -61 -692 0 +633 642 -476 0 +703 -681 264 0 +-964 -595 537 0 +-504 -664 615 0 +504 336 -996 0 +434 551 589 0 +-607 604 313 0 +81 -600 -27 0 +-729 -810 977 0 +-716 603 -838 0 +645 -320 297 0 +-12 124 -152 0 +-436 -342 935 0 +-175 -195 925 0 +-786 -848 -276 0 +947 -761 328 0 +539 967 -986 0 +-809 -912 489 0 +999 549 966 0 +74 880 347 0 +596 -863 -22 0 +-249 -521 -60 0 +-977 654 887 0 +545 -813 204 0 +-317 -152 543 0 +515 965 935 0 +153 6 -86 0 +554 -773 100 0 +97 -875 94 0 +-363 852 -331 0 +778 -28 -503 0 +-344 567 -966 0 +-262 -73 997 0 +36 666 -675 0 +345 591 -426 0 +61 -869 -606 0 +605 -934 229 0 +-279 89 -103 0 +-449 -479 -652 0 +365 -570 -651 0 +229 201 479 0 +-352 238 -324 0 +-948 480 -19 0 +-120 -605 -127 0 +-316 875 923 0 +-243 -684 -543 0 +331 640 -429 0 +907 359 -272 0 +-757 446 -794 0 +-118 -684 -570 0 +413 154 -141 0 +270 -850 75 0 +-189 514 797 0 +-685 193 -4 0 +-849 -588 963 0 +489 19 -117 0 +-192 353 496 0 +148 653 206 0 +-475 -610 848 0 +558 919 489 0 +-62 -726 566 0 +-747 -844 772 0 +-342 15 -371 0 +115 -42 150 0 +-724 -171 915 0 +772 -292 470 0 +79 -848 -941 0 +-797 -592 -159 0 +418 247 763 0 +-696 -784 590 0 +-625 -696 -49 0 +134 791 -559 0 +708 -792 -775 0 +-367 -62 -264 0 +-607 -264 -195 0 +663 -500 -307 0 +924 584 458 0 +785 -117 -100 0 +-229 -687 -883 0 +910 -642 -830 0 +149 775 -175 0 +38 498 -827 0 +-621 -212 415 0 +-793 -42 -221 0 +140 886 -74 0 +-654 635 419 0 +624 585 798 0 +401 -604 -820 0 +-279 23 629 0 +-890 783 -106 0 +-842 -506 108 0 +477 864 830 0 +-109 -470 178 0 +443 -598 -328 0 +493 -687 -562 0 +-757 -85 -296 0 +-462 254 -128 0 +-307 -651 653 0 +-47 -560 436 0 +-161 540 597 0 +-39 510 -708 0 +954 594 536 0 +994 106 -969 0 +446 431 -196 0 +-342 -719 -451 0 +946 -547 -167 0 +-678 -968 -817 0 +643 941 -254 0 diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/MTTP-instances/mttp100.dat b/ProyectoFinal/CHC/malva/ProblemInstances/MTTP-instances/mttp100.dat new file mode 100644 index 0000000000000000000000000000000000000000..9d358cf6aa8c39b595c0c985ad8d402bfcaa92ca --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/MTTP-instances/mttp100.dat @@ -0,0 +1,307 @@ +100 + +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 +3 +6 +9 +12 +15 + +5 +10 +15 +20 +25 +29 +34 +39 +44 +49 +53 +58 +63 +68 +73 +77 +82 +87 +92 +97 +101 +106 +111 +116 +121 +125 +130 +135 +140 +145 +149 +154 +159 +164 +169 +173 +178 +183 +188 +193 +197 +202 +207 +212 +217 +221 +226 +231 +236 +241 +245 +250 +255 +260 +265 +269 +274 +279 +284 +289 +293 +298 +303 +308 +313 +317 +322 +327 +332 +337 +341 +346 +351 +356 +361 +365 +370 +375 +380 +385 +389 +394 +399 +404 +409 +413 +418 +423 +428 +433 +437 +442 +447 +452 +457 +461 +466 +471 +476 +481 + +60.000000 +40.000000 +7.000000 +3.000000 +50.000000 +120.000000 +80.000000 +7.000000 +3.000000 +100.000000 +180.000000 +120.000000 +7.000000 +3.000000 +150.000000 +240.000000 +160.000000 +7.000000 +3.000000 +200.000000 +300.000000 +200.000000 +7.000000 +3.000000 +250.000000 +360.000000 +240.000000 +7.000000 +3.000000 +300.000000 +420.000000 +280.000000 +7.000000 +3.000000 +350.000000 +480.000000 +320.000000 +7.000000 +3.000000 +400.000000 +540.000000 +360.000000 +7.000000 +3.000000 +450.000000 +600.000000 +400.000000 +7.000000 +3.000000 +500.000000 +660.000000 +440.000000 +7.000000 +3.000000 +550.000000 +720.000000 +480.000000 +7.000000 +3.000000 +600.000000 +780.000000 +520.000000 +7.000000 +3.000000 +650.000000 +840.000000 +560.000000 +7.000000 +3.000000 +700.000000 +900.000000 +600.000000 +7.000000 +3.000000 +750.000000 +960.000000 +640.000000 +7.000000 +3.000000 +800.000000 +1020.000000 +680.000000 +7.000000 +3.000000 +850.000000 +1080.000000 +720.000000 +7.000000 +3.000000 +900.000000 +1140.000000 +760.000000 +7.000000 +3.000000 +950.000000 +1200.000000 +800.000000 +7.000000 +3.000000 +1000.000000 + +200 +) diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/MTTP-instances/mttp20.dat b/ProyectoFinal/CHC/malva/ProblemInstances/MTTP-instances/mttp20.dat new file mode 100644 index 0000000000000000000000000000000000000000..9dde3f3f6c33f8af480223ccbb65e4d85f7a7f32 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/MTTP-instances/mttp20.dat @@ -0,0 +1,84 @@ +20 + +2 +4 +1 +7 +4 +3 +5 +2 +4 +7 +2 +9 +8 +6 +1 +4 +9 +7 +8 +2 + +3 +5 +6 +8 +10 +15 +16 +20 +25 +29 +30 +36 +49 +59 +80 +81 +89 +97 +100 +105 + +15.000000 +20.000000 +16.000000 +19.000000 +10.000000 +25.000000 +17.000000 +18.000000 +21.000000 +17.000000 +31.000000 +2.000000 +26.000000 +42.000000 +50.000000 +19.000000 +17.000000 +21.000000 +22.000000 +13.000000 + + +00001111111111111111 70.000000 + +01001110111011111111 70.000000 + +01101101101011111111 70.000000 + +01101101111011110111 70.000000 + +01101101111111101111 70.000000 + +10001111111011111110 70.000000 + +10100111011111111111 70.000000 + +10100111111011101111 70.000000 + +10100111111111111011 70.000000 +) diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/ONEMAX-instances/format.txt b/ProyectoFinal/CHC/malva/ProblemInstances/ONEMAX-instances/format.txt new file mode 100644 index 0000000000000000000000000000000000000000..179a679c6acdd98547519dd0a9817f97d090c1e2 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/ONEMAX-instances/format.txt @@ -0,0 +1 @@ +// dimension of the bitstring. diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/ONEMAX-instances/onemax10.txt b/ProyectoFinal/CHC/malva/ProblemInstances/ONEMAX-instances/onemax10.txt new file mode 100644 index 0000000000000000000000000000000000000000..f599e28b8ab0d8c9c57a486c89c4a5132dcbd3b2 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/ONEMAX-instances/onemax10.txt @@ -0,0 +1 @@ +10 diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/RAS-instances/RAS10.txt b/ProyectoFinal/CHC/malva/ProblemInstances/RAS-instances/RAS10.txt new file mode 100644 index 0000000000000000000000000000000000000000..46fc036a365b6974c890aa814bedd3051d6f7fc1 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/RAS-instances/RAS10.txt @@ -0,0 +1,2 @@ +10 +-5.12 5.12 diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/RAS-instances/RAS20.txt b/ProyectoFinal/CHC/malva/ProblemInstances/RAS-instances/RAS20.txt new file mode 100644 index 0000000000000000000000000000000000000000..1b596f14a84500a18015f4cb01cd98662fa8d5e1 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/RAS-instances/RAS20.txt @@ -0,0 +1,2 @@ +20 +-5.12 5.12 diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/RAS-instances/format.txt b/ProyectoFinal/CHC/malva/ProblemInstances/RAS-instances/format.txt new file mode 100644 index 0000000000000000000000000000000000000000..5be6f83d9fddd6a5d1d6c0d0db8e3ed83ffecae3 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/RAS-instances/format.txt @@ -0,0 +1,2 @@ +// number of variables +// range of the variables diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/RND-instances/rnd149.txt b/ProyectoFinal/CHC/malva/ProblemInstances/RND-instances/rnd149.txt new file mode 100644 index 0000000000000000000000000000000000000000..15c44e939beddcc8939956fca407b31ab7e8c3f2 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/RND-instances/rnd149.txt @@ -0,0 +1 @@ +149 diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/SPHERE-instances/SPH10.txt b/ProyectoFinal/CHC/malva/ProblemInstances/SPHERE-instances/SPH10.txt new file mode 100644 index 0000000000000000000000000000000000000000..46fc036a365b6974c890aa814bedd3051d6f7fc1 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/SPHERE-instances/SPH10.txt @@ -0,0 +1,2 @@ +10 +-5.12 5.12 diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/SPHERE-instances/SPH20.txt b/ProyectoFinal/CHC/malva/ProblemInstances/SPHERE-instances/SPH20.txt new file mode 100644 index 0000000000000000000000000000000000000000..1b596f14a84500a18015f4cb01cd98662fa8d5e1 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/SPHERE-instances/SPH20.txt @@ -0,0 +1,2 @@ +20 +-5.12 5.12 diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/SPHERE-instances/format.txt b/ProyectoFinal/CHC/malva/ProblemInstances/SPHERE-instances/format.txt new file mode 100644 index 0000000000000000000000000000000000000000..5be6f83d9fddd6a5d1d6c0d0db8e3ed83ffecae3 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/SPHERE-instances/format.txt @@ -0,0 +1,2 @@ +// number of variables +// range of the variables diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/format.txt b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/format.txt new file mode 100644 index 0000000000000000000000000000000000000000..abccebeceea08458897056d271204612c007bfdd --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/format.txt @@ -0,0 +1,3 @@ +// Number of customers, Vehicle capacity, Maximum time per route, Service time and best known cost +// Depot Coordenates +// Customer coordenates and demand diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpinfo.txt b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpinfo.txt new file mode 100644 index 0000000000000000000000000000000000000000..a63a622379b2f179d21292e5d5c159208ae49efa --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpinfo.txt @@ -0,0 +1,47 @@ +There are currently 24 data files. + +The first set of data files are the 10 test problems from +Chapter 9 of S.Eilon, C.D.T.Watson-Gandy and N.Christofides +"Distribution management: mathematical modelling and +practical analysis" Griffin, London 1971. + +Test problems 1, 2, ..., 10 from Chapter 9 are available +in files vrp1, vrp2, ..., vrp10 respectively. + +The format of these data files is apparent from the tables +of data given in the above reference. + +The second set of data files are the 14 test problems from +Chapter 11 of N.Christofides, A.Mingozzi, P.Toth and C.Sandi +(eds) "Combinatorial optimization", John Wiley, Chichester 1979. + +Test problems 1, 2, ..., 14 from Chapter 11 are available +in files vrpnc1, vrpnc2, ..., vrpnc14 respectively. + +The format of these data files is: +number of customers, vehicle capacity, maximum route time, drop time +depot x-coordinate, depot y-coordinate +for each customer in turn: x-coordinate, y-coordinate, quantity + +Both sets of files are of size 15Kb (approximately). + + + +OTHER SOURCES + +Test data for vehicle routing problems is also available +using the Web from http://www-apache.imag.fr/~paugerat/VRP/INSTANCES + +A variety of vehicle routing problems are also available from the +elib library: +telnet elib.zib.de and login as elib +WWW access available at: +ftp://ftp.zib.de/pub/Packages/mp-testdata/index.html + + + +A full listing of the problem areas covered by OR-library can +be found in the file info + +ftp access available at mscmga.ms.ic.ac.uk +WWW access available at http://mscmga.ms.ic.ac.uk/ diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc1.txt b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc1.txt new file mode 100644 index 0000000000000000000000000000000000000000..fb9bd54da242164bf97d2c33ee41ef9d7b42e825 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc1.txt @@ -0,0 +1,52 @@ + 50 160 999999 0 524.61 + 30 40 + 37 52 7 + 49 49 30 + 52 64 16 + 20 26 9 + 40 30 21 + 21 47 15 + 17 63 19 + 31 62 23 + 52 33 11 + 51 21 5 + 42 41 19 + 31 32 29 + 5 25 23 + 12 42 21 + 36 16 10 + 52 41 15 + 27 23 3 + 17 33 41 + 13 13 9 + 57 58 28 + 62 42 8 + 42 57 8 + 16 57 16 + 8 52 10 + 7 38 28 + 27 68 7 + 30 48 15 + 43 67 14 + 58 48 6 + 58 27 19 + 37 69 11 + 38 46 12 + 46 10 23 + 61 33 26 + 62 63 17 + 63 69 6 + 32 22 9 + 45 35 15 + 59 15 14 + 5 6 7 + 10 17 27 + 21 10 13 + 5 64 11 + 30 15 16 + 39 10 10 + 32 39 5 + 25 32 25 + 25 55 17 + 48 28 18 + 56 37 10 diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc10.txt b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc10.txt new file mode 100644 index 0000000000000000000000000000000000000000..bd6fc1bc1fb5e50565e8f2ceb004465900fab284 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc10.txt @@ -0,0 +1,201 @@ + 199 200 200 10 865.94 + 35 35 + 41 49 10 + 35 17 7 + 55 45 13 + 55 20 19 + 15 30 26 + 25 30 3 + 20 50 5 + 10 43 9 + 55 60 16 + 30 60 16 + 20 65 12 + 50 35 19 + 30 25 23 + 15 10 20 + 30 5 8 + 10 20 19 + 5 30 2 + 20 40 12 + 15 60 17 + 45 65 9 + 45 20 11 + 45 10 18 + 55 5 29 + 65 35 3 + 65 20 6 + 45 30 17 + 35 40 16 + 41 37 16 + 64 42 9 + 40 60 21 + 31 52 27 + 35 69 23 + 53 52 11 + 65 55 14 + 63 65 8 + 2 60 5 + 20 20 8 + 5 5 16 + 60 12 31 + 40 25 9 + 42 7 5 + 24 12 5 + 23 3 7 + 11 14 18 + 6 38 16 + 2 48 1 + 8 56 27 + 13 52 36 + 6 68 30 + 47 47 13 + 49 58 10 + 27 43 9 + 37 31 14 + 57 29 18 + 63 23 2 + 53 12 6 + 32 12 7 + 36 26 18 + 21 24 28 + 17 34 3 + 12 24 13 + 24 58 19 + 27 69 10 + 15 77 9 + 62 77 20 + 49 73 25 + 67 5 25 + 56 39 36 + 37 47 6 + 37 56 5 + 57 68 15 + 47 16 25 + 44 17 9 + 46 13 8 + 49 11 18 + 49 42 13 + 53 43 14 + 61 52 3 + 57 48 23 + 56 37 6 + 55 54 26 + 15 47 16 + 14 37 11 + 11 31 7 + 16 22 41 + 4 18 35 + 28 18 26 + 26 52 9 + 26 35 15 + 31 67 3 + 15 19 1 + 22 22 2 + 18 24 22 + 26 27 27 + 25 24 20 + 22 27 11 + 25 21 12 + 19 21 10 + 20 26 9 + 18 18 17 + 37 52 7 + 49 49 30 + 52 64 16 + 20 26 9 + 40 30 21 + 21 47 15 + 17 63 19 + 31 62 23 + 52 33 11 + 51 21 5 + 42 41 19 + 31 32 29 + 5 25 23 + 12 42 21 + 36 16 10 + 52 41 15 + 27 23 3 + 17 33 41 + 13 13 9 + 57 58 28 + 62 42 8 + 42 57 8 + 16 57 16 + 8 52 10 + 7 38 28 + 27 68 7 + 30 48 15 + 43 67 14 + 58 48 6 + 58 27 19 + 37 69 11 + 38 46 12 + 46 10 23 + 61 33 26 + 62 63 17 + 63 69 6 + 32 22 9 + 45 35 15 + 59 15 14 + 5 6 7 + 10 17 27 + 21 10 13 + 5 64 11 + 30 15 16 + 39 10 10 + 32 39 5 + 25 32 25 + 25 55 17 + 48 28 18 + 56 37 10 + 22 22 18 + 36 26 26 + 21 45 11 + 45 35 30 + 55 20 21 + 33 34 19 + 50 50 15 + 55 45 16 + 26 59 29 + 40 66 26 + 55 65 37 + 35 51 16 + 62 35 12 + 62 57 31 + 62 24 8 + 21 36 19 + 33 44 20 + 9 56 13 + 62 48 15 + 66 14 22 + 44 13 28 + 26 13 12 + 11 28 6 + 7 43 27 + 17 64 14 + 41 46 18 + 55 34 17 + 35 16 29 + 52 26 13 + 43 26 22 + 31 76 25 + 22 53 28 + 26 29 27 + 50 40 19 + 55 50 10 + 54 10 12 + 60 15 14 + 47 66 24 + 30 60 16 + 30 50 33 + 12 17 15 + 15 14 11 + 16 19 18 + 21 48 17 + 50 30 21 + 51 42 27 + 50 15 19 + 48 21 20 + 12 38 5 diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc11.txt b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc11.txt new file mode 100644 index 0000000000000000000000000000000000000000..adea50e594c6d2f24dab30d6a34b55247880a65b --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc11.txt @@ -0,0 +1,122 @@ + 120 200 999999 0 866.37 + 10 45 + 25 1 25 + 25 3 7 + 31 5 13 + 32 5 6 + 31 7 14 + 32 9 5 + 34 9 11 + 46 9 19 + 35 7 5 + 34 6 15 + 35 5 15 + 47 6 17 + 40 5 13 + 39 3 12 + 36 3 18 + 73 6 13 + 73 8 18 + 24 36 12 + 76 6 17 + 76 10 4 + 76 13 7 + 78 3 12 + 78 9 13 + 79 3 8 + 79 5 16 + 79 11 15 + 82 3 6 + 82 7 5 + 90 15 9 + 84 3 11 + 84 5 10 + 84 9 3 + 85 1 7 + 87 5 2 + 85 8 4 + 87 7 4 + 86 41 18 + 86 44 14 + 86 46 12 + 85 55 17 + 89 43 20 + 89 46 14 + 89 52 16 + 92 42 10 + 92 52 9 + 94 42 11 + 94 44 7 + 94 48 13 + 96 42 5 + 99 46 4 + 99 50 21 + 83 80 13 + 83 83 11 + 85 81 12 + 85 85 14 + 85 89 10 + 87 80 8 + 87 86 16 + 90 77 19 + 90 88 5 + 93 82 17 + 93 84 7 + 93 89 16 + 94 86 14 + 95 80 17 + 99 89 13 + 37 83 17 + 50 80 13 + 35 85 14 + 35 87 16 + 44 86 7 + 46 89 13 + 46 83 9 + 46 87 11 + 46 89 35 + 48 83 5 + 50 85 28 + 50 88 7 + 54 86 3 + 54 90 10 + 10 35 7 + 10 40 12 + 18 30 11 + 17 35 10 + 16 38 8 + 14 40 11 + 15 42 21 + 11 42 4 + 18 40 15 + 21 39 16 + 20 40 4 + 18 41 16 + 20 44 7 + 22 44 10 + 16 45 9 + 20 45 11 + 25 45 17 + 30 55 12 + 20 50 11 + 22 51 7 + 18 49 9 + 16 48 11 + 20 55 12 + 18 53 7 + 14 50 8 + 15 51 6 + 16 54 5 + 28 33 12 + 33 38 13 + 30 50 7 + 13 40 7 + 15 36 8 + 18 31 11 + 25 37 13 + 30 46 11 + 25 52 10 + 16 33 7 + 25 35 4 + 5 40 20 + 5 50 13 diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc12.txt b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc12.txt new file mode 100644 index 0000000000000000000000000000000000000000..939f5dd0516f7cd0f9ccc4e7f478be5f16796fd1 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc12.txt @@ -0,0 +1,102 @@ + 100 200 999999 0 1541.14 + 40 50 + 45 68 10 + 45 70 30 + 42 66 10 + 42 68 10 + 42 65 10 + 40 69 20 + 40 66 20 + 38 68 20 + 38 70 10 + 35 66 10 + 35 69 10 + 25 85 20 + 22 75 30 + 22 85 10 + 20 80 40 + 20 85 40 + 18 75 20 + 15 75 20 + 15 80 10 + 30 50 10 + 30 52 20 + 28 52 20 + 28 55 10 + 25 50 10 + 25 52 40 + 25 55 10 + 23 52 10 + 23 55 20 + 20 50 10 + 20 55 10 + 10 35 20 + 10 40 30 + 8 40 40 + 8 45 20 + 5 35 10 + 5 45 10 + 2 40 20 + 0 40 30 + 0 45 20 + 35 30 10 + 35 32 10 + 33 32 20 + 33 35 10 + 32 30 10 + 30 30 10 + 30 32 30 + 30 35 10 + 28 30 10 + 28 35 10 + 26 32 10 + 25 30 10 + 25 35 10 + 44 5 20 + 42 10 40 + 42 15 10 + 40 5 30 + 40 15 40 + 38 5 30 + 38 15 10 + 35 5 20 + 50 30 10 + 50 35 20 + 50 40 50 + 48 30 10 + 48 40 10 + 47 35 10 + 47 40 10 + 45 30 10 + 45 35 10 + 95 30 30 + 95 35 20 + 53 30 10 + 92 30 10 + 53 35 50 + 45 65 20 + 90 35 10 + 88 30 10 + 88 35 20 + 87 30 10 + 85 25 10 + 85 35 30 + 75 55 20 + 72 55 10 + 70 58 20 + 68 60 30 + 66 55 10 + 65 55 20 + 65 60 30 + 63 58 10 + 60 55 10 + 60 60 10 + 67 85 20 + 65 85 40 + 65 82 10 + 62 80 30 + 60 80 10 + 60 85 30 + 58 75 20 + 55 80 10 + 55 85 20 diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc13.txt b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc13.txt new file mode 100644 index 0000000000000000000000000000000000000000..975ff61d3de5f392401e22590f3b3cb0c632992f --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc13.txt @@ -0,0 +1,122 @@ + 120 200 720 50 1162.55 + 10 45 + 25 1 25 + 25 3 7 + 31 5 13 + 32 5 6 + 31 7 14 + 32 9 5 + 34 9 11 + 46 9 19 + 35 7 5 + 34 6 15 + 35 5 15 + 47 6 17 + 40 5 13 + 39 3 12 + 36 3 18 + 73 6 13 + 73 8 18 + 24 36 12 + 76 6 17 + 76 10 4 + 76 13 7 + 78 3 12 + 78 9 13 + 79 3 8 + 79 5 16 + 79 11 15 + 82 3 6 + 82 7 5 + 90 15 9 + 84 3 11 + 84 5 10 + 84 9 3 + 85 1 7 + 87 5 2 + 85 8 4 + 87 7 4 + 86 41 18 + 86 44 14 + 86 46 12 + 85 55 17 + 89 43 20 + 89 46 14 + 89 52 16 + 92 42 10 + 92 52 9 + 94 42 11 + 94 44 7 + 94 48 13 + 96 42 5 + 99 46 4 + 99 50 21 + 83 80 13 + 83 83 11 + 85 81 12 + 85 85 14 + 85 89 10 + 87 80 8 + 87 86 16 + 90 77 19 + 90 88 5 + 93 82 17 + 93 84 7 + 93 89 16 + 94 86 14 + 95 80 17 + 99 89 13 + 37 83 17 + 50 80 13 + 35 85 14 + 35 87 16 + 44 86 7 + 46 89 13 + 46 83 9 + 46 87 11 + 46 89 35 + 48 83 5 + 50 85 28 + 50 88 7 + 54 86 3 + 54 90 10 + 10 35 7 + 10 40 12 + 18 30 11 + 17 35 10 + 16 38 8 + 14 40 11 + 15 42 21 + 11 42 4 + 18 40 15 + 21 39 16 + 20 40 4 + 18 41 16 + 20 44 7 + 22 44 10 + 16 45 9 + 20 45 11 + 25 45 17 + 30 55 12 + 20 50 11 + 22 51 7 + 18 49 9 + 16 48 11 + 20 55 12 + 18 53 7 + 14 50 8 + 15 51 6 + 16 54 5 + 28 33 12 + 33 38 13 + 30 50 7 + 13 40 7 + 15 36 8 + 18 31 11 + 25 37 13 + 30 46 11 + 25 52 10 + 16 33 7 + 25 35 4 + 5 40 20 + 5 50 13 diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc14.txt b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc14.txt new file mode 100644 index 0000000000000000000000000000000000000000..02946d9e3b9e76b09e6a5fd36cbe27ba3e7d9045 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc14.txt @@ -0,0 +1,102 @@ + 100 200 1040 90 1395.85 + 40 50 + 45 68 10 + 45 70 30 + 42 66 10 + 42 68 10 + 42 65 10 + 40 69 20 + 40 66 20 + 38 68 20 + 38 70 10 + 35 66 10 + 35 69 10 + 25 85 20 + 22 75 30 + 22 85 10 + 20 80 40 + 20 85 40 + 18 75 20 + 15 75 20 + 15 80 10 + 30 50 10 + 30 52 20 + 28 52 20 + 28 55 10 + 25 50 10 + 25 52 40 + 25 55 10 + 23 52 10 + 23 55 20 + 20 50 10 + 20 55 10 + 10 35 20 + 10 40 30 + 8 40 40 + 8 45 20 + 5 35 10 + 5 45 10 + 2 40 20 + 0 40 30 + 0 45 20 + 35 30 10 + 35 32 10 + 33 32 20 + 33 35 10 + 32 30 10 + 30 30 10 + 30 32 30 + 30 35 10 + 28 30 10 + 28 35 10 + 26 32 10 + 25 30 10 + 25 35 10 + 44 5 20 + 42 10 40 + 42 15 10 + 40 5 30 + 40 15 40 + 38 5 30 + 38 15 10 + 35 5 20 + 50 30 10 + 50 35 20 + 50 40 50 + 48 30 10 + 48 40 10 + 47 35 10 + 47 40 10 + 45 30 10 + 45 35 10 + 95 30 30 + 95 35 20 + 53 30 10 + 92 30 10 + 53 35 50 + 45 65 20 + 90 35 10 + 88 30 10 + 88 35 20 + 87 30 10 + 85 25 10 + 85 35 30 + 75 55 20 + 72 55 10 + 70 58 20 + 68 60 30 + 66 55 10 + 65 55 20 + 65 60 30 + 63 58 10 + 60 55 10 + 60 60 10 + 67 85 20 + 65 85 40 + 65 82 10 + 62 80 30 + 60 80 10 + 60 85 30 + 58 75 20 + 55 80 10 + 55 85 20 diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc2.txt b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc2.txt new file mode 100644 index 0000000000000000000000000000000000000000..214012a909ccd3117a058d0bd58aeab4dceb7011 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc2.txt @@ -0,0 +1,77 @@ + 75 140 999999 0 835.26 + 40 40 + 22 22 18 + 36 26 26 + 21 45 11 + 45 35 30 + 55 20 21 + 33 34 19 + 50 50 15 + 55 45 16 + 26 59 29 + 40 66 26 + 55 65 37 + 35 51 16 + 62 35 12 + 62 57 31 + 62 24 8 + 21 36 19 + 33 44 20 + 9 56 13 + 62 48 15 + 66 14 22 + 44 13 28 + 26 13 12 + 11 28 6 + 7 43 27 + 17 64 14 + 41 46 18 + 55 34 17 + 35 16 29 + 52 26 13 + 43 26 22 + 31 76 25 + 22 53 28 + 26 29 27 + 50 40 19 + 55 50 10 + 54 10 12 + 60 15 14 + 47 66 24 + 30 60 16 + 30 50 33 + 12 17 15 + 15 14 11 + 16 19 18 + 21 48 17 + 50 30 21 + 51 42 27 + 50 15 19 + 48 21 20 + 12 38 5 + 15 56 22 + 29 39 12 + 54 38 19 + 55 57 22 + 67 41 16 + 10 70 7 + 6 25 26 + 65 27 14 + 40 60 21 + 70 64 24 + 64 4 13 + 36 6 15 + 30 20 18 + 20 30 11 + 15 5 28 + 50 70 9 + 57 72 37 + 45 42 30 + 38 33 10 + 50 4 8 + 66 8 11 + 59 5 3 + 35 60 1 + 27 24 6 + 40 20 10 + 40 37 20 diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc3.txt b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc3.txt new file mode 100644 index 0000000000000000000000000000000000000000..8bfcc47fe499af55bd1213cc23848420d71e7309 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc3.txt @@ -0,0 +1,102 @@ + 100 200 999999 0 826.14 + 35 35 + 41 49 10 + 35 17 7 + 55 45 13 + 55 20 19 + 15 30 26 + 25 30 3 + 20 50 5 + 10 43 9 + 55 60 16 + 30 60 16 + 20 65 12 + 50 35 19 + 30 25 23 + 15 10 20 + 30 5 8 + 10 20 19 + 5 30 2 + 20 40 12 + 15 60 17 + 45 65 9 + 45 20 11 + 45 10 18 + 55 5 29 + 65 35 3 + 65 20 6 + 45 30 17 + 35 40 16 + 41 37 16 + 64 42 9 + 40 60 21 + 31 52 27 + 35 69 23 + 53 52 11 + 65 55 14 + 63 65 8 + 2 60 5 + 20 20 8 + 5 5 16 + 60 12 31 + 40 25 9 + 42 7 5 + 24 12 5 + 23 3 7 + 11 14 18 + 6 38 16 + 2 48 1 + 8 56 27 + 13 52 36 + 6 68 30 + 47 47 13 + 49 58 10 + 27 43 9 + 37 31 14 + 57 29 18 + 63 23 2 + 53 12 6 + 32 12 7 + 36 26 18 + 21 24 28 + 17 34 3 + 12 24 13 + 24 58 19 + 27 69 10 + 15 77 9 + 62 77 20 + 49 73 25 + 67 5 25 + 56 39 36 + 37 47 6 + 37 56 5 + 57 68 15 + 47 16 25 + 44 17 9 + 46 13 8 + 49 11 18 + 49 42 13 + 53 43 14 + 61 52 3 + 57 48 23 + 56 37 6 + 55 54 26 + 15 47 16 + 14 37 11 + 11 31 7 + 16 22 41 + 4 18 35 + 28 18 26 + 26 52 9 + 26 35 15 + 31 67 3 + 15 19 1 + 22 22 2 + 18 24 22 + 26 27 27 + 25 24 20 + 22 27 11 + 25 21 12 + 19 21 10 + 20 26 9 + 18 18 17 diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc4.txt b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc4.txt new file mode 100644 index 0000000000000000000000000000000000000000..3faf64a16902da76036b6afb2ebe4ab1185ecb0f --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc4.txt @@ -0,0 +1,152 @@ + 150 200 999999 0 819.56 + 35 35 + 41 49 10 + 35 17 7 + 55 45 13 + 55 20 19 + 15 30 26 + 25 30 3 + 20 50 5 + 10 43 9 + 55 60 16 + 30 60 16 + 20 65 12 + 50 35 19 + 30 25 23 + 15 10 20 + 30 5 8 + 10 20 19 + 5 30 2 + 20 40 12 + 15 60 17 + 45 65 9 + 45 20 11 + 45 10 18 + 55 5 29 + 65 35 3 + 65 20 6 + 45 30 17 + 35 40 16 + 41 37 16 + 64 42 9 + 40 60 21 + 31 52 27 + 35 69 23 + 53 52 11 + 65 55 14 + 63 65 8 + 2 60 5 + 20 20 8 + 5 5 16 + 60 12 31 + 40 25 9 + 42 7 5 + 24 12 5 + 23 3 7 + 11 14 18 + 6 38 16 + 2 48 1 + 8 56 27 + 13 52 36 + 6 68 30 + 47 47 13 + 49 58 10 + 27 43 9 + 37 31 14 + 57 29 18 + 63 23 2 + 53 12 6 + 32 12 7 + 36 26 18 + 21 24 28 + 17 34 3 + 12 24 13 + 24 58 19 + 27 69 10 + 15 77 9 + 62 77 20 + 49 73 25 + 67 5 25 + 56 39 36 + 37 47 6 + 37 56 5 + 57 68 15 + 47 16 25 + 44 17 9 + 46 13 8 + 49 11 18 + 49 42 13 + 53 43 14 + 61 52 3 + 57 48 23 + 56 37 6 + 55 54 26 + 15 47 16 + 14 37 11 + 11 31 7 + 16 22 41 + 4 18 35 + 28 18 26 + 26 52 9 + 26 35 15 + 31 67 3 + 15 19 1 + 22 22 2 + 18 24 22 + 26 27 27 + 25 24 20 + 22 27 11 + 25 21 12 + 19 21 10 + 20 26 9 + 18 18 17 + 37 52 7 + 49 49 30 + 52 64 16 + 20 26 9 + 40 30 21 + 21 47 15 + 17 63 19 + 31 62 23 + 52 33 11 + 51 21 5 + 42 41 19 + 31 32 29 + 5 25 23 + 12 42 21 + 36 16 10 + 52 41 15 + 27 23 3 + 17 33 41 + 13 13 9 + 57 58 28 + 62 42 8 + 42 57 8 + 16 57 16 + 8 52 10 + 7 38 28 + 27 68 7 + 30 48 15 + 43 67 14 + 58 48 6 + 58 27 19 + 37 69 11 + 38 46 12 + 46 10 23 + 61 33 26 + 62 63 17 + 63 69 6 + 32 22 9 + 45 35 15 + 59 15 14 + 5 6 7 + 10 17 27 + 21 10 13 + 5 64 11 + 30 15 16 + 39 10 10 + 32 39 5 + 25 32 25 + 25 55 17 + 48 28 18 + 56 37 10 diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc5.txt b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc5.txt new file mode 100644 index 0000000000000000000000000000000000000000..3cacfb74613d58105d9417abfab50591b2461a5e --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc5.txt @@ -0,0 +1,201 @@ + 199 200 999999 0 1042.11 + 35 35 + 41 49 10 + 35 17 7 + 55 45 13 + 55 20 19 + 15 30 26 + 25 30 3 + 20 50 5 + 10 43 9 + 55 60 16 + 30 60 16 + 20 65 12 + 50 35 19 + 30 25 23 + 15 10 20 + 30 5 8 + 10 20 19 + 5 30 2 + 20 40 12 + 15 60 17 + 45 65 9 + 45 20 11 + 45 10 18 + 55 5 29 + 65 35 3 + 65 20 6 + 45 30 17 + 35 40 16 + 41 37 16 + 64 42 9 + 40 60 21 + 31 52 27 + 35 69 23 + 53 52 11 + 65 55 14 + 63 65 8 + 2 60 5 + 20 20 8 + 5 5 16 + 60 12 31 + 40 25 9 + 42 7 5 + 24 12 5 + 23 3 7 + 11 14 18 + 6 38 16 + 2 48 1 + 8 56 27 + 13 52 36 + 6 68 30 + 47 47 13 + 49 58 10 + 27 43 9 + 37 31 14 + 57 29 18 + 63 23 2 + 53 12 6 + 32 12 7 + 36 26 18 + 21 24 28 + 17 34 3 + 12 24 13 + 24 58 19 + 27 69 10 + 15 77 9 + 62 77 20 + 49 73 25 + 67 5 25 + 56 39 36 + 37 47 6 + 37 56 5 + 57 68 15 + 47 16 25 + 44 17 9 + 46 13 8 + 49 11 18 + 49 42 13 + 53 43 14 + 61 52 3 + 57 48 23 + 56 37 6 + 55 54 26 + 15 47 16 + 14 37 11 + 11 31 7 + 16 22 41 + 4 18 35 + 28 18 26 + 26 52 9 + 26 35 15 + 31 67 3 + 15 19 1 + 22 22 2 + 18 24 22 + 26 27 27 + 25 24 20 + 22 27 11 + 25 21 12 + 19 21 10 + 20 26 9 + 18 18 17 + 37 52 7 + 49 49 30 + 52 64 16 + 20 26 9 + 40 30 21 + 21 47 15 + 17 63 19 + 31 62 23 + 52 33 11 + 51 21 5 + 42 41 19 + 31 32 29 + 5 25 23 + 12 42 21 + 36 16 10 + 52 41 15 + 27 23 3 + 17 33 41 + 13 13 9 + 57 58 28 + 62 42 8 + 42 57 8 + 16 57 16 + 8 52 10 + 7 38 28 + 27 68 7 + 30 48 15 + 43 67 14 + 58 48 6 + 58 27 19 + 37 69 11 + 38 46 12 + 46 10 23 + 61 33 26 + 62 63 17 + 63 69 6 + 32 22 9 + 45 35 15 + 59 15 14 + 5 6 7 + 10 17 27 + 21 10 13 + 5 64 11 + 30 15 16 + 39 10 10 + 32 39 5 + 25 32 25 + 25 55 17 + 48 28 18 + 56 37 10 + 22 22 18 + 36 26 26 + 21 45 11 + 45 35 30 + 55 20 21 + 33 34 19 + 50 50 15 + 55 45 16 + 26 59 29 + 40 66 26 + 55 65 37 + 35 51 16 + 62 35 12 + 62 57 31 + 62 24 8 + 21 36 19 + 33 44 20 + 9 56 13 + 62 48 15 + 66 14 22 + 44 13 28 + 26 13 12 + 11 28 6 + 7 43 27 + 17 64 14 + 41 46 18 + 55 34 17 + 35 16 29 + 52 26 13 + 43 26 22 + 31 76 25 + 22 53 28 + 26 29 27 + 50 40 19 + 55 50 10 + 54 10 12 + 60 15 14 + 47 66 24 + 30 60 16 + 30 50 33 + 12 17 15 + 15 14 11 + 16 19 18 + 21 48 17 + 50 30 21 + 51 42 27 + 50 15 19 + 48 21 20 + 12 38 5 diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc6.txt b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc6.txt new file mode 100644 index 0000000000000000000000000000000000000000..449fd5c6edd716fedf83c6067ae3bdc302948e8b --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc6.txt @@ -0,0 +1,52 @@ + 50 160 200 10 1028.42 + 30 40 + 37 52 7 + 49 49 30 + 52 64 16 + 20 26 9 + 40 30 21 + 21 47 15 + 17 63 19 + 31 62 23 + 52 33 11 + 51 21 5 + 42 41 19 + 31 32 29 + 5 25 23 + 12 42 21 + 36 16 10 + 52 41 15 + 27 23 3 + 17 33 41 + 13 13 9 + 57 58 28 + 62 42 8 + 42 57 8 + 16 57 16 + 8 52 10 + 7 38 28 + 27 68 7 + 30 48 15 + 43 67 14 + 58 48 6 + 58 27 19 + 37 69 11 + 38 46 12 + 46 10 23 + 61 33 26 + 62 63 17 + 63 69 6 + 32 22 9 + 45 35 15 + 59 15 14 + 5 6 7 + 10 17 27 + 21 10 13 + 5 64 11 + 30 15 16 + 39 10 10 + 32 39 5 + 25 32 25 + 25 55 17 + 48 28 18 + 56 37 10 diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc7.txt b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc7.txt new file mode 100644 index 0000000000000000000000000000000000000000..1b8aa97fd732fca2b996c584f26864092e1f621e --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc7.txt @@ -0,0 +1,77 @@ + 75 140 160 10 1291.45 + 40 40 + 22 22 18 + 36 26 26 + 21 45 11 + 45 35 30 + 55 20 21 + 33 34 19 + 50 50 15 + 55 45 16 + 26 59 29 + 40 66 26 + 55 65 37 + 35 51 16 + 62 35 12 + 62 57 31 + 62 24 8 + 21 36 19 + 33 44 20 + 9 56 13 + 62 48 15 + 66 14 22 + 44 13 28 + 26 13 12 + 11 28 6 + 7 43 27 + 17 64 14 + 41 46 18 + 55 34 17 + 35 16 29 + 52 26 13 + 43 26 22 + 31 76 25 + 22 53 28 + 26 29 27 + 50 40 19 + 55 50 10 + 54 10 12 + 60 15 14 + 47 66 24 + 30 60 16 + 30 50 33 + 12 17 15 + 15 14 11 + 16 19 18 + 21 48 17 + 50 30 21 + 51 42 27 + 50 15 19 + 48 21 20 + 12 38 5 + 15 56 22 + 29 39 12 + 54 38 19 + 55 57 22 + 67 41 16 + 10 70 7 + 6 25 26 + 65 27 14 + 40 60 21 + 70 64 24 + 64 4 13 + 36 6 15 + 30 20 18 + 20 30 11 + 15 5 28 + 50 70 9 + 57 72 37 + 45 42 30 + 38 33 10 + 50 4 8 + 66 8 11 + 59 5 3 + 35 60 1 + 27 24 6 + 40 20 10 + 40 37 20 diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc8.txt b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc8.txt new file mode 100644 index 0000000000000000000000000000000000000000..03838873fea6c997640e3a9bf827dbc1191493e7 --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc8.txt @@ -0,0 +1,102 @@ + 100 200 230 10 555.43 + 35 35 + 41 49 10 + 35 17 7 + 55 45 13 + 55 20 19 + 15 30 26 + 25 30 3 + 20 50 5 + 10 43 9 + 55 60 16 + 30 60 16 + 20 65 12 + 50 35 19 + 30 25 23 + 15 10 20 + 30 5 8 + 10 20 19 + 5 30 2 + 20 40 12 + 15 60 17 + 45 65 9 + 45 20 11 + 45 10 18 + 55 5 29 + 65 35 3 + 65 20 6 + 45 30 17 + 35 40 16 + 41 37 16 + 64 42 9 + 40 60 21 + 31 52 27 + 35 69 23 + 53 52 11 + 65 55 14 + 63 65 8 + 2 60 5 + 20 20 8 + 5 5 16 + 60 12 31 + 40 25 9 + 42 7 5 + 24 12 5 + 23 3 7 + 11 14 18 + 6 38 16 + 2 48 1 + 8 56 27 + 13 52 36 + 6 68 30 + 47 47 13 + 49 58 10 + 27 43 9 + 37 31 14 + 57 29 18 + 63 23 2 + 53 12 6 + 32 12 7 + 36 26 18 + 21 24 28 + 17 34 3 + 12 24 13 + 24 58 19 + 27 69 10 + 15 77 9 + 62 77 20 + 49 73 25 + 67 5 25 + 56 39 36 + 37 47 6 + 37 56 5 + 57 68 15 + 47 16 25 + 44 17 9 + 46 13 8 + 49 11 18 + 49 42 13 + 53 43 14 + 61 52 3 + 57 48 23 + 56 37 6 + 55 54 26 + 15 47 16 + 14 37 11 + 11 31 7 + 16 22 41 + 4 18 35 + 28 18 26 + 26 52 9 + 26 35 15 + 31 67 3 + 15 19 1 + 22 22 2 + 18 24 22 + 26 27 27 + 25 24 20 + 22 27 11 + 25 21 12 + 19 21 10 + 20 26 9 + 18 18 17 diff --git a/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc9.txt b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc9.txt new file mode 100644 index 0000000000000000000000000000000000000000..1910e87325a89771f512980c78148177ac49429a --- /dev/null +++ b/ProyectoFinal/CHC/malva/ProblemInstances/VRP-instances/vrpnc9.txt @@ -0,0 +1,152 @@ + 150 200 200 10 909.68 + 35 35 + 41 49 10 + 35 17 7 + 55 45 13 + 55 20 19 + 15 30 26 + 25 30 3 + 20 50 5 + 10 43 9 + 55 60 16 + 30 60 16 + 20 65 12 + 50 35 19 + 30 25 23 + 15 10 20 + 30 5 8 + 10 20 19 + 5 30 2 + 20 40 12 + 15 60 17 + 45 65 9 + 45 20 11 + 45 10 18 + 55 5 29 + 65 35 3 + 65 20 6 + 45 30 17 + 35 40 16 + 41 37 16 + 64 42 9 + 40 60 21 + 31 52 27 + 35 69 23 + 53 52 11 + 65 55 14 + 63 65 8 + 2 60 5 + 20 20 8 + 5 5 16 + 60 12 31 + 40 25 9 + 42 7 5 + 24 12 5 + 23 3 7 + 11 14 18 + 6 38 16 + 2 48 1 + 8 56 27 + 13 52 36 + 6 68 30 + 47 47 13 + 49 58 10 + 27 43 9 + 37 31 14 + 57 29 18 + 63 23 2 + 53 12 6 + 32 12 7 + 36 26 18 + 21 24 28 + 17 34 3 + 12 24 13 + 24 58 19 + 27 69 10 + 15 77 9 + 62 77 20 + 49 73 25 + 67 5 25 + 56 39 36 + 37 47 6 + 37 56 5 + 57 68 15 + 47 16 25 + 44 17 9 + 46 13 8 + 49 11 18 + 49 42 13 + 53 43 14 + 61 52 3 + 57 48 23 + 56 37 6 + 55 54 26 + 15 47 16 + 14 37 11 + 11 31 7 + 16 22 41 + 4 18 35 + 28 18 26 + 26 52 9 + 26 35 15 + 31 67 3 + 15 19 1 + 22 22 2 + 18 24 22 + 26 27 27 + 25 24 20 + 22 27 11 + 25 21 12 + 19 21 10 + 20 26 9 + 18 18 17 + 37 52 7 + 49 49 30 + 52 64 16 + 20 26 9 + 40 30 21 + 21 47 15 + 17 63 19 + 31 62 23 + 52 33 11 + 51 21 5 + 42 41 19 + 31 32 29 + 5 25 23 + 12 42 21 + 36 16 10 + 52 41 15 + 27 23 3 + 17 33 41 + 13 13 9 + 57 58 28 + 62 42 8 + 42 57 8 + 16 57 16 + 8 52 10 + 7 38 28 + 27 68 7 + 30 48 15 + 43 67 14 + 58 48 6 + 58 27 19 + 37 69 11 + 38 46 12 + 46 10 23 + 61 33 26 + 62 63 17 + 63 69 6 + 32 22 9 + 45 35 15 + 59 15 14 + 5 6 7 + 10 17 27 + 21 10 13 + 5 64 11 + 30 15 16 + 39 10 10 + 32 39 5 + 25 32 25 + 25 55 17 + 48 28 18 + 56 37 10 diff --git a/ProyectoFinal/CHC/malva/README.md b/ProyectoFinal/CHC/malva/README.md new file mode 100644 index 0000000000000000000000000000000000000000..53d6d5d29a50f948ac47b3338c2857d4be082fe6 --- /dev/null +++ b/ProyectoFinal/CHC/malva/README.md @@ -0,0 +1,278 @@ +## What is Malva? + +Malva is a fork of the MALLBA project. MALLBA is an effort to develop, in an integrated way, a +library of skeletons for combinatorial optimization (including exact, heuristic and hybrid methods) +that can deal with parallelism in a user-friendly and, at the same time, efficient manner. +Its three target environments are sequential computers, LANs of workstations and WANs. The main features of MALLBA are: + +* Integration of all the skeletons under the same design principles. +* Facility to switch from sequential to parallel optimization engines. +By providing sequential implementations users obtain parallel implementations. +* Cooperation between engines makes possible to provide more powerful hybrid engines. +* Ready to use on commodity machines. +* Flexible and extensible software architecture. New skeletons can easily be added, alternative communication layers +can be used, etc. + +## How to install and compile Malva + +First of all, you have to install MPICH library. Get the instructions here: http://www.mpich.org/. In OSX, you can just +type: + + brew install mpich --disable-fortran + +Disabling Fortran is needed since we are working with C++ instead of Fortran. + +After that, you have to clone this repository using `git clone https://github.com/gabrielfagundez/malva`, and configure Malva modifying the `environment` file. + +Then, execute the following command: + + make all + +Your Malva directory should contain the following content after the make: + +``` + -rw-r--r-- 1 user users 378 sep 24 09:39 Makefile + drwxr-xr-x 4 user users 4096 sep 24 09:48 ProblemInstances + -rw-r--r-- 1 user users 345 sep 24 16:29 environment + drwxr-xr-x 2 user users 4096 sep 24 16:43 inc + drwxr-xr-x 2 user users 4096 sep 24 17:49 lib + drwxr-xr-x 5 user users 4096 sep 24 09:41 rep + drwxr-xr-x 2 user users 4096 sep 24 17:49 src +``` + +## Testing the installation + +Go to `MALLBA_DIR/rep_new/CHC` or `MALLBA_DIR/rep_new/GA` and execute `make SEQ` or `make LAN`. If you have in your console +the result of the execution, everything looks great! + +## Important notes + +The only new fully-functional algorithms are the GA and the CHC. + +## Architecture + +Mallba skeletons are based on the separation of two concepts: the concrete problem to be solved and the general +resolution method to be used. They can be seen as generic templates that just need to be instantiated with the +features of a problem in order to solve it. All features related to the selected generic resolution method and +its interaction with the concrete problem are implemented by the skeleton. While the particular features related +to the problem must be given by the user, the knowledge to parallelize the execution of the resolution method is +implemented in the skeleton, so that users do not need to deal with parallelism issues. + +The design of the Mallba library focuses on easy to use skeletons and general and efficient implementations. +To achieve both objectives, the C++ programming language was selected due to its high level, modularity, +flexibility and efficiency features. We have reduced to a minimum the use of inheritance and virtual methods in +order to provide better efficiency and ease of use. To instantiate most problems, a basic knowledge of C++ is enough, +and only sequential code without side effects is needed. + +Skeletons are implemented by a set of required and provided C++ classes that represent an abstraction of the entities +participating in the resolution method. The provided classes implement internal aspects of the skeleton in a +problem-independent way. The required classes specify information and behavior related to the problem. +This conceptual separation allows us to define required classes with a fixed interface but without any implementation, +so that provided classes can use required classes in a generic way. + +More specifically, each skeleton includes the Problem and Solution required classes, that encapsulate the +problem-dependent entities needed by the resolution method. The Problem class abstracts the features of the +problem that are relevant to the selected optimization method. The Solution class abstracts the features of the +feasible solutions that are relevant to the selected resolution method. Depending on the skeleton, other classes +may be required. On the other hand, each skeleton offers two provided classes: Solver and SetUpParams. The former +abstracts the selected resolution method. The later contains the setup parameters needed to perform the execution +(e.g. number of iterations, number of independent runs, parameters guiding the search, etc.). The Solver class provides +methods to run the resolution scheme and methods to consult its progress or change its state. The only information the +solver needs is an instance of the problem to solve and the setup parameters. In order to enable an skeleton to have +different solver engines, the Solver class defines a unique interface and provides several subclasses that provide +different sequential and parallel implementations (Solver_Seq, Solver_Lan and Solver_Wan). In Fig. 1 is shown the +common design of Mallba skeletons. + + + +## Implementation + +The implementation of each skeleton is contained in three files: + +* <skeleton>.hh: The file containing the definition of all classes (provides and requires). +* <skeleton>.pro.cc: The file containing the source code of the classes needed for the internal implementation of the method. +* <skeleton>.req.cc: The source file where all the required classes will be implemented. + +In additional, the user must configure the method parameters in the file <skeleton>.cfg. + +## Supported Algorithms + +### Genetic Algorithm + +A Genetic Algorithm is an evolutionary computation technique inspired by the principles of natural selection to search +a solution space. It evolves a population of individuals encoded as chromosomes by creating new generations of +offsprings through an iterative process until some convergence criteria or conditions are met. The best chromosome +generated is then decoded, providing the corresponding solution. The underlying reproduction process is mainly aimed +at improving the fitness of individuals, a measure of profit, utility or goodness to be maximized (or minimized) while +exploring the solution space. The algorithm applies stochastic operators such as selection, crossover, and mutation, +on an initially random population in order to compute a new generation of individuals. The whole process is sketched +in the following figure. + +``` + 1 t = 0 + 2 initialize P(t) + 3 evaluate structures in P(t) + 4 while not end do + 5 t = t + 1 + 6 select C(t) from P(t-1) + 7 recombine structures in C(t) forming C'(t) + 8 mutate structures in C'(t) forming C''(t) + 9 evaluate structures in C''(t) +10 replace P(t) from C''(t) and/or P(t-1) +``` + +It can be seen that the algorithm comprises three major stages: selection, reproduction and replacement. During the +selection stage, a temporary population is created in which the fittest individuals (those corresponding to the best +solutions contained in the population) have a higher number of instances than those less fit (natural selection). The +reproductive operators are applied to the individuals in this population yielding a new population. Finally, individuals +of the original population are substituted by the new created individuals. This replacement usually tries to keep the +best individuals deleting the worst ones. The whole process is repeated until a certain termination criterion is +achieved (usually after a given number of iterations). + +The Genetic Algorithm skeleton (GA) requires the classes: + +* Problem +* Solution +* Crossover +* Mutation + +The class Problem corresponds to the definition of a problem instance. The skeleton filler must provide a complete +definition of this class. + +The class Solution corresponds to the definition of a solution (feasible or not) of a problem instance. The skeleton +filler must provide a complete definition of the class Solution. + +The class Crossover corresponds to the definition of a crossover operator. The skeleton filler must provide a complete +definition of this class. + +And finally, the class Mutation corresponds to the definition of a mutation operator. The skeleton filler must provide +a complete definition of this class. + +In adition, the user must configure the following algorithm parameters (in file GA.cfg): + +* number of independent runs. +* number of generations. +* size of population. +* size of offsprings in each generation. +* replace mode (if replaces parents for offsprings, or only offsprings may be new parents). +* Selection operators parameters (selection of parents and selection of offsprings parameters). +* Intra operators parameters (crossover and mutation parameters). +* Inter operators (operators to apply between sub-populations) parameters: operator number, operator rate, number of individuals and selection of individual to send and replace. +* Parallel Configuracion: interval of generation to refresh global state, running mode (synchronized or asyncronized) and interval of generations to check solutions from other populations. + +There are several basic steps to running a problem solve with GA skeleton: + +* Change to the problem directory + + `cd Mallba/rep/GA/problem` + +* Compile skeleton. + + `make` + +* Configure algorithm parameters (GA.cfg file) + +* Run problem: +Sequential Version: + +``` +make SEQ + or +MainSeq GA.cfg_path instance_path res_file_path +``` + +Parallel Version: + +Configure Config.cfg file. +Configure pgfileLan (or pgfileWan) : machines where we run the program. +Run + +``` +make LAN + or +make WAN +``` + +### CHC + +A CHC is a non-traditional GA which combines a conservative selection strategy (that always preserves the best +individuals found so far) with a highly disruptive recombination (HUX) that produces offsprings that are maximally +different from their two parents. The traditional though of preferring a recombination operator with a low disrupting +properties may not hold when such a conservative selection strategy is used. On the contrary, certain highly disruptive +crossover operator provide more effective search in many problems, which represents the core idea behind the + +CHC search method. This algorithm introduce a new bias against mating individuals who are too similar (incest +prevention). Mutation is not performed, instead, a restart process re-introduces diversity whenever convergence is +detected. + +``` + 1 t = 0 + 2 initialize P(t) + 3 evaluate structures in P(t) + 4 while not end do + 5 t = t + 1 + 6 select: C(t) = P(t-1) + 7 recombine: C'(t) = 'incest prevention' + HUX(C'(t)) + 8 evaluate structures in C'(t) + 9 replace P(t) from C''(t) and P(t-1) +10 if convergence(P(t)) +11 diverge P(t) +``` + +The CHC method skeleton (CHC) requires the classes: + +* Problem +* Solution + +The class Problem corresponds to the definition of a problem instance. The skeleton filler must provide a complete +definition of this class. + +And finally, the class Solution corresponds to the definition of a solution (feasible or not) of a problem instance. +The skeleton filler must provide a complete definition of the class Solution. + +In adition, the user must configure the following algorithm parameters (in file CHC.cfg): + +* number of independent runs. +* number of generations. +* size of population. +* Selection operator parameters (selection of new parents and the diverge method that the algorithm uses whenever the +convergence is detected). +* Intra operators parameters (crossover and mutation parameters). +* Inter operators (operators to apply between sub-populations) parameters: operator number, operator rate, number of +individuals and selection of individual to send and replace. +* Parallel Configuracion: interval of generation to refresh global state, running mode (synchronized or asyncronized) +and interval of generations to check solutions from other populations. + +There are several basic steps to running a problem solve with CHC skeleton: + +* Change to the problem directory + + `cd Mallba/rep/CHC/problem` + +* Compile skeleton + + `make` + +* Configure algorithm parameters (CHC.cfg file) + +* Run problem: + +Sequential Version: + +``` +make SEQ + or +MainSeq GA.cfg_path instance_path res_file_path +``` + +Parallel Version: + +Configure Config.cfg file. +Configure pgfileLan (or pgfileWan) : machines where we run the program. +Run + +``` +make LAN + or +make WAN +``` diff --git a/ProyectoFinal/CHC/malva/environment b/ProyectoFinal/CHC/malva/environment new file mode 100644 index 0000000000000000000000000000000000000000..4976de6761bf2491e7a5976290961d6410764b4b --- /dev/null +++ b/ProyectoFinal/CHC/malva/environment @@ -0,0 +1,19 @@ +# Malva Configuration. +MALLBA_DIR=/ens/home01/g/gonzalo.menendez/AEPractico/malva + +# MPI library +MPI_BIN=/lib64/mpich/bin +# Malva information +MALLBA_INC=${MALLBA_DIR}/src +MALLBA_LIB=${MALLBA_DIR}/lib +MALLBA_SRC=${MALLBA_DIR}/src +MALLBA_REP=${MALLBA_DIR}/rep + +# Run variables +CXX=$(MPI_BIN)/mpic++ +RUN=$(MPI_BIN)/mpirun + +# Other options: -g for debugging and -pg for profiling +CPPFLAGS=-I$(MALLBA_INC) -Wno-deprecated -O3 +LDFLAGS=-L$(MALLBA_LIB) +LOADLIBES=-lmallba -lm diff --git a/ProyectoFinal/CHC/malva/inc/Mallba b/ProyectoFinal/CHC/malva/inc/Mallba new file mode 100644 index 0000000000000000000000000000000000000000..5cd551cf2693e4b4f65d7954ec621454c2b20326 --- /dev/null +++ b/ProyectoFinal/CHC/malva/inc/Mallba @@ -0,0 +1 @@ +../src \ No newline at end of file diff --git a/ProyectoFinal/CHC/malva/inc/inc.env b/ProyectoFinal/CHC/malva/inc/inc.env new file mode 100644 index 0000000000000000000000000000000000000000..3976b861255a9a072f55cd0a7978917ada9b23ad --- /dev/null +++ b/ProyectoFinal/CHC/malva/inc/inc.env @@ -0,0 +1 @@ +ln -s ../src Mallba diff --git a/ProyectoFinal/CHC/malva/lib/Makefile b/ProyectoFinal/CHC/malva/lib/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..5bacf25696f5e617bf9780a8d220fcdcea96ac80 --- /dev/null +++ b/ProyectoFinal/CHC/malva/lib/Makefile @@ -0,0 +1,8 @@ +all: + rm -f libmallba.a + ar -r libmallba.a ../src/*.o + ranlib libmallba.a + +clean: + rm -f libmallba.a + diff --git a/ProyectoFinal/CHC/malva/lib/libmallba.a b/ProyectoFinal/CHC/malva/lib/libmallba.a new file mode 100644 index 0000000000000000000000000000000000000000..db7f3cab7df60324f9676e75019a0ef727333a3e Binary files /dev/null and b/ProyectoFinal/CHC/malva/lib/libmallba.a differ diff --git a/ProyectoFinal/CHC/malva/rep/CHC/CHC.cfg b/ProyectoFinal/CHC/malva/rep/CHC/CHC.cfg new file mode 100644 index 0000000000000000000000000000000000000000..0f6c796c4402f0d45f08b79afee9b59fe36dd4bc --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/CHC/CHC.cfg @@ -0,0 +1,15 @@ +10 // number of independent runs +100 // number of generations +60 // number of individuals +1 // display state ? +Selection-Parameters // selections to apply +0.9 1 0.5 // selection parameter , diverge operator & its probability +Intra-Operators // operators to apply in the population +0 0.8 // crossover & its probability +Inter-Operators // operators to apply between this population and anothers +0 25 5 1 3 1 5 // operator number, operator rate, number of individuals, selection of indidivual to send and remplace +LAN-configuration +101 // refresh global state +1 // 0: running in asynchronized mode / 1: running in synchronized mode +1 // interval of generations to check solutions from other populations + diff --git a/ProyectoFinal/CHC/malva/rep/CHC/CHC.hh b/ProyectoFinal/CHC/malva/rep/CHC/CHC.hh new file mode 100644 index 0000000000000000000000000000000000000000..0c89fe4077468e8dfd5084c3c754a083e50b4978 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/CHC/CHC.hh @@ -0,0 +1,909 @@ +/********************************************************************************************************* +*** *** +*** CHC Skeleton v1.5 *** +*** Developed by: Gabriel Jesús Luque Polo *** +*** *** +*** Last Update: 30-01-2004 *** +*** *** +**********************************************************************************************************/ + +#ifndef INC_CHC +#define INC_CHC +#include "CHCstructures.hh" + +skeleton CHC +{ +#define MAX_USER_OP 5 +#define MAX_PROB_PER_OP 5 + + provides class SetUpParams; + provides class Statistics; + provides class Population; + provides class Intra_Operator; + provides class Crossover; + provides class Diverge; + provides class Inter_Operator; + provides class Migration; + provides class Selection; + provides class Selection_New_Population; + provides class Selection_Parents; + provides class Operator_Pool; + provides class Solver; + provides class Solver_Seq; + provides class Solver_Lan; + provides class Solver_Wan; + provides class StopCondition; + + requires class Problem; + requires class Solution; + requires class UserStatistics; + requires class User_Operator; + requires class StopCondition_1; + requires bool terminateQ (const Problem& pbm, const Solver& solver, const SetUpParams& setup); + +// Problem ---------------------------------------------------------------------------- + + requires class Problem + { + public: + Problem (); + ~Problem(); + + friend ostream& operator<< (ostream& os, const Problem& pbm); + friend istream& operator>> (istream& is, Problem& pbm); + + Problem& operator= (const Problem& pbm); + bool operator== (const Problem& pbm) const; + bool operator!= (const Problem& pbm) const; + + Direction direction () const; + int dimension() const; + + private: + + int _dimension; + }; + +//Solution ---------------------------------------------------------------------------- + + requires class Solution + { + public: + Solution (const Problem& pbm); + Solution (const Solution& sol); + ~Solution(); + + friend ostream& operator<< (ostream& os, const Solution& sol); + friend istream& operator>> (istream& is, Solution& sol); + friend NetStream& operator << (NetStream& ns, const Solution& sol); + friend NetStream& operator >> (NetStream& ns, Solution& sol); + + const Problem& pbm() const; + + Solution& operator= (const Solution& sol); + bool operator== (const Solution& sol) const; + bool operator!= (const Solution& sol) const; + + char *to_String() const; + void to_Solution(char *_cadena_); + + void initialize(); + double fitness () const; + unsigned int size() const; + + int lengthInBits() const; + void flip(const int index); + bool equalb(const int index,Solution &s); + void swap(const int index, Solution &s); + void invalid(); + + int& var(const int index); + Rarray<int>& array_var(); + + private: + Rarray<int> _var; + const Problem& _pbm; + + }; + +// UserStatistics ---------------------------------------------------------------------------- + + requires class UserStatistics + { + private: + struct user_stat + { + unsigned int trial; + unsigned long nb_evaluation_best_found_trial; + unsigned long nb_iteration_best_found_trial; + double best_cost_trial; + double worst_cost_trial; + float time_best_found_trial; + float time_spent_trial; + }; + + Rlist<struct user_stat> result_trials; + + public: + UserStatistics (); + ~UserStatistics(); + + friend ostream& operator<< (ostream& os, const UserStatistics& usertats); + + UserStatistics& operator= (const UserStatistics& userstats); + void update(const Solver& solver); + void clear(); + }; + +// Intra_Operator ( clase abstracta ) -------------------------------------------------------------- + + provides class Intra_Operator + { + protected: + unsigned int _number_operator; + float *probability; + + public: + Intra_Operator(const unsigned int _number_op); + virtual ~Intra_Operator(); + + static Intra_Operator *create(const unsigned int _number_op); + friend ostream& operator<< (ostream& os, const Intra_Operator& intra); + + virtual void execute(Rarray<Solution*>& sols) const=0; + virtual void setup(char line[MAX_BUFFER]) = 0; + unsigned int number_operator() const; + + virtual void RefreshState(const StateCenter& _sc) const=0; + virtual void UpdateFromState(const StateCenter& _sc)=0; + }; + +// Crossover ---------------------------------------------------------------------------------- + + provides class Crossover: public Intra_Operator + { + public: + Crossover(); + virtual ~Crossover(); + + friend ostream& operator << (ostream& os, const Crossover& cross); + + void cross(Solution &sol1,Solution &sol2) const; + virtual void execute(Rarray<Solution*>& sols) const; + virtual void setup(char line[MAX_BUFFER]); + + virtual void RefreshState(const StateCenter& _sc) const; + virtual void UpdateFromState(const StateCenter& _sc); + }; + +// Diverge ---------------------------------------------------------------------------------- + + provides class Diverge: public Intra_Operator + { + public: + Diverge(); + virtual ~Diverge(); + + friend ostream& operator<< (ostream& os, const Diverge& diverge); + + void diverge(Solution& s) const; + // applies mutation over all solutions in array sols + virtual void execute(Rarray<Solution*>& sols) const; + virtual void setup(char line[MAX_BUFFER]); + + virtual void RefreshState(const StateCenter& _sc) const; + virtual void UpdateFromState(const StateCenter& _sc); + }; + +// User_Operator ---------------------------------------------------------------------------------- + + requires class User_Operator: public Intra_Operator + { + public: + User_Operator(const unsigned int _number_op); + virtual ~User_Operator(); + + static Intra_Operator *create(const unsigned int _number_op); + friend ostream& operator<< (ostream& os, const User_Operator& User_Operator); + + // applies mutation over all solutions in array sols + virtual void execute(Rarray<Solution*>& sols) const; + virtual void setup(char line[MAX_BUFFER]); + + virtual void RefreshState(const StateCenter& _sc) const; + virtual void UpdateFromState(const StateCenter& _sc); + }; + +// StopCondition ----------------------------------------------------------------------------------- + provides class StopCondition + { + public: + StopCondition(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup)=0; + ~StopCondition(); + }; + +// StopCondition_1 ----------------------------------------------------------------------------------- + requires class StopCondition_1 : public StopCondition + { + public: + StopCondition_1(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_1(); + }; + +// SetUpParams ------------------------------------------------------------------------------- + + provides class SetUpParams + { + private: + unsigned int _independent_runs; + unsigned long _nb_evolution_steps; + unsigned long _nb_iteration_steps; + unsigned int _population_size; // number of individuals + bool _display_state; + + unsigned long _refresh_global_state; + bool _synchronized; + unsigned int _check_asynchronous; + + // selection of parents and offsprings + mutable unsigned int _select_parents; + mutable unsigned int _select_offsprings; + + Rlist<unsigned int> _intra_operators; + Rlist<unsigned int> _inter_operators; + + Operator_Pool& _pool; + + public: + SetUpParams (Operator_Pool& pool); + Operator_Pool& pool() const; + + friend ostream& operator<< (ostream& os, const SetUpParams& setup); + friend istream& operator>> (istream& is, SetUpParams& setup); + + const unsigned int independent_runs() const; + const unsigned long nb_evolution_steps() const; + const unsigned int population_size() const; + const bool display_state() const; + const unsigned long refresh_global_state() const; + const bool synchronized() const; + const unsigned int check_asynchronous() const; + + void independent_runs(const unsigned int val); + void nb_evolution_steps(const unsigned long val); + void population_size(const unsigned int val); + void display_state(const bool val); + void refresh_global_state(const unsigned long val); + void synchronized(const bool val); + void check_asynchronous(const unsigned int val); + + // gets the i-th operator of inter-population + const unsigned int inter_operator_index(const unsigned int index) const; + const unsigned int inter_operators_size() const; + + // gets the i-th operator of intra-population + const unsigned int intra_operator_index(const unsigned int index) const; + const unsigned int intra_operators_size() const; + + const unsigned int select_parents() const; + const unsigned int select_offsprings() const; + + void select_parents(const unsigned int val); + void select_offsprings(const unsigned int val); + + void RefreshState(const StateCenter& _sc) const; + void UpdateFromState(const StateCenter& _sc) const; + + ~SetUpParams(); + }; + +// Statistics --------------------------------------------------------------------------------- + + provides class Statistics + { + private: + struct stat + { + unsigned int trial; + unsigned long nb_generation; + unsigned long nb_evaluation; + double best_cost; + double global_best_cost; + double average_cost; + double standard_deviation; + }; + + Rlist<struct stat> stats_data; + + public: + Statistics(); + ~Statistics(); + + friend ostream& operator<< (ostream& os, const Statistics& stats); + + Statistics& operator= (const Statistics& stats); + void update(const Solver& solver); + void clear(); + }; + +// Population --------------------------------------------------------------------------------- + + provides class Population + { + private: + Rarray<Solution*> _parents; // individuals in population + Rarray<Solution*> _offsprings; // offsprings of current population + Rarray<Solution*> _new_parents; // individuals of previous population + Rarray<struct individual> _fitness_values; + Rarray<struct individual> _fitness_aux; + const SetUpParams& _setup; + unsigned int _upper_cost,_lower_cost; // lower and upper fitness of individuals in population + unsigned int _evaluations; + double _average_cost; + + public: + inline void Evaluate(Solution *s, struct individual & _f); + + Population(const Problem& pbm,const SetUpParams& setup); // crea un array de objetos population; + ~Population(); + + friend ostream& operator<< (ostream& os, const Population& population); + friend istream& operator>> (istream& is, Population& population); + Population& operator= (const Population& pop); + const SetUpParams& setup() const; + const Problem& pbm() const; + void initialize(); + + // Generate a new pool of individuals in population + void evolution(); + + // interchange solutions between island + void interchange(const unsigned long current_generation, NetStream& channel); + + // creates a array with fitness of all individuals in population and its position in the population + void evaluate_parents(); + + // creates a array with fitness of all individuals and offsprings in population and its position in the population + void evaluate_offsprings(); + + // selects parents to creates offsprings + void select_parents(); + + // selects individuals for the new population + void select_offsprings(); + + const Rarray<Solution*>& parents() const; + const Rarray<Solution*>& offsprings() const; + Rarray<struct individual>& fitness_values(); + + unsigned int upper_cost() const; + unsigned int lower_cost() const; + unsigned int evaluations() const; + Solution& solution(const unsigned int index) const; + double fitness(const unsigned int index) const; + + double best_cost() const; + double worst_cost() const; + Solution& best_solution() const; + Solution& worst_solution() const; + double average_cost() const; + double standard_deviation() const; + }; + +// Inter_Operator ( abstract )----------------------------------------------------------- + + provides class Inter_Operator + { + protected: + unsigned int migration_rate; + unsigned int migration_size; + unsigned int migration_selection_1; + unsigned int migration_selection_2; + unsigned int migration_selection_conf_1; + unsigned int migration_selection_conf_2; + + unsigned int _number_operator; + const Direction direction; + + public: + Inter_Operator(const unsigned int _number_op, const Direction dir); + virtual ~Inter_Operator(); + + friend ostream& operator<< (ostream& os, const Inter_Operator& inter); + + virtual void execute(Population& pop,const unsigned long current_generation,NetStream& _netstream,const bool synchronized,const unsigned int check_asyncrhonous) const=0; + virtual void setup(char line[MAX_BUFFER]); + unsigned int number_operator() const; + + virtual void RefreshState(const StateCenter& _sc) const; + virtual void UpdateFromState(const StateCenter& _sc); + }; + +// Migration: public Inter_Operator ----------------------------------------------------------- + + provides class Migration: public Inter_Operator + { + public: + Migration(const Direction dir); + virtual ~Migration(); + + friend ostream& operator<< (ostream& os, const Migration& migration); + + virtual void execute(Population& pop,const unsigned long current_generation,NetStream& _netstream,const bool synchronized,const unsigned int check_asyncrhonous) const; + }; + +// Selection --------------------------------------------------------- + + provides class Selection + { + protected: + unsigned int _number_selection; + const Direction direction; + + public: + + Selection(const Direction dir); + Selection(const unsigned int _number_sel, const Direction dir); + virtual ~Selection(); + + friend ostream& operator<< (ostream& os, const Selection& sel); + + virtual void prepare(Rarray<struct individual>& fitness_values,const bool remplace); // const; + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int dummy,const bool remplace) const; + unsigned int number_selection() const; + + virtual void setup(char line[MAX_BUFFER]); + virtual void RefreshState(const StateCenter& _sc) const; + virtual void UpdateFromState(const StateCenter& _sc); + + }; + +// Selection_Parents --------------------------------------------------------------------------------- + + provides class Selection_Parents: public Selection + { + private: + mutable unsigned int selection_position; + + public: + Selection_Parents(const Direction dir); + virtual ~Selection_Parents(); + + friend ostream& operator<< (ostream& os, const Selection_Parents& sel); + + virtual void prepare(Rarray<struct individual>& fitness_values,const bool remplace); // const; + + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int param,const bool remplace) const; + }; + +// Selection_New_Population --------------------------------------------------------------------------- + + provides class Selection_New_Population: public Selection + { + private: + mutable unsigned int selection_position; + mutable int d; + Intra_Operator *diverge; + float r; + + public: + Selection_New_Population(const Direction dir); + virtual ~Selection_New_Population(); + + friend ostream& operator<< (ostream& os, const Selection_New_Population& sel); + + virtual void prepare(Rarray<struct individual>& fitness_values,const bool remplace); // const; + + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int param,const bool remplace) const; + + virtual void setup(char line[MAX_BUFFER]); + virtual void RefreshState(const StateCenter& _sc) const; + virtual void UpdateFromState(const StateCenter& _sc); + }; + +// Selection_Tournament --------------------------------------------------------------------------------- + + provides class Selection_Tournament: public Selection + { + public: + Selection_Tournament(const Direction dir); + virtual ~Selection_Tournament(); + + friend ostream& operator<< (ostream& os, const Selection_Tournament& sel); + + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int tourment_size,const bool remplace) const; + }; + +// Selection_Roulette_Wheel --------------------------------------------------------------------------------- + + provides class Selection_Roulette_Wheel: public Selection + { + public: + Selection_Roulette_Wheel(const Direction); + virtual ~Selection_Roulette_Wheel(); + + friend ostream& operator<< (ostream& os, const Selection_Roulette_Wheel& sel); + + virtual void prepare(Rarray<struct individual>& fitness_values,const bool remplace); // const; + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int dummy,const bool remplace) const; + }; + +// Selection_Rank --------------------------------------------------------------------------------- + + provides class Selection_Rank: public Selection + { + public: + Selection_Rank(const Direction dir); + Selection_Rank(const unsigned int _number_sel, const Direction dir); + virtual ~Selection_Rank(); + + friend ostream& operator<< (ostream& os, const Selection_Rank& sel); + + virtual void prepare(Rarray<struct individual>& fitness_values,const bool remplace); // const; + virtual void reset(); + + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int portion,const bool remplace) const; + }; + +// Selection_Best --------------------------------------------------------------------------------- + + provides class Selection_Best: public Selection_Rank + { + private: + mutable unsigned int selection_best_position; + + public: + Selection_Best(const Direction); + virtual ~Selection_Best(); + + friend ostream& operator<< (ostream& os, const Selection_Best& sel); + + virtual void reset(); + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int position,const bool remplace) const; + }; + +// Selection_Worst --------------------------------------------------------------------------------- + + provides class Selection_Worst: public Selection_Rank + { + private: + mutable unsigned int selection_worst_position; + + public: + Selection_Worst(const Direction); + virtual ~Selection_Worst(); + + friend ostream& operator<< (ostream& os, const Selection_Worst& sel); + + virtual void reset(); + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int position,const bool remplace) const; + }; + +// Operator_Pool ------------------------------------------------------------------------- + + // pool with all operators and selections that can be chosen in the setup file + provides class Operator_Pool + { + private: + mutable Rlist<Intra_Operator> _intra_operators; + Rlist<Selection> _selectors; + Rlist<Inter_Operator> _inter_operators; + + public: + Operator_Pool(const Problem& pbm); + ~Operator_Pool(); + + Intra_Operator& intra_operator(const unsigned int index) const; + Rlist<Intra_Operator>& intra_operators() const; + Selection& selector(const unsigned int index) const; + const Rlist<Selection>& selectors() const; + Inter_Operator& inter_operator(const unsigned int index) const; + const Rlist<Inter_Operator>& inter_operators() const; + + }; + +// Solver --------------------------------------------------------------------------------- + + provides class Solver + { + protected: + const Problem& problem; + const SetUpParams& params; + UserStatistics _userstat; + Statistics _stat; + Population current_population; + StateCenter _sc; + + double best_cost; + double worst_cost; + Solution best_solution; + double average_cost; + double standard_deviation; + float total_time_spent; + float time_spent_in_trial; + float start_trial; + float start_global; + + bool _end_trial; + + State_Vble _current_trial; + State_Vble _current_iteration; + State_Vble _current_evaluations; + + State_Vble _current_best_solution; + State_Vble _current_best_cost; + State_Vble _current_worst_cost; + State_Vble _current_average_cost; + State_Vble _current_standard_deviation; + State_Vble _current_time_spent; + + State_Vble _best_solution_trial; + State_Vble _best_cost_trial; + State_Vble _worst_cost_trial; + State_Vble _iteration_best_found_in_trial; + State_Vble _evaluations_best_found_in_trial; + State_Vble _time_best_found_trial; + State_Vble _time_spent_trial; + + State_Vble _trial_best_found; + State_Vble _iteration_best_found; + State_Vble _evaluations_best_found; + State_Vble _global_best_solution; + State_Vble _global_best_cost; + State_Vble _global_worst_cost; + State_Vble _time_best_found; + + State_Vble _crossover_probability; // probability of applying the operator over population + State_Vble _diverge_probability; // probability of applying the operator over population + State_Vble _user_op_probability[MAX_USER_OP]; // probabilities of user operators + State_Vble _migration_rate; + State_Vble _migration_size; + State_Vble _migration_selection_1; + State_Vble _migration_selection_2; + State_Vble _migration_selection_conf_1; + State_Vble _migration_selection_conf_2; + State_Vble _select_parents; + State_Vble _select_offsprings; + State_Vble _parameter_select_new_pop; + + State_Vble _display_state; + + public: + Solver (const Problem& pbm, const SetUpParams& setup); + virtual ~Solver (); + + virtual int pid() const; + bool end_trial() const; + void end_trial(bool et); + + // Execution methods ----------------------------------------------------------------------- + + // Full execution + virtual void run () =0; + virtual void run (const unsigned long int nb_generations) =0; + virtual void run (const Population& pop,const unsigned long int nb_generations) =0; + + //Partial execution + virtual void StartUp()=0; + virtual void StartUp(const Population& pop)=0; + + virtual void DoStep()=0; + + // Statistics handling ---------------------------------------------------------------------- + + Statistics& statistics(); + UserStatistics& userstatistics (); + Population& population(); + const SetUpParams& setup() const; + const Problem& pbm() const; + + // State handling --------------------------------------------------------------------------- + + void RefreshState(); + void RefreshCfgState(); + void UpdateFromState(); + void UpdateFromCfgState(); + StateCenter* GetState(); + + unsigned int current_trial() const; + unsigned long current_iteration() const; + unsigned long current_evaluations() const; + Solution current_best_solution() const; + double current_best_cost() const; + double current_worst_cost() const; + double current_average_cost() const; + double current_standard_deviation() const; + float current_time_spent() const; + Solution best_solution_trial() const; + double best_cost_trial() const; + double worst_cost_trial() const; + unsigned int iteration_best_found_in_trial() const; + unsigned int evaluations_best_found_in_trial() const; + float time_best_found_trial() const; + float time_spent_trial() const; + unsigned int trial_best_found() const; + unsigned int iteration_best_found() const; + unsigned int evaluations_best_found() const; + Solution global_best_solution() const; + double global_best_cost() const; + double global_worst_cost() const; + float time_best_found() const; + int display_state() const; + + float *crossover_probability() const; + float *diverge_probability() const; + float *user_op_probability(const int index) const; + unsigned int migration_rate() const; + unsigned int migration_size() const; + unsigned int migration_selection_1() const; + unsigned int migration_selection_2() const; + unsigned int migration_selection_conf_1() const; + unsigned int migration_selection_conf_2() const; + unsigned int select_parents() const; + unsigned int select_offprings() const; + float parameter_select_new_pop() const; + + void current_trial(const unsigned int value); + void current_iteration(const unsigned long value); + void current_evaluations(const unsigned long value); + void current_best_solution(const Solution& sol); + void current_best_cost(const double value); + void current_worst_cost(const double value); + void current_average_cost(const double value); + void current_standard_deviation(const double value); + void current_time_spent(const float value); + void best_solution_trial(const Solution& sol); + void best_cost_trial(const double value); + void worst_cost_trial(const double value); + void iteration_best_found_in_trial(const unsigned int value); + void evaluations_best_found_in_trial(const unsigned int value); + void time_best_found_trial(const float value); + void time_spent_trial(const float value); + void trial_best_found(const unsigned int value); + void iteration_best_found(const unsigned int value); + void evaluations_best_found(const unsigned int value); + void global_best_solution(const Solution& sol); + void global_best_cost(const double value); + void global_worst_cost(const double value); + void time_best_found(const float value); + void display_state(const int value); + + void crossover_probability(const float *probability); + void diverge_probability(const float *probability); + void user_op_probability(const int index,const float *probability); + void migration_rate(const unsigned int rate); + void migration_size(const unsigned int size); + void migration_selection_1(const unsigned int seleciton_1); + void migration_selection_2(const unsigned int selection_2); + void migration_selection_conf_1(const unsigned int selection_conf_1); + void migration_selection_conf_2(const unsigned int selection_conf_2); + void select_parents(const unsigned int selection); + void select_offsprings(const unsigned int selection); + void parameter_select_new_pop(const float value); + + void KeepHistory(const Solution& best_sol,const double best_cost,const double worst_cost,const float time_spent_trial,const float total_time_spent); + + void show_state() const; + }; + + provides class Solver_Seq: public Solver + { + public: + Solver_Seq ( const Problem& pbm, const SetUpParams& setup); + virtual ~Solver_Seq (); + + // Execution methods ----------------------------------------------------------------------- + + // Full execution + virtual void run (); + virtual void run (const unsigned long int nb_generations); + virtual void run (const Population& pop,const unsigned long int nb_generations); + + //Partial execution + virtual void StartUp(); + virtual void StartUp(const Population& pop); + + virtual void DoStep(); + }; + + provides class Solver_Lan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state(); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned long _current_iteration; + unsigned long _current_evaluations; + double _best_cost_trial; + Solution _best_solution_trial; + double _worst_cost_trial; + float _time_best_found_in_trial; + unsigned long _iteration_best_found_in_trial; + unsigned long _evaluations_best_found_in_trial; + + // Termination phase // + bool final_phase; + int acum_evaluations; + int acum_iterations; + + public: + Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Lan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods ----------------------------------------------------------------------- + + // Full execution + virtual void run (); + virtual void run (const unsigned long int nb_generations); + virtual void run (const Population& pop,const unsigned long int nb_generations); + + //Partial execution + virtual void StartUp(); + virtual void StartUp(const Population& pop); + + virtual void DoStep(); + + void reset(); + }; + + provides class Solver_Wan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state(); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned long _current_iteration; + unsigned long _current_evaluations; + double _best_cost_trial; + Solution _best_solution_trial; + double _worst_cost_trial; + float _time_best_found_in_trial; + unsigned long _iteration_best_found_in_trial; + unsigned long _evaluations_best_found_in_trial; + + // Termination phase // + bool final_phase; + int acum_evaluations; + int acum_iterations; + + public: + Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Wan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods ----------------------------------------------------------------------- + + // Full execution + virtual void run (); + virtual void run (const unsigned long int nb_generations); + virtual void run (const Population& pop,const unsigned long int nb_generations); + + //Partial execution + virtual void StartUp(); + virtual void StartUp(const Population& pop); + + virtual void DoStep(); + + void reset(); + }; + +} + +#endif diff --git a/ProyectoFinal/CHC/malva/rep/CHC/CHC.pro.cc b/ProyectoFinal/CHC/malva/rep/CHC/CHC.pro.cc new file mode 100644 index 0000000000000000000000000000000000000000..65672fddd9a1410d56b382f5941777a301e2e85c --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/CHC/CHC.pro.cc @@ -0,0 +1,3033 @@ +#include "CHC.hh" + +skeleton CHC +{ +// StopCondition ------------------------------------------------------------------------------------- + + StopCondition::StopCondition() + {} + + StopCondition::~StopCondition() + {} + +// SetUpParams ----------------------------------------------------------- + + SetUpParams::SetUpParams (Operator_Pool& pool) + : _independent_runs(0), + _nb_evolution_steps(0), + _population_size(0), + _select_parents(6), // Selection of parents: Select all individuals. (fixed) + _select_offsprings(7), // Selection of offspring : Select the best individuals. (fixed) + _inter_operators(), + _intra_operators(), + _refresh_global_state(1), + _synchronized(0), + _check_asynchronous(1), + _display_state(0), + _pool(pool) + {} + + Operator_Pool& SetUpParams::pool() const + { + return _pool; + } + + istream& operator>> (istream& is, SetUpParams& setup) + { + char buffer[MAX_BUFFER]; // current line in the setup file + char command[50]; + long op; + int parameter; + short int nb_section=0; + short int nb_io = 0; + short int nb_param=0; + short int nb_LAN_param=0; + + while (is.getline(buffer,MAX_BUFFER,'\n')) + { + sscanf(buffer," %s ",command); + if (!(strcmp(command,"General"))) nb_section=0; + if (!(strcmp(command,"Selection-Parameters"))) nb_section=1; + if (!(strcmp(command,"Intra-Operators"))) nb_section=2; + if (!(strcmp(command,"Inter-Operators"))) nb_section=3; + if (!(strcmp(command,"LAN-configuration"))) nb_section=4; + + op=-1; + sscanf(buffer," %ld%*s ",&op); + if (op<0) continue; + switch (nb_section) + { + case 0: switch (nb_param) + { + case 0: setup.independent_runs(op); break; + case 1: setup.nb_evolution_steps(op); break; + case 2: setup.population_size(op); break; + case 3: setup.display_state(op); break; + } + nb_param++; + break; + case 1: setup.pool().selector(setup.select_offsprings()).setup(buffer); + break; + case 2: setup.pool().intra_operators().append(Intra_Operator::create(op)); + setup.pool().intra_operator(nb_io).setup(buffer); + setup._intra_operators.append(new unsigned int(nb_io)); + nb_io++; + break; + case 3: setup._inter_operators.append(new unsigned int(op)); + setup.pool().inter_operator(op).setup(buffer); + break; + case 4: if (nb_LAN_param>=3) break; + switch (nb_LAN_param) + { + case 0: setup.refresh_global_state(op); break; + case 1: setup.synchronized(op); break; + case 2: assert(op>0); + setup.check_asynchronous(op); break; + } + nb_LAN_param++; + break; + } + } + + return is; + } + + ostream& operator<< (ostream& os, const SetUpParams& setup) + { + os << "CONFIGURATION -------------------------------------------" << endl << endl; + os << "\t" << "Independent runs : " << setup.independent_runs() << endl + << "\t" << "Evolution steps: " << setup.nb_evolution_steps() << endl + << "\t" << "Size of Population: " << setup.population_size() << endl; + os << "\t" <<"With combination between parents and offsprings" << endl; + + os << "\t" << "Display State: " << setup.display_state() << endl << endl + << "\t" << "Selections:" << endl + << "\t" << "-----------" << endl << endl + << "\t" << "Selection parents -> " << setup.pool().selector(setup.select_parents()) << endl + << "\t" << "Selection offsprings -> " << setup.pool().selector(setup.select_offsprings()) << endl + << "\t" << "Intra_Operators: " << endl + << "\t" << "-----------" << endl << endl; + + for (int i=0;i<setup.intra_operators_size();i++) + os << "\t" << (setup.pool().intra_operator(setup.intra_operator_index(i))) << endl; + + os << endl << "\t" << "Inter_Operators: " << endl + << "\t" << "-----------" << endl << endl; + + for (int i=0;i<setup.inter_operators_size();i++) + os << "\t" << "Operator: " << setup.pool().inter_operator(setup.inter_operator_index(i)) << endl; + + os << endl << "\t" << "LAN configuration:" << endl + << "\t" << "----------------------" << endl << endl + << "\t" << "Refresh global state in number of generations: " << setup.refresh_global_state() << endl; + + if (setup.synchronized()) + os << "\t" << "Running in synchronous mode" << endl; + else + os << "\t" << "Running in asynchronous mode" << endl; + os << "\t" << "Interval for checking asynchronous receptions: " << setup.check_asynchronous() << endl << endl; + + os << endl << endl << "END CONFIGURATION -------------------------------------------" << endl << endl; + continue_question(); + return os; + } + + const unsigned int SetUpParams::independent_runs() const + { + return _independent_runs; + } + + const unsigned long SetUpParams::nb_evolution_steps() const + { + return _nb_evolution_steps; + } + + const unsigned int SetUpParams::population_size() const + { + return _population_size; + } + + const unsigned long SetUpParams::refresh_global_state() const + { + return _refresh_global_state; + } + + const bool SetUpParams::synchronized() const + { + return _synchronized; + } + + const unsigned int SetUpParams::check_asynchronous() const + { + return _check_asynchronous; + } + + const bool SetUpParams::display_state() const + { + return _display_state; + } + + void SetUpParams::independent_runs(const unsigned int val) + { + _independent_runs=val; + } + + void SetUpParams::nb_evolution_steps(const unsigned long val) + { + _nb_evolution_steps=val; + } + + void SetUpParams::population_size(const unsigned int val) + { + _population_size=val; + } + + void SetUpParams::display_state(const bool val) + { + _display_state=val; + } + + void SetUpParams::refresh_global_state(const unsigned long val) + { + _refresh_global_state=val; + } + + void SetUpParams::synchronized(const bool val) + { + _synchronized=val; + } + + void SetUpParams::check_asynchronous(const unsigned int val) + { + _check_asynchronous=val; + } + + const unsigned int SetUpParams::select_parents() const + { + return _select_parents; + } + + const unsigned int SetUpParams::select_offsprings() const + { + return _select_offsprings; + } + + void SetUpParams::select_parents(const unsigned int val) + { + _select_parents=val; + } + + void SetUpParams::select_offsprings(const unsigned int val) + { + _select_offsprings=val; + } + + const unsigned int SetUpParams::intra_operator_index(const unsigned int index) const + { + return _intra_operators[index]; + } + + const unsigned int SetUpParams::intra_operators_size() const + { + return _intra_operators.size(); + } + + const unsigned int SetUpParams::inter_operator_index(const unsigned int index) const + { + return _inter_operators[index]; + } + + const unsigned int SetUpParams::inter_operators_size() const + { + return _inter_operators.size(); + } + + void SetUpParams::RefreshState(const StateCenter& _sc) const + { + _sc.set_contents_state_variable("_select_parents",(char *)&_select_parents,1,sizeof(_select_parents)); + _sc.set_contents_state_variable("_select_offsprings",(char *)&_select_offsprings,1,sizeof(_select_offsprings)); + _sc.set_contents_state_variable("_display_state",(char *)&_display_state,1,sizeof(bool)); + } + + void SetUpParams::UpdateFromState(const StateCenter& _sc) const + { + unsigned long nbytes,length; + _sc.get_contents_state_variable("_select_parents",(char *)&_select_parents,nbytes,length); + _sc.get_contents_state_variable("_select_offsprings",(char *)&_select_offsprings,nbytes,length); + _sc.get_contents_state_variable("_display_state",(char *)&_display_state,nbytes,length); + } + + SetUpParams::~SetUpParams() + {} + +// Statistics ------------------------------------------------------ + + Statistics::Statistics() + {} + + ostream& operator<< (ostream& os, const Statistics& stats) + { + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF CURRENT TRIAL " << endl; + os << "------------------------------------------------------------------" << endl; + for (int i=0;i< stats.stats_data.size();i++) + { + os << endl + << " Trial: " << stats.stats_data[i].trial + << " Generation: " << stats.stats_data[i].nb_generation + << " Evaluation: " << stats.stats_data[i].nb_evaluation + << " Current best cost: " << stats.stats_data[i].best_cost + << " Global best cost: " << stats.stats_data[i].global_best_cost + << " Avg: " << stats.stats_data[i].average_cost + << " Std. Dev.: " << stats.stats_data[i].standard_deviation; + } + + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + Statistics& Statistics::operator= (const Statistics& stats) + { + stats_data = stats.stats_data; + return *this; + } + + void Statistics::update(const Solver& solver) + { + struct stat *new_stat=(struct stat *)malloc(sizeof(struct stat)); + + new_stat->trial=solver.current_trial(); + new_stat->nb_generation=solver.current_iteration(); + new_stat->nb_evaluation=solver.current_evaluations(); + new_stat->average_cost=solver.current_average_cost(); + new_stat->standard_deviation=solver.current_standard_deviation(); + new_stat->best_cost=solver.current_best_cost(); + new_stat->global_best_cost=solver.global_best_cost(); + + stats_data.append(*new_stat); + } + + void Statistics::clear() + { + stats_data.remove(); + } + + Statistics::~Statistics() + {} + +// Population ------------------------------------------------------ + + Population::Population(const Problem& pbm,const SetUpParams& setup) + :_parents(setup.population_size()), + _fitness_values(setup.population_size()), + _new_parents(setup.population_size()), + _offsprings(setup.population_size()), + _setup(setup), + _evaluations(0) + { + for (int i=0;i<_parents.size();i++) + { + _parents[i]=new Solution(pbm); + _new_parents[i]=new Solution(pbm); + _fitness_values[i].index = i; + _fitness_values[i].change = true; + } + for (int i=0;i<_offsprings.size();i++) + _offsprings[i]=new Solution(pbm); + + } + + void Population::Evaluate(Solution* sols,struct individual &_f) + { + if(_f.change) + { + _f.change = false; + _f.fitness = sols->fitness(); + _evaluations++; + } + } + + Population& Population::operator= (const Population& pop) + { + for (int i=0;i<_parents.size();i++) + { + *_parents[i]=*((pop.parents())[i]); + _fitness_values[i] = pop._fitness_values[i]; + _evaluations = pop._evaluations; + } + return (*this); + } + + istream& operator>> (istream& is, Population& population) + { + return is; + } + + ostream& operator<< (ostream& os, const Population& population) + { + os << "---------------------------------------------------------------" << endl; + os << " PRESENT POPULATION " << endl << endl; + for (int i=0;i<population._parents.size();i++) + os << *population._parents[i] << endl; + os << endl << "---------------------------------------------------------------" << endl; + return os; + } + + const SetUpParams& Population::setup() const + { + return _setup; + } + + void Population::initialize() + { + for (int i=0;i<_parents.size();i++) + { + _parents[i]->initialize(); + _fitness_values[i].index = i; + _fitness_values[i].change = true; + } + evaluate_parents(); + } + + void Population::evaluate_parents() + { + double upper_fitness=(infinity() * (-1)); + double lower_fitness=(infinity()); + double current_fitness; + double cost=0.0; + + for (int i=0;i<_fitness_values.size();i++) + { + Evaluate(_parents[_fitness_values[i].index],_fitness_values[i]); + current_fitness = _fitness_values[i].fitness; + + if (current_fitness > upper_fitness ) + { + _upper_cost=i; + upper_fitness = current_fitness; + } + + if (current_fitness < lower_fitness ) + { + _lower_cost=i; + lower_fitness = current_fitness; + } + + cost += current_fitness; + } + + _average_cost = cost / _fitness_values.size(); + } + + void Population::evaluate_offsprings() + { + int i=0; + + _fitness_aux=Rarray<struct individual>(_parents.size() + _offsprings.size()); + for (i=0;i<_parents.size();i++) + { + Evaluate(_parents[_fitness_values[i].index],_fitness_values[i]); + _fitness_aux[i] = _fitness_values[i]; + } + + for (int j=i;(j-i)<_offsprings.size();j++) + { + _fitness_aux[j].index=j; + _fitness_aux[j].change=true; + Evaluate(_offsprings[j-i],_fitness_aux[j]); + } + } + + void Population::evolution() + { + select_parents(); // selects individuals to apply operators + + // apply selected operators + for (int i=0;i<_setup.intra_operators_size();i++) + _setup.pool().intra_operator(_setup.intra_operator_index(i)).execute(_offsprings); + + evaluate_offsprings(); + select_offsprings(); // selects new individuals + evaluate_parents(); // calculates fitness of new individuals + } + + void Population::interchange(const unsigned long current_generation, NetStream& channel) + { + // apply selected operators + for (int i=0;i<_setup.inter_operators_size();i++) + _setup.pool().inter_operator(_setup.inter_operator_index(i)).execute((*this),current_generation,channel,_setup.synchronized(),_setup.check_asynchronous()); + } + + void Population::select_parents() + { + _setup.pool().selector(_setup.select_parents()).prepare(_fitness_values,false); + struct individual ind; + for (int i=0;i<_offsprings.size();i++) + { + ind = _setup.pool().selector(_setup.select_parents()).select_one(_parents,_offsprings,_fitness_values,0,false); + *_offsprings[i] = *_parents[ind.index]; + } + } + + void Population::select_offsprings() + { + _setup.pool().selector(_setup.select_offsprings()).prepare(_fitness_aux,false); + const int ps = _parents.size(); + Rarray<struct individual> aux(ps); + + for (int i=0;i<ps;i++) + { + aux[i] = _setup.pool().selector(_setup.select_offsprings()).select_one(_parents,_offsprings,_fitness_aux,0,false); + if(aux[i].index < ps) + { + *_new_parents[i] = *_parents[aux[i].index]; + aux[i].index = i; + } + else + { + *_new_parents[i] = *_offsprings[aux[i].index-ps]; + aux[i].index = i; + } + } + + Solution *interchange; + for (int i=0;i<ps;i++) + { + interchange=_parents[i]; + _parents[i]=_new_parents[i]; // interchanges pointers to solutions ( NO solutions !! ) + _new_parents[i]=interchange; + } + + for (int i=0;i<ps;i++) + { + _fitness_values[i] = aux[i]; + } + } + + const Rarray<Solution*>& Population::parents() const + { + return _parents; + } + + const Rarray<Solution*>& Population::offsprings() const + { + return _offsprings; + } + + Rarray<struct individual>& Population::fitness_values() + { + return _fitness_values; + } + + unsigned int Population::upper_cost() const + { + return _upper_cost; + } + + unsigned int Population::lower_cost() const + { + return _lower_cost; + } + + unsigned int Population::evaluations() const + { + return _evaluations; + } + + double Population::best_cost() const + { + if ((*_parents[0]).pbm().direction() == minimize) + return _fitness_values[_lower_cost].fitness; + else + return _fitness_values[_upper_cost].fitness; + } + + double Population::worst_cost() const + { + if ((*_parents[0]).pbm().direction() == minimize) + return _fitness_values[_upper_cost].fitness; + else + return _fitness_values[_lower_cost].fitness; + } + + Solution& Population::best_solution() const + { + if ((*_parents[0]).pbm().direction() == minimize) + return *_parents[_fitness_values[_lower_cost].index]; + else + return *_parents[_fitness_values[_upper_cost].index]; + } + + Solution& Population::worst_solution() const + { + if ((*_parents[0]).pbm().direction() == minimize) + return *_parents[_fitness_values[_upper_cost].index]; + else + return *_parents[_fitness_values[_lower_cost].index]; + } + + Solution& Population::solution(const unsigned int index) const + { + return *_parents[index]; + } + + double Population::fitness(const unsigned int index) const + { + return _fitness_values[index].fitness; + } + + double Population::average_cost() const + { + return _average_cost; + } + + double Population::standard_deviation() const + { + double standard=0.0; + for (int i=0;i<_fitness_values.size();i++) + standard += pow ((_fitness_values[i].fitness - _average_cost),2); + standard=sqrt(standard / (_fitness_values.size()-1)); + return standard; + } + + Population::~Population() + { + for (int i=0;i<_parents.size();i++) + delete(_parents[i]); + for (int i=0;i<_offsprings.size();i++) + delete(_offsprings[i]); + for (int j=0;j<_new_parents.size();j++) + delete(_new_parents[j]); + } + +// Intra_operator -------------------------------------------------------------- + + Intra_Operator::Intra_Operator(const unsigned int _number_op):_number_operator(_number_op),probability(NULL) + {} + + unsigned int Intra_Operator::number_operator() const + { + return _number_operator; + } + + Intra_Operator *Intra_Operator::create(unsigned int _number_op) + { + switch (_number_op) + { + case 0: return new Crossover();break; + case 1: return new Diverge();break; + default: return User_Operator::create(_number_op); break; + } + } + + ostream& operator<< (ostream& os, const Intra_Operator& intra) + { + switch (intra.number_operator()) + { + case 0: os << (Crossover&)intra;break; + case 1: os << (Diverge&)intra;break; + default: os << (User_Operator&)intra;break; + } + return os; + } + + Intra_Operator::~Intra_Operator() + {} + +// Crossover:Intra_operator ------------------------------------------------------------- + + Crossover::Crossover():Intra_Operator(0) + { + probability = new float[1]; + probability[0] = -1.0; + } + + void Crossover::cross(Solution& sol1,Solution& sol2) const // dadas dos soluciones de la poblacion, las cruza + { + int dh = 0; + + if(probability[0] <= 0.0) + { + probability[0] = sol1.lengthInBits()/4; + } + + for(int i = 0; i < sol1.lengthInBits();i++) + if(!sol1.equalb(i,sol2)) dh++; + + if((dh/2) > probability[0]) + { + for(int i = 0; i < sol1.lengthInBits();i++) + if((!sol1.equalb(i,sol2)) && (0.5 <= rand01())) + { + sol1.swap(i,sol2); + } + } + else + { + sol1.invalid(); + sol2.invalid(); + } + } + + void Crossover::execute(Rarray<Solution*>& sols) const + { + for(int i=0;i+1<sols.size();i=i+2) + cross(*sols[i],*sols[i+1]); + } + + ostream& operator<< (ostream& os, const Crossover& cross) + { + os << "Crossover."; + return os; + } + + void Crossover::RefreshState(const StateCenter& _sc) const + {} + + void Crossover::UpdateFromState(const StateCenter& _sc) + { + unsigned long nbytes,length; + _sc.get_contents_state_variable("_parameter_select_new_pop",(char *)probability,nbytes,length); + } + + void Crossover::setup(char line[MAX_BUFFER]) + { + int op; + sscanf(line," %d ",&op); + } + + Crossover::~Crossover() + { + delete [] probability; + } + + +// Diverge: Sub_operator ------------------------------------------------------------- + + Diverge::Diverge():Intra_Operator(1) + { + probability = new float[1]; + } + + void Diverge::diverge(Solution& sol) const + { + for(int i = 0; i < sol.lengthInBits(); i++) + if(rand01() < probability[0]) sol.flip(i); + } + + void Diverge::execute(Rarray<Solution*>& sols) const + { + for (int i=0;i<sols.size();i++) + diverge(*sols[i]); + } + + ostream& operator<< (ostream& os, const Diverge& diverge) + { + os << "Diverge." << " Probability: " << diverge.probability[0]; + return os; + } + + void Diverge::setup(char line[MAX_BUFFER]) + { + int op; + sscanf(line," %d %f ",&op,&probability[0]); + assert(probability[0]>=0); + } + + void Diverge::RefreshState(const StateCenter& _sc) const + { + _sc.set_contents_state_variable("_diverge_probability",(char *)probability,1,sizeof(float)); + } + + void Diverge::UpdateFromState(const StateCenter& _sc) + { + unsigned long nbytes,length; + _sc.get_contents_state_variable("_diverge_probability",(char *)probability,nbytes,length); + } + + Diverge::~Diverge() + { + delete [] probability; + } + + +// Inter_operator ------------------------------------------------------------------- + + Inter_Operator::Inter_Operator(const unsigned int _number_op,const Direction dir): + _number_operator(_number_op), + direction(dir), + migration_rate(1), + migration_size(1), + migration_selection_1(0), + migration_selection_2(0), + migration_selection_conf_1(0), + migration_selection_conf_2(0) + {} + + unsigned int Inter_Operator::number_operator() const + { + return _number_operator; + } + + void Inter_Operator::setup(char line[MAX_BUFFER]) + { + int op; + int new_migration_rate=1; + int new_migration_size=1; + int new_migration_selection_1=0; + int new_migration_selection_conf_1=0; + int new_migration_selection_2=0; + int new_migration_selection_conf_2=0; + + sscanf(line," %d %d %d %d %d %d %d ",&op,&new_migration_rate,&new_migration_size,&new_migration_selection_1,&new_migration_selection_conf_1,&new_migration_selection_2,&new_migration_selection_conf_2); + + assert(new_migration_rate>0); + assert(new_migration_size>0); + assert(new_migration_selection_1>=0); + assert(new_migration_selection_conf_1>=0); + assert(new_migration_selection_2>=0); + assert(new_migration_selection_conf_2>=0); + + migration_rate=new_migration_rate; + migration_size=new_migration_size; + migration_selection_1=new_migration_selection_1; + migration_selection_conf_1=new_migration_selection_conf_1; + migration_selection_2=new_migration_selection_2; + migration_selection_conf_2=new_migration_selection_conf_2; + } + + void Inter_Operator::RefreshState(const StateCenter& _sc) const + { + _sc.set_contents_state_variable("_migration_rate",(char *)&migration_rate,1,sizeof(migration_rate)); + _sc.set_contents_state_variable("_migration_size",(char *)&migration_size,1,sizeof(migration_size)); + _sc.set_contents_state_variable("_migration_selection_1",(char *)&migration_selection_1,1,sizeof(migration_selection_1)); + _sc.set_contents_state_variable("_migration_selection_2",(char *)&migration_selection_2,1,sizeof(migration_selection_2)); + _sc.set_contents_state_variable("_migration_selection_conf_1",(char *)&migration_selection_conf_1,1,sizeof(migration_selection_conf_1)); + _sc.set_contents_state_variable("_migration_selection_conf_2",(char *)&migration_selection_conf_2,1,sizeof(migration_selection_conf_2)); + } + + void Inter_Operator::UpdateFromState(const StateCenter& _sc) + { + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_rate",(char *)&migration_rate,nitems,length); + _sc.get_contents_state_variable("_migration_size",(char *)&migration_size,nitems,length); + _sc.get_contents_state_variable("_migration_selection_1",(char *)&migration_selection_1,nitems,length); + _sc.get_contents_state_variable("_migration_selection_2",(char *)&migration_selection_2,nitems,length); + _sc.get_contents_state_variable("_migration_selection_conf_1",(char *)&migration_selection_conf_1,nitems,length); + _sc.get_contents_state_variable("_migration_selection_conf_2",(char *)&migration_selection_conf_2,nitems,length); + } + + ostream& operator<< (ostream& os, const Inter_Operator& inter) + { + switch (inter.number_operator()) + { + case 0: os << (Migration&)inter;break; + } + return os; + } + + Inter_Operator::~Inter_Operator() + {} + +// Migration ------------------------------------------------------------ + + Migration::Migration(const Direction dir):Inter_Operator(0,dir) + {} + + void Migration::execute(Population& pop,const unsigned long current_generation,NetStream& _netstream,const bool synchronized,const unsigned int check_asynchronous) const + { + + Solution* solution_to_send; + Solution* solution_received; + Solution* solution_to_remplace; + bool need_to_revaluate=false; + int mypid; + + int nb_proc=_netstream.pnumber(); // Get the number of processes running + + mypid=_netstream.my_pid(); + + int to = (mypid + 1) % nb_proc; // Source (from) and Target (to) of processes + int from = (nb_proc + mypid - 1) % nb_proc; + + // process number 0 is only to store the global state + if (to==0) to=1; + if (from==0) from=nb_proc - 1; + + _netstream << set_target(to) << set_source(from) + << get_target(&to) << get_source(&from); + + if ( (current_generation % migration_rate) == 0 + && (current_generation!=pop.setup().nb_evolution_steps())) // in this generation this operator have to be applied + { + pop.setup().pool().selector(migration_selection_1).prepare(pop.fitness_values(),false); + + _netstream << pack_begin; + for (int i=0;i<migration_size;i++) + { + // select individual to send + solution_to_send = pop.parents()[pop.setup().pool().selector(migration_selection_1).select_one( + pop.parents(),pop.offsprings(),pop.fitness_values(),migration_selection_conf_1,false).index]; + + _netstream << *solution_to_send; + } + _netstream << pack_end; + + if (synchronized) // synchronous mode: blocked until data are received + { + pop.setup().pool().selector(migration_selection_2).prepare(pop.fitness_values(),true); + + _netstream << set_source(MPI_ANY_SOURCE); + int tipo = 0; + _netstream._wait2(any,tipo); + + if (tipo == 1){ + return; + } + + _netstream << wait(packed); + _netstream << pack_begin; + for (int i=0;i<migration_size;i++) + { + // select individual to be remplaced + struct individual ind; + ind = pop.setup().pool().selector(migration_selection_2).select_one( + pop.parents(),pop.offsprings(),pop.fitness_values(),migration_selection_conf_2,true); + solution_to_remplace = pop.parents()[ind.index]; + solution_received=new Solution(solution_to_remplace->pbm()); + _netstream >> *solution_received; + + // remplace policy + if ((solution_received->fitness()<=solution_to_remplace->fitness() && direction==minimize) + || (solution_received->fitness()>=solution_to_remplace->fitness() && direction==maximize)) + { + need_to_revaluate=true; + for(int j = 0; j < pop.parents().size(); j++) + { + if(pop.fitness_values()[j].index == ind.index) + { + pop.fitness_values()[j].change = true; + *pop.parents()[ind.index] = *solution_received; + } + } + } + delete(solution_received); + } + _netstream << pack_end; + + } + } // end if + + if (!synchronized && ((current_generation % check_asynchronous) ==0)) + { // asynchronous mode: if there are not data, continue; + // but, if there are data, i have to receive it + int pending=false; + _netstream._probe(packed,pending); + if (pending) + { + pop.setup().pool().selector(migration_selection_2).prepare(pop.fitness_values(),true); + + _netstream << pack_begin; + for (int i=0;i<migration_size;i++) + { + pending=false; + _netstream._probe(regular,pending); + if (!pending) break; + + // select individual to be remplaced + struct individual ind; + ind = pop.setup().pool().selector(migration_selection_2).select_one( + pop.parents(),pop.offsprings(),pop.fitness_values(),migration_selection_conf_2,true); + solution_to_remplace = pop.parents()[ind.index]; + solution_received=new Solution(solution_to_remplace->pbm()); + _netstream >> *solution_received; + + // remplace policy + if ((solution_received->fitness()<=solution_to_remplace->fitness() && direction==minimize) + || (solution_received->fitness()>=solution_to_remplace->fitness() && direction==maximize)) + { + need_to_revaluate=true; + for(int j = 0; j < pop.parents().size(); j++) + { + if(pop.fitness_values()[j].index == ind.index) + { + pop.fitness_values()[j].change = true; + *pop.parents()[ind.index] = *solution_received; + } + } + } + delete(solution_received); + } // end for + _netstream << pack_begin; + } // end if + } + + if (need_to_revaluate) pop.evaluate_parents(); + } + + ostream& operator<< (ostream& os, const Migration& migration) + { + os << "Migration." + << endl << "\t" << " Rate: " << migration.migration_rate + << endl << "\t" << " Size: " << migration.migration_size + << endl << "\t" << " Selection 1: " << migration.migration_selection_1 + << endl << "\t" << " Selection 1 Parameter: " << migration.migration_selection_conf_1 + << endl << "\t" << " Selection 2: " << migration.migration_selection_2 + << endl << "\t" << " Selection 2 Parameter: " << migration.migration_selection_conf_2; + return os; + } + + Migration::~Migration() + {} + +// Selection ------------------------------------------------------------ + + Selection::Selection(const Direction dir):_number_selection(0),direction(dir) + {} + + Selection::Selection(const unsigned int _number_sel, const Direction dir):_number_selection(_number_sel),direction(dir) + {} + + void Selection::prepare(Rarray<struct individual>& fitness_values,const bool remplace) + {} + + struct individual Selection::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int dummy,const bool remplace) const + { // select a random individual + return fitness_values[rand_int(0,fitness_values.size()-1)]; + } + + unsigned int Selection::number_selection() const + { + return _number_selection; + } + + ostream& operator<< (ostream& os, const Selection& sel) + { + switch (sel.number_selection()) + { + case 0: os << "Random Selection"; break; + case 1: os << (Selection_Tournament&)sel; break; + case 2: os << (Selection_Roulette_Wheel&)sel; break; + case 3: os << (Selection_Rank&)sel; break; + case 4: os << (Selection_Best&)sel; break; + case 5: os << (Selection_Worst&)sel; break; + case 6: os << (Selection_Parents&)sel; break; + case 7: os << (Selection_New_Population&)sel; break; + } + return os; + } + + void Selection::setup(char line[MAX_BUFFER]) + {} + + void Selection::RefreshState(const StateCenter& _sc) const + {} + + void Selection::UpdateFromState(const StateCenter& _sc) + {} + + + Selection::~Selection() + {} + +// Selection_Tournament---------------------------------------------------- + + Selection_Tournament::Selection_Tournament(const Direction dir):Selection(1,dir) + {} + + struct individual Selection_Tournament::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int tournament_size, const bool remplace) const + { + unsigned int best_sol=0; + double best_fitness=((-1) * direction * infinity()); + unsigned int index; + + if (remplace) best_fitness = -1 * best_fitness; + + unsigned int new_tournament_size=tournament_size; + if (tournament_size==0) new_tournament_size=1; + + for (int i=0;i<new_tournament_size;i++) + { + index=rand_int(0,fitness_values.size()-1); + + switch (direction) + { + case (minimize): if (((!remplace) && (fitness_values[index].fitness<best_fitness)) + || ((remplace) && (fitness_values[index].fitness>best_fitness))) + { + best_sol = index; + best_fitness = fitness_values[index].fitness; + } + break; + case (maximize): if (((!remplace) && (fitness_values[index].fitness>best_fitness)) + || ((remplace) && (fitness_values[index].fitness<best_fitness))) + { + best_sol = index; + best_fitness = fitness_values[index].fitness; + } + break; + } + } + + return fitness_values[best_sol]; + } + + ostream& operator<< (ostream& os, const Selection_Tournament& sel) + { + os << "Tournament Selection."; + return os; + } + + Selection_Tournament::~Selection_Tournament() + {} + +// Selection_Roulette_Wheel --------------------------------------------------- + + Selection_Roulette_Wheel::Selection_Roulette_Wheel(const Direction dir):Selection(2,dir) + {} + + void Selection_Roulette_Wheel::prepare(Rarray<struct individual>& fitness_values,const bool remplace) + { + + double overall_fitness=0.0; + + // inverts fitness values to select less fitness individuals with a high probability + if ((direction==maximize && (remplace)) || ((direction==minimize) && (!(remplace)))) + { + // fitness assigned if the fitness value is 0 in this case + double value_if_zero=DBL_MAX; + unsigned int nb_zeros=0; + + for (int i=0;i<fitness_values.size();i++) + { + if (fitness_values[i].fitness!=0) + value_if_zero-=fitness_values[i].fitness; + else + nb_zeros++; + } + + value_if_zero=value_if_zero/nb_zeros; + + // Warning !! if fitness is 0 (1/0 ?) + for (int i=0;i<fitness_values.size();i++) + { + if (fitness_values[i].fitness!=0) + fitness_values[i].sel_parameter = (1 / fitness_values[i].fitness ); + else + fitness_values[i].sel_parameter = value_if_zero; + overall_fitness+= fitness_values[i].sel_parameter; + } + } + else + { + for (int i=0;i<fitness_values.size();i++) + { + fitness_values[i].sel_parameter = fitness_values[i].fitness; + overall_fitness+= fitness_values[i].sel_parameter; + } + + } + + if (overall_fitness>DBL_MAX) overall_fitness=DBL_MAX; + + // calculate relative fitness + double previous=0.0; + for (int i=0;i<fitness_values.size();i++) + { + fitness_values[i].sel_parameter = (fitness_values[i].sel_parameter / overall_fitness) + previous; + previous = fitness_values[i].sel_parameter; + } + } + + struct individual Selection_Roulette_Wheel::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int dummy, const bool remplace) const + { + double random_selected=rand01(); + int i=0; + + while (random_selected > fitness_values[i].sel_parameter ) + i++; + + return fitness_values[i]; + } + + ostream& operator<< (ostream& os, const Selection_Roulette_Wheel& sel) + { + os << "Roulette Wheel Selection."; + return os; + } + + Selection_Roulette_Wheel::~Selection_Roulette_Wheel() + {} + +// Selection_Rank -------------------------------------------------- + + int lessF(const struct individual &i1,const struct individual &i2) + { + return i1.fitness < i2.fitness; + } + + int greaterF(const struct individual &i1,const struct individual &i2) + { + return i1.fitness > i2.fitness; + } + + Selection_Rank::Selection_Rank(const Direction dir):Selection(3,dir) + {} + + Selection_Rank::Selection_Rank(const unsigned int _number_sel, const Direction dir):Selection(_number_sel,dir) + {} + + void Selection_Rank::reset() + {} + + void Selection_Rank::prepare(Rarray<struct individual>& fitness_values,const bool remplace) + { + reset(); + + // sort individuals + if (((direction==maximize) && (!(remplace))) || ((direction==minimize) && (remplace))) + fitness_values.sort(lessF); + else + fitness_values.sort(greaterF); + } + + struct individual Selection_Rank::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int portion,const bool remplace) const + { + + unsigned int new_portion=portion; + if (portion==0 || portion>100) new_portion=100; + + return fitness_values[rand_int(0,(( fitness_values.size() * new_portion )/ 100)-1)]; + } + + ostream& operator<< (ostream& os, const Selection_Rank& sel) + { + os << "Rank-Ordered Selection."; + return os; + } + + Selection_Rank::~Selection_Rank() + {} + +// Selection_Best -------------------------------------------------- + + Selection_Best::Selection_Best(const Direction dir):Selection_Rank(4,dir),selection_best_position(0) + {} + + struct individual Selection_Best::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int position,const bool remplace) const + { + int position_to_return=position-1; + if (position_to_return<0) + { + position_to_return = selection_best_position; + selection_best_position++; + } + + position_to_return=(int)position_to_return % fitness_values.size(); + + return fitness_values[position_to_return]; + } + + void Selection_Best::reset() + { + selection_best_position=0; + } + + ostream& operator<< (ostream& os, const Selection_Best& sel) + { + os << "Selection of best ordered individuals."; + return os; + } + + Selection_Best::~Selection_Best() + {} + +// Selection_Worst -------------------------------------------------- + + Selection_Worst::Selection_Worst(const Direction dir):Selection_Rank(5,dir),selection_worst_position(0) + {} + + struct individual Selection_Worst::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int position,const bool remplace) const + { + int position_to_return=position-1; + if (position_to_return<0) + { + position_to_return = selection_worst_position; + selection_worst_position++; + } + + position_to_return=(int)position_to_return % fitness_values.size(); + + int index=(fitness_values.size()-1) - position_to_return; + return fitness_values[index]; + } + + void Selection_Worst::reset() + { + selection_worst_position=0; + } + + ostream& operator<< (ostream& os, const Selection_Worst& sel) + { + os << "Selection of worst ordered individuals."; + return os; + } + + Selection_Worst::~Selection_Worst() + {} + +// Selection_Parents --------------------------------------------------------------------------------- + + Selection_Parents::Selection_Parents(const Direction dir):Selection(6,dir),selection_position(0) + {} + + Selection_Parents::~Selection_Parents() + {} + + ostream& operator<< (ostream& os, const Selection_Parents& sel) + { + os << "CHC Selection: Parents Selection."; + return os; + } + + void Selection_Parents::prepare(Rarray<struct individual>& fitness_values,const bool remplace) // const + { + selection_position = 0; + int limit1,limit2; + register int max = fitness_values.size(); + + struct individual interchange; + + for (int i=0;i<max*3;i++) + { + limit1 = rand_int(0,max-1); + limit2 = rand_int(0,max-1); + interchange=fitness_values[limit1]; + fitness_values[limit1]=fitness_values[limit2]; + fitness_values[limit2]=interchange; + } + } + + struct individual Selection_Parents::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int param,const bool remplace) const + { + int index = selection_position; + selection_position++; + + index = index % fitness_values.size(); + + return fitness_values[index]; + } + +// Selection_New_Population --------------------------------------------------------------------------- + + Selection_New_Population::Selection_New_Population(const Direction dir) + :Selection(7,dir) + ,diverge(NULL) + ,d(-1) + {} + + Selection_New_Population::~Selection_New_Population() + { + if(diverge != NULL) delete diverge; + } + + ostream& operator<< (ostream& os, const Selection_New_Population& sel) + { + os << "CHC Selection: New Population Selection." << " Diverge Operator: " << *sel.diverge; + return os; + } + + + void Selection_New_Population::prepare(Rarray<struct individual>& fitness_values,const bool remplace) // const + { + selection_position = 0; + + // sort individuals + if (((direction==maximize) && (!(remplace))) || ((direction==minimize) && (remplace))) + fitness_values.sort(greaterF); + else + fitness_values.sort(lessF); + } + + struct individual Selection_New_Population::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int param,const bool remplace) const + { + bool change = false; + if(d == -1) d = to_select_1[0]->lengthInBits() / 4; + + if(selection_position == 0) + { + for(int i= 0; i < to_select_1.size(); i++) + if(fitness_values[i].index > (to_select_1.size()-1)) change = true; + if(change) selection_position++; + else selection_position--; + } + + if(selection_position == -1) + { + d--; + if(d < 0) + { + selection_position--; + d = (int) (r * (1.0-r) * to_select_1[0]->lengthInBits()); + } + else selection_position = 1; + } + + if(selection_position == -2) + { + assert(diverge != NULL); + for(int i = 1; i < to_select_1.size(); i++) + { + if(rand01() < r) ((Diverge *)diverge)->diverge(*to_select_1[i]); + } + for(int i= 0; i < fitness_values.size(); i++) + if(fitness_values[i].index < (to_select_1.size()-1)) fitness_values[i].change = true; + + selection_position = 1; + } + + if(selection_position > 0) + { + int index = selection_position-1; + selection_position++; + return fitness_values[index]; + } + } + + void Selection_New_Population::setup(char line[MAX_BUFFER]) + { + int div; + float div_par; + + sscanf(line," %f %d %f ",&r,&div, &div_par); + assert(r>=0); + + sprintf(line,"%d %f ",div,div_par); + + diverge = Intra_Operator::create(div); + assert(diverge != NULL); + + diverge->setup(line); + } + + void Selection_New_Population::RefreshState(const StateCenter& _sc) const + { + _sc.set_contents_state_variable("_parameter_select_new_pop",(char *)&r,1,sizeof(float)); + } + + void Selection_New_Population::UpdateFromState(const StateCenter& _sc) + { + unsigned long nbytes,length; + _sc.get_contents_state_variable("_parameter_select_new_pop",(char *)&r,nbytes,length); + } + +// Operator_Pool ------------------------------------------------------------------------ + + Operator_Pool::Operator_Pool(const Problem& pbm) + { + // introduces all operators and selections in lists + + // Index to be chosen in setup file + //------------------------------------- + // The Intra_Operators are introduced dimanicly in setup + + _selectors.append(new Selection(pbm.direction())); // 0 + _selectors.append(new Selection_Tournament(pbm.direction())); // 1 + _selectors.append(new Selection_Roulette_Wheel(pbm.direction())); // 2 + _selectors.append(new Selection_Rank(pbm.direction())); // 3 + _selectors.append(new Selection_Best(pbm.direction())); // 4 + _selectors.append(new Selection_Worst(pbm.direction())); // 5 + _selectors.append(new Selection_Parents(pbm.direction())); // 6 + _selectors.append(new Selection_New_Population(pbm.direction())); // 7 + + _inter_operators.append(new Migration(pbm.direction())); // 0 + } + + Intra_Operator& Operator_Pool::intra_operator(const unsigned int index) const + { + assert(index < _intra_operators.size()); + return _intra_operators[index]; + } + + Rlist<Intra_Operator>& Operator_Pool::intra_operators() const + { + return _intra_operators; + } + + Selection& Operator_Pool::selector(const unsigned int index) const + { + assert(index < _selectors.size()); + return _selectors[index]; + } + + const Rlist<Selection>& Operator_Pool::selectors() const + { + return _selectors; + } + + Inter_Operator& Operator_Pool::inter_operator(const unsigned int index) const + { + assert(index < _inter_operators.size()); + return _inter_operators[index]; + } + + const Rlist<Inter_Operator>& Operator_Pool::inter_operators() const + { + return _inter_operators; + } + + Operator_Pool::~Operator_Pool() + {} + +// Solver (superclasse)--------------------------------------------------- + + Solver::Solver (const Problem& pbm, const SetUpParams& setup) + : problem(pbm), + params(setup), + _stat(), + _userstat(), + _sc(), + current_population(pbm,setup), + best_cost((-1) * pbm.direction() * infinity()), + worst_cost((-1) * best_cost), + best_solution(problem), + average_cost(0.0), + standard_deviation(0.0), + time_spent_in_trial(0.0), + total_time_spent(0.0), + start_trial(0.0), + start_global(0.0), + _current_trial("_current_trial",_sc), + _current_iteration("_current_iteration",_sc), + _current_evaluations("_current_evaluations",_sc), + _current_best_solution("_current_best_solution",_sc), + _current_best_cost("_current_best_cost",_sc), + _current_worst_cost("_current_worst_cost",_sc), + _current_average_cost("_current_average_cost",_sc), + _current_standard_deviation("_current_standard_deviation",_sc), + _current_time_spent("_current_time_spent",_sc), + _best_solution_trial("_best_sol_trial",_sc), + _best_cost_trial("_best_cost_trial",_sc), + _worst_cost_trial("_worst_cost_trial",_sc), + _iteration_best_found_in_trial("_iteration_best_found_in_trial",_sc), + _evaluations_best_found_in_trial("_evaluations_best_found_in_trial",_sc), + _time_best_found_trial("_time_best_found_trial",_sc), + _time_spent_trial("_time_spent_trial",_sc), + _trial_best_found("_trial_best_found",_sc), + _iteration_best_found("_iteration_best_found",_sc), + _evaluations_best_found("_evaluations_best_found",_sc), + _global_best_solution("_global_best_solution",_sc), + _global_best_cost("_global_best_cost",_sc), + _global_worst_cost("_global_worst_cost",_sc), + _time_best_found("_time_best_found",_sc), + _crossover_probability("_crossover_probability",_sc), + _diverge_probability("_diverge_probability",_sc), + _migration_rate("_migration_rate",_sc), + _migration_size("_migration_size",_sc), + _migration_selection_1("_migration_selection_1",_sc), + _migration_selection_2("_migration_selection_2",_sc), + _migration_selection_conf_1("_migration_selection_conf_1",_sc), + _migration_selection_conf_2("_migration_selection_conf_2",_sc), + _select_parents("_select_parents",_sc), + _select_offsprings("_select_offsprings",_sc), + _parameter_select_new_pop("_parameter_select_new_pop",_sc), + _display_state("_display_state",_sc) + { + current_trial(0); + current_iteration(0); + current_evaluations(0); + current_best_solution(best_solution); + current_best_cost(best_cost); + current_worst_cost(worst_cost); + current_average_cost(average_cost); + current_standard_deviation(standard_deviation); + current_time_spent(total_time_spent); + best_solution_trial(best_solution); + best_cost_trial(best_cost); + worst_cost_trial(worst_cost); + iteration_best_found_in_trial(0); + evaluations_best_found_in_trial(0); + time_best_found_trial(time_spent_in_trial); + time_spent_trial(time_spent_in_trial); + trial_best_found(0); + iteration_best_found(0); + evaluations_best_found(0); + global_best_solution(best_solution); + global_best_cost(best_cost); + global_worst_cost(worst_cost); + time_best_found(total_time_spent); + + float prob[MAX_PROB_PER_OP] = {0.0}; + crossover_probability(prob); + diverge_probability(prob); + + char aux[] = "_user_op_probability"; + char nombre[30]; + for(int i = 0; i < MAX_USER_OP; i++) + { + sprintf(nombre,"%s%d",aux,i); + _user_op_probability[i].set_name((char *)nombre); + _sc.add(_user_op_probability[i]); + user_op_probability(i,prob); + } + + migration_rate(0); + migration_size(0); + migration_selection_1(0); + migration_selection_2(0); + migration_selection_conf_1(0); + migration_selection_conf_2(0); + select_parents(0); + select_offsprings(0); + parameter_select_new_pop(0.0); + display_state(setup.display_state()); + } + + int Solver::pid() const + { + return 0; + } + + bool Solver::end_trial() const + { + return _end_trial; + } + + void Solver::end_trial(bool et) + { + _end_trial = et; + } + + unsigned int Solver::current_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _current_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned long Solver::current_iteration() const + { + unsigned long value=0; + unsigned long nitems,length; + _current_iteration.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned long Solver::current_evaluations() const + { + unsigned long value=0; + unsigned long nitems,length; + _current_evaluations.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::current_best_solution() const + { + Solution sol(problem); + unsigned long nitems,length; + char data_stored[_current_best_solution.get_nitems() + _current_best_solution.get_length()]; + _current_best_solution.get_contents(data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::current_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _current_best_cost.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::current_worst_cost() const + { + double value=0.0; + unsigned long nitems,length; + _current_worst_cost.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::current_average_cost() const + { + double value=0.0; + unsigned long nitems,length; + _current_average_cost.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::current_standard_deviation() const + { + double value=0.0; + unsigned long nitems,length; + _current_standard_deviation.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::current_time_spent() const + { + float value=0.0; + unsigned long nitems,length; + _current_time_spent.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::best_solution_trial() const + { + Solution sol(problem); + char data_stored[_best_solution_trial.get_nitems() + _best_solution_trial.get_length()]; + unsigned long nitems,length; + _best_solution_trial.get_contents(data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::best_cost_trial() const + { + double value=0.0; + unsigned long nitems,length; + _best_cost_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::worst_cost_trial() const + { + double value=0.0; + unsigned long nitems,length; + _worst_cost_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found_in_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found_in_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::evaluations_best_found_in_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _evaluations_best_found_in_trial.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_spent_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_spent_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::trial_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _trial_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::evaluations_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _evaluations_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::global_best_solution() const + { + Solution sol(problem); + char data_stored[_global_best_solution.get_nitems() + _global_best_solution.get_length()]; + unsigned long nitems,length; + _global_best_solution.get_contents(data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::global_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _global_best_cost.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::global_worst_cost() const + { + double value=0.0; + unsigned long nitems,length; + _global_worst_cost.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + int Solver::display_state() const + { + int value=0; + unsigned long nitems,length; + _display_state.get_contents((char *)&value, nitems, length); + return value; + } + + float *Solver::crossover_probability() const + { + float *current_probability = new float[MAX_PROB_PER_OP]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_crossover_probability",(char *)¤t_probability,nitems,length); + return current_probability; + } + + float *Solver::diverge_probability() const + { + float *current_probability = new float[MAX_PROB_PER_OP]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_diverge_probability",(char *)¤t_probability,nitems,length); + return current_probability; + } + + float *Solver::user_op_probability(const int index) const + { + float *current_probability = new float[MAX_PROB_PER_OP]; + unsigned long nitems,length; + char aux[30] = "_user_op_probability"; + sprintf(aux,"%s%d",aux,index); + + _sc.get_contents_state_variable(aux,(char *)¤t_probability,nitems,length); + return current_probability; + } + + unsigned int Solver::migration_rate() const + { + unsigned int rate=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_rate",(char *)&rate,nitems,length); + return rate; + } + + unsigned int Solver::migration_size() const + { + unsigned int size=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_size",(char *)&size,nitems,length); + return size; + } + + unsigned int Solver::migration_selection_1() const + { + unsigned int selection_1=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_selection_1",(char *)&selection_1,nitems,length); + return selection_1; + } + + unsigned int Solver::migration_selection_2() const + { + unsigned int selection_2=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_selection_2",(char *)&selection_2,nitems,length); + return selection_2; + } + + unsigned int Solver::migration_selection_conf_1() const + { + unsigned int selection_conf_1=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_selection_conf_1",(char *)&selection_conf_1,nitems,length); + return selection_conf_1; + } + + unsigned int Solver::migration_selection_conf_2() const + { + unsigned int selection_conf_2=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_selection_conf_2",(char *)&selection_conf_2,nitems,length); + return selection_conf_2; + } + + unsigned int Solver::select_parents() const + { + unsigned int select_parents=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_select_parents",(char *)&select_parents,nitems,length); + return select_parents; + } + + unsigned int Solver::select_offprings() const + { + unsigned int select_offsprings=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_select_offsprings",(char *)&select_offsprings,nitems,length); + return select_offsprings; + } + + float Solver::parameter_select_new_pop() const + { + float parameter_select_new_pop; + unsigned long nitems,length; + _sc.get_contents_state_variable("_parameter_select_new_pop",(char *)¶meter_select_new_pop,nitems,length); + return parameter_select_new_pop; + } + + void Solver::current_trial(const unsigned int value) + { + _current_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::current_iteration(const unsigned long value) + { + _current_iteration.set_contents((char *)&value,1,sizeof(long)); + } + + void Solver::current_evaluations(const unsigned long value) + { + _current_evaluations.set_contents((char *)&value,1,sizeof(long)); + } + + void Solver::current_best_solution(const Solution& sol) + { + _current_best_solution.set_contents(sol.to_String(),1,sol.size()); + } + + void Solver::current_best_cost(const double value) + { + _current_best_cost.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::current_worst_cost(const double value) + { + _current_worst_cost.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::current_average_cost(const double value) + { + _current_average_cost.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::current_standard_deviation(const double value) + { + _current_standard_deviation.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::current_time_spent(const float value) + { + _current_time_spent.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::best_solution_trial(const Solution& sol) + { + _best_solution_trial.set_contents(sol.to_String(),1,sol.size()); + } + + void Solver::best_cost_trial(const double value) + { + _best_cost_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::worst_cost_trial(const double value) + { + _worst_cost_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::iteration_best_found_in_trial(const unsigned int value) + { + _iteration_best_found_in_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::evaluations_best_found_in_trial(const unsigned int value) + { + _evaluations_best_found_in_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::time_best_found_trial(const float value) + { + _time_best_found_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::time_spent_trial(const float value) + { + _time_spent_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::trial_best_found(const unsigned int value) + { + _trial_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::iteration_best_found(const unsigned int value) + { + _iteration_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::evaluations_best_found(const unsigned int value) + { + _evaluations_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::global_best_solution(const Solution& sol) + { + _global_best_solution.set_contents(sol.to_String(),1,sol.size()); + } + + void Solver::global_best_cost(const double value) + { + _global_best_cost.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::global_worst_cost(const double value) + { + _global_worst_cost.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::time_best_found(const float value) + { + _time_best_found.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::display_state(const int value) + { + _display_state.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::crossover_probability(const float *new_probability) + { + _sc.set_contents_state_variable("_crossover_probability",(char *)new_probability,MAX_PROB_PER_OP,sizeof(float)); + } + + void Solver::diverge_probability(const float *new_probability) + { + _sc.set_contents_state_variable("_diverge_probability",(char *)new_probability,MAX_PROB_PER_OP,sizeof(float)); + } + + void Solver::user_op_probability(const int index, const float *new_probability) + { + char aux[30] = "_user_op_probability"; + sprintf(aux,"%s%d",aux,index); + + _sc.set_contents_state_variable(aux,(char *)new_probability,MAX_PROB_PER_OP,sizeof(float)); + } + + void Solver::migration_rate(const unsigned int rate) + { + _sc.set_contents_state_variable("_migration_rate",(char *)&rate,1,sizeof(int)); + } + + void Solver::migration_size(const unsigned int size) + { + _sc.set_contents_state_variable("_migration_size",(char *)&size,1,sizeof(int)); + } + + void Solver::migration_selection_1(const unsigned int selection_1) + { + _sc.set_contents_state_variable("_migration_selection_1",(char *)&selection_1,1,sizeof(int)); + } + + void Solver::migration_selection_2(const unsigned int selection_2) + { + _sc.set_contents_state_variable("_migration_selection_2",(char *)&selection_2,1,sizeof(int)); + } + + void Solver::migration_selection_conf_1(const unsigned int selection_conf_1) + { + _sc.set_contents_state_variable("_migration_selection_conf_1",(char *)&selection_conf_1,1,sizeof(int)); + } + + void Solver::migration_selection_conf_2(const unsigned int selection_conf_2) + { + _sc.set_contents_state_variable("_migration_selection_conf_2",(char *)&selection_conf_2,1,sizeof(int)); + } + + void Solver::select_parents(const unsigned int selection) + { + _sc.set_contents_state_variable("_select_parents",(char *)&selection,1,sizeof(int)); + } + + void Solver::select_offsprings(const unsigned int selection) + { + _sc.set_contents_state_variable("_select_offsprings",(char *)&selection,1,sizeof(int)); + } + + void Solver::parameter_select_new_pop(const float value) + { + _sc.set_contents_state_variable("_parameter_select_new_pop",(char *)&value,1,sizeof(float)); + } + + Statistics& Solver::statistics() + { + return _stat; + } + + UserStatistics& Solver::userstatistics() + { + return _userstat; + } + + Population& Solver::population() + { + return current_population; + } + + const SetUpParams& Solver::setup() const + { + return params; + } + + const Problem& Solver::pbm() const + { + return problem; + } + + void Solver::KeepHistory(const Solution& best_sol,const double best_cost,const double worst_cost,const float time_spent_in_trial,const float total_time_spent) + { + bool betterG=false; + bool worseG=false; + bool betterT=false; + bool worseT=false; + + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_spent_in_trial < time_best_found())); + worseG = (worst_cost > global_worst_cost()); + betterT = (best_cost < best_cost_trial() || (best_cost == best_cost_trial() && time_spent_in_trial < time_best_found_trial())); + worseT = (worst_cost > worst_cost_trial()); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_spent_in_trial < time_best_found())); + worseG = (worst_cost < global_worst_cost()); + betterT = (best_cost > best_cost_trial() || (best_cost == best_cost_trial() && time_spent_in_trial < time_best_found_trial())); + worseT = (worst_cost < worst_cost_trial()); + break; + } + + if (betterT) + { + best_solution_trial(best_sol); + best_cost_trial(best_cost); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_in_trial(current_iteration()); + evaluations_best_found_in_trial(current_evaluations()); + if (betterG) + { + global_best_solution(best_sol); + global_best_cost(best_cost); + time_best_found(time_spent_in_trial); + trial_best_found(current_trial()); + iteration_best_found(current_iteration()); + evaluations_best_found(current_evaluations()); + } + } + + if (worseT) + { + worst_cost_trial(worst_cost); + if (worseG) + global_worst_cost(worst_cost); + } + } + + StateCenter *Solver::GetState() + { + return &_sc; + } + + void Solver::RefreshState() + { + current_best_solution(best_solution); + current_best_cost(best_cost); + current_worst_cost(worst_cost); + current_average_cost(average_cost); + current_standard_deviation(standard_deviation); + current_time_spent(total_time_spent); + time_spent_trial(time_spent_in_trial); + KeepHistory(best_solution,best_cost,worst_cost,time_spent_in_trial,total_time_spent); + } + + void Solver::RefreshCfgState() + { + for (int i=0;i<params.pool().intra_operators().size();i++) + params.pool().intra_operator(i).RefreshState(_sc); + for (int i=0;i<params.pool().inter_operators().size();i++) + params.pool().inter_operator(i).RefreshState(_sc); + for (int i=0;i<params.pool().selectors().size();i++) + params.pool().selector(i).RefreshState(_sc); + params.RefreshState(_sc); + } + + void Solver::UpdateFromState() + { + best_solution=current_best_solution(); + best_cost=current_best_cost(); + worst_cost=current_worst_cost(); + average_cost=current_average_cost(); + standard_deviation=current_standard_deviation(); + total_time_spent=current_time_spent(); + time_spent_in_trial=time_spent_trial(); + KeepHistory(best_solution,best_cost,worst_cost,time_spent_in_trial,total_time_spent); + } + + void Solver::UpdateFromCfgState() + { + for (int i=0;i<params.pool().intra_operators().size();i++) + params.pool().intra_operator(i).UpdateFromState(_sc); + for (int i=0;i<params.pool().inter_operators().size();i++) + params.pool().inter_operator(i).UpdateFromState(_sc); + for (int i=0;i<params.pool().selectors().size();i++) + params.pool().selector(i).UpdateFromState(_sc); + params.UpdateFromState(_sc); + } + + void Solver::show_state() const + { + cout << endl << " Current State ---------------------------------------------" << endl; +/* cout << endl << "Selection parents -> " << select_parents(); + cout << endl << "Parameter of selection: " << parameter_select_parents(); + cout << endl << "Selection offsprings -> " << select_offprings(); + cout << endl << "Parameter of selection: " << parameter_select_offsprings() << endl; + cout << endl << "Crossover_probability: " << crossover_probability(); + cout << endl << "Mutation_probability: " << mutation_probability(); + cout << endl << "User_Operator_probability: " << user_op_probability(0); + cout << endl << "Migration_rate: " << migration_rate(); + cout << endl << "Migration_size: " << migration_size(); + cout << endl << "Migration_selection_1: " << migration_selection_1(); + cout << endl << "Migration_selection_conf_1: " << migration_selection_conf_1(); + cout << endl << "Migration_selection_2: " << migration_selection_2(); + cout << endl << "Migration_selection_conf_2: " << migration_selection_conf_2() << endl; +*/ cout << endl << "Current trial: " << current_trial(); + cout << endl << "Current iteration: " << current_iteration(); + cout << endl << "Current evaluations: " << current_evaluations(); + cout << endl << "Current best cost: " << current_best_cost(); + cout << endl << "Current worst cost: " << current_worst_cost(); + cout << endl << "Current Average cost: " << current_average_cost(); + cout << endl << "Current Standard Deviation: " << current_standard_deviation(); + cout << endl << endl << "Trial: "; + cout << endl << "Best cost trial: " << best_cost_trial(); + cout << endl << "Worst cost trial: " << worst_cost_trial(); + cout << endl << "Iteration best found in trial: " << iteration_best_found_in_trial(); + cout << endl << "Time best found trial: " << time_best_found_trial(); + cout << endl << "Time spent in trial: " << time_spent_trial(); + cout << endl << endl << "Global: "; + cout << endl << "Global best cost: " << global_best_cost(); + cout << endl << "Global worst cost: " << global_worst_cost(); + cout << endl << "Trial best found: " << trial_best_found(); + cout << endl << "Iteration best found: " << iteration_best_found(); + cout << endl << "Time best found: " << time_best_found(); +// cout << endl << endl << "Best Solution: " << endl << global_best_solution(); + cout << endl << endl << "Current time spent (so far): " << current_time_spent() << endl; + } + + Solver::~Solver() + { + _sc.removeAll(); + } + +// Solver sequencial ----------------------------------------------------- + + Solver_Seq::Solver_Seq (const Problem& pbm, const SetUpParams& setup) + : Solver(pbm,setup) + { + random_seed(time(0)); + _end_trial=true; + } + + Solver_Seq::~Solver_Seq () + {} + + void Solver_Seq::StartUp() + { + Population pop(problem,params); + pop.initialize(); + StartUp(pop); + } + + void Solver_Seq::StartUp(const Population& pop) + { + start_trial=_used_time(); + start_global=total_time_spent; + + current_trial(current_trial()+1); + current_iteration(0); + current_evaluations(pop.evaluations()); + + // initialize state variables in the current trial + + Solution initial_solution(problem); + + time_spent_in_trial=0.0; + best_cost_trial((-1) * problem.direction() * infinity()); + worst_cost_trial((-1) * best_cost_trial()); + best_solution_trial(initial_solution); + time_best_found_trial(0.0); + + current_population=pop; + current_population.evaluate_parents(); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + UpdateFromCfgState(); + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + void Solver_Seq::DoStep() + { + + current_iteration(current_iteration()+1); + current_population.evolution(); + current_evaluations(current_population.evaluations()); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + if( (current_iteration() % params.refresh_global_state()) == 0) + UpdateFromCfgState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + void Solver_Seq::run () + { + while (current_trial() < params.independent_runs() ) + run(params.nb_evolution_steps()); + } + + void Solver_Seq::run (const unsigned long int nb_generations) + { + StartUp(); + while ((current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + + } + + void Solver_Seq::run (const Population& pop,const unsigned long int nb_generations) + { + StartUp(pop); + while ((current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + + } + + // Solver LAN ------------------------------------------------------------ + + Solver_Lan::Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0),acum_iterations(0) + { + + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + // random_seed(time(0) + (mypid+1)); + } + + Solver_Lan::~Solver_Lan () + { + NetStream::finalize(); + } + + int Solver_Lan::pid() const + { + return mypid; + } + + NetStream& Solver_Lan::netstream() + { + return _netstream; + } + + void Solver_Lan::StartUp() + { + Population pop(problem,params); + pop.initialize(); + StartUp(pop); + } + + void Solver_Lan::StartUp(const Population& pop) + { + _netstream << barrier; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + acum_iterations = 0; + + start_trial=_used_time(); + start_global=total_time_spent; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + current_evaluations(pop.evaluations()); + + // initialize state variables in the current trial + + Solution initial_solution(problem); + + time_spent_in_trial=0.0; + best_cost_trial((-1) * problem.direction() * infinity()); + worst_cost_trial((-1) * best_cost_trial()); + best_solution_trial(initial_solution); + iteration_best_found_in_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current_population=pop; + current_population.evaluate_parents(); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + } + } + + void Solver_Lan::DoStep() + { + current_iteration(current_iteration()+1); + current_population.evolution(); + current_evaluations(current_population.evaluations()); + + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(regular, pending); + if(pending) + final_phase = true; + //////////////////////// + + current_population.interchange(current_iteration(),_netstream); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + // in this iteration i have to send data about my local state to the global state + if ((int)current_iteration() % params.refresh_global_state() ==0) + { + send_local_state_to(mypid); + UpdateFromCfgState(); + } + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + + + void Solver_Lan::send_local_state_to(int _mypid) { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_evaluations() + << best_solution_trial() + << current_best_solution() + << best_cost_trial() + << worst_cost_trial() + << time_best_found_trial() + << current_best_cost() + << current_worst_cost() + << current_average_cost() + << current_standard_deviation() + << iteration_best_found_in_trial() + << evaluations_best_found_in_trial() + << pack_end; + } + + int Solver_Lan::receive_local_state() { + int r_pid=0; + + _netstream._wait(packed); + + _netstream << pack_begin + >> r_pid + >> _current_trial + >> _current_iteration + >> _current_evaluations + >> _best_solution_trial + >> best_solution + >> _best_cost_trial + >> _worst_cost_trial + >> _time_best_found_in_trial + >> best_cost + >> worst_cost + >> average_cost + >> standard_deviation + >> _iteration_best_found_in_trial + >> _evaluations_best_found_in_trial + << pack_end; + return r_pid; + } + + void Solver_Lan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + _netstream << set_source(MPI_ANY_SOURCE); + + while (!_end_trial) + { + received_pid=0; + received_pid=receive_local_state(); + + current_trial(_current_trial); + + // refresh the global state with received data ( a local state ) + current_iteration(_iteration_best_found_in_trial); + current_evaluations(_evaluations_best_found_in_trial); + KeepHistory(_best_solution_trial,_best_cost_trial,_worst_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + // the process that has send data has finished the current trial + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && terminateQ(problem,*this,params)) + { + acum_iterations = params.nb_evolution_steps() * nb_finalized_processes; + acum_evaluations = acum_iterations* params.population_size() + + nb_finalized_processes*params.population_size(); + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << 1; + } + final_phase = true; + } + nb_finalized_processes++; + acum_iterations += _iteration_best_found_in_trial; + acum_evaluations += _evaluations_best_found_in_trial; + } + if (nb_finalized_processes==nb_proc-1) + _end_trial=true; + + current_iteration(_current_iteration); + current_evaluations(_current_evaluations); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + RefreshState(); + RefreshCfgState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualizaci�n de las estad�sticas // Termination phase // + iteration_best_found_in_trial(acum_iterations/(_netstream.pnumber()-1)); + evaluations_best_found_in_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = best_cost_trial(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + { + iteration_best_found(iteration_best_found_in_trial()); + evaluations_best_found(evaluations_best_found_in_trial()); + } + + RefreshState(); + RefreshCfgState(); + + _stat.update(*this); + _userstat.update(*this); + + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Lan::run () + { + while (current_trial() < params.independent_runs()) + run(params.nb_evolution_steps()); + } + + void Solver_Lan::run (const unsigned long int nb_generations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Population& pop,const unsigned long int nb_generations) + { + StartUp(pop); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::reset() + { + Solution left_solution(problem); + int i; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> i; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } + + // Solver WAN ------------------------------------------------------------ + + Solver_Wan::Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0),acum_iterations(0) + { + + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + // random_seed(time(0) + (mypid+1)); + } + + Solver_Wan::~Solver_Wan () + { + NetStream::finalize(); + } + + int Solver_Wan::pid() const + { + return mypid; + } + + NetStream& Solver_Wan::netstream() + { + return _netstream; + } + + void Solver_Wan::StartUp() + { + Population pop(problem,params); + pop.initialize(); + StartUp(pop); + } + + void Solver_Wan::StartUp(const Population& pop) + { + _netstream << barrier; + + // Termination phase // + final_phase = false; + acum_evaluations = 0; + acum_iterations = 0; + + start_trial=_used_time(); + start_global=total_time_spent; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + current_evaluations(pop.evaluations()); + + // initialize state variables in the current trial + + Solution initial_solution(problem); + + time_spent_in_trial=0.0; + best_cost_trial((-1) * problem.direction() * infinity()); + worst_cost_trial((-1) * best_cost_trial()); + best_solution_trial(initial_solution); + iteration_best_found_in_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current_population=pop; + current_population.evaluate_parents(); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + } + } + + void Solver_Wan::DoStep() + { + current_iteration(current_iteration()+1); + current_population.evolution(); + current_evaluations(current_population.evaluations()); + + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(regular, pending); + if(pending) + final_phase = true; + //////////////////////// + + current_population.interchange(current_iteration(),_netstream); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + // in this iteration i have to send data about my local state to the global state + if ((int)current_iteration() % params.refresh_global_state() ==0) + { + send_local_state_to(mypid); + UpdateFromCfgState(); + } + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + + + void Solver_Wan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_evaluations() + << best_cost_trial() + << best_solution_trial() + << iteration_best_found_in_trial() + << evaluations_best_found_in_trial() + << time_best_found_trial() + << worst_cost_trial() + << current_best_cost() + << current_best_solution() + << current_worst_cost() + << current_average_cost() + << current_standard_deviation() + << pack_end; + } + + int Solver_Wan::receive_local_state() + { + int r_pid=0; + + _netstream._wait(packed); + + _netstream << pack_begin + >> r_pid + >> _current_trial + >> _current_iteration + >> _current_evaluations + >> _best_cost_trial + >> _best_solution_trial + >> _iteration_best_found_in_trial + >> _evaluations_best_found_in_trial + >> _time_best_found_in_trial + >> _worst_cost_trial + >> best_cost + >> best_solution + >> worst_cost + >> average_cost + >> standard_deviation + << pack_end; + return r_pid; + } + + void Solver_Wan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + _netstream << set_source(MPI_ANY_SOURCE); + + while (!_end_trial) + { + received_pid=0; + received_pid=receive_local_state(); + + current_trial(_current_trial); + + // refresh the global state with received data ( a local state ) + current_iteration(_iteration_best_found_in_trial); + current_evaluations(_evaluations_best_found_in_trial); + KeepHistory(_best_solution_trial,_best_cost_trial,_worst_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + // the process that has send data has finished the current trial + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && terminateQ(problem,*this,params)) + { + acum_iterations = params.nb_evolution_steps() * nb_finalized_processes; + acum_evaluations = acum_iterations* params.population_size() + + nb_finalized_processes*params.population_size(); + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << 1; + } + final_phase = true; + } + nb_finalized_processes++; + acum_iterations += _iteration_best_found_in_trial; + acum_evaluations += _evaluations_best_found_in_trial; + } + if (nb_finalized_processes==nb_proc-1) + _end_trial=true; + + current_iteration(_current_iteration); + current_evaluations(_current_evaluations); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + RefreshState(); + RefreshCfgState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Update Stats // Termination phase // + iteration_best_found_in_trial(acum_iterations/(_netstream.pnumber()-1)); + evaluations_best_found_in_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = best_cost_trial(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + { + iteration_best_found(iteration_best_found_in_trial()); + evaluations_best_found(evaluations_best_found_in_trial()); + } + + RefreshState(); + RefreshCfgState(); + + _stat.update(*this); + _userstat.update(*this); + + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Wan::run () + { + while (current_trial() < params.independent_runs()) + run(params.nb_evolution_steps()); + } + + void Solver_Wan::run (const unsigned long int nb_generations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Population& pop,const unsigned long int nb_generations) + { + StartUp(pop); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::reset() + { + Solution left_solution(problem); + int i; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> i; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + + } + _netstream << barrier; + } + +} + + diff --git a/ProyectoFinal/CHC/malva/rep/CHC/CHC.pro.o b/ProyectoFinal/CHC/malva/rep/CHC/CHC.pro.o new file mode 100644 index 0000000000000000000000000000000000000000..41f66470a6785a1cd1b0639260dbc9f227f6ad39 Binary files /dev/null and b/ProyectoFinal/CHC/malva/rep/CHC/CHC.pro.o differ diff --git a/ProyectoFinal/CHC/malva/rep/CHC/CHC.req.cc b/ProyectoFinal/CHC/malva/rep/CHC/CHC.req.cc new file mode 100644 index 0000000000000000000000000000000000000000..df05c01fec88760531488a5f2bb22cb7abd1e435 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/CHC/CHC.req.cc @@ -0,0 +1,332 @@ +#ifndef INC_REQ_CHC +#define INC_REQ_CHC +#include "CHC.hh" +#include <math.h> + +skeleton CHC +{ + + // Problem --------------------------------------------------------------- + + Problem::Problem ():_dimension(0) + {} + + ostream& operator<< (ostream& os, const Problem& pbm) + { + os << endl << endl << "Number of Variables " << pbm._dimension + << endl; + return os; + } + + istream& operator>> (istream& is, Problem& pbm) + { + char buffer[MAX_BUFFER]; + int i; + + is.getline(buffer,MAX_BUFFER,'\n'); + sscanf(buffer,"%d",&pbm._dimension); + + return is; + } + + Problem& Problem::operator= (const Problem& pbm) + { + return *this; + } + + bool Problem::operator== (const Problem& pbm) const + { + if (_dimension!=pbm.dimension()) return false; + return true; + } + + bool Problem::operator!= (const Problem& pbm) const + { + return !(*this == pbm); + } + + Direction Problem::direction() const + { + return maximize; + //return minimize; + } + + int Problem::dimension() const + { + return _dimension; + } + + Problem::~Problem() + {} + + // Solution -------------------------------------------------------------- + + Solution::Solution (const Problem& pbm):_pbm(pbm),_var(pbm.dimension()) + {} + + + const Problem& Solution::pbm() const + { + return _pbm; + } + + Solution::Solution(const Solution& sol):_pbm(sol.pbm()) + { + *this=sol; + } + + + istream& operator>> (istream& is, Solution& sol) + { + for (int i=0;i<sol.pbm().dimension();i++) + is >> sol._var[i]; + + return is; + } + + ostream& operator<< (ostream& os, const Solution& sol) + { + for (int i=0;i<sol.pbm().dimension();i++) + os << " " << sol._var[i]; + return os; + } + + NetStream& operator << (NetStream& ns, const Solution& sol) + { + for (int i=0;i<sol._var.size();i++) + ns << sol._var[i]; + return ns; + } + + + NetStream& operator >> (NetStream& ns, Solution& sol) + { + for (int i=0;i<sol._var.size();i++) + ns >> sol._var[i]; + return ns; + } + + + Solution& Solution::operator= (const Solution &sol) + { + _var=sol._var; + return *this; + } + + + bool Solution::operator== (const Solution& sol) const + { + if (sol.pbm() != _pbm) return false; + return true; + } + + bool Solution::operator!= (const Solution& sol) const + { + return !(*this == sol); + } + + void Solution::initialize() + { + for (int i=0;i<_pbm.dimension();i++) + _var[i]=rand_int(0,1); + } + + + double Solution::fitness () const + { + double fitness = 0.0; + + if(_var[0] == 2) return 0.0; + + for (int i=0;i<_var.size();i++) + fitness += _var[i]; + + return fitness; + } + + + char *Solution::to_String() const + { + return (char *)_var.get_first(); + } + + + void Solution::to_Solution(char *_string_) + { + int *ptr=(int *)_string_; + for (int i=0;i<_pbm.dimension();i++) + { + _var[i]=*ptr; + ptr++; + } + } + + unsigned int Solution::size() const + { + return (_pbm.dimension() * sizeof(int)); + } + + int Solution::lengthInBits() const + { + return _pbm.dimension(); + } + + void Solution::flip(const int index) + { + _var[index] = 1 - _var[index]; + } + + bool Solution::equalb(const int index,Solution &s) + { + return _var[index] == s._var[index]; + } + + void Solution::swap(const int index, Solution &s) + { + int aux = s._var[index]; + s._var[index] = _var[index]; + _var[index] = aux; + } + + void Solution::invalid() + { + _var[0] = 2; + } + + int& Solution::var(const int index) + { + return _var[index]; + } + + + Rarray<int>& Solution::array_var() + { + return _var; + } + + Solution::~Solution() + {} + + // UserStatistics ------------------------------------------------------- + + UserStatistics::UserStatistics () + {} + + ostream& operator<< (ostream& os, const UserStatistics& userstat) + { + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF TRIALS " << endl; + os << "------------------------------------------------------------------" << endl; + + for (int i=0;i< userstat.result_trials.size();i++) + { + os << endl + << userstat.result_trials[i].trial + << "\t" << userstat.result_trials[i].best_cost_trial + << "\t\t" << userstat.result_trials[i].worst_cost_trial + << "\t\t\t" << userstat.result_trials[i].nb_evaluation_best_found_trial + << "\t\t\t" << userstat.result_trials[i].nb_iteration_best_found_trial + << "\t\t\t" << userstat.result_trials[i].time_best_found_trial + << "\t\t" << userstat.result_trials[i].time_spent_trial; + } + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + UserStatistics& UserStatistics::operator= (const UserStatistics& userstats) + { + result_trials=userstats.result_trials; + return (*this); + } + + void UserStatistics::update(const Solver& solver) + { + if( (solver.pid()!=0) || (solver.end_trial()!=true) + || ((solver.current_iteration()!=solver.setup().nb_evolution_steps()) + && !terminateQ(solver.pbm(),solver,solver.setup()))) + return; + + struct user_stat *new_stat; + + if ((new_stat=(struct user_stat *)malloc(sizeof(struct user_stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluation_best_found_trial = solver.evaluations_best_found_in_trial(); + new_stat->nb_iteration_best_found_trial = solver.iteration_best_found_in_trial(); + new_stat->worst_cost_trial = solver.worst_cost_trial(); + new_stat->best_cost_trial = solver.best_cost_trial(); + new_stat->time_best_found_trial = solver.time_best_found_trial(); + new_stat->time_spent_trial = solver.time_spent_trial(); + + result_trials.append(*new_stat); + } + + void UserStatistics::clear() + { + result_trials.remove(); + } + + UserStatistics::~UserStatistics() + { + result_trials.remove(); + } + + // User_Operator:Intra_operator --------------------------------------------------------- + + User_Operator::User_Operator(const unsigned int _number_op):Intra_Operator(_number_op) + {} + + void User_Operator::execute(Rarray<Solution*>& sols) const + {} + + void User_Operator::setup(char line[MAX_BUFFER]) + {} + + Intra_Operator *User_Operator::create(const unsigned int _number_op) + { + return new User_Operator(_number_op); + } + + ostream& operator<< (ostream& os, const User_Operator& u_op) + { + os << "User Operator."; + return os; + } + + void User_Operator::RefreshState(const StateCenter& _sc) const + {} + + void User_Operator::UpdateFromState(const StateCenter& _sc) + {} + + User_Operator::~User_Operator() + {} + + +// StopCondition_1 ------------------------------------------------------------------------------------- + + StopCondition_1::StopCondition_1():StopCondition() + {} + + bool StopCondition_1::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return ((int)solver.best_cost_trial() == pbm.dimension()); + } + + StopCondition_1::~StopCondition_1() + {} + + + //------------------------------------------------------------------------ + // Specific methods ------------------------------------------------------ + //------------------------------------------------------------------------ + + bool terminateQ (const Problem& pbm, const Solver& solver, + const SetUpParams& setup) + { + StopCondition_1 stop; + return stop.EvaluateCondition(pbm,solver,setup); + } +} +#endif + diff --git a/ProyectoFinal/CHC/malva/rep/CHC/CHC.req.o b/ProyectoFinal/CHC/malva/rep/CHC/CHC.req.o new file mode 100644 index 0000000000000000000000000000000000000000..5120ba4992fe5f72ea6118d14c689c490b673b40 Binary files /dev/null and b/ProyectoFinal/CHC/malva/rep/CHC/CHC.req.o differ diff --git a/ProyectoFinal/CHC/malva/rep/CHC/CHCstructures.hh b/ProyectoFinal/CHC/malva/rep/CHC/CHCstructures.hh new file mode 100644 index 0000000000000000000000000000000000000000..70aba854025619b1cfde91817e9f99ef79c108a6 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/CHC/CHCstructures.hh @@ -0,0 +1,29 @@ +#ifndef INC_CHC_mallba_hh +#define INC_CHC_mallba_hh + +#include <iostream> +#include <fstream> +#include <math.h> +#include <limits.h> +#include <float.h> +#include <Rlist.h> +#include <Rarray.h> +#include <Messages.h> +#include <mallba.hh> +#include <States.hh> +#include <random.hh> +#include <time.hh> +#include <netstream.hh> +#include <assert.h> + +using namespace std; + +struct individual // index of a individual in the population and its fitness +{ + int index; + double fitness; + double sel_parameter; + bool change; +}; + +#endif diff --git a/ProyectoFinal/CHC/malva/rep/CHC/Config.cfg b/ProyectoFinal/CHC/malva/rep/CHC/Config.cfg new file mode 100644 index 0000000000000000000000000000000000000000..b34042ed91bb7878723705342d69af63f13dec97 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/CHC/Config.cfg @@ -0,0 +1,3 @@ +CHC.cfg +../../ProblemInstances/ONEMAX-instances/onemax10.txt +res/om10.chc.lan.txt diff --git a/ProyectoFinal/CHC/malva/rep/CHC/MainLan b/ProyectoFinal/CHC/malva/rep/CHC/MainLan new file mode 100644 index 0000000000000000000000000000000000000000..f71c6e405ea5e9ef5a0fe9ad9c3c33807afa6d2a Binary files /dev/null and b/ProyectoFinal/CHC/malva/rep/CHC/MainLan differ diff --git a/ProyectoFinal/CHC/malva/rep/CHC/MainLan.cc b/ProyectoFinal/CHC/malva/rep/CHC/MainLan.cc new file mode 100644 index 0000000000000000000000000000000000000000..279b550e51fff6cd85ba1fb85ade32eccef30a4d --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/CHC/MainLan.cc @@ -0,0 +1,49 @@ +#include <iostream> +#include <fstream> +#include "CHC.hh" + +using namespace std; + +int main (int argc, char** argv) +{ + using skeleton CHC; + char path[MAX_BUFFER] = ""; + + system("clear"); + + strcat(path,argv[1]); + ifstream f(path); + if(!f) show_message(10); + + f.getline(path,MAX_BUFFER,'\n'); + ifstream f1(path); + if(!f1) show_message(11); + + f.getline(path,MAX_BUFFER,'\n'); + ifstream f2(path); + if(!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + Operator_Pool pool(pbm); + SetUpParams cfg(pool); + f1 >> cfg; + + Solver_Lan solver(pbm,cfg,argc,argv); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solucion: " << solver.global_best_solution() << " Fitness: " << solver.global_best_solution().fitness(); + + f.getline(path,MAX_BUFFER,'\n'); + ofstream fexit(path); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + cout << endl << endl << " :( ---------------------- THE END --------------- :) " << endl; + } + return(0); +} diff --git a/ProyectoFinal/CHC/malva/rep/CHC/MainLan.o b/ProyectoFinal/CHC/malva/rep/CHC/MainLan.o new file mode 100644 index 0000000000000000000000000000000000000000..719588ecb004d2c7131a859e6905d3a50cbaa302 Binary files /dev/null and b/ProyectoFinal/CHC/malva/rep/CHC/MainLan.o differ diff --git a/ProyectoFinal/CHC/malva/rep/CHC/MainSeq b/ProyectoFinal/CHC/malva/rep/CHC/MainSeq new file mode 100644 index 0000000000000000000000000000000000000000..eb6ade233d92ae2f16601f662f46bad816b80747 Binary files /dev/null and b/ProyectoFinal/CHC/malva/rep/CHC/MainSeq differ diff --git a/ProyectoFinal/CHC/malva/rep/CHC/MainSeq.cc b/ProyectoFinal/CHC/malva/rep/CHC/MainSeq.cc new file mode 100644 index 0000000000000000000000000000000000000000..4c291f8536235167c501b779e8c92cc95536233f --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/CHC/MainSeq.cc @@ -0,0 +1,43 @@ +#include <iostream> +#include <fstream> +#include "CHC.hh" + +int main (int argc, char** argv) +{ + using skeleton CHC; + + system("clear"); + + if(argc < 4) + show_message(1); + + ifstream f1(argv[1]); + if (!f1) show_message(11); + + ifstream f2(argv[2]); + if (!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + Operator_Pool pool(pbm); + SetUpParams cfg(pool); + f1 >> cfg; + + Solver_Seq solver(pbm,cfg); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solution" << solver.global_best_solution() << endl + << " Fitness: " << solver.global_best_solution().fitness() << endl; + cout << "\n\n :( ---------------------- THE END --------------- :) "; + + ofstream fexit(argv[3]); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + } + return(0); +} diff --git a/ProyectoFinal/CHC/malva/rep/CHC/MainSeq.o b/ProyectoFinal/CHC/malva/rep/CHC/MainSeq.o new file mode 100644 index 0000000000000000000000000000000000000000..2f4acd33d6c1a0632a10acbd32adcc384510244b Binary files /dev/null and b/ProyectoFinal/CHC/malva/rep/CHC/MainSeq.o differ diff --git a/ProyectoFinal/CHC/malva/rep/CHC/MainWan.cc b/ProyectoFinal/CHC/malva/rep/CHC/MainWan.cc new file mode 100644 index 0000000000000000000000000000000000000000..4ee19e551feb1537b218110610efe0beeaeda53f --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/CHC/MainWan.cc @@ -0,0 +1,52 @@ +#include "CHC.hh" + +int main (int argc, char** argv) +{ + using skeleton CHC; + char path[MAX_BUFFER]; + int len; + int longitud; + + system("clear"); + + get_path(argv[0],path); + len = strlen(path); + longitud = MAX_BUFFER - len; + + strcat(path,"Config.cfg"); + ifstream f(path); + if(!f) show_message(10); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f1(path); + if(!f1) show_message(11); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f2(path); + if(!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + Operator_Pool pool(pbm); + SetUpParams cfg(pool); + f1 >> cfg; + + + Solver_Lan solver(pbm,cfg,argc,argv); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solucion: " << solver.global_best_solution() << " Fitness: " << solver.global_best_solution().fitness(); + + f.getline(&(path[len]),longitud,'\n'); + ofstream fexit(path); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + cout << endl << endl << " :( ---------------------- THE END --------------- :) " << endl; + } + return(0); +} diff --git a/ProyectoFinal/CHC/malva/rep/CHC/Makefile b/ProyectoFinal/CHC/malva/rep/CHC/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..3225d38fd55374c615954159aa5522c857cfa145 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/CHC/Makefile @@ -0,0 +1,24 @@ +include ../../environment + +all: MainSeq MainLan + +clean: + rm -f MainLan MainSeq *.o *% *~ + +MainSeq: CHC.req.o CHC.pro.o MainSeq.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainLan: CHC.req.o CHC.pro.o MainLan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainWan: CHC.req.o CHC.pro.o MainWan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +LAN: + $(RUN) -np 10 ./MainLan Config.cfg + +WAN: + $(RUN) -v -p4pg pgfileWan MainWan + +SEQ: + ./MainSeq CHC.cfg ../../ProblemInstances/ONEMAX-instances/onemax10.txt res/sol.txt diff --git a/ProyectoFinal/CHC/malva/rep/CHC/res/empty.txt b/ProyectoFinal/CHC/malva/rep/CHC/res/empty.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ProyectoFinal/CHC/malva/rep/GA/Config.cfg b/ProyectoFinal/CHC/malva/rep/GA/Config.cfg new file mode 100644 index 0000000000000000000000000000000000000000..ad19d328a359ff31b8991f4f76696811bb90321e --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/GA/Config.cfg @@ -0,0 +1,3 @@ +newGA.cfg +../../ProblemInstances/ONEMAX-instances/onemax10.txt +res/om10.newga.lan.txt diff --git a/ProyectoFinal/CHC/malva/rep/GA/MainLan b/ProyectoFinal/CHC/malva/rep/GA/MainLan new file mode 100644 index 0000000000000000000000000000000000000000..4412f1cad77b8b6332c1c698973a12e75d51ddba Binary files /dev/null and b/ProyectoFinal/CHC/malva/rep/GA/MainLan differ diff --git a/ProyectoFinal/CHC/malva/rep/GA/MainLan.cc b/ProyectoFinal/CHC/malva/rep/GA/MainLan.cc new file mode 100644 index 0000000000000000000000000000000000000000..494e82e0c3d235cd88c33a595277af29f7f4e148 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/GA/MainLan.cc @@ -0,0 +1,53 @@ +#include "newGA.hh" + +int main (int argc, char** argv) +{ + using skeleton newGA; + + char path[MAX_BUFFER]; + int len; + int longitud; + + system("clear"); + + get_path(argv[0],path); + len = strlen(path); + longitud = MAX_BUFFER - len; + + strcat(path,"Config.cfg"); + ifstream f(path); + if(!f) show_message(10); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f1(path); + if(!f1) show_message(11); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f2(path); + if(!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + Operator_Pool pool(pbm); + SetUpParams cfg(pool); + f1 >> cfg; + + + Solver_Lan solver(pbm,cfg,argc,argv); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solution: " << solver.global_best_solution() << " Fitness: " << solver.global_best_solution().fitness(); + + f.getline(&(path[len]),longitud,'\n'); + ofstream fexit(path); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + cout << endl << endl << " :( ---------------------- THE END --------------- :) " << endl; + } + return(0); +} diff --git a/ProyectoFinal/CHC/malva/rep/GA/MainLan.o b/ProyectoFinal/CHC/malva/rep/GA/MainLan.o new file mode 100644 index 0000000000000000000000000000000000000000..9385dd20caa64bf3c0a87783a4225bf3b2e79568 Binary files /dev/null and b/ProyectoFinal/CHC/malva/rep/GA/MainLan.o differ diff --git a/ProyectoFinal/CHC/malva/rep/GA/MainSeq b/ProyectoFinal/CHC/malva/rep/GA/MainSeq new file mode 100644 index 0000000000000000000000000000000000000000..da4383cc2eb7ad38bb626ee134b3475b21c1aae0 Binary files /dev/null and b/ProyectoFinal/CHC/malva/rep/GA/MainSeq differ diff --git a/ProyectoFinal/CHC/malva/rep/GA/MainSeq.cc b/ProyectoFinal/CHC/malva/rep/GA/MainSeq.cc new file mode 100644 index 0000000000000000000000000000000000000000..d4a7c14ce97eeaa129e3f34238fa18ec8972cede --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/GA/MainSeq.cc @@ -0,0 +1,41 @@ +#include "newGA.hh" + +int main (int argc, char** argv) +{ + using skeleton newGA; + + system("clear"); + + if(argc < 4) + show_message(1); + + ifstream f1(argv[1]); + if (!f1) show_message(11); + + ifstream f2(argv[2]); + if (!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + Operator_Pool pool(pbm); + SetUpParams cfg(pool); + f1 >> cfg; + + Solver_Seq solver(pbm,cfg); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solution: " << solver.global_best_solution() + << " Fitness: " << solver.global_best_solution().fitness() << endl; + cout << "\n\n :( ---------------------- THE END --------------- :) "; + + ofstream fexit(argv[3]); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + } + return(0); +} diff --git a/ProyectoFinal/CHC/malva/rep/GA/MainSeq.o b/ProyectoFinal/CHC/malva/rep/GA/MainSeq.o new file mode 100644 index 0000000000000000000000000000000000000000..155133b817cf52480267b552dd709539a640c87c Binary files /dev/null and b/ProyectoFinal/CHC/malva/rep/GA/MainSeq.o differ diff --git a/ProyectoFinal/CHC/malva/rep/GA/Makefile b/ProyectoFinal/CHC/malva/rep/GA/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..71b1892f1c23a348b3791c8361321077fe48e29c --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/GA/Makefile @@ -0,0 +1,24 @@ +include ../../environment + +all: MainLan MainSeq + +clean: + rm -f MainLan MainSeq MainWan *.o *% *~ + +MainLan: newGA.req.o newGA.pro.o MainLan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainWan: newGA.req.o newGA.pro.o MainWan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainSeq: newGA.req.o newGA.pro.o MainSeq.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +LAN: + $(RUN) -np 10 ./MainLan Config.cfg + +WAN: + $(RUN) -v -p4pg pgfileWan MainWan + +SEQ: + ./MainSeq newGA.cfg ../../ProblemInstances/ONEMAX-instances/onemax10.txt res/sol.txt \ No newline at end of file diff --git a/ProyectoFinal/CHC/malva/rep/GA/asignacion_colores.csv b/ProyectoFinal/CHC/malva/rep/GA/asignacion_colores.csv new file mode 100644 index 0000000000000000000000000000000000000000..83840363d469cec56434d0f6c25e841eb42688df --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/GA/asignacion_colores.csv @@ -0,0 +1,10 @@ +1,5 +2,5 +3,5 +4,5 +5,5 +6,5 +7,5 +8,0 +9,4 +10,4 diff --git a/ProyectoFinal/CHC/malva/rep/GA/datos_cantidad_empleados b/ProyectoFinal/CHC/malva/rep/GA/datos_cantidad_empleados new file mode 100644 index 0000000000000000000000000000000000000000..7813681f5b41c028345ca62a2be376bae70b7f61 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/GA/datos_cantidad_empleados @@ -0,0 +1 @@ +5 \ No newline at end of file diff --git a/ProyectoFinal/CHC/malva/rep/GA/datos_cantidad_tareas b/ProyectoFinal/CHC/malva/rep/GA/datos_cantidad_tareas new file mode 100644 index 0000000000000000000000000000000000000000..301160a93062df23030a69f4b5e4d9bf71866ee9 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/GA/datos_cantidad_tareas @@ -0,0 +1 @@ +8 \ No newline at end of file diff --git a/ProyectoFinal/CHC/malva/rep/GA/datos_empleados b/ProyectoFinal/CHC/malva/rep/GA/datos_empleados new file mode 100644 index 0000000000000000000000000000000000000000..f7cc5e5ffd3d2a61ae5180d3f7da918b35f73197 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/GA/datos_empleados @@ -0,0 +1,4 @@ +e1 e2 e3 e4 e5 +4 5 5 3 3 +0.05 0.20 0.30 0.95 0.50 +120 200 210 230 180 diff --git a/ProyectoFinal/CHC/malva/rep/GA/datos_tareas b/ProyectoFinal/CHC/malva/rep/GA/datos_tareas new file mode 100644 index 0000000000000000000000000000000000000000..589272f5c15492f95741ff1b7c8bd9669e9d4993 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/GA/datos_tareas @@ -0,0 +1,3 @@ +20 +t1 t2 t3 t4 t5 t6 t7 t8 +16 28 11 51 2 23 43 15 diff --git a/ProyectoFinal/CHC/malva/rep/GA/ejercicio2.py b/ProyectoFinal/CHC/malva/rep/GA/ejercicio2.py new file mode 100644 index 0000000000000000000000000000000000000000..6705a027263a0079907ffb4f8b9905db20c4001a --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/GA/ejercicio2.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import sys +import random +import math +import os + +try: + #Sanity check + if (len(sys.argv)<4): + print "Ejecutar con la siguiente linea: ./ejercicio2 <ruta_tareas> <ruta_empleados> <ruta_solucion>" + sys.exit(1) + + ruta_tareas=sys.argv[1] + ruta_empleados=sys.argv[2] + ruta_solucion=sys.argv[3] + + os.system("make clean") + os.system("make all") + os.system("make SEQ") + + #os.system("python verificador.py " + ruta_tareas + " " + ruta_empleados + " " + ruta_solucion) + + """ + habilidad_empleados=[] + sueldo_diario_empleado=[] + dedicacion_diaria_diponible_empleado=[] + esfuerzo_requerido_tarea=[] + nombres_tareas=[] + nombre_empleados=[] + costo_proyecto=0 + tiempo_solucion_proyecto=0 + + # se sabe que son 3 lineas + archivo_tareas=open(ruta_tareas) + lineasTareas=archivo_tareas.readlines() + deadLine=lineasTareas[0] + nombres_tareas=lineasTareas[1].strip().split(" ") + esfuerzo_requerido_tarea=lineasTareas[2].strip().split(" ") + + # se sabe que son 4 lineas + archivo_empleados=open(ruta_empleados) + lineasEmpleados=archivo_empleados.readlines() + nombre_empleados=lineasEmpleados[0].strip().split(" ") + dedicacion_diaria_diponible_empleado=lineasEmpleados[1].strip().split(" ") + habilidad_empleados=lineasEmpleados[2].strip().split(" ") + sueldo_diario_empleado=lineasEmpleados[3].strip().split(" ") + + # se convierten a entero + dedicacion_diaria_diponible_empleado = map(int, dedicacion_diaria_diponible_empleado) + sueldo_diario_empleado = map(int, sueldo_diario_empleado) + deadLine=int(deadLine) + esfuerzo_requerido_tarea = map(int, esfuerzo_requerido_tarea) + + # se convierte a float + habilidad_empleados = map(float, habilidad_empleados) + + # se levanta la solucion del archivo + matriz_solucion=[] + + archivo_solucion=open(ruta_solucion) + + solucion_empleados_tareas=[] + solucion_empleados=[] + solucion_tareas=[] + + for line in archivo_solucion.readlines(): + empleados_tareas=line.strip().split(" ") + if( not (empleados_tareas[0] in nombre_empleados)): + print "No existe en la instancia el empleado: " + empleados_tareas[0] + sys.exit(1) + solucion_empleados.append(empleados_tareas[0]) + for i in range(1,len(empleados_tareas)): + if( not (empleados_tareas[i] in nombres_tareas)): + print "No existe en la instancia la terea: " + empleados_tareas[i] + sys.exit(1) + solucion_tareas.append(empleados_tareas[i]) + + + for i in range(0,len(solucion_empleados)): + for j in range(i+1,len(solucion_empleados)): + if(solucion_empleados[i]==solucion_empleados[j]): + print "Empleado repetido: " + solucion_empleados[i] + sys.exit(1) + + for i in range(0,len(solucion_tareas)): + for j in range(i+1,len(solucion_tareas)): + if(solucion_tareas[i]==solucion_tareas[j]): + print "Tarea asignada más de una vez: " + solucion_tareas[i] + sys.exit(1) + + + # todas las tareas asignadas + if(len(solucion_tareas)!=len(nombres_tareas)): + print "La cantidad de tareas asignadas es distinta a la cantidad de tareas de la instancia." + sys.exit(1) + + for i in range(0,len(nombres_tareas)): + if( not (nombres_tareas[i] in solucion_tareas)): + print "Tarea no asignada " + nombres_tareas[i] + sys.exit(1) + + costo_total=0 + archivo_solucion=open(ruta_solucion) + maximo_tiempo=0 + tiempo_en_dias=0 + # se hacen los calculos con la informacion en los archivos + for line in archivo_solucion.readlines(): + empleados_tareas=line.strip().split(" ") + indice_empleado = nombre_empleados.index(empleados_tareas[0]) + tiempo_en_horas=0 + for i in range(1,len(empleados_tareas)): + indice_tarea = nombres_tareas.index(empleados_tareas[i]) + tiempo_en_horas=tiempo_en_horas+(esfuerzo_requerido_tarea[indice_tarea] / (0.5 + habilidad_empleados[indice_empleado])) + tiempo_en_dias= int(math.ceil(tiempo_en_horas/dedicacion_diaria_diponible_empleado[indice_empleado])) + costo_total=costo_total+sueldo_diario_empleado[indice_empleado]*tiempo_en_dias + if(tiempo_en_dias>maximo_tiempo): + maximo_tiempo=tiempo_en_dias + + if(maximo_tiempo<=deadLine): + # todo OK! + print costo_total,maximo_tiempo + else: + print "No cumple con el tiempo máximo de finalización ({0} > {1}).".format(maximo_tiempo, deadLine) + sys.exit(1) + + """ + +except IOError as error: + print error diff --git a/ProyectoFinal/CHC/malva/rep/GA/generador.py b/ProyectoFinal/CHC/malva/rep/GA/generador.py new file mode 100644 index 0000000000000000000000000000000000000000..c699bd6a516ed41a7dbdc0e2b81d2065bda67dfe --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/GA/generador.py @@ -0,0 +1,143 @@ +import sys +import random +import math +from collections import defaultdict + +try: + #Constantes + mayor_duracion_horas_tarea=200 + menor_duracion_horas_tarea=12 + mayor_disponibilidad_diaria_horas_empleado=10 + menor_disponibilidad_diaria_horas_empleado=1 + sueldo_hora_base_empleado_sin_experiencia=110 + sueldo_valor_maximo_bono_por_buen_empleado_hora=23 + deadline_dias=0 + + #Sanity check + if (len(sys.argv)<4): + print "Ejecutar con la siguiente linea: ./generador <cant_tereas> <cant_empleados> <archivo_salida>" + sys.exit(1) + + cantidad_tareas=int(sys.argv[1]) + cantidad_empleados=int(sys.argv[2]) + archivo_salida=sys.argv[3] + + if (cantidad_tareas<1): + print "La cantidad de tareas debe ser mayor o igual a 1." + sys.exit(1) + + + if (cantidad_empleados<1): + print "La cantidad de empleados debe ser mayor o igual a 1." + sys.exit(1) + + if (cantidad_empleados>cantidad_tareas): + print "La cantidad de empleados debe ser menor a la cantidad de tareas." + sys.exit(1) + + + #VARIABLES: + + #habilidades de los empleados valor entre 0 y 1 + habilidad_empleados=[] + sueldo_semanal_empleado=[] + dedicacion_diaria_diponible_empleado=[] + esfuerzo_requerido_tarea=[] + + for i in range(0,cantidad_empleados): + dedicacion_diaria_diponible_empleado.append(random.randint(menor_disponibilidad_diaria_horas_empleado,mayor_disponibilidad_diaria_horas_empleado)) + + for i in range(0,cantidad_empleados): + habilidad_empleados.append(round(random.uniform(0, 1),2)) + + #los empleados cobran un bono (random) de rendimiento + #empleados con habilidad 0 cobran el sueldo de horas base por la cantidad de horas semanales + #empleados con habilidad mayor a 0 cobran un plus por habilidad proporcional a su habilidad + #empleado con habilidad 1 cobra aproximadamente el doble que el de experiencia 0 + for i in range(0,cantidad_empleados): + bono_por_buen_empleado=random.randint(0,sueldo_valor_maximo_bono_por_buen_empleado_hora) + sueldo_base=sueldo_hora_base_empleado_sin_experiencia+bono_por_buen_empleado + plus_por_experiencia=sueldo_hora_base_empleado_sin_experiencia*habilidad_empleados[i] + sueldo_semanal_empleado.append(int(math.ceil((sueldo_base+plus_por_experiencia)*dedicacion_diaria_diponible_empleado[i]))) + + for i in range(0,cantidad_tareas): + esfuerzo_requerido_tarea.append(random.randint(menor_duracion_horas_tarea,mayor_duracion_horas_tarea)) + + ###################### + #calculo del deadline + ###################### + + + tiempo_ocupado_empleado = {} + for indice_empleado in range(0,cantidad_empleados): + tiempo_ocupado_empleado[indice_empleado]=0 + + tiempo_en_horas=0 + tiempo_en_dias_con_decimales=0 + indice_empleado_menor_tiempo=0 + for indice_tarea in range(0,cantidad_tareas): + minimo_tiempo=sys.float_info.max + for indice_empleado in range(0,cantidad_empleados): + tiempo_en_horas=(esfuerzo_requerido_tarea[indice_tarea] / (0.5 + habilidad_empleados[indice_empleado])) + tiempo_en_dias_con_decimales= tiempo_en_horas/dedicacion_diaria_diponible_empleado[indice_empleado] + tiempo_en_el_que_termina_si_se_le_da_esta_tarea=tiempo_ocupado_empleado[indice_empleado]+tiempo_en_dias_con_decimales + if(tiempo_en_el_que_termina_si_se_le_da_esta_tarea < minimo_tiempo): + indice_empleado_menor_tiempo=indice_empleado + minimo_tiempo=tiempo_en_el_que_termina_si_se_le_da_esta_tarea + tiempo_ocupado_empleado[indice_empleado_menor_tiempo]=minimo_tiempo + + + deadline_dias=0 + #busca maxima duracion + for indice_empleado in range(0,cantidad_empleados): + if(tiempo_ocupado_empleado[indice_empleado]>deadline_dias): + deadline_dias=tiempo_ocupado_empleado[indice_empleado] + + #print tiempo_ocupado_empleado + #se redondean los dias para pagar el dia entero a los que trabajan menos + deadline_dias=int(math.ceil(deadline_dias))*1.2 + + #archivo de salida de empleados + archivo = open ("%s_empleados"%archivo_salida, "w") + archivo.write("e%d"%1) + for i in range(1,cantidad_empleados): + #nombre del empleado + archivo.write(" e%d"%(i+1)) + archivo.write("\n") + archivo.write("%d"%dedicacion_diaria_diponible_empleado[0]) + for i in range(1,cantidad_empleados): + archivo.write(" %d"%dedicacion_diaria_diponible_empleado[i]) + archivo.write("\n") + archivo.write("%.2f"%habilidad_empleados[0]) + for i in range(1,cantidad_empleados): + archivo.write(" %.2f"%habilidad_empleados[i]) + archivo.write("\n") + archivo.write("%d"%sueldo_semanal_empleado[0]) + for i in range(1,cantidad_empleados): + archivo.write(" %d"%sueldo_semanal_empleado[i]) + + #archivo de salida de tareas + archivo = open ("%s_tareas"%archivo_salida, "w") + archivo.write("%d"%deadline_dias) + archivo.write("\n") + archivo.write("t%d"%1) + for i in range(1,cantidad_tareas): + #nombre de la tarea + archivo.write(" t%d"%(i+1)) + archivo.write("\n") + archivo.write("%d"%esfuerzo_requerido_tarea[0]) + for i in range(1,cantidad_tareas): + archivo.write(" %d"%esfuerzo_requerido_tarea[i]) + + + #archivo cantidad de tareas + archivo = open ("%s_cantidad_tareas"%archivo_salida, "w") + archivo.write("%d"%cantidad_tareas) + + #archivo cantidad de trabajos + archivo = open ("%s_cantidad_empleados"%archivo_salida, "w") + archivo.write("%d"%cantidad_empleados) + + +except IOError as error: + print error diff --git a/ProyectoFinal/CHC/malva/rep/GA/newGA.cfg b/ProyectoFinal/CHC/malva/rep/GA/newGA.cfg new file mode 100644 index 0000000000000000000000000000000000000000..c7caf7a288f728c5dade1cf41a5313771d977886 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/GA/newGA.cfg @@ -0,0 +1,18 @@ +10 // number of independent runs +100 // number of generations +60 // number of individuals +100 // size of offsprings in each generation +1 // if replaces parents for offsprings, or only offsprings may be new parents +1 // display state ? +Selections // selections to apply +1 3 // selection of parents +2 0 // selection of offsprings +Intra-Operators // operators to apply in the population +0 0.6 // crossover & its probability +1 1.0 0.01 // mutation & its probability +Inter-Operators // operators to apply between this population and anothers +0 10 5 1 3 1 5 // operator number, operator rate, number of individuals, selection of indidivual to send and remplace +LAN-configuration +1 // refresh global state +0 // 0: running in asynchronized mode / 1: running in synchronized mode +1 // interval of generations to check solutions from other populations diff --git a/ProyectoFinal/CHC/malva/rep/GA/newGA.hh b/ProyectoFinal/CHC/malva/rep/GA/newGA.hh new file mode 100644 index 0000000000000000000000000000000000000000..552b2648923ec9383125099fb7ad87e4f924c4a9 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/GA/newGA.hh @@ -0,0 +1,868 @@ +/********************************************************************************************************* +*** *** +*** new Genetic Algorithm Skeleton v1.5 *** +*** Developed by: Gabriel Jesús Luque Polo *** +*** Last Update: 27-01-2003 *** +*** *** +*** tabular size = 4 *** +**********************************************************************************************************/ + +#ifndef INC_newGA +#define INC_newGA +#include "newGAstructures.hh" + +skeleton newGA +{ +// Si se definen más de 5 nuevos operadores por parte del usuario, se debe cambiar esta constante. +#define MAX_OP_USER 5 +// Si se algún operador tiene más de 5 parámetros se debe modificar esta variable +#define MAX_PROB_PER_OP 5 + + provides class SetUpParams; + provides class Statistics; + provides class Population; + provides class Inter_Operator; + provides class Migration; + provides class Selection; + provides class Selection_Tournament; + provides class Selection_Roulette_Wheel; + provides class Selection_Rank; + provides class Selection_Best; + provides class Selection_Worst; + provides class Operator_Pool; + provides class Solver; + provides class Solver_Seq; + provides class Solver_Lan; + provides class Solver_Wan; + provides class StopCondition; + + requires class Problem; + requires class Solution; + requires class UserStatistics; + requires class Intra_Operator; + requires class Crossover; + requires class Mutation; + requires class StopCondition_1; + requires bool terminateQ (const Problem& pbm, const Solver& solver, const SetUpParams& setup); + +// Problem ---------------------------------------------------------------------------- + + requires class Problem + { + public: + Problem(); + ~Problem(); + + friend ostream& operator<< (ostream& os, const Problem& pbm); + friend istream& operator>> (istream& is, Problem& pbm); + + Problem& operator= (const Problem& pbm); + bool operator== (const Problem& pbm) const; + bool operator!= (const Problem& pbm) const; + + Direction direction () const; + + int cantDias() const; + int cantEmpleados() const; + int dimension() const; + + Empleado * empleados() const; + int * tareasEsf() const; + int * tareasIndex() const; + int ** limite_barrios() const; + const char* getfield(char* line, int num); + + private: + int _cantDias; + Empleado * _empleados; + int * _tareasEsf; + int * _tareasIndex; + int _cantEmpleados; + int _dimension; + int ** _limite_barrios; + }; + +//Solution ---------------------------------------------------------------------------- + + requires class Solution + { + public: + Solution (const Problem& pbm); + Solution (const Solution& sol); + ~Solution(); + + friend ostream& operator<< (ostream& os, const Solution& sol); + friend istream& operator>> (istream& is, Solution& sol); + friend NetStream& operator << (NetStream& ns, const Solution& sol); + friend NetStream& operator >> (NetStream& ns, Solution& sol); + + const Problem& pbm() const; + + Solution& operator= (const Solution& sol); + bool operator== (const Solution& sol) const; + bool operator!= (const Solution& sol) const; + + char *to_String() const; + void to_Solution(char *_cadena_); + + void initialize(); + double fitness (); + unsigned int size() const; + + int& var(const int index); + Rarray<int>& array_var(); + + private: + Rarray<int> _var; + const Problem& _pbm; + }; + +// UserStatistics ---------------------------------------------------------------------------- + + requires class UserStatistics + { + private: + struct user_stat + { + unsigned int trial; + unsigned long nb_evaluation_best_found_trial; + unsigned long nb_iteration_best_found_trial; + double best_cost_trial; + double worst_cost_trial; + float time_best_found_trial; + float time_spent_trial; + }; + + Rlist<struct user_stat> result_trials; + + public: + UserStatistics (); + ~UserStatistics(); + + friend ostream& operator<< (ostream& os, const UserStatistics& usertats); + + UserStatistics& operator= (const UserStatistics& userstats); + void update(const Solver& solver); + void clear(); + }; + +// Intra_Operator ( clase abstracta ) -------------------------------------------------------------- + + requires class Intra_Operator + { + protected: + unsigned int _number_operator; + float *probability; + + public: + Intra_Operator(const unsigned int _number_op); + virtual ~Intra_Operator(); + + static Intra_Operator *create(const unsigned int _number_op); + friend ostream& operator<< (ostream& os, const Intra_Operator& intra); + + virtual void execute(Rarray<Solution*>& sols) const=0; + virtual void setup(char line[MAX_BUFFER]) = 0; + unsigned int number_operator() const; + + virtual void RefreshState(const StateCenter& _sc) const=0; + virtual void UpdateFromState(const StateCenter& _sc)=0; + }; + +// Crossover ---------------------------------------------------------------------------------- + + requires class Crossover: public Intra_Operator + { + public: + Crossover(); + virtual ~Crossover(); + + friend ostream& operator << (ostream& os, const Crossover& cross); + + void cross(Solution &sol1,Solution &sol2) const; + virtual void execute(Rarray<Solution*>& sols) const; + virtual void setup(char line[MAX_BUFFER]); + + virtual void RefreshState(const StateCenter& _sc) const; + virtual void UpdateFromState(const StateCenter& _sc); + }; + +// Mutation ---------------------------------------------------------------------------------- + + requires class Mutation: public Intra_Operator + { + public: + Mutation(); + virtual ~Mutation(); + + friend ostream& operator<< (ostream& os, const Mutation& mutation); + + void mutate(Solution& sol) const; + // applies mutation over all solutions in array sols + virtual void execute(Rarray<Solution*>& sols) const; + virtual void setup(char line[MAX_BUFFER]); + + virtual void RefreshState(const StateCenter& _sc) const; + virtual void UpdateFromState(const StateCenter& _sc); + + }; + +// StopCondition ---------------------------------------------------------------------------------- + provides class StopCondition + { + public: + StopCondition(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup)=0; + ~StopCondition(); + }; + +// StopCondition_1 {subclase------------------------------------------------------------------------- + + requires class StopCondition_1 : public StopCondition + { + public: + StopCondition_1(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_1(); + }; +// SetUpParams ------------------------------------------------------------------------------- + + provides class SetUpParams + { + private: + unsigned int _independent_runs; + unsigned long _nb_evolution_steps; + unsigned int _population_size; // number of individuals + unsigned int _population_additional_size; // size of offspring in each generation + bool _combine; // combines parents and offsprings to select new parents ? + bool _display_state; + + unsigned long _refresh_global_state; + bool _synchronized; + unsigned int _check_asynchronous; + + // selection of parents and offsprings + mutable unsigned int _select_parents; + mutable unsigned int _select_offsprings; + mutable unsigned int _parameter_select_parents; + mutable unsigned int _parameter_select_offsprings; + + Rlist<unsigned int> _intra_operators; + Rlist<unsigned int> _inter_operators; + + Operator_Pool& _pool; + + public: + SetUpParams (Operator_Pool& pool); + Operator_Pool& pool() const; + + friend ostream& operator<< (ostream& os, const SetUpParams& setup); + friend istream& operator>> (istream& is, SetUpParams& setup); + + const unsigned int independent_runs() const; + const unsigned long nb_evolution_steps() const; + const unsigned int population_size() const; + const unsigned int population_additional_size() const; + const bool combine() const; + const bool display_state() const; + const unsigned long refresh_global_state() const; + const bool synchronized() const; + const unsigned int check_asynchronous() const; + + void independent_runs(const unsigned int val); + void nb_evolution_steps(const unsigned long val); + void population_size(const unsigned int val); + void population_additional_size(const unsigned int val); + void combine(const bool val); + void display_state(const bool val); + void refresh_global_state(const unsigned long val); + void synchronized(const bool val); + void check_asynchronous(const unsigned int val); + + // gets the i-th operator of inter-population + const unsigned int inter_operator_index(const unsigned int index) const; + const unsigned int inter_operators_size() const; + + // gets the i-th operator of intra-population + const unsigned int intra_operator_index(const unsigned int index) const; + const unsigned int intra_operators_size() const; + + const unsigned int select_parents() const; + const unsigned int select_offsprings() const; + const unsigned int parameter_select_parents() const; + const unsigned int parameter_select_offsprings() const; + + void select_parents(const unsigned int val); + void select_offsprings(const unsigned int val); + void parameter_select_parents(const unsigned int val); + void parameter_select_offsprings(const unsigned int val); + + void RefreshState(const StateCenter& _sc) const; + void UpdateFromState(const StateCenter& _sc) const; + + ~SetUpParams(); + }; + +// Statistics --------------------------------------------------------------------------------- + + provides class Statistics + { + private: + struct stat + { + unsigned int trial; + unsigned long nb_generation; + unsigned long nb_evaluation; + double best_cost; + double global_best_cost; + double average_cost; + double standard_deviation; + }; + + Rlist<struct stat> stats_data; + + public: + Statistics(); + ~Statistics(); + + friend ostream& operator<< (ostream& os, const Statistics& stats); + + Statistics& operator= (const Statistics& stats); + void update(const Solver& solver); + void clear(); + }; + +// Population --------------------------------------------------------------------------------- + + provides class Population + { + private: + Rarray<Solution*> _parents; // individuals in population + Rarray<Solution*> _offsprings; // offsprings of current population + Rarray<Solution*> _new_parents; // individuals of previous population + Rarray<struct individual> _fitness_values; + Rarray<struct individual> _fitness_aux; + const SetUpParams& _setup; + unsigned int _upper_cost,_lower_cost; // lower and upper fitness of individuals in population + unsigned long _evaluations; + double _average_cost; + + inline void Evaluate(Solution* sols,struct individual &_f); + + public: + Population(const Problem& pbm,const SetUpParams& setup); // crea un array de objetos population; + ~Population(); + + friend ostream& operator<< (ostream& os, const Population& population); + friend istream& operator>> (istream& is, Population& population); + Population& operator= (const Population& pop); + const SetUpParams& setup() const; + void initialize(); + + // Generate a new pool of individuals in population + void evolution(); + + // interchange solutions between island + void interchange(const unsigned long current_generation, NetStream& channel); + + // creates a array with fitness of all individuals in population and its position in the population + void evaluate_parents(); + + // creates a array with fitness of all individuals and offsprings in population and its position in the population + void evaluate_offsprings(); + + // selects parents to creates offsprings + void select_parents(); + + // selects individuals for the new population + void select_offsprings(); + + const Rarray<Solution*>& parents() const; + const Rarray<Solution*>& offsprings() const; + Rarray<struct individual>& fitness_values(); + + unsigned int upper_cost() const; + unsigned int lower_cost() const; + unsigned int evaluations() const; + Solution& solution(const unsigned int index) const; + double fitness(const unsigned int index) const; + + double best_cost() const; + double worst_cost() const; + Solution& best_solution() const; + Solution& worst_solution() const; + double average_cost() const; + double standard_deviation() const; + }; + +// Inter_Operator ( abstract )----------------------------------------------------------- + + provides class Inter_Operator + { + protected: + unsigned int migration_rate; + unsigned int migration_size; + unsigned int migration_selection_1; + unsigned int migration_selection_2; + unsigned int migration_selection_conf_1; + unsigned int migration_selection_conf_2; + + unsigned int _number_operator; + const Direction direction; + + public: + Inter_Operator(const unsigned int _number_op, const Direction dir); + virtual ~Inter_Operator(); + + friend ostream& operator<< (ostream& os, const Inter_Operator& inter); + + virtual void execute(Population& pop,const unsigned long current_generation,NetStream& _netstream,const bool synchronized,const unsigned int check_asyncrhonous) const=0; + virtual void setup(char line[MAX_BUFFER]); + unsigned int number_operator() const; + + virtual void RefreshState(const StateCenter& _sc) const; + virtual void UpdateFromState(const StateCenter& _sc); + }; + +// Migration: public Inter_Operator ----------------------------------------------------------- + + provides class Migration: public Inter_Operator + { + public: + Migration(const Direction dir); + virtual ~Migration(); + + friend ostream& operator<< (ostream& os, const Migration& migration); + + virtual void execute(Population& pop,const unsigned long current_generation,NetStream& _netstream,const bool synchronized,const unsigned int check_asyncrhonous) const; + }; + +// Selection ( Makes a random selection ) ----------------------------------------- + + provides class Selection + { + protected: + unsigned int _number_selection; + const Direction direction; + + public: + + Selection(const Direction dir); + Selection(const unsigned int _number_sel, const Direction dir); + virtual ~Selection(); + + friend ostream& operator<< (ostream& os, const Selection& sel); + + virtual void prepare(Rarray<struct individual>& fitness_values,const bool remplace); // const; + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int dummy,const bool remplace) const; + unsigned int number_selection() const; + }; + +// Selection_Tournament --------------------------------------------------------------------------------- + + provides class Selection_Tournament: public Selection + { + public: + Selection_Tournament(const Direction dir); + virtual ~Selection_Tournament(); + + friend ostream& operator<< (ostream& os, const Selection_Tournament& sel); + + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int tourment_size,const bool remplace) const; + }; + +// Selection_Roulette_Wheel --------------------------------------------------------------------------------- + + provides class Selection_Roulette_Wheel: public Selection + { + public: + Selection_Roulette_Wheel(const Direction); + virtual ~Selection_Roulette_Wheel(); + + friend ostream& operator<< (ostream& os, const Selection_Roulette_Wheel& sel); + + virtual void prepare(Rarray<struct individual>& fitness_values,const bool remplace); // const; + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int dummy,const bool remplace) const; + }; + +// Selection_Rank --------------------------------------------------------------------------------- + + provides class Selection_Rank: public Selection + { + public: + Selection_Rank(const Direction dir); + Selection_Rank(const unsigned int _number_sel, const Direction dir); + virtual ~Selection_Rank(); + + friend ostream& operator<< (ostream& os, const Selection_Rank& sel); + + virtual void prepare(Rarray<struct individual>& fitness_values,const bool remplace); // const; + virtual void reset(); + + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int portion,const bool remplace) const; + }; + +// Selection_Best --------------------------------------------------------------------------------- + + provides class Selection_Best: public Selection_Rank + { + private: + mutable unsigned int selection_best_position; + + public: + Selection_Best(const Direction); + virtual ~Selection_Best(); + + friend ostream& operator<< (ostream& os, const Selection_Best& sel); + + virtual void reset(); + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int position,const bool remplace) const; + }; + +// Selection_Worst --------------------------------------------------------------------------------- + + provides class Selection_Worst: public Selection_Rank + { + private: + mutable unsigned int selection_worst_position; + + public: + Selection_Worst(const Direction); + virtual ~Selection_Worst(); + + friend ostream& operator<< (ostream& os, const Selection_Worst& sel); + + virtual void reset(); + virtual struct individual select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int position,const bool remplace) const; + }; + +// Operator_Pool ------------------------------------------------------------------------- + + // pool with all operators and selections that can be chosen in the setup file + provides class Operator_Pool + { + private: + mutable Rlist<Intra_Operator> _intra_operators; + Rlist<Selection> _selectors; + Rlist<Inter_Operator> _inter_operators; + + public: + Operator_Pool(const Problem& pbm); + ~Operator_Pool(); + + Intra_Operator& intra_operator(const unsigned int index) const; + Rlist<Intra_Operator>& intra_operators() const; + Selection& selector(const unsigned int index) const; + const Rlist<Selection>& selectors() const; + Inter_Operator& inter_operator(const unsigned int index) const; + const Rlist<Inter_Operator>& inter_operators() const; + + }; + +// Solver --------------------------------------------------------------------------------- + + provides class Solver + { + protected: + const Problem& problem; + const SetUpParams& params; + UserStatistics _userstat; + Statistics _stat; + Population current_population; + StateCenter _sc; + + double best_cost; + double worst_cost; + Solution best_solution; + double average_cost; + double standard_deviation; + float total_time_spent; + float time_spent_in_trial; + float start_trial; + float start_global; + + bool _end_trial; + + State_Vble _current_trial; + State_Vble _current_iteration; + State_Vble _current_evaluations; + + State_Vble _current_best_solution; + State_Vble _current_best_cost; + State_Vble _current_worst_cost; + State_Vble _current_average_cost; + State_Vble _current_standard_deviation; + State_Vble _current_time_spent; + + State_Vble _best_solution_trial; + State_Vble _best_cost_trial; + State_Vble _worst_cost_trial; + State_Vble _iteration_best_found_in_trial; + State_Vble _evaluations_best_found_in_trial; + State_Vble _time_best_found_trial; + State_Vble _time_spent_trial; + + State_Vble _trial_best_found; + State_Vble _iteration_best_found; + State_Vble _evaluations_best_found; + State_Vble _global_best_solution; + State_Vble _global_best_cost; + State_Vble _global_worst_cost; + State_Vble _time_best_found; + + State_Vble _crossover_probability; // probability of applying the operator over population + State_Vble _mutation_probability; // probability of applying the operator over population + State_Vble _user_op_probability[MAX_OP_USER]; // probabilities of user operators + State_Vble _migration_rate; + State_Vble _migration_size; + State_Vble _migration_selection_1; + State_Vble _migration_selection_2; + State_Vble _migration_selection_conf_1; + State_Vble _migration_selection_conf_2; + State_Vble _select_parents; + State_Vble _select_offsprings; + State_Vble _parameter_select_parents; + State_Vble _parameter_select_offsprings; + + State_Vble _display_state; + + + public: + Solver (const Problem& pbm, const SetUpParams& setup); + virtual ~Solver (); + + virtual int pid() const; + bool end_trial() const; + void end_trial(bool et); + + // Execution methods ----------------------------------------------------------------------- + + // Full execution + virtual void run () =0; + virtual void run (const unsigned long int nb_generations) =0; + virtual void run (const Population& pop,const unsigned long int nb_generations) =0; + + //Partial execution + virtual void StartUp()=0; + virtual void StartUp(const Population& pop)=0; + + virtual void DoStep()=0; + + // Statistics handling ---------------------------------------------------------------------- + + Statistics& statistics(); + UserStatistics& userstatistics (); + Population& population(); + const SetUpParams& setup() const; + const Problem& pbm() const; + + // State handling --------------------------------------------------------------------------- + + void RefreshState(); + void RefreshCfgState(); + void UpdateFromState(); + void UpdateFromCfgState(); + StateCenter* GetState(); + + unsigned int current_trial() const; + unsigned long current_iteration() const; + unsigned long current_evaluations() const; + Solution current_best_solution() const; + double current_best_cost() const; + double current_worst_cost() const; + double current_average_cost() const; + double current_standard_deviation() const; + float current_time_spent() const; + Solution best_solution_trial() const; + double best_cost_trial() const; + double worst_cost_trial() const; + unsigned int iteration_best_found_in_trial() const; + unsigned int evaluations_best_found_in_trial() const; + float time_best_found_trial() const; + float time_spent_trial() const; + unsigned int trial_best_found() const; + unsigned int iteration_best_found() const; + unsigned int evaluations_best_found() const; + Solution global_best_solution() const; + double global_best_cost() const; + double global_worst_cost() const; + float time_best_found() const; + int display_state() const; + + float *crossover_probability() const; + float *mutation_probability() const; + float *user_op_probability(const int index) const; + unsigned int migration_rate() const; + unsigned int migration_size() const; + unsigned int migration_selection_1() const; + unsigned int migration_selection_2() const; + unsigned int migration_selection_conf_1() const; + unsigned int migration_selection_conf_2() const; + unsigned int select_parents() const; + unsigned int select_offprings() const; + unsigned int parameter_select_parents() const; + unsigned int parameter_select_offsprings() const; + + void current_trial(const unsigned int value); + void current_iteration(const unsigned long value); + void current_evaluations(const unsigned long value); + void current_best_solution(const Solution& sol); + void current_best_cost(const double value); + void current_worst_cost(const double value); + void current_average_cost(const double value); + void current_standard_deviation(const double value); + void current_time_spent(const float value); + void best_solution_trial(const Solution& sol); + void best_cost_trial(const double value); + void worst_cost_trial(const double value); + void iteration_best_found_in_trial(const unsigned int value); + void evaluations_best_found_in_trial(const unsigned int value); + void time_best_found_trial(const float value); + void time_spent_trial(const float value); + void trial_best_found(const unsigned int value); + void iteration_best_found(const unsigned int value); + void evaluations_best_found(const unsigned int value); + void global_best_solution(const Solution& sol); + void global_best_cost(const double value); + void global_worst_cost(const double value); + void time_best_found(const float value); + void display_state(const int value); + + void crossover_probability(const float *probability); + void mutation_probability(const float *probability); + void user_op_probability(const int index,const float *probability); + void migration_rate(const unsigned int rate); + void migration_size(const unsigned int size); + void migration_selection_1(const unsigned int seleciton_1); + void migration_selection_2(const unsigned int selection_2); + void migration_selection_conf_1(const unsigned int selection_conf_1); + void migration_selection_conf_2(const unsigned int selection_conf_2); + void select_parents(const unsigned int selection); + void select_offsprings(const unsigned int selection); + void parameter_select_parents(const unsigned int value); + void parameter_select_offsprings(const unsigned int value); + + void show_state() const; + void KeepHistory(const Solution& best_sol,const double best_cost,const double worst_cost,const float time_spent_trial,const float total_time_spent); + }; + + provides class Solver_Seq: public Solver + { + public: + Solver_Seq ( const Problem& pbm, const SetUpParams& setup); + virtual ~Solver_Seq (); + + // Execution methods ----------------------------------------------------------------------- + + // Full execution + virtual void run (); + virtual void run (const unsigned long int nb_generations); + virtual void run (const Population& pop,const unsigned long int nb_generations); + + //Partial execution + virtual void StartUp(); + virtual void StartUp(const Population& pop); + + virtual void DoStep(); + }; + + provides class Solver_Lan: public Solver + { + private: + NetStream _netstream; + int mypid; + + int receive_local_state(); + + unsigned int _current_trial; + unsigned long _current_iteration; + unsigned long _current_evaluations; + double _best_cost_trial; + Solution _best_solution_trial; + double _worst_cost_trial; + float _time_best_found_in_trial; + unsigned long _iteration_best_found_in_trial; + unsigned long _evaluations_best_found_in_trial; + + // Termination phase // + bool final_phase; + unsigned long acum_iterations; + unsigned long acum_evaluations; + + + public: + Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Lan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods ----------------------------------------------------------------------- + + // Full execution + virtual void run (); + virtual void run (const unsigned long int nb_generations); + virtual void run (const Population& pop,const unsigned long int nb_generations); + + //Partial execution + virtual void StartUp(); + virtual void StartUp(const Population& pop); + + virtual void DoStep(); + + //Communication + void send_local_state_to(int _mypid); + void check_for_refresh_global_state(); + void reset(); + }; + + provides class Solver_Wan: public Solver + { + private: + NetStream _netstream; + int mypid; + + int receive_local_state(); + + unsigned int _current_trial; + unsigned long _current_iteration; + unsigned long _current_evaluations; + double _best_cost_trial; + Solution _best_solution_trial; + double _worst_cost_trial; + float _time_best_found_in_trial; + unsigned long _iteration_best_found_in_trial; + unsigned long _evaluations_best_found_in_trial; + + // Termination phase // + bool final_phase; + unsigned long acum_iterations; + unsigned long acum_evaluations; + + public: + Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Wan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods ----------------------------------------------------------------------- + + // Full execution + virtual void run (); + virtual void run (const unsigned long int nb_generations); + virtual void run (const Population& pop,const unsigned long int nb_generations); + + //Partial execution + virtual void StartUp(); + virtual void StartUp(const Population& pop); + + virtual void DoStep(); + + //Communication + void send_local_state_to(int _mypid); + void check_for_refresh_global_state(); + void reset(); + }; + +} + +#endif diff --git a/ProyectoFinal/CHC/malva/rep/GA/newGA.pro.cc b/ProyectoFinal/CHC/malva/rep/GA/newGA.pro.cc new file mode 100644 index 0000000000000000000000000000000000000000..dfdd244b4322ca4b6ef4b9066b857263a7a4c784 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/GA/newGA.pro.cc @@ -0,0 +1,2831 @@ +#include "newGA.hh" + +skeleton newGA +{ + +// StopCondition ------------------------------------------------------------------------------------- + + StopCondition::StopCondition() + {} + + StopCondition::~StopCondition() + {} + +// SetUpParams ----------------------------------------------------------- + + SetUpParams::SetUpParams (Operator_Pool& pool) + : _independent_runs(0), + _nb_evolution_steps(0), + _population_size(0), + _population_additional_size(0), + _select_parents(0), + _select_offsprings(0), + _parameter_select_parents(0), + _parameter_select_offsprings(0), // Parameter of selection is fixed to 0 + _inter_operators(), + _intra_operators(), + _combine(1), + _refresh_global_state(1), + _synchronized(0), + _check_asynchronous(1), + _display_state(0), + _pool(pool) + {} + + Operator_Pool& SetUpParams::pool() const + { + return _pool; + } + + istream& operator>> (istream& is, SetUpParams& setup) + { + char buffer[MAX_BUFFER]; // current line in the setup file + char command[50]; + long op; + int parameter; + short int nb_section=0; + short int nb_io = 0; + short int nb_selection = 0; + short int nb_param=0; + short int nb_LAN_param=0; + + while (is.getline(buffer,MAX_BUFFER,'\n')) + { + sscanf(buffer," %s ",command); + if (!(strcmp(command,"General"))) nb_section=0; + if (!(strcmp(command,"Selections"))) nb_section=1; + if (!(strcmp(command,"Intra-Operators"))) nb_section=2; + if (!(strcmp(command,"Inter-Operators"))) nb_section=3; + if (!(strcmp(command,"LAN-configuration"))) nb_section=4; + + op=-1; + sscanf(buffer," %ld%*s ",&op); + if (op<0) continue; + switch (nb_section) + { + case 0: switch (nb_param) + { + case 0: setup.independent_runs(op); break; + case 1: setup.nb_evolution_steps(op); break; + case 2: setup.population_size(op); break; + case 3: setup.population_additional_size(op); break; + case 4: setup.combine(op); break; + case 5: setup.display_state(op); break; + } + nb_param++; + break; + case 1: op=-1; // creates the chosen selection method + parameter=0; + sscanf(buffer," %d %d",&op,¶meter); + if (nb_selection>=2) break; + assert(parameter>=0); + if (nb_selection==0) + { + setup.select_parents(op); + setup.parameter_select_parents(parameter); + } + else + { + setup.select_offsprings(op); + setup.parameter_select_offsprings(parameter); + } + nb_selection++; + break; + case 2: setup.pool().intra_operators().append(Intra_Operator::create(op)); + setup.pool().intra_operator(nb_io).setup(buffer); + setup._intra_operators.append(new unsigned int(nb_io)); + nb_io++; + break; + case 3: setup._inter_operators.append(new unsigned int(op)); + setup.pool().inter_operator(op).setup(buffer); + break; + case 4: if (nb_LAN_param>=3) break; + switch (nb_LAN_param) + { + case 0: setup.refresh_global_state(op); break; + case 1: setup.synchronized(op); break; + case 2: assert(op>0); + setup.check_asynchronous(op); break; + } + nb_LAN_param++; + break; + } + } + + return is; + } + + ostream& operator<< (ostream& os, const SetUpParams& setup) + { + os << "CONFIGURATION -------------------------------------------" << endl << endl; + os << "\t" << "Independent runs : " << setup.independent_runs() << endl + << "\t" << "Evolution steps: " << setup.nb_evolution_steps() << endl + << "\t" << "Size of Population: " << setup.population_size() << endl + << "\t" << "Size of Additional population: " << setup.population_additional_size() << endl; + if (setup.combine()) + os << "\t" <<"With combination between parents and offsprings" << endl; + else + os << "\t" <<"Without combination between parents and offsprings" << endl; + + os << "\t" << "Display State: " << setup.display_state() << endl << endl + << "\t" << "Selections:" << endl + << "\t" << "-----------" << endl << endl + << "\t" << "Selection parents -> " << setup.pool().selector(setup.select_parents()) << endl + << "\t" << "Parameter of selection: " << setup.parameter_select_parents() << endl + << "\t" << "Selection offsprings -> " << setup.pool().selector(setup.select_offsprings()) << endl + << "\t" << "Parameter of selection: " << setup.parameter_select_offsprings() << endl << endl + << "\t" << "Intra_Operators: " << endl + << "\t" << "-----------" << endl << endl; + + for (int i=0;i<setup.intra_operators_size();i++) + os << "\t" << (setup.pool().intra_operator(setup.intra_operator_index(i))) << endl; + + os << endl << "\t" << "Inter_Operators: " << endl + << "\t" << "-----------" << endl << endl; + + for (int i=0;i<setup.inter_operators_size();i++) + os << "\t" << "Operator: " << setup.pool().inter_operator(setup.inter_operator_index(i)) << endl; + + os << endl << "\t" << "LAN configuration:" << endl + << "\t" << "----------------------" << endl << endl + << "\t" << "Refresh global state in number of generations: " << setup.refresh_global_state() << endl; + + if (setup.synchronized()) + os << "\t" << "Running in synchronous mode" << endl; + else + os << "\t" << "Running in asynchronous mode" << endl; + os << "\t" << "Interval for checking asynchronous receptions: " << setup.check_asynchronous() << endl << endl; + + os << endl << endl << "END CONFIGURATION -------------------------------------------" << endl << endl; + return os; + } + + const unsigned int SetUpParams::independent_runs() const + { + return _independent_runs; + } + + const unsigned long SetUpParams::nb_evolution_steps() const + { + return _nb_evolution_steps; + } + + const unsigned int SetUpParams::population_size() const + { + return _population_size; + } + + const unsigned int SetUpParams::population_additional_size() const + { + return _population_additional_size; + } + + const bool SetUpParams::combine() const + { + return _combine; + } + + const unsigned long SetUpParams::refresh_global_state() const + { + return _refresh_global_state; + } + + const bool SetUpParams::synchronized() const + { + return _synchronized; + } + + const unsigned int SetUpParams::check_asynchronous() const + { + return _check_asynchronous; + } + + const bool SetUpParams::display_state() const + { + return _display_state; + } + + void SetUpParams::independent_runs(const unsigned int val) + { + _independent_runs=val; + } + + void SetUpParams::nb_evolution_steps(const unsigned long val) + { + _nb_evolution_steps=val; + } + + void SetUpParams::population_size(const unsigned int val) + { + _population_size=val; + } + + void SetUpParams::population_additional_size(const unsigned int val) + { + _population_additional_size=val; + } + + void SetUpParams::combine(const bool val) + { + _combine=val; + } + + void SetUpParams::display_state(const bool val) + { + _display_state=val; + } + + void SetUpParams::refresh_global_state(const unsigned long val) + { + _refresh_global_state=val; + } + + void SetUpParams::synchronized(const bool val) + { + _synchronized=val; + } + + void SetUpParams::check_asynchronous(const unsigned int val) + { + _check_asynchronous=val; + } + + const unsigned int SetUpParams::select_parents() const + { + return _select_parents; + } + + const unsigned int SetUpParams::select_offsprings() const + { + return _select_offsprings; + } + + const unsigned int SetUpParams::parameter_select_parents() const + { + return _parameter_select_parents; + } + + const unsigned int SetUpParams::parameter_select_offsprings() const + { + return _parameter_select_offsprings; + } + + void SetUpParams::select_parents(const unsigned int val) + { + _select_parents=val; + } + + void SetUpParams::select_offsprings(const unsigned int val) + { + _select_offsprings=val; + } + + void SetUpParams::parameter_select_parents(const unsigned int val) + { + _parameter_select_parents=val; + } + + void SetUpParams::parameter_select_offsprings(const unsigned int val) + { + _parameter_select_offsprings=val; + } + + const unsigned int SetUpParams::intra_operator_index(const unsigned int index) const + { + return _intra_operators[index]; + } + + const unsigned int SetUpParams::intra_operators_size() const + { + return _intra_operators.size(); + } + + const unsigned int SetUpParams::inter_operator_index(const unsigned int index) const + { + return _inter_operators[index]; + } + + const unsigned int SetUpParams::inter_operators_size() const + { + return _inter_operators.size(); + } + + void SetUpParams::RefreshState(const StateCenter& _sc) const + { + _sc.set_contents_state_variable("_select_parents",(char *)&_select_parents,1,sizeof(_select_parents)); + _sc.set_contents_state_variable("_parameter_select_parents",(char *)&_parameter_select_parents,1,sizeof(_parameter_select_parents)); + _sc.set_contents_state_variable("_select_offsprings",(char *)&_select_offsprings,1,sizeof(_select_offsprings)); + _sc.set_contents_state_variable("_parameter_select_offsprings",(char *)&_parameter_select_offsprings,1,sizeof(_parameter_select_offsprings)); + _sc.set_contents_state_variable("_display_state",(char *)&_display_state,1,sizeof(bool)); + } + + void SetUpParams::UpdateFromState(const StateCenter& _sc) const + { + unsigned long nbytes,length; + _sc.get_contents_state_variable("_select_parents",(char *)&_select_parents,nbytes,length); + _sc.get_contents_state_variable("_parameter_select_parents",(char *)&_parameter_select_parents,nbytes,length); + _sc.get_contents_state_variable("_select_offsprings",(char *)&_select_offsprings,nbytes,length); + _sc.get_contents_state_variable("_parameter_select_offsprings",(char *)&_parameter_select_offsprings,nbytes,length); + _sc.get_contents_state_variable("_display_state",(char *)&_display_state,nbytes,length); + } + + SetUpParams::~SetUpParams() + {} + +// Statistics ------------------------------------------------------ + + Statistics::Statistics() + {} + + ostream& operator<< (ostream& os, const Statistics& stats) + { + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF CURRENT TRIAL " << endl; + os << "------------------------------------------------------------------" << endl; + for (int i=0;i< stats.stats_data.size();i++) + { + os << endl + << " Trial: " << stats.stats_data[i].trial + << " Generation: " << stats.stats_data[i].nb_generation + << " Evaluation: " << stats.stats_data[i].nb_evaluation + << " Current best cost: " << stats.stats_data[i].best_cost + << " Global best cost: " << stats.stats_data[i].global_best_cost + << " Avg: " << stats.stats_data[i].average_cost + << " Std. Dev.: " << stats.stats_data[i].standard_deviation; + } + + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + Statistics& Statistics::operator= (const Statistics& stats) + { + stats_data = stats.stats_data; + return *this; + } + + void Statistics::update(const Solver& solver) + { + struct stat *new_stat=(struct stat *)malloc(sizeof(struct stat)); + + new_stat->trial=solver.current_trial(); + new_stat->nb_generation=solver.current_iteration(); + new_stat->nb_evaluation=solver.current_evaluations(); + new_stat->average_cost=solver.current_average_cost(); + new_stat->standard_deviation=solver.current_standard_deviation(); + new_stat->best_cost=solver.current_best_cost(); + new_stat->global_best_cost=solver.global_best_cost(); + + stats_data.append(*new_stat); + } + + void Statistics::clear() + { + stats_data.remove(); + } + + Statistics::~Statistics() + {} + +// Population ------------------------------------------------------ + + Population::Population(const Problem& pbm,const SetUpParams& setup) + :_parents(setup.population_size()), + _fitness_values(setup.population_size()), + _new_parents(setup.population_size()), + _offsprings(setup.population_additional_size()), + _setup(setup), + _evaluations(0) + { + for (int i=0;i<_parents.size();i++) + { + _parents[i]=new Solution(pbm); + _new_parents[i]=new Solution(pbm); + _fitness_values[i].index = i; + _fitness_values[i].change = true; + } + for (int i=0;i<_offsprings.size();i++) + _offsprings[i]=new Solution(pbm); + + } + + void Population::Evaluate(Solution* sols,struct individual &_f) + { + if(_f.change) + { + _f.change = false; + _f.fitness = sols->fitness(); + _evaluations++; + } + } + + Population& Population::operator= (const Population& pop) + { + for (int i=0;i<_parents.size();i++) + { + *_parents[i]=*((pop.parents())[i]); + _fitness_values[i] = pop._fitness_values[i]; + _evaluations = pop._evaluations; + } + return (*this); + } + + istream& operator>> (istream& is, Population& population) + { + return is; + } + + ostream& operator<< (ostream& os, const Population& population) + { + os << "---------------------------------------------------------------" << endl; + os << " PRESENT POPULATION " << endl << endl; + for (int i=0;i<population._parents.size();i++) + os << *population._parents[i] << endl; + os << endl << "---------------------------------------------------------------" << endl; + return os; + } + + const SetUpParams& Population::setup() const + { + return _setup; + } + + void Population::initialize() + { + for (int i=0;i<_parents.size();i++) + { + _parents[i]->initialize(); + _fitness_values[i].index = i; + _fitness_values[i].change = true; + } + evaluate_parents(); + } + + void Population::evaluate_parents() + { + double upper_fitness=(infinity() * (-1)); + double lower_fitness=(infinity()); + double current_fitness; + double cost=0.0; + + for (int i=0;i<_fitness_values.size();i++) + { + Evaluate(_parents[_fitness_values[i].index],_fitness_values[i]); + current_fitness = _fitness_values[i].fitness; + + if (current_fitness > upper_fitness ) + { + _upper_cost=i; + upper_fitness = current_fitness; + } + + if (current_fitness < lower_fitness ) + { + _lower_cost=i; + lower_fitness = current_fitness; + } + + cost += current_fitness; + } + + _average_cost = cost / _fitness_values.size(); + } + + void Population::evaluate_offsprings() + { + int i=0; + if (_setup.combine()) // new individuals selected between current individuals and offsprings + { + _fitness_aux=Rarray<struct individual>(_parents.size() + _offsprings.size()); + for (i=0;i<_parents.size();i++) + { + Evaluate(_parents[_fitness_values[i].index],_fitness_values[i]); + _fitness_aux[i] = _fitness_values[i]; + } + + for (int j=i;(j-i)<_offsprings.size();j++) + { + _fitness_aux[j].index=j; + _fitness_aux[j].change=true; + Evaluate(_offsprings[j-i],_fitness_aux[j]); + } + } + else // new individuals selected only between offsprings + { + _fitness_aux=Rarray<struct individual>(_offsprings.size()); + for (i=0;i<_offsprings.size();i++) + { + _fitness_aux[i].index=i; + _fitness_aux[i].change=true; + Evaluate(_offsprings[i],_fitness_aux[i]); + } + } + } + + void Population::evolution() + { + select_parents(); // selects individuals to apply operators + + // apply selected operators + for (int i=0;i<_setup.intra_operators_size();i++) + _setup.pool().intra_operator(_setup.intra_operator_index(i)).execute(_offsprings); + + evaluate_offsprings(); + select_offsprings(); // selects new individuals + evaluate_parents(); // calculates fitness of new individuals + } + + void Population::interchange(const unsigned long current_generation, NetStream& channel) + { + // apply selected operators + for (int i=0;i<_setup.inter_operators_size();i++) + _setup.pool().inter_operator(_setup.inter_operator_index(i)).execute((*this),current_generation,channel,_setup.synchronized(),_setup.check_asynchronous()); + } + + void Population::select_parents() + { + _setup.pool().selector(_setup.select_parents()).prepare(_fitness_values,false); + struct individual ind; + for (int i=0;i<_offsprings.size();i++) + { + ind = _setup.pool().selector(_setup.select_parents()).select_one(_parents,_offsprings,_fitness_values,_setup.parameter_select_parents(),false); + *_offsprings[i] = *_parents[ind.index]; + } + } + + void Population::select_offsprings() + { + _setup.pool().selector(_setup.select_offsprings()).prepare(_fitness_aux,false); + const int ps = _parents.size(); + Rarray<struct individual> aux(ps); + + for (int i=0;i<ps;i++) + { + if (_setup.combine()) + { + aux[i] = _setup.pool().selector(_setup.select_offsprings()).select_one(_parents,_offsprings,_fitness_aux,_setup.parameter_select_offsprings(),false); + if(aux[i].index < ps) + { + *_new_parents[i] = *_parents[aux[i].index]; + aux[i].index = i; + } + else + { + *_new_parents[i] = *_offsprings[aux[i].index-ps]; + aux[i].index = i; + } + } + else + { + aux[i]=_setup.pool().selector(_setup.select_offsprings()).select_one(_offsprings,_offsprings,_fitness_aux,_setup.parameter_select_offsprings(),false); + *_parents[i] = *_offsprings[aux[i].index]; + aux[i].index = i; + } + } + + if (_setup.combine()) // interchanges current and new parents in the population + { + Solution *interchange; + for (int i=0;i<ps;i++) + { + interchange=_parents[i]; + _parents[i]=_new_parents[i]; // interchanges pointers to solutions ( NO solutions !! ) + _new_parents[i]=interchange; + } + } + for (int i=0;i<ps;i++) + { + _fitness_values[i] = aux[i]; + } + } + + const Rarray<Solution*>& Population::parents() const + { + return _parents; + } + + const Rarray<Solution*>& Population::offsprings() const + { + return _offsprings; + } + + Rarray<struct individual>& Population::fitness_values() + { + return _fitness_values; + } + + unsigned int Population::upper_cost() const + { + return _upper_cost; + } + + unsigned int Population::lower_cost() const + { + return _lower_cost; + } + + unsigned int Population::evaluations() const + { + return _evaluations; + } + + double Population::best_cost() const + { + if ((*_parents[0]).pbm().direction() == minimize) + return _fitness_values[_lower_cost].fitness; + else + return _fitness_values[_upper_cost].fitness; + } + + double Population::worst_cost() const + { + if ((*_parents[0]).pbm().direction() == minimize) + return _fitness_values[_upper_cost].fitness; + else + return _fitness_values[_lower_cost].fitness; + } + + Solution& Population::best_solution() const + { + if ((*_parents[0]).pbm().direction() == minimize) + return *_parents[_fitness_values[_lower_cost].index]; + else + return *_parents[_fitness_values[_upper_cost].index]; + } + + Solution& Population::worst_solution() const + { + if ((*_parents[0]).pbm().direction() == minimize) + return *_parents[_fitness_values[_upper_cost].index]; + else + return *_parents[_fitness_values[_lower_cost].index]; + } + + Solution& Population::solution(const unsigned int index) const + { + return *_parents[index]; + } + + double Population::fitness(const unsigned int index) const + { + return _fitness_values[index].fitness; + } + + double Population::average_cost() const + { + return _average_cost; + } + + double Population::standard_deviation() const + { + double standard=0.0; + for (int i=0;i<_fitness_values.size();i++) + standard += pow ((_fitness_values[i].fitness - _average_cost),2); + standard=sqrt(standard / (_fitness_values.size()-1)); + return standard; + } + + Population::~Population() + { + for (int i=0;i<_parents.size();i++) + delete(_parents[i]); + for (int i=0;i<_offsprings.size();i++) + delete(_offsprings[i]); + for (int j=0;j<_new_parents.size();j++) + delete(_new_parents[j]); + } + + +// Inter_operator ------------------------------------------------------------------- + + Inter_Operator::Inter_Operator(const unsigned int _number_op,const Direction dir): + _number_operator(_number_op), + direction(dir), + migration_rate(1), + migration_size(1), + migration_selection_1(0), + migration_selection_2(0), + migration_selection_conf_1(0), + migration_selection_conf_2(0) + {} + + unsigned int Inter_Operator::number_operator() const + { + return _number_operator; + } + + void Inter_Operator::setup(char line[MAX_BUFFER]) + { + int op; + int new_migration_rate=1; + int new_migration_size=1; + int new_migration_selection_1=0; + int new_migration_selection_conf_1=0; + int new_migration_selection_2=0; + int new_migration_selection_conf_2=0; + + sscanf(line," %d %d %d %d %d %d %d ",&op,&new_migration_rate,&new_migration_size,&new_migration_selection_1,&new_migration_selection_conf_1,&new_migration_selection_2,&new_migration_selection_conf_2); + + assert(new_migration_rate>0); + assert(new_migration_size>0); + assert(new_migration_selection_1>=0); + assert(new_migration_selection_conf_1>=0); + assert(new_migration_selection_2>=0); + assert(new_migration_selection_conf_2>=0); + + migration_rate=new_migration_rate; + migration_size=new_migration_size; + migration_selection_1=new_migration_selection_1; + migration_selection_conf_1=new_migration_selection_conf_1; + migration_selection_2=new_migration_selection_2; + migration_selection_conf_2=new_migration_selection_conf_2; + } + + void Inter_Operator::RefreshState(const StateCenter& _sc) const + { + _sc.set_contents_state_variable("_migration_rate",(char *)&migration_rate,1,sizeof(migration_rate)); + _sc.set_contents_state_variable("_migration_size",(char *)&migration_size,1,sizeof(migration_size)); + _sc.set_contents_state_variable("_migration_selection_1",(char *)&migration_selection_1,1,sizeof(migration_selection_1)); + _sc.set_contents_state_variable("_migration_selection_2",(char *)&migration_selection_2,1,sizeof(migration_selection_2)); + _sc.set_contents_state_variable("_migration_selection_conf_1",(char *)&migration_selection_conf_1,1,sizeof(migration_selection_conf_1)); + _sc.set_contents_state_variable("_migration_selection_conf_2",(char *)&migration_selection_conf_2,1,sizeof(migration_selection_conf_2)); + } + + void Inter_Operator::UpdateFromState(const StateCenter& _sc) + { + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_rate",(char *)&migration_rate,nitems,length); + _sc.get_contents_state_variable("_migration_size",(char *)&migration_size,nitems,length); + _sc.get_contents_state_variable("_migration_selection_1",(char *)&migration_selection_1,nitems,length); + _sc.get_contents_state_variable("_migration_selection_2",(char *)&migration_selection_2,nitems,length); + _sc.get_contents_state_variable("_migration_selection_conf_1",(char *)&migration_selection_conf_1,nitems,length); + _sc.get_contents_state_variable("_migration_selection_conf_2",(char *)&migration_selection_conf_2,nitems,length); + } + + ostream& operator<< (ostream& os, const Inter_Operator& inter) + { + switch (inter.number_operator()) + { + case 0: os << (Migration&)inter;break; + } + return os; + } + + Inter_Operator::~Inter_Operator() + {} + +// Migration ------------------------------------------------------------ + + Migration::Migration(const Direction dir):Inter_Operator(0,dir) + {} + + void Migration::execute(Population& pop,const unsigned long current_generation,NetStream& _netstream,const bool synchronized,const unsigned int check_asynchronous) const + { + + Solution* solution_to_send; + Solution* solution_received; + Solution* solution_to_remplace; + bool need_to_revaluate=false; + int mypid; + + int nb_proc=_netstream.pnumber(); // Get the number of processes running + + mypid=_netstream.my_pid(); + + int to = (mypid + 1) % nb_proc; // Source (from) and Target (to) of processes + int from = (nb_proc + mypid - 1) % nb_proc; + + // process number 0 is only to store the global state + if (to==0) to=1; + if (from==0) from=nb_proc - 1; + + _netstream << set_target(to) << set_source(from) + << get_target(&to) << get_source(&from); + + if ( (current_generation % migration_rate) == 0 + && (current_generation!=pop.setup().nb_evolution_steps())) // in this generation this operator have to be applied + { + pop.setup().pool().selector(migration_selection_1).prepare(pop.fitness_values(),false); + + _netstream << pack_begin; + for (int i=0;i<migration_size;i++) + { + // select individual to send + solution_to_send = pop.parents()[pop.setup().pool().selector(migration_selection_1).select_one( + pop.parents(),pop.offsprings(),pop.fitness_values(),migration_selection_conf_1,false).index]; + + _netstream << *solution_to_send; + } + _netstream << pack_end; + + if (synchronized) // synchronous mode: blocked until data are received + { + pop.setup().pool().selector(migration_selection_2).prepare(pop.fitness_values(),true); + + _netstream << set_source(MPI_ANY_SOURCE); + int tipo = 0; + _netstream._wait2(any,tipo); + + if (tipo == 1){ + return; + } + + _netstream << wait(packed); + _netstream << pack_begin; + for (int i=0;i<migration_size;i++) + { + // select individual to be remplaced + struct individual ind; + ind = pop.setup().pool().selector(migration_selection_2).select_one( + pop.parents(),pop.offsprings(),pop.fitness_values(),migration_selection_conf_2,true); + solution_to_remplace = pop.parents()[ind.index]; + solution_received=new Solution(solution_to_remplace->pbm()); + _netstream >> *solution_received; + + // remplace policy + if ((solution_received->fitness()<=solution_to_remplace->fitness() && direction==minimize) + || (solution_received->fitness()>=solution_to_remplace->fitness() && direction==maximize)) + { + need_to_revaluate=true; + for(int j = 0; j < pop.parents().size(); j++) + { + if(pop.fitness_values()[j].index == ind.index) + { + pop.fitness_values()[j].change = true; + *pop.parents()[ind.index] = *solution_received; + } + } + } + delete(solution_received); + } + _netstream << pack_end; + + } + } // end if + + if (!synchronized && ((current_generation % check_asynchronous) ==0)) + { // asynchronous mode: if there are not data, continue; + // but, if there are data, i have to receive it + int pending=false; + _netstream._probe(packed,pending); + if (pending) + { + pop.setup().pool().selector(migration_selection_2).prepare(pop.fitness_values(),true); + + _netstream << pack_begin; + for (int i=0;i<migration_size;i++) + { + pending=false; + _netstream._probe(regular,pending); + if (!pending) break; + + // select individual to be remplaced + struct individual ind; + ind = pop.setup().pool().selector(migration_selection_2).select_one( + pop.parents(),pop.offsprings(),pop.fitness_values(),migration_selection_conf_2,true); + solution_to_remplace = pop.parents()[ind.index]; + solution_received=new Solution(solution_to_remplace->pbm()); + _netstream >> *solution_received; + + // remplace policy + if ((solution_received->fitness()<=solution_to_remplace->fitness() && direction==minimize) + || (solution_received->fitness()>=solution_to_remplace->fitness() && direction==maximize)) + { + need_to_revaluate=true; + for(int j = 0; j < pop.parents().size(); j++) + { + if(pop.fitness_values()[j].index == ind.index) + { + pop.fitness_values()[j].change = true; + *pop.parents()[ind.index] = *solution_received; + } + } + } + delete(solution_received); + } // end for + _netstream << pack_begin; + } // end if + } + + if (need_to_revaluate) pop.evaluate_parents(); + } + + ostream& operator<< (ostream& os, const Migration& migration) + { + os << "Migration." + << endl << "\t" << " Rate: " << migration.migration_rate + << endl << "\t" << " Size: " << migration.migration_size + << endl << "\t" << " Selection 1: " << migration.migration_selection_1 + << endl << "\t" << " Selection 1 Parameter: " << migration.migration_selection_conf_1 + << endl << "\t" << " Selection 2: " << migration.migration_selection_2 + << endl << "\t" << " Selection 2 Parameter: " << migration.migration_selection_conf_2; + return os; + } + + Migration::~Migration() + {} + +// Selection ------------------------------------------------------------ + + Selection::Selection(const Direction dir):_number_selection(0),direction(dir) + {} + + Selection::Selection(const unsigned int _number_sel, const Direction dir):_number_selection(_number_sel),direction(dir) + {} + + void Selection::prepare(Rarray<struct individual>& fitness_values,const bool remplace) + {} + + struct individual Selection::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int dummy,const bool remplace) const + { // select a random individual + return fitness_values[rand_int(0,fitness_values.size()-1)]; + } + + unsigned int Selection::number_selection() const + { + return _number_selection; + } + + ostream& operator<< (ostream& os, const Selection& sel) + { + switch (sel.number_selection()) + { + case 0: os << "Random Selection"; break; + case 1: os << (Selection_Tournament&)sel; break; + case 2: os << (Selection_Roulette_Wheel&)sel; break; + case 3: os << (Selection_Rank&)sel; break; + case 4: os << (Selection_Best&)sel; break; + case 5: os << (Selection_Worst&)sel; break; + } + return os; + } + + Selection::~Selection() + {} + +// Selection_Tournament---------------------------------------------------- + + Selection_Tournament::Selection_Tournament(const Direction dir):Selection(1,dir) + {} + + struct individual Selection_Tournament::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int tournament_size, const bool remplace) const + { + unsigned int best_sol=0; + double best_fitness=((-1) * direction * infinity()); + unsigned int index; + + if (remplace) best_fitness = -1 * best_fitness; + + unsigned int new_tournament_size=tournament_size; + if (tournament_size==0) new_tournament_size=1; + + for (int i=0;i<new_tournament_size;i++) + { + index=rand_int(0,fitness_values.size()-1); + + switch (direction) + { + case (minimize): if (((!remplace) && (fitness_values[index].fitness<best_fitness)) + || ((remplace) && (fitness_values[index].fitness>best_fitness))) + { + best_sol = index; + best_fitness = fitness_values[index].fitness; + } + break; + case (maximize): if (((!remplace) && (fitness_values[index].fitness>best_fitness)) + || ((remplace) && (fitness_values[index].fitness<best_fitness))) + { + best_sol = index; + best_fitness = fitness_values[index].fitness; + } + break; + } + } + + return fitness_values[best_sol]; + } + + ostream& operator<< (ostream& os, const Selection_Tournament& sel) + { + os << "Tournament Selection."; + return os; + } + + Selection_Tournament::~Selection_Tournament() + {} + +// Selection_Roulette_Wheel --------------------------------------------------- + + Selection_Roulette_Wheel::Selection_Roulette_Wheel(const Direction dir):Selection(2,dir) + {} + + void Selection_Roulette_Wheel::prepare(Rarray<struct individual>& fitness_values,const bool remplace) + { + double overall_fitness=0.0; + + // inverts fitness values to select less fitness individuals with a high probability + if ((direction==maximize && (remplace)) || ((direction==minimize) && (!(remplace)))) + { + // fitness assigned if the fitness value is 0 in this case + double value_if_zero=DBL_MAX; + unsigned int nb_zeros=0; + + for (int i=0;i<fitness_values.size();i++) + { + if (fitness_values[i].fitness!=0) + value_if_zero-=fitness_values[i].fitness; + else + nb_zeros++; + } + + value_if_zero=value_if_zero/nb_zeros; + + // Warning !! if fitness is 0 (1/0 ?) + for (int i=0;i<fitness_values.size();i++) + { + if (fitness_values[i].fitness!=0) + fitness_values[i].sel_parameter = (1 / fitness_values[i].fitness ); + else + fitness_values[i].sel_parameter = value_if_zero; + overall_fitness+= fitness_values[i].sel_parameter; + } + } + else + { + for (int i=0;i<fitness_values.size();i++) + { + fitness_values[i].sel_parameter = fitness_values[i].fitness; + overall_fitness+= fitness_values[i].sel_parameter; + } + + } + + if (overall_fitness>DBL_MAX) overall_fitness=DBL_MAX; + + // calculate relative fitness + double previous=0.0; + for (int i=0;i<fitness_values.size();i++) + { + fitness_values[i].sel_parameter = (fitness_values[i].sel_parameter / overall_fitness) + previous; + previous = fitness_values[i].sel_parameter; + } + } + + struct individual Selection_Roulette_Wheel::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int dummy, const bool remplace) const + { + double random_selected=rand01(); + int i=0; + + while (random_selected > fitness_values[i].sel_parameter ) + i++; + + return fitness_values[i]; + } + + ostream& operator<< (ostream& os, const Selection_Roulette_Wheel& sel) + { + os << "Roulette Wheel Selection."; + return os; + } + + Selection_Roulette_Wheel::~Selection_Roulette_Wheel() + {} + +// Selection_Rank -------------------------------------------------- + + int lessF(const struct individual &i1,const struct individual &i2) + { + return i1.fitness < i2.fitness; + } + + int greaterF(const struct individual &i1,const struct individual &i2) + { + return i1.fitness > i2.fitness; + } + + Selection_Rank::Selection_Rank(const Direction dir):Selection(3,dir) + {} + + Selection_Rank::Selection_Rank(const unsigned int _number_sel, const Direction dir):Selection(_number_sel,dir) + {} + + void Selection_Rank::reset() + {} + + void Selection_Rank::prepare(Rarray<struct individual>& fitness_values,const bool remplace) + { + reset(); + + // sort individuals + if (((direction==maximize) && (!(remplace))) || ((direction==minimize) && (remplace))) + fitness_values.sort(greaterF); + else + fitness_values.sort(lessF); + } + + struct individual Selection_Rank::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int portion,const bool remplace) const + { + + unsigned int new_portion=portion; + if (portion==0 || portion>100) new_portion=100; + + return fitness_values[rand_int(0,(( fitness_values.size() * new_portion )/ 100)-1)]; + } + + ostream& operator<< (ostream& os, const Selection_Rank& sel) + { + os << "Rank-Ordered Selection."; + return os; + } + + Selection_Rank::~Selection_Rank() + {} + +// Selection_Best -------------------------------------------------- + + Selection_Best::Selection_Best(const Direction dir):Selection_Rank(4,dir),selection_best_position(0) + {} + + struct individual Selection_Best::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int position,const bool remplace) const + { + int position_to_return=position-1; + if (position_to_return<0) + { + position_to_return = selection_best_position; + selection_best_position++; + } + + position_to_return=(int)position_to_return % fitness_values.size(); + + return fitness_values[position_to_return]; + } + + void Selection_Best::reset() + { + selection_best_position=0; + } + + ostream& operator<< (ostream& os, const Selection_Best& sel) + { + os << "Selection of best ordered individuals."; + return os; + } + + Selection_Best::~Selection_Best() + {} + +// Selection_Worst -------------------------------------------------- + + Selection_Worst::Selection_Worst(const Direction dir):Selection_Rank(5,dir),selection_worst_position(0) + {} + + struct individual Selection_Worst::select_one(const Rarray<Solution*>& to_select_1,const Rarray<Solution*>& to_select_2,const Rarray<struct individual>& fitness_values,const unsigned int position,const bool remplace) const + { + int position_to_return=position-1; + if (position_to_return<0) + { + position_to_return = selection_worst_position; + selection_worst_position++; + } + + position_to_return=(int)position_to_return % fitness_values.size(); + + int index=(fitness_values.size()-1) - position_to_return; + return fitness_values[index]; + } + + void Selection_Worst::reset() + { + selection_worst_position=0; + } + + ostream& operator<< (ostream& os, const Selection_Worst& sel) + { + os << "Selection of worst ordered individuals."; + return os; + } + + Selection_Worst::~Selection_Worst() + {} + +// Operator_Pool ------------------------------------------------------------------------ + + Operator_Pool::Operator_Pool(const Problem& pbm) + { + // introduces all operators and selections in lists + + // Index to be chosen in setup file + //------------------------------------- + // The Intra_Operators are introduced dimanicly in setup + + _selectors.append(new Selection(pbm.direction())); // 0 + _selectors.append(new Selection_Tournament(pbm.direction())); // 1 + _selectors.append(new Selection_Roulette_Wheel(pbm.direction())); // 2 + _selectors.append(new Selection_Rank(pbm.direction())); // 3 + _selectors.append(new Selection_Best(pbm.direction())); // 4 + _selectors.append(new Selection_Worst(pbm.direction())); // 5 + + _inter_operators.append(new Migration(pbm.direction())); // 0 + } + + Intra_Operator& Operator_Pool::intra_operator(const unsigned int index) const + { + assert(index < _intra_operators.size()); + return _intra_operators[index]; + } + + Rlist<Intra_Operator>& Operator_Pool::intra_operators() const + { + return _intra_operators; + } + + Selection& Operator_Pool::selector(const unsigned int index) const + { + assert(index < _selectors.size()); + return _selectors[index]; + } + + const Rlist<Selection>& Operator_Pool::selectors() const + { + return _selectors; + } + + Inter_Operator& Operator_Pool::inter_operator(const unsigned int index) const + { + assert(index < _inter_operators.size()); + return _inter_operators[index]; + } + + const Rlist<Inter_Operator>& Operator_Pool::inter_operators() const + { + return _inter_operators; + } + + Operator_Pool::~Operator_Pool() + {} + +// Solver (superclasse)--------------------------------------------------- + + Solver::Solver (const Problem& pbm, const SetUpParams& setup) + : problem(pbm), + params(setup), + _stat(), + _userstat(), + _sc(), + current_population(pbm,setup), + best_cost((-1) * pbm.direction() * infinity()), + worst_cost((-1) * best_cost), + best_solution(problem), + average_cost(0.0), + standard_deviation(0.0), + time_spent_in_trial(0.0), + total_time_spent(0.0), + start_trial(0.0), + start_global(0.0), + _current_trial("_current_trial",_sc), + _current_iteration("_current_iteration",_sc), + _current_evaluations("_current_evaluations",_sc), + _current_best_solution("_current_best_solution",_sc), + _current_best_cost("_current_best_cost",_sc), + _current_worst_cost("_current_worst_cost",_sc), + _current_average_cost("_current_average_cost",_sc), + _current_standard_deviation("_current_standard_deviation",_sc), + _current_time_spent("_current_time_spent",_sc), + _best_solution_trial("_best_sol_trial",_sc), + _best_cost_trial("_best_cost_trial",_sc), + _worst_cost_trial("_worst_cost_trial",_sc), + _iteration_best_found_in_trial("_iteration_best_found_in_trial",_sc), + _evaluations_best_found_in_trial("_evaluations_best_found_in_trial",_sc), + _time_best_found_trial("_time_best_found_trial",_sc), + _time_spent_trial("_time_spent_trial",_sc), + _trial_best_found("_trial_best_found",_sc), + _iteration_best_found("_iteration_best_found",_sc), + _evaluations_best_found("_evaluations_best_found",_sc), + _global_best_solution("_global_best_solution",_sc), + _global_best_cost("_global_best_cost",_sc), + _global_worst_cost("_global_worst_cost",_sc), + _time_best_found("_time_best_found",_sc), + _crossover_probability("_crossover_probability",_sc), + _mutation_probability("_mutation_probability",_sc), + _migration_rate("_migration_rate",_sc), + _migration_size("_migration_size",_sc), + _migration_selection_1("_migration_selection_1",_sc), + _migration_selection_2("_migration_selection_2",_sc), + _migration_selection_conf_1("_migration_selection_conf_1",_sc), + _migration_selection_conf_2("_migration_selection_conf_2",_sc), + _select_parents("_select_parents",_sc), + _select_offsprings("_select_offsprings",_sc), + _parameter_select_parents("_parameter_select_parents",_sc), + _parameter_select_offsprings("_parameter_select_offsprings",_sc), + _display_state("_display_state",_sc) + { + current_trial(0); + current_iteration(0); + current_evaluations(0); + current_best_solution(best_solution); + current_best_cost(best_cost); + current_worst_cost(worst_cost); + current_average_cost(average_cost); + current_standard_deviation(standard_deviation); + current_time_spent(total_time_spent); + best_solution_trial(best_solution); + best_cost_trial(best_cost); + worst_cost_trial(worst_cost); + iteration_best_found_in_trial(0); + evaluations_best_found_in_trial(0); + time_best_found_trial(time_spent_in_trial); + time_spent_trial(time_spent_in_trial); + trial_best_found(0); + iteration_best_found(0); + evaluations_best_found(0); + global_best_solution(best_solution); + global_best_cost(best_cost); + global_worst_cost(worst_cost); + time_best_found(total_time_spent); + + float prob[MAX_PROB_PER_OP] = {0.0}; + crossover_probability(prob); + mutation_probability(prob); + + char aux[] = "_user_op_probability"; + char nombre[30]; + for(int i = 0; i < MAX_OP_USER; i++) + { + sprintf(nombre,"%s%d",aux,i); + _user_op_probability[i].set_name((char *)nombre); + _sc.add(_user_op_probability[i]); + user_op_probability(i,prob); + } + + migration_rate(0); + migration_size(0); + migration_selection_1(0); + migration_selection_2(0); + migration_selection_conf_1(0); + migration_selection_conf_2(0); + select_parents(0); + select_offsprings(0); + parameter_select_parents(0); + parameter_select_offsprings(0); + display_state(setup.display_state()); + } + + int Solver::pid() const + { + return 0; + } + + bool Solver::end_trial() const + { + return _end_trial; + } + + void Solver::end_trial(bool et) + { + _end_trial = et; + } + + unsigned int Solver::current_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _current_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned long Solver::current_iteration() const + { + unsigned long value=0; + unsigned long nitems,length; + _current_iteration.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned long Solver::current_evaluations() const + { + unsigned long value=0; + unsigned long nitems,length; + _current_evaluations.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::current_best_solution() const + { + Solution sol(problem); + unsigned long nitems,length; + char data_stored[_current_best_solution.get_nitems() + _current_best_solution.get_length()]; + _current_best_solution.get_contents(data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::current_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _current_best_cost.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::current_worst_cost() const + { + double value=0.0; + unsigned long nitems,length; + _current_worst_cost.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::current_average_cost() const + { + double value=0.0; + unsigned long nitems,length; + _current_average_cost.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::current_standard_deviation() const + { + double value=0.0; + unsigned long nitems,length; + _current_standard_deviation.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::current_time_spent() const + { + float value=0.0; + unsigned long nitems,length; + _current_time_spent.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::best_solution_trial() const + { + Solution sol(problem); + char data_stored[_best_solution_trial.get_nitems() + _best_solution_trial.get_length()]; + unsigned long nitems,length; + _best_solution_trial.get_contents(data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::best_cost_trial() const + { + double value=0.0; + unsigned long nitems,length; + _best_cost_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::worst_cost_trial() const + { + double value=0.0; + unsigned long nitems,length; + _worst_cost_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found_in_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found_in_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::evaluations_best_found_in_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _evaluations_best_found_in_trial.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_spent_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_spent_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::trial_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _trial_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::evaluations_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _evaluations_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::global_best_solution() const + { + Solution sol(problem); + char data_stored[_global_best_solution.get_nitems() + _global_best_solution.get_length()]; + unsigned long nitems,length; + _global_best_solution.get_contents(data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::global_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _global_best_cost.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::global_worst_cost() const + { + double value=0.0; + unsigned long nitems,length; + _global_worst_cost.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + int Solver::display_state() const + { + int value=0; + unsigned long nitems,length; + _display_state.get_contents((char *)&value, nitems, length); + return value; + } + + float *Solver::crossover_probability() const + { + float *current_probability = new float[MAX_PROB_PER_OP]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_crossover_probability",(char *)¤t_probability,nitems,length); + return current_probability; + } + + float *Solver::mutation_probability() const + { + float *current_probability = new float[MAX_PROB_PER_OP]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_mutation_probability",(char *)¤t_probability,nitems,length); + return current_probability; + } + + float *Solver::user_op_probability(const int index) const + { + float *current_probability = new float[MAX_PROB_PER_OP]; + unsigned long nitems,length; + char aux[30] = "_user_op_probability"; + sprintf(aux,"%s%d",aux,index); + + _sc.get_contents_state_variable(aux,(char *)¤t_probability,nitems,length); + return current_probability; + } + + unsigned int Solver::migration_rate() const + { + unsigned int rate=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_rate",(char *)&rate,nitems,length); + return rate; + } + + unsigned int Solver::migration_size() const + { + unsigned int size=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_size",(char *)&size,nitems,length); + return size; + } + + unsigned int Solver::migration_selection_1() const + { + unsigned int selection_1=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_selection_1",(char *)&selection_1,nitems,length); + return selection_1; + } + + unsigned int Solver::migration_selection_2() const + { + unsigned int selection_2=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_selection_2",(char *)&selection_2,nitems,length); + return selection_2; + } + + unsigned int Solver::migration_selection_conf_1() const + { + unsigned int selection_conf_1=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_selection_conf_1",(char *)&selection_conf_1,nitems,length); + return selection_conf_1; + } + + unsigned int Solver::migration_selection_conf_2() const + { + unsigned int selection_conf_2=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_migration_selection_conf_2",(char *)&selection_conf_2,nitems,length); + return selection_conf_2; + } + + unsigned int Solver::select_parents() const + { + unsigned int select_parents=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_select_parents",(char *)&select_parents,nitems,length); + return select_parents; + } + + unsigned int Solver::select_offprings() const + { + unsigned int select_offsprings=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_select_offsprings",(char *)&select_offsprings,nitems,length); + return select_offsprings; + } + + unsigned int Solver::parameter_select_parents() const + { + unsigned int parameter_select_parents; + unsigned long nitems,length; + _sc.get_contents_state_variable("_parameter_select_parents",(char *)¶meter_select_parents,nitems,length); + return parameter_select_parents; + } + + unsigned int Solver::parameter_select_offsprings() const + { + unsigned int parameter_select_offsprings; + unsigned long nitems,length; + _sc.get_contents_state_variable("_parameter_select_offsprings",(char *)¶meter_select_offsprings,nitems,length); + return parameter_select_offsprings; + } + + void Solver::current_trial(const unsigned int value) + { + _current_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::current_iteration(const unsigned long value) + { + _current_iteration.set_contents((char *)&value,1,sizeof(long)); + } + + void Solver::current_evaluations(const unsigned long value) + { + _current_evaluations.set_contents((char *)&value,1,sizeof(long)); + } + + void Solver::current_best_solution(const Solution& sol) + { + _current_best_solution.set_contents(sol.to_String(),1,sol.size()); + } + + void Solver::current_best_cost(const double value) + { + _current_best_cost.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::current_worst_cost(const double value) + { + _current_worst_cost.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::current_average_cost(const double value) + { + _current_average_cost.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::current_standard_deviation(const double value) + { + _current_standard_deviation.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::current_time_spent(const float value) + { + _current_time_spent.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::best_solution_trial(const Solution& sol) + { + _best_solution_trial.set_contents(sol.to_String(),1,sol.size()); + } + + void Solver::best_cost_trial(const double value) + { + _best_cost_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::worst_cost_trial(const double value) + { + _worst_cost_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::iteration_best_found_in_trial(const unsigned int value) + { + _iteration_best_found_in_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::evaluations_best_found_in_trial(const unsigned int value) + { + _evaluations_best_found_in_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::time_best_found_trial(const float value) + { + _time_best_found_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::time_spent_trial(const float value) + { + _time_spent_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::trial_best_found(const unsigned int value) + { + _trial_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::iteration_best_found(const unsigned int value) + { + _iteration_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::evaluations_best_found(const unsigned int value) + { + _evaluations_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::global_best_solution(const Solution& sol) + { + _global_best_solution.set_contents(sol.to_String(),1,sol.size()); + } + + void Solver::global_best_cost(const double value) + { + _global_best_cost.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::global_worst_cost(const double value) + { + _global_worst_cost.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::time_best_found(const float value) + { + _time_best_found.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::display_state(const int value) + { + _display_state.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::crossover_probability(const float *new_probability) + { + _sc.set_contents_state_variable("_crossover_probability",(char *)new_probability,MAX_PROB_PER_OP,sizeof(float)); + } + + void Solver::mutation_probability(const float *new_probability) + { + _sc.set_contents_state_variable("_mutation_probability",(char *)new_probability,MAX_PROB_PER_OP,sizeof(float)); + } + + void Solver::user_op_probability(const int index, const float *new_probability) + { + char aux[30] = "_user_op_probability"; + sprintf(aux,"%s%d",aux,index); + + _sc.set_contents_state_variable(aux,(char *)new_probability,MAX_PROB_PER_OP,sizeof(float)); + } + + void Solver::migration_rate(const unsigned int rate) + { + _sc.set_contents_state_variable("_migration_rate",(char *)&rate,1,sizeof(int)); + } + + void Solver::migration_size(const unsigned int size) + { + _sc.set_contents_state_variable("_migration_size",(char *)&size,1,sizeof(int)); + } + + void Solver::migration_selection_1(const unsigned int selection_1) + { + _sc.set_contents_state_variable("_migration_selection_1",(char *)&selection_1,1,sizeof(int)); + } + + void Solver::migration_selection_2(const unsigned int selection_2) + { + _sc.set_contents_state_variable("_migration_selection_2",(char *)&selection_2,1,sizeof(int)); + } + + void Solver::migration_selection_conf_1(const unsigned int selection_conf_1) + { + _sc.set_contents_state_variable("_migration_selection_conf_1",(char *)&selection_conf_1,1,sizeof(int)); + } + + void Solver::migration_selection_conf_2(const unsigned int selection_conf_2) + { + _sc.set_contents_state_variable("_migration_selection_conf_2",(char *)&selection_conf_2,1,sizeof(int)); + } + + void Solver::select_parents(const unsigned int selection) + { + _sc.set_contents_state_variable("_select_parents",(char *)&selection,1,sizeof(int)); + } + + void Solver::select_offsprings(const unsigned int selection) + { + _sc.set_contents_state_variable("_select_offsprings",(char *)&selection,1,sizeof(int)); + } + + void Solver::parameter_select_parents(const unsigned int value) + { + _sc.set_contents_state_variable("_parameter_select_parents",(char *)&value,1,sizeof(int)); + } + + void Solver::parameter_select_offsprings(const unsigned int value) + { + _sc.set_contents_state_variable("_parameter_select_offsprings",(char *)&value,1,sizeof(int)); + } + + Statistics& Solver::statistics() + { + return _stat; + } + + UserStatistics& Solver::userstatistics() + { + return _userstat; + } + + Population& Solver::population() + { + return current_population; + } + + const SetUpParams& Solver::setup() const + { + return params; + } + + const Problem& Solver::pbm() const + { + return problem; + } + + void Solver::KeepHistory(const Solution& best_sol,const double best_cost,const double worst_cost,const float time_spent_in_trial,const float total_time_spent) + { + bool betterG=false; + bool worseG=false; + bool betterT=false; + bool worseT=false; + + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_spent_in_trial < time_best_found())); + worseG = (worst_cost > global_worst_cost()); + betterT = (best_cost < best_cost_trial() || (best_cost == best_cost_trial() && time_spent_in_trial < time_best_found_trial())); + worseT = (worst_cost > worst_cost_trial()); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_spent_in_trial < time_best_found())); + worseG = (worst_cost < global_worst_cost()); + betterT = (best_cost > best_cost_trial() || (best_cost == best_cost_trial() && time_spent_in_trial < time_best_found_trial())); + worseT = (worst_cost < worst_cost_trial()); + break; + } + + if (betterT) + { + best_solution_trial(best_sol); + best_cost_trial(best_cost); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_in_trial(current_iteration()); + evaluations_best_found_in_trial(current_evaluations()); + if (betterG) + { + global_best_solution(best_sol); + global_best_cost(best_cost); + time_best_found(time_spent_in_trial); + trial_best_found(current_trial()); + iteration_best_found(current_iteration()); + evaluations_best_found(current_evaluations()); + } + } + + if (worseT) + { + worst_cost_trial(worst_cost); + if (worseG) + global_worst_cost(worst_cost); + } + } + + StateCenter *Solver::GetState() + { + return &_sc; + } + + void Solver::RefreshState() + { + current_best_solution(best_solution); + current_best_cost(best_cost); + current_worst_cost(worst_cost); + current_average_cost(average_cost); + current_standard_deviation(standard_deviation); + current_time_spent(total_time_spent); + time_spent_trial(time_spent_in_trial); + KeepHistory(best_solution,best_cost,worst_cost,time_spent_in_trial,total_time_spent); + } + + void Solver::RefreshCfgState() + { + for (int i=0;i<params.pool().intra_operators().size();i++) + params.pool().intra_operator(i).RefreshState(_sc); + for (int i=0;i<params.pool().inter_operators().size();i++) + params.pool().inter_operator(i).RefreshState(_sc); + params.RefreshState(_sc); + } + + void Solver::UpdateFromState() + { + best_solution=current_best_solution(); + best_cost=current_best_cost(); + worst_cost=current_worst_cost(); + average_cost=current_average_cost(); + standard_deviation=current_standard_deviation(); + total_time_spent=current_time_spent(); + time_spent_in_trial=time_spent_trial(); + KeepHistory(best_solution,best_cost,worst_cost,time_spent_in_trial,total_time_spent); + } + + void Solver::UpdateFromCfgState() + { + for (int i=0;i<params.pool().intra_operators().size();i++) + params.pool().intra_operator(i).UpdateFromState(_sc); + for (int i=0;i<params.pool().inter_operators().size();i++) + params.pool().inter_operator(i).UpdateFromState(_sc); + params.UpdateFromState(_sc); + } + + void Solver::show_state() const + { + cout << endl << " Current State ---------------------------------------------" << endl; +/* cout << endl << "Selection parents -> " << select_parents(); + cout << endl << "Parameter of selection: " << parameter_select_parents(); + cout << endl << "Selection offsprings -> " << select_offprings(); + cout << endl << "Parameter of selection: " << parameter_select_offsprings() << endl; + cout << endl << "Crossover_probability: " << crossover_probability(); + cout << endl << "Mutation_probability: " << mutation_probability(); + cout << endl << "User_Operator_probability: " << user_op_probability(0); + cout << endl << "Migration_rate: " << migration_rate(); + cout << endl << "Migration_size: " << migration_size(); + cout << endl << "Migration_selection_1: " << migration_selection_1(); + cout << endl << "Migration_selection_conf_1: " << migration_selection_conf_1(); + cout << endl << "Migration_selection_2: " << migration_selection_2(); + cout << endl << "Migration_selection_conf_2: " << migration_selection_conf_2() << endl; +*/ cout << endl << "Current trial: " << current_trial(); + cout << endl << "Current iteration: " << current_iteration(); + cout << endl << "Current evaluations: " << current_evaluations(); + cout << endl << "Current best cost: " << current_best_cost(); + cout << endl << "Current worst cost: " << current_worst_cost(); + cout << endl << "Current Average cost: " << current_average_cost(); + cout << endl << "Current Standard Deviation: " << current_standard_deviation(); + cout << endl << endl << "Trial: "; + cout << endl << "Best cost trial: " << best_cost_trial(); + cout << endl << "Worst cost trial: " << worst_cost_trial(); + cout << endl << "Iteration best found in trial: " << iteration_best_found_in_trial(); + cout << endl << "Evaluations best found in trial: " << evaluations_best_found_in_trial(); + cout << endl << "Time best found trial: " << time_best_found_trial(); + cout << endl << "Time spent in trial: " << time_spent_trial(); + cout << endl << endl << "Global: "; + cout << endl << "Global best cost: " << global_best_cost(); + cout << endl << "Global worst cost: " << global_worst_cost(); + cout << endl << "Trial best found: " << trial_best_found(); + cout << endl << "Iteration best found: " << iteration_best_found(); + cout << endl << "Evaluations best found: " << evaluations_best_found(); + cout << endl << "Time best found: " << time_best_found(); +// cout << endl << endl << "Best Solution: " << endl << global_best_solution(); + cout << endl << endl << "Current time spent (so far): " << current_time_spent() << endl; + } + + Solver::~Solver() + { + _sc.removeAll(); + } + +// Solver sequencial ----------------------------------------------------- + + Solver_Seq::Solver_Seq (const Problem& pbm, const SetUpParams& setup) + : Solver(pbm,setup) + { + random_seed(time(0)); + _end_trial=true; + } + + Solver_Seq::~Solver_Seq () + {} + + void Solver_Seq::StartUp() + { + Population pop(problem,params); + pop.initialize(); + StartUp(pop); + } + + void Solver_Seq::StartUp(const Population& pop) + { + start_trial=_used_time(); + start_global=total_time_spent; + + current_trial(current_trial()+1); + current_iteration(0); + current_evaluations(pop.evaluations()); + + // initialize state variables in the current trial + + Solution initial_solution(problem); + + time_spent_in_trial=0.0; + best_cost_trial((-1) * problem.direction() * infinity()); + worst_cost_trial((-1) * best_cost_trial()); + best_solution_trial(initial_solution); + time_best_found_trial(0.0); + + current_population=pop; + current_population.evaluate_parents(); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + void Solver_Seq::DoStep() + { + + current_iteration(current_iteration()+1); + current_population.evolution(); + current_evaluations(current_population.evaluations()); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + if( (current_iteration() % params.refresh_global_state()) == 0) + UpdateFromCfgState(); + + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + void Solver_Seq::run () + { + while (current_trial() < params.independent_runs()) + run(params.nb_evolution_steps()); + } + + void Solver_Seq::run (const unsigned long int nb_generations) + { + StartUp(); + while ((current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + + } + + void Solver_Seq::run (const Population& pop,const unsigned long int nb_generations) + { + StartUp(pop); + while ((current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + + } + + // Solver LAN ------------------------------------------------------------ + + Solver_Lan::Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0),acum_iterations(0) + + { + + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + // random_seed(time(0) + (mypid+1)); + } + + Solver_Lan::~Solver_Lan () + { + NetStream::finalize(); + } + + int Solver_Lan::pid() const + { + return mypid; + } + + NetStream& Solver_Lan::netstream() + { + return _netstream; + } + + void Solver_Lan::StartUp() + { + Population pop(problem,params); + pop.initialize(); + StartUp(pop); + } + + void Solver_Lan::StartUp(const Population& pop) + { + _netstream << barrier; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + acum_iterations = 0; + + start_trial=_used_time(); + start_global=total_time_spent; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + current_evaluations(pop.evaluations()); + + // initialize state variables in the current trial + + Solution initial_solution(problem); + + time_spent_in_trial=0.0; + best_cost_trial((-1) * problem.direction() * infinity()); + worst_cost_trial((-1) * best_cost_trial()); + best_solution_trial(initial_solution); + iteration_best_found_in_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current_population=pop; + current_population.evaluate_parents(); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + } + } + + void Solver_Lan::DoStep() + { + current_iteration(current_iteration()+1); + current_population.evolution(); + current_evaluations(current_population.evaluations()); + + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(regular, pending); + if(pending) + final_phase = true; + //////////////////////// + + current_population.interchange(current_iteration(),_netstream); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + // in this iteration i have to send data about my local state to the global state + if ((int)current_iteration() % params.refresh_global_state() ==0) + { + send_local_state_to(mypid); + UpdateFromCfgState(); + } + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + + + void Solver_Lan::send_local_state_to(int _mypid) { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_evaluations() + << best_solution_trial() + << current_best_solution() + << best_cost_trial() + << worst_cost_trial() + << time_best_found_trial() + << current_best_cost() + << current_worst_cost() + << current_average_cost() + << current_standard_deviation() + << iteration_best_found_in_trial() + << evaluations_best_found_in_trial() + << pack_end; + } + + int Solver_Lan::receive_local_state() { + int r_pid=0; + + _netstream._wait(packed); + + _netstream << pack_begin + >> r_pid + >> _current_trial + >> _current_iteration + >> _current_evaluations + >> _best_solution_trial + >> best_solution + >> _best_cost_trial + >> _worst_cost_trial + >> _time_best_found_in_trial + >> best_cost + >> worst_cost + >> average_cost + >> standard_deviation + >> _iteration_best_found_in_trial + >> _evaluations_best_found_in_trial + << pack_end; + return r_pid; + } + + void Solver_Lan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + _netstream << set_source(MPI_ANY_SOURCE); + + while (!_end_trial) + { + received_pid=0; + received_pid=receive_local_state(); + + current_trial(_current_trial); + + // refresh the global state with received data ( a local state ) + current_iteration(_iteration_best_found_in_trial); + current_evaluations(_evaluations_best_found_in_trial); + KeepHistory(_best_solution_trial,_best_cost_trial,_worst_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + // the process that has send data has finished the current trial + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && terminateQ(problem,*this,params)) + { + acum_iterations = params.nb_evolution_steps() * nb_finalized_processes; + acum_evaluations = acum_iterations* params.population_additional_size() + + nb_finalized_processes*params.population_size(); + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << 1; + } + final_phase = true; + } + nb_finalized_processes++; + acum_iterations += _iteration_best_found_in_trial; + acum_evaluations += _evaluations_best_found_in_trial; + } + if (nb_finalized_processes==nb_proc-1) + _end_trial=true; + + current_iteration(_current_iteration); + current_evaluations(_current_evaluations); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + RefreshState(); + RefreshCfgState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualizaci�n de las estad�sticas // Termination phase // + iteration_best_found_in_trial(acum_iterations/(_netstream.pnumber()-1)); + evaluations_best_found_in_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = best_cost_trial(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + { + iteration_best_found(iteration_best_found_in_trial()); + evaluations_best_found(evaluations_best_found_in_trial()); + } + + RefreshState(); + RefreshCfgState(); + + _stat.update(*this); + _userstat.update(*this); + + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Lan::run () + { + while (current_trial() < params.independent_runs()) + run(params.nb_evolution_steps()); + } + + void Solver_Lan::run (const unsigned long int nb_generations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Population& pop,const unsigned long int nb_generations) + { + StartUp(pop); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::reset() + { + Solution left_solution(problem); + int i; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> i; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } + + // Solver WAN ------------------------------------------------------------ + + Solver_Wan::Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0),acum_iterations(0) + { + + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + // random_seed(time(0) + (mypid+1)); + } + + Solver_Wan::~Solver_Wan () + { + NetStream::finalize(); + } + + int Solver_Wan::pid() const + { + return mypid; + } + + NetStream& Solver_Wan::netstream() + { + return _netstream; + } + + void Solver_Wan::StartUp() + { + Population pop(problem,params); + pop.initialize(); + StartUp(pop); + } + + void Solver_Wan::StartUp(const Population& pop) + { + _netstream << barrier; + + // Termination phase // + final_phase = false; + acum_evaluations = 0; + acum_iterations = 0; + + start_trial=_used_time(); + start_global=total_time_spent; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + current_evaluations(pop.evaluations()); + + // initialize state variables in the current trial + + Solution initial_solution(problem); + + time_spent_in_trial=0.0; + best_cost_trial((-1) * problem.direction() * infinity()); + worst_cost_trial((-1) * best_cost_trial()); + best_solution_trial(initial_solution); + iteration_best_found_in_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current_population=pop; + current_population.evaluate_parents(); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + } + } + + void Solver_Wan::DoStep() + { + current_iteration(current_iteration()+1); + current_population.evolution(); + current_evaluations(current_population.evaluations()); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(regular, pending); + if(pending) + final_phase = true; + //////////////////////// + + current_population.interchange(current_iteration(),_netstream); + + // gets current interesting values in the current population + + best_cost=current_population.best_cost(); + best_solution=current_population.best_solution(); + worst_cost=current_population.worst_cost(); + average_cost=current_population.average_cost(); + standard_deviation=current_population.standard_deviation(); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + // refresh state with these values + RefreshState(); + RefreshCfgState(); + + // in this iteration i have to send data about my local state to the global state + if ((int)current_iteration() % params.refresh_global_state() ==0) + { + send_local_state_to(mypid); + UpdateFromCfgState(); + } + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + + + void Solver_Wan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_evaluations() + << best_cost_trial() + << best_solution_trial() + << iteration_best_found_in_trial() + << evaluations_best_found_in_trial() + << time_best_found_trial() + << worst_cost_trial() + << current_best_cost() + << current_best_solution() + << current_worst_cost() + << current_average_cost() + << current_standard_deviation() + << pack_end; + } + + int Solver_Wan::receive_local_state() + { + int r_pid=0; + + _netstream._wait(packed); + + _netstream << pack_begin + >> r_pid + >> _current_trial + >> _current_iteration + >> _current_evaluations + >> _best_cost_trial + >> _best_solution_trial + >> _iteration_best_found_in_trial + >> _evaluations_best_found_in_trial + >> _time_best_found_in_trial + >> _worst_cost_trial + >> best_cost + >> best_solution + >> worst_cost + >> average_cost + >> standard_deviation + << pack_end; + return r_pid; + } + + void Solver_Wan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + _netstream << set_source(MPI_ANY_SOURCE); + + while (!_end_trial) + { + received_pid=0; + received_pid=receive_local_state(); + + current_trial(_current_trial); + + // refresh the global state with received data ( a local state ) + current_iteration(_iteration_best_found_in_trial); + current_evaluations(_evaluations_best_found_in_trial); + KeepHistory(_best_solution_trial,_best_cost_trial,_worst_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + // the process that has send data has finished the current trial + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && terminateQ(problem,*this,params)) + { + acum_iterations = params.nb_evolution_steps() * nb_finalized_processes; + acum_evaluations = acum_iterations* params.population_additional_size() + + nb_finalized_processes*params.population_size(); + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << 1; + } + final_phase = true; + } + nb_finalized_processes++; + acum_iterations += _iteration_best_found_in_trial; + acum_evaluations += _evaluations_best_found_in_trial; + } + if (nb_finalized_processes==nb_proc-1) + _end_trial=true; + + current_iteration(_current_iteration); + current_evaluations(_current_evaluations); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + RefreshState(); + RefreshCfgState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Update Stats // Termination phase // + iteration_best_found_in_trial(acum_iterations/(_netstream.pnumber()-1)); + evaluations_best_found_in_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = best_cost_trial(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + { + iteration_best_found(iteration_best_found_in_trial()); + evaluations_best_found(evaluations_best_found_in_trial()); + } + + RefreshState(); + RefreshCfgState(); + + _stat.update(*this); + _userstat.update(*this); + + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Wan::run () + { + while (current_trial() < params.independent_runs()) + run(params.nb_evolution_steps()); + } + + void Solver_Wan::run (const unsigned long int nb_generations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Population& pop,const unsigned long int nb_generations) + { + StartUp(pop); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < nb_generations) && !(terminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::reset() + { + Solution left_solution(problem); + int i; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> i ; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + + } + _netstream << barrier; + } + +} + + diff --git a/ProyectoFinal/CHC/malva/rep/GA/newGA.pro.o b/ProyectoFinal/CHC/malva/rep/GA/newGA.pro.o new file mode 100644 index 0000000000000000000000000000000000000000..8a79374826a57f9269ae72e0a8447080a445c8b4 Binary files /dev/null and b/ProyectoFinal/CHC/malva/rep/GA/newGA.pro.o differ diff --git a/ProyectoFinal/CHC/malva/rep/GA/newGA.req.cc b/ProyectoFinal/CHC/malva/rep/GA/newGA.req.cc new file mode 100644 index 0000000000000000000000000000000000000000..653d43b819666278652d4834d7116555127fdffd --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/GA/newGA.req.cc @@ -0,0 +1,778 @@ +#ifndef INC_REQ_newGA +#define INC_REQ_newGA +#include "newGA.hh" +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sstream> +#include <algorithm> + +skeleton newGA +{ + + // Problem --------------------------------------------------------------- + + Problem::Problem ():_dimension(0),_limite_barrios(NULL),_tareasEsf(NULL),_tareasIndex(NULL),_empleados(NULL),_cantDias(0),_cantEmpleados(0) + { + //cout << "uf6"; + } + + ostream& operator<< (ostream& os, const Problem& pbm) + { + os << endl << endl << "Number of Variables " << pbm._dimension + << endl; + + //Imprimo el arreglo con los limites de barrios + os<<"Limites de barrios: "<<endl<<endl; + for (int i=0;i<pbm._dimension;i++){ + os<<i<<": "; + int indice=0; + while (pbm._limite_barrios[i][indice]!=-1){ + os<<pbm._limite_barrios[i][indice]<<","; + indice++; + } + os<<endl; + } + os<<endl; + return os; + } + + + + istream& operator>> (istream& is, Problem& pbm) + { + + char buffer[MAX_BUFFER]; + int i; + + //is.getline(buffer,MAX_BUFFER,'\n'); + //sscanf(buffer,"%d",&pbm._dimension); + + //CARGAR DATO CANT Tareas + ifstream inFile; + inFile.open("datos_cantidad_tareas"); + if (!inFile) + { + cerr << "Unable to open file datafile.txt"; + exit(1); // call system to stop + } + string x; + getline(inFile,x); + pbm._dimension = stoi(x); + inFile.close(); + + //Pido memoria para almacenar los limites de los barrios + pbm._limite_barrios=new int *[pbm._dimension]; + for (int i=0;i<pbm._dimension;i++) + { + pbm._limite_barrios[i]=new int [10]; + for (int j=0;j<10;j++) + pbm._limite_barrios[i][j]=-1; + } + + //CARGAR DATO CANT EMPLEADOS + inFile; + inFile.open("datos_cantidad_empleados"); + if (!inFile) + { + cerr << "Unable to open file datafile.txt"; + exit(1); // call system to stop + } + //string x; + getline(inFile,x); + pbm._cantEmpleados = stoi(x); + inFile.close(); + //INICIALIZAR DATOS TAREAS ESFUERZO + pbm._tareasEsf=new int [pbm._dimension]; + for (int ii=0;ii<pbm._dimension;ii++) + { + pbm._tareasEsf[ii]=0; + } + + + //CARGAR DATOS TAREAS ESFUERZO + + inFile.open("datos_tareas"); + if (!inFile) + { + cerr << "Unable to open file datafile.txt"; + exit(1); // call system to stop + } + string line2; + getline(inFile,line2); + pbm._cantDias = stoi(line2); + getline(inFile, line2); + getline(inFile, line2); + + int n = line2.length(); + char char_array[n+1]; + int len=1; + int t=0; + int z=0; + for(int i=0; i<=line2.length(); i++) + { + if(line2[i] == ' '|| i==line2.length()) + { + string rr = line2.substr(z,len); + pbm._tareasEsf[t] = stoi(rr); + //cout << rr << " "; + t=t+1; + z=i+1; + len=1; + //s.erase(i,1); + } + else len=len+1; + } + inFile.close(); + + + pbm._tareasIndex = new int[pbm._dimension]; + for (int i = 0 ; i != pbm._dimension ; i++) + { + pbm._tareasIndex[i] = i; + } + sort(pbm._tareasIndex, pbm._tareasIndex + pbm._dimension,[&](const int& a, const int& b) { return (pbm._tareasEsf[a] < pbm._tareasEsf[b]); }); + /* + for (int i = 0 ; i != pbm._dimension ; i++) + { + cout << pbm._tareasIndex[i] << " "; + } + exit(0); + */ + + //INICIALIZAR EMPLEADOS + pbm._empleados=new Empleado [pbm._cantEmpleados]; + for (int zz=0;zz<pbm._cantEmpleados;zz++) + { + + pbm._empleados[zz]._sueldo = 0; + pbm._empleados[zz]._habilidad=0; + pbm._empleados[zz]._horas=0; + } + + //CARGAS DATOS EMPLEADOS + + string line23; + inFile.open("datos_empleados"); + getline(inFile, line23); + getline(inFile, line23); + int no = line23.length(); + char_array[n+1]; + len=1; + t=0; + z=0; + for(int i=0; i<=line23.length(); i++) + { + if(line23[i] == ' ' || i==line23.length()) + { + string rrr = line23.substr(z,len); + pbm._empleados[t]._horas = stoi(rrr); + //cout << rr << " "; + t=t+1; + z=i+1; + len=1; + //s.erase(i,1); + } + else len=len+1; + } + cout << pbm._empleados[0]._horas <<" " << pbm._empleados[1]._horas <<" " << pbm._empleados[2]._horas <<" " << pbm._empleados[3]._horas << " " << pbm._empleados[4]._horas << " " << endl; + + getline(inFile, line23); + no = line23.length(); + char_array[n+1]; + len=1; + t=0; + z=0; + // cout << line23; + for(int i=0; i<=line23.length(); i++) + { + if(line23[i] == ' ' || i==line23.length()) + { + string rrr = line23.substr(z,len); + pbm._empleados[t]._habilidad = stof(rrr); + //cout << rrr << " "; + t=t+1; + z=i+1; + len=1; + //s.erase(i,1); + } + else len=len+1; + } + cout << pbm._empleados[0]._habilidad <<" " << pbm._empleados[1]._habilidad <<" " << pbm._empleados[2]._habilidad <<" " << pbm._empleados[3]._habilidad << " " << pbm._empleados[4]._habilidad << " " << endl; + + getline(inFile, line23); + no = line23.length(); + char_array[n+1]; + len=1; + t=0; + z=0; + for(int i=0; i<=line23.length(); i++) + { + if(line23[i] == ' ' || i==line23.length()) + { + string rrr = line23.substr(z,len); + pbm._empleados[t]._sueldo = stoi(rrr); + //cout << rr << " "; + t=t+1; + z=i+1; + len=1; + //s.erase(i,1); + } + else len=len+1; + } + cout << pbm._empleados[0]._sueldo <<" " << pbm._empleados[1]._sueldo <<" " << pbm._empleados[2]._sueldo <<" " << pbm._empleados[3]._sueldo << " " << pbm._empleados[4]._sueldo << " " << endl; + //assert(false); + inFile.close(); + + /* + //Cargo el archivo con los limites de los barrios + FILE* stream = fopen("limite_barrios.csv", "r"); + + char line[1024]; + while (fgets(line, 1024, stream)) + { + char* tmp = strdup(line); + const char * barrio = pbm.getfield(tmp,1); + int barrio_int=atoi(barrio); + tmp = strdup(line); + const char * limite= pbm.getfield(tmp,2); + int i=0; + while (limite!=NULL) + { + pbm._limite_barrios[barrio_int-1][i]=atoi(limite)-1; + i++; + tmp = strdup(line); + limite=pbm.getfield(tmp,i+2); + } + free(tmp); + } + */ + cout<<pbm; + return is; + } + + //Funcion para leer el archivo CSV + const char* Problem::getfield(char* line, int num) + { + const char* tok; + for (tok = strtok(line, ","); + tok && *tok; + tok = strtok(NULL, ",\n")) + { + if (!--num) + return tok; + } + return NULL; + } + + int ** Problem::limite_barrios() const{ + return _limite_barrios; + } + + + bool Problem::operator== (const Problem& pbm) const + { + if (_dimension!=pbm.dimension()) return false; + return true; + } + + bool Problem::operator!= (const Problem& pbm) const + { + return !(*this == pbm); + } + + Direction Problem::direction() const + { + //return maximize; + return minimize; + } + + int Problem::dimension() const + { + return _dimension; + } + int Problem::cantEmpleados() const + { + return _cantEmpleados; + } + int Problem::cantDias() const + { + return _cantDias; + } + + int * Problem::tareasEsf() const + { + return _tareasEsf; + } + + int * Problem::tareasIndex() const + { + return _tareasIndex; + } + + Empleado *Problem::empleados() const + { + return _empleados; + } + + Problem::~Problem() + { + //Libero la memoria pedida para almacenar los limites de los barrios + for (int i=0;i<_dimension;i++) + delete [] _limite_barrios[i]; + delete [] _limite_barrios; + delete [] _empleados; + delete [] _tareasEsf; + } + + // Solution -------------------------------------------------------------- + + Solution::Solution (const Problem& pbm):_pbm(pbm),_var(pbm.dimension()) + {} + + const Problem& Solution::pbm() const + { + return _pbm; + } + + Solution::Solution(const Solution& sol):_pbm(sol.pbm()) + { + *this=sol; + } + + istream& operator>> (istream& is, Solution& sol) + { + for (int i=0;i<sol.pbm().dimension();i++) + is >> sol._var[i]; + return is; + } + + ostream& operator<< (ostream& os, const Solution& sol) + { + + //for (int i=0;i<sol.pbm().dimension();i++) + // os << " " << sol._var[i]; + stringstream ss; + + ofstream outfile("solution"); + + os << endl; + + for (int j = 0; j < sol.pbm().cantEmpleados(); j++) + { + bool found1 = false; + for (int i = 0; i < sol.pbm().dimension(); i++) + { + if (sol._var[i] == j) + { + if (!found1) + { + ss << "e" << j + 1; + found1 = true; + } + + ss << " t" << sol.pbm().tareasIndex()[i] + 1; + } + } + + if (found1) + { + ss << endl; + } + } + + outfile << ss.str(); + outfile.close(); + + os << ss.str(); + + return os; + } + + NetStream& operator << (NetStream& ns, const Solution& sol) + { + for (int i=0;i<sol._var.size();i++) + ns << sol._var[i]; + return ns; + } + + NetStream& operator >> (NetStream& ns, Solution& sol) + { + for (int i=0;i<sol._var.size();i++) + ns >> sol._var[i]; + return ns; + } + + Solution& Solution::operator= (const Solution &sol) + { + _var=sol._var; + return *this; + } + + bool Solution::operator== (const Solution& sol) const + { + if (sol.pbm() != _pbm) return false; + for(int i = 0; i < _var.size(); i++) + if(_var[i] != sol._var[i]) return false; + return true; + } + + bool Solution::operator!= (const Solution& sol) const + { + return !(*this == sol); + } + + void Solution::initialize() + { + //cout << _pbm.dimension(); + for (int i=0;i<_pbm.dimension();i++) + { + _var[i]=rand_int(0,_pbm.cantEmpleados() - 1); + //_var[i]=rand_int(0,3); + } + } + + double Solution::fitness () + { + + double fitness = 0.0; + double* horasTrabajados = new double[_pbm.cantEmpleados()]; + for (int q=0; q < _pbm.cantEmpleados(); q++) + { + horasTrabajados[q] = 0; + } + + for (int i=0;i< _pbm.dimension();i++) + { + Empleado tipo = _pbm.empleados()[_var[i]]; + double horasReq = ((double)_pbm.tareasEsf()[_pbm.tareasIndex()[i]]/(double)(0.5+tipo._habilidad)); + horasTrabajados[_var[i]] += horasReq; + + } + + + for (int j = 0; j < _pbm.cantEmpleados(); j++) + { + double diasTrabajadosTemp = (double)horasTrabajados[j] / (double)_pbm.empleados()[j]._horas; + fitness += (double)diasTrabajadosTemp * (double)_pbm.empleados()[j]._sueldo; + if (isnan(fitness)) + exit(0); + if (diasTrabajadosTemp > _pbm.cantDias()) + { + fitness += 100000; + } + } + + return fitness; + + } + + char *Solution::to_String() const + { + return (char *)_var.get_first(); + } + + void Solution::to_Solution(char *_string_) + { + int *ptr=(int *)_string_; + for (int i=0;i<_pbm.dimension();i++) + { + _var[i]=*ptr; + ptr++; + } + } + + unsigned int Solution::size() const + { + return (_pbm.dimension() * sizeof(int)); + } + + + int& Solution::var(const int index) + { + return _var[index]; + } + + + Rarray<int>& Solution::array_var() + { + return _var; + } + + Solution::~Solution() + {} + + // UserStatistics ------------------------------------------------------- + + UserStatistics::UserStatistics () + {} + + ostream& operator<< (ostream& os, const UserStatistics& userstat) + { + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF TRIALS " << endl; + os << "------------------------------------------------------------------" << endl; + + for (int i=0;i< userstat.result_trials.size();i++) + { + os << endl + << userstat.result_trials[i].trial + << "\t" << userstat.result_trials[i].best_cost_trial + << "\t\t" << userstat.result_trials[i].worst_cost_trial + << "\t\t\t" << userstat.result_trials[i].nb_evaluation_best_found_trial + << "\t\t\t" << userstat.result_trials[i].nb_iteration_best_found_trial + << "\t\t\t" << userstat.result_trials[i].time_best_found_trial + << "\t\t" << userstat.result_trials[i].time_spent_trial; + } + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + UserStatistics& UserStatistics::operator= (const UserStatistics& userstats) + { + result_trials=userstats.result_trials; + return (*this); + } + + void UserStatistics::update(const Solver& solver) + { + if( (solver.pid()!=0) || (solver.end_trial()!=true) + || ((solver.current_iteration()!=solver.setup().nb_evolution_steps()) + && !terminateQ(solver.pbm(),solver,solver.setup()))) + return; + + struct user_stat *new_stat; + + if ((new_stat=(struct user_stat *)malloc(sizeof(struct user_stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluation_best_found_trial = solver.evaluations_best_found_in_trial(); + new_stat->nb_iteration_best_found_trial = solver.iteration_best_found_in_trial(); + new_stat->worst_cost_trial = solver.worst_cost_trial(); + new_stat->best_cost_trial = solver.best_cost_trial(); + new_stat->time_best_found_trial = solver.time_best_found_trial(); + new_stat->time_spent_trial = solver.time_spent_trial(); + + result_trials.append(*new_stat); + } + + void UserStatistics::clear() + { + result_trials.remove(); + } + + UserStatistics::~UserStatistics() + { + result_trials.remove(); + } + +// Intra_operator -------------------------------------------------------------- + + Intra_Operator::Intra_Operator(const unsigned int _number_op):_number_operator(_number_op),probability(NULL) + {} + + unsigned int Intra_Operator::number_operator() const + { + return _number_operator; + } + + Intra_Operator *Intra_Operator::create(const unsigned int _number_op) + { + switch (_number_op) + { + case 0: return new Crossover;break; + case 1: return new Mutation();break; + } + } + + ostream& operator<< (ostream& os, const Intra_Operator& intra) + { + switch (intra.number_operator()) + { + case 0: os << (Crossover&)intra;break; + case 1: os << (Mutation&)intra;break; + } + return os; + } + + Intra_Operator::~Intra_Operator() + {} + +// Crossover:Intra_operator ------------------------------------------------------------- + + Crossover::Crossover():Intra_Operator(0) + { + probability = new float[1]; + } + + void Crossover::cross(Solution& sol1,Solution& sol2) const // dadas dos soluciones de la poblacion, las cruza + { + //Usamos cruzamiento de dos puntos (2PX) + int i=0; + Rarray<int> aux(sol1.pbm().dimension()); + aux=sol2.array_var(); + + /* + if (current_time_spent() < 1000000) + { + int limit=rand_int((0,sol1.pbm().dimension()-1)); + + for (i=0;i<limit;i++) + sol2.var(i)=sol1.var(i); + for (i=0;i<limit;i++) + sol1.var(i)=aux[i]; + } + if (current_time_spent() >= 1000000) + {*/ + int limit=rand_int((sol1.pbm().dimension()/2)+1,sol1.pbm().dimension()-1); + int limit2=rand_int(0,limit-1); + + for (i=0;i<limit2;i++) + sol2.var(i)=sol1.var(i); + for (i=0;i<limit2;i++) + sol1.var(i)=aux[i]; + for (i=limit;i<sol1.pbm().dimension();i++) + sol2.var(i)=sol1.var(i); + for (i=limit;i<sol1.pbm().dimension();i++) + sol1.var(i)=aux[i]; + //} + } + + void Crossover::execute(Rarray<Solution*>& sols) const + { + for (int i=0;i+1<sols.size();i=i+2) + if (rand01()<=probability[0]) cross(*sols[i],*sols[i+1]); + } + + ostream& operator<< (ostream& os, const Crossover& cross) + { + os << "Crossover." << " Probability: " + << cross.probability[0] + << endl; + return os; + } + + void Crossover::RefreshState(const StateCenter& _sc) const + { + _sc.set_contents_state_variable("_crossover_probability",(char *)probability,1,sizeof(float)); + } + + void Crossover::UpdateFromState(const StateCenter& _sc) + { + unsigned long nbytes,length; + _sc.get_contents_state_variable("_crossover_probability",(char *)probability,nbytes,length); + } + + void Crossover::setup(char line[MAX_BUFFER]) + { + int op; + sscanf(line," %d %f ",&op,&probability[0]); + assert(probability[0]>=0); + } + + Crossover::~Crossover() + { + delete [] probability; + } + + // Mutation: Sub_operator ------------------------------------------------------------- + + Mutation::Mutation():Intra_Operator(1) + { + probability = new float[2]; + } + + void Mutation::mutate(Solution& sol) const + { + for (int i=0;i<sol.pbm().dimension();i++) + { + if (rand01()<=probability[1]) + { + //La mutacion modifica un gen aleatoriamente con probabilidad uniforme en {0,3} + int temp = rand_int(0,sol.pbm().cantEmpleados() - 1); + sol.var(i)= temp; + //sol.var(i)=rand_int(0,3); + } + } + } + + void Mutation::execute(Rarray<Solution*>& sols) const + { + for (int i=0;i<sols.size();i++) + if(rand01() <= probability[0]) mutate(*sols[i]); + } + + ostream& operator<< (ostream& os, const Mutation& mutation) + { + os << "Mutation." << " Probability: " << mutation.probability[0] + << " Probability1: " << mutation.probability[1] + << endl; + return os; + } + + void Mutation::setup(char line[MAX_BUFFER]) + { + int op; + sscanf(line," %d %f %f ",&op,&probability[0],&probability[1]); + assert(probability[0]>=0); + assert(probability[1]>=0); + } + + void Mutation::RefreshState(const StateCenter& _sc) const + { + _sc.set_contents_state_variable("_mutation_probability",(char *)probability,2,sizeof(probability)); + } + + void Mutation::UpdateFromState(const StateCenter& _sc) + { + unsigned long nbytes,length; + _sc.get_contents_state_variable("_mutation_probability",(char *)probability,nbytes,length); + } + + Mutation::~Mutation() + { + delete [] probability; + } + +// StopCondition_1 ------------------------------------------------------------------------------------- + + StopCondition_1::StopCondition_1():StopCondition() + {} + + bool StopCondition_1::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + bool fin=(int) (solver.current_time_spent() - solver.time_best_found_trial()) > 20000000; + //Condicion de parada. Si el fitness es 0 terminamos la ejecucion. + //bool fin=(int)solver.best_cost_trial() == 0; + //cout << pbm.cantEmpleados(); + /*if (fin){ + //Escribo el resultado en el archivo de salida + FILE * pFile; + pFile = fopen ("asignacion_colores.csv","w"); + for (int i=0;i<pbm.dimension();i++){ + fprintf (pFile, "%d,%d\n",i+1,solver.best_solution_trial().var(i)); + } + fclose (pFile); + }*/ + //return (fin); + return fin; + + } + + StopCondition_1::~StopCondition_1() + {} + + //------------------------------------------------------------------------ + // Specific methods ------------------------------------------------------ + //------------------------------------------------------------------------ + + bool terminateQ (const Problem& pbm, const Solver& solver, + const SetUpParams& setup) + { + StopCondition_1 stop; + return stop.EvaluateCondition(pbm,solver,setup); + } +} +#endif + diff --git a/ProyectoFinal/CHC/malva/rep/GA/newGA.req.o b/ProyectoFinal/CHC/malva/rep/GA/newGA.req.o new file mode 100644 index 0000000000000000000000000000000000000000..b38ae8dbb12876fd40eff199783aea8c7db92186 Binary files /dev/null and b/ProyectoFinal/CHC/malva/rep/GA/newGA.req.o differ diff --git a/ProyectoFinal/CHC/malva/rep/GA/newGAstructures.hh b/ProyectoFinal/CHC/malva/rep/GA/newGAstructures.hh new file mode 100644 index 0000000000000000000000000000000000000000..d542639f222df0d80bef4ac47ef28b5d9c878b26 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/GA/newGAstructures.hh @@ -0,0 +1,60 @@ +#ifndef INC_newGA_mallba_hh +#define INC_newGA_mallba_hh + + +#include <iostream> +#include <fstream> +#include <math.h> +#include <limits.h> +#include <float.h> +#include <Rlist.h> +#include <Rarray.h> +#include <Messages.h> +#include <mallba.hh> +#include <States.hh> +#include <random.hh> +#include <time.hh> +#include <netstream.hh> +#include <assert.h> + +using namespace std; + +#ifndef _INDIVIDUAL_ +#define _INDIVIDUAL_ + +struct individual // index of a individual in the population and its fitness +{ + int index; + double fitness; + double sel_parameter; + bool change; +}; +struct Empleado // index of a individual in the population and its fitness +{ + int _horas; + float _habilidad; + double _sueldo; +}; + + +/*int lessF(const struct individual &i1,const struct individual &i2) +{ + return i1.fitness < i2.fitness; +} + +int lessS(const struct individual &i1,const struct individual &i2) +{ + return i1.sel_parameter < i2.sel_parameter; +} + +int greaterF(const struct individual &i1,const struct individual &i2) +{ + return i1.fitness > i2.fitness; +} + +int greaterS(const struct individual &i1,const struct individual &i2) +{ + return i1.sel_parameter > i2.sel_parameter; +}*/ +#endif +#endif diff --git a/ProyectoFinal/CHC/malva/rep/GA/res/datos_cantidad_empleados b/ProyectoFinal/CHC/malva/rep/GA/res/datos_cantidad_empleados new file mode 100644 index 0000000000000000000000000000000000000000..7813681f5b41c028345ca62a2be376bae70b7f61 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/GA/res/datos_cantidad_empleados @@ -0,0 +1 @@ +5 \ No newline at end of file diff --git a/ProyectoFinal/CHC/malva/rep/GA/res/datos_cantidad_tareas b/ProyectoFinal/CHC/malva/rep/GA/res/datos_cantidad_tareas new file mode 100644 index 0000000000000000000000000000000000000000..301160a93062df23030a69f4b5e4d9bf71866ee9 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/GA/res/datos_cantidad_tareas @@ -0,0 +1 @@ +8 \ No newline at end of file diff --git a/ProyectoFinal/CHC/malva/rep/GA/res/datos_empleados b/ProyectoFinal/CHC/malva/rep/GA/res/datos_empleados new file mode 100644 index 0000000000000000000000000000000000000000..f7cc5e5ffd3d2a61ae5180d3f7da918b35f73197 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/GA/res/datos_empleados @@ -0,0 +1,4 @@ +e1 e2 e3 e4 e5 +4 5 5 3 3 +0.05 0.20 0.30 0.95 0.50 +120 200 210 230 180 diff --git a/ProyectoFinal/CHC/malva/rep/GA/res/datos_tareas b/ProyectoFinal/CHC/malva/rep/GA/res/datos_tareas new file mode 100644 index 0000000000000000000000000000000000000000..589272f5c15492f95741ff1b7c8bd9669e9d4993 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/GA/res/datos_tareas @@ -0,0 +1,3 @@ +20 +t1 t2 t3 t4 t5 t6 t7 t8 +16 28 11 51 2 23 43 15 diff --git a/ProyectoFinal/CHC/malva/rep/GA/res/empty.txt b/ProyectoFinal/CHC/malva/rep/GA/res/empty.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ProyectoFinal/CHC/malva/rep/GA/res/sol.txt b/ProyectoFinal/CHC/malva/rep/GA/res/sol.txt new file mode 100644 index 0000000000000000000000000000000000000000..94d8af392a9a33d04b7d961d7eabcdded57dc43a --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/GA/res/sol.txt @@ -0,0 +1,16 @@ + +--------------------------------------------------------------- + STATISTICS OF TRIALS +------------------------------------------------------------------ + +1 10029.7 210883 1060 10 1591 14184 +2 10010.4 210882 5560 55 6233 12361 +3 10010.4 210656 4160 41 8672 14731 +4 10009.9 210921 160 1 106 9399 +5 10010.4 210807 4660 46 4349 9349 +6 10010.4 210921 760 7 657 9224 +7 10016.5 210990 3060 30 5449 11825 +8 10015.4 210452 4960 49 5341 10215 +9 10035.1 210876 5960 59 5591 9491 +10 10017.7 210873 360 3 295 9422 +------------------------------------------------------------------ diff --git a/ProyectoFinal/CHC/malva/rep/GA/solution b/ProyectoFinal/CHC/malva/rep/GA/solution new file mode 100644 index 0000000000000000000000000000000000000000..534d0b7a1dbc05e068cc2ef7d4af1f20ef8ed28c --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/GA/solution @@ -0,0 +1,3 @@ +e1 t3 t1 +e3 t5 t6 t4 +e4 t8 t2 t7 diff --git a/ProyectoFinal/CHC/malva/rep/GA/verificador.py b/ProyectoFinal/CHC/malva/rep/GA/verificador.py new file mode 100644 index 0000000000000000000000000000000000000000..0924a327b9ff14cc512ce6195fef79c66afcd093 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/GA/verificador.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import sys +import random +import math + +try: + #Sanity check + if (len(sys.argv)<4): + print "Ejecutar con la siguiente linea: ./validador <ruta_tareas> <ruta_empleados> <ruta_solucion>" + sys.exit(1) + + ruta_tareas=sys.argv[1] + ruta_empleados=sys.argv[2] + ruta_solucion=sys.argv[3] + habilidad_empleados=[] + sueldo_diario_empleado=[] + dedicacion_diaria_diponible_empleado=[] + esfuerzo_requerido_tarea=[] + nombres_tareas=[] + nombre_empleados=[] + costo_proyecto=0 + tiempo_solucion_proyecto=0 + + # se sabe que son 3 lineas + archivo_tareas=open(ruta_tareas) + lineasTareas=archivo_tareas.readlines() + deadLine=lineasTareas[0] + nombres_tareas=lineasTareas[1].strip().split(" ") + esfuerzo_requerido_tarea=lineasTareas[2].strip().split(" ") + + # se sabe que son 4 lineas + archivo_empleados=open(ruta_empleados) + lineasEmpleados=archivo_empleados.readlines() + nombre_empleados=lineasEmpleados[0].strip().split(" ") + dedicacion_diaria_diponible_empleado=lineasEmpleados[1].strip().split(" ") + habilidad_empleados=lineasEmpleados[2].strip().split(" ") + sueldo_diario_empleado=lineasEmpleados[3].strip().split(" ") + + # se convierten a entero + dedicacion_diaria_diponible_empleado = map(int, dedicacion_diaria_diponible_empleado) + sueldo_diario_empleado = map(int, sueldo_diario_empleado) + deadLine=int(deadLine) + esfuerzo_requerido_tarea = map(int, esfuerzo_requerido_tarea) + + # se convierte a float + habilidad_empleados = map(float, habilidad_empleados) + + # se levanta la solucion del archivo + matriz_solucion=[] + + archivo_solucion=open(ruta_solucion) + + solucion_empleados_tareas=[] + solucion_empleados=[] + solucion_tareas=[] + + for line in archivo_solucion.readlines(): + empleados_tareas=line.strip().split(" ") + if( not (empleados_tareas[0] in nombre_empleados)): + print "No existe en la instancia el empleado: " + empleados_tareas[0] + sys.exit(1) + solucion_empleados.append(empleados_tareas[0]) + for i in range(1,len(empleados_tareas)): + if( not (empleados_tareas[i] in nombres_tareas)): + print "No existe en la instancia la terea: " + empleados_tareas[i] + sys.exit(1) + solucion_tareas.append(empleados_tareas[i]) + + + for i in range(0,len(solucion_empleados)): + for j in range(i+1,len(solucion_empleados)): + if(solucion_empleados[i]==solucion_empleados[j]): + print "Empleado repetido: " + solucion_empleados[i] + sys.exit(1) + + for i in range(0,len(solucion_tareas)): + for j in range(i+1,len(solucion_tareas)): + if(solucion_tareas[i]==solucion_tareas[j]): + print "Tarea asignada más de una vez: " + solucion_tareas[i] + sys.exit(1) + + + # todas las tareas asignadas + if(len(solucion_tareas)!=len(nombres_tareas)): + print "La cantidad de tareas asignadas es distinta a la cantidad de tareas de la instancia." + sys.exit(1) + + for i in range(0,len(nombres_tareas)): + if( not (nombres_tareas[i] in solucion_tareas)): + print "Tarea no asignada " + nombres_tareas[i] + sys.exit(1) + + costo_total=0 + archivo_solucion=open(ruta_solucion) + maximo_tiempo=0 + tiempo_en_dias=0 + # se hacen los calculos con la informacion en los archivos + for line in archivo_solucion.readlines(): + empleados_tareas=line.strip().split(" ") + indice_empleado = nombre_empleados.index(empleados_tareas[0]) + tiempo_en_horas=0 + for i in range(1,len(empleados_tareas)): + indice_tarea = nombres_tareas.index(empleados_tareas[i]) + tiempo_en_horas=tiempo_en_horas+(esfuerzo_requerido_tarea[indice_tarea] / (0.5 + habilidad_empleados[indice_empleado])) + tiempo_en_dias= int(math.ceil(tiempo_en_horas/dedicacion_diaria_diponible_empleado[indice_empleado])) + costo_total=costo_total+sueldo_diario_empleado[indice_empleado]*tiempo_en_dias + if(tiempo_en_dias>maximo_tiempo): + maximo_tiempo=tiempo_en_dias + + if(maximo_tiempo<=deadLine): + # todo OK! + print costo_total,maximo_tiempo + else: + print "No cumple con el tiempo máximo de finalización ({0} > {1}).".format(maximo_tiempo, deadLine) + sys.exit(1) + +except IOError as error: + print error diff --git a/ProyectoFinal/CHC/malva/rep/Makefile b/ProyectoFinal/CHC/malva/rep/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..2b7ed1503e73358a5787a7ed1eabcc8c12de78fd --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/Makefile @@ -0,0 +1,6 @@ +all: + (cd CHC ; make) + (cd GA ; make) +clean: + (cd CHC ; make clean) + (cd GA ; make clean) \ No newline at end of file diff --git a/ProyectoFinal/CHC/malva/rep/SA/Config.cfg b/ProyectoFinal/CHC/malva/rep/SA/Config.cfg new file mode 100644 index 0000000000000000000000000000000000000000..c515435da2092c6d52b8ecdc12a01334e495d199 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/Config.cfg @@ -0,0 +1,3 @@ +SA.cfg +Instance Problem Path +Result File Path diff --git a/ProyectoFinal/CHC/malva/rep/SA/MainLan.cc b/ProyectoFinal/CHC/malva/rep/SA/MainLan.cc new file mode 100644 index 0000000000000000000000000000000000000000..8949422e10f93211d953aba1308c203d13f30f0a --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/MainLan.cc @@ -0,0 +1,53 @@ +#include "SA.hh" +#include <iostream.h> +#include <fstream.h> + +int main (int argc, char** argv) +{ + using skeleton SA; + char path[MAX_BUFFER]; + int len; + int longitud; + + system("clear"); + + get_path(argv[0],path); + len = strlen(path); + longitud = MAX_BUFFER - len; + + strcat(path,"Config.cfg"); + ifstream f(path); + if(!f) show_message(10); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f1(path); + if(!f1) show_message(11); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f2(path); + if(!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + SetUpParams cfg; + f1 >> cfg; + + + Solver_Lan solver(pbm,cfg,argc,argv); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solucion: " << solver.global_best_solution() << " Fitness: " << solver.global_best_solution().fitness(); + + f.getline(&(path[len]),longitud,'\n'); + ofstream fexit(path); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + cout << endl << endl << " :( ---------------------- THE END --------------- :) " << endl; + } + return(0); +} diff --git a/ProyectoFinal/CHC/malva/rep/SA/MainSeq.cc b/ProyectoFinal/CHC/malva/rep/SA/MainSeq.cc new file mode 100644 index 0000000000000000000000000000000000000000..41d8a720793c0d10b14e1d5dfa05b7f11e9c4dda --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/MainSeq.cc @@ -0,0 +1,42 @@ +#include "SA.hh" +#include <iostream.h> +#include <fstream.h> + +int main (int argc, char** argv) +{ + using skeleton SA; + + system("clear"); + + if(argc < 4) + show_message(1); + + ifstream f1(argv[1]); + if (!f1) show_message(11); + + ifstream f2(argv[2]); + if (!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + SetUpParams cfg; + f1 >> cfg; + + Solver_Seq solver(pbm,cfg); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << solver.global_best_solution() + << " Fitness: " << solver.global_best_solution().fitness() << endl; + cout << "\n\n :( ---------------------- THE END --------------- :) "; + + ofstream fexit(argv[3]); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + } + return(0); +} diff --git a/ProyectoFinal/CHC/malva/rep/SA/MainWan.cc b/ProyectoFinal/CHC/malva/rep/SA/MainWan.cc new file mode 100644 index 0000000000000000000000000000000000000000..8949422e10f93211d953aba1308c203d13f30f0a --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/MainWan.cc @@ -0,0 +1,53 @@ +#include "SA.hh" +#include <iostream.h> +#include <fstream.h> + +int main (int argc, char** argv) +{ + using skeleton SA; + char path[MAX_BUFFER]; + int len; + int longitud; + + system("clear"); + + get_path(argv[0],path); + len = strlen(path); + longitud = MAX_BUFFER - len; + + strcat(path,"Config.cfg"); + ifstream f(path); + if(!f) show_message(10); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f1(path); + if(!f1) show_message(11); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f2(path); + if(!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + SetUpParams cfg; + f1 >> cfg; + + + Solver_Lan solver(pbm,cfg,argc,argv); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solucion: " << solver.global_best_solution() << " Fitness: " << solver.global_best_solution().fitness(); + + f.getline(&(path[len]),longitud,'\n'); + ofstream fexit(path); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + cout << endl << endl << " :( ---------------------- THE END --------------- :) " << endl; + } + return(0); +} diff --git a/ProyectoFinal/CHC/malva/rep/SA/Makefile b/ProyectoFinal/CHC/malva/rep/SA/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..43b74faaa879f5b52178056e8783eeeca26c3c39 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/Makefile @@ -0,0 +1,22 @@ +include ../../../environment + +all: MainSeq MainLan MainWan + +clean: + rm -f MainLan MainSeq MainWan *.o *% *~ + +MainLan: SA.req.o SA.pro.o StopCondition.o MainLan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainWan: SA.req.o SA.pro.o StopCondition.o MainWan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainSeq: SA.req.o SA.pro.o StopCondition.o MainSeq.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +LAN: + $(RUN) -v -p4pg pgfileLan MainLan +WAN: + $(RUN) -v -p4pg pgfileWan MainWan +SEQ: + ./MainSeq SA.cfg ../../../ProblemInstances/instance.txt res/res.txt diff --git a/ProyectoFinal/CHC/malva/rep/SA/SA.cfg b/ProyectoFinal/CHC/malva/rep/SA/SA.cfg new file mode 100644 index 0000000000000000000000000000000000000000..290f7e98c2c700b4ec7b5587eb489ad5c2f27704 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/SA.cfg @@ -0,0 +1,9 @@ + // number of independent runs + // number of evaluations + // Markov-Chain Length (temperature is updated in every number of evaluations) + // temperature Decay + // display state ? +LAN-configuration + // the global state is updated in this number of evaluations + // 0: asynchronized mode // 1: synchronized mode + // interval of iterations to cooperate (if 0 no cooperation) diff --git a/ProyectoFinal/CHC/malva/rep/SA/SA.hh b/ProyectoFinal/CHC/malva/rep/SA/SA.hh new file mode 100644 index 0000000000000000000000000000000000000000..9c7901a634f3ca445bf1fc7a268360c776baae5f --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/SA.hh @@ -0,0 +1,478 @@ +#ifndef INC_SA +#define INC_SA + +#include "Mallba/mallba.hh" +#include "Mallba/States.hh" +#include "Mallba/Rarray.h" +#include "Mallba/time.hh" +#include "Mallba/netstream.hh" +#include <math.h> +#include <string.h> + +skeleton SA +{ + + provides class SetUpParams; + provides class Statistics; + provides class Move; + provides class StopCondition; + provides class Solver; + provides class Solver_Seq; + provides class Solver_Lan; + provides class Solver_Wan; + + requires class Problem; + requires class Solution; + requires class StopCondition_1; + requires class StopCondition_2; + requires class StopCondition_3; + requires class DefaultMove; + requires class UserStatistics; + requires bool TerminateQ (const Problem& pbm, const Solver& solver, const SetUpParams& setup); + +// Problem ---------------------------------------------------------------------------- + + requires class Problem + { + public: + Problem (); + ~Problem (); + + friend ostream& operator<< (ostream& os, const Problem& pbm); + friend istream& operator>> (istream& is, Problem& pbm); + + Problem& operator= (const Problem& pbm); + bool operator== (const Problem& pbm) const; + bool operator!= (const Problem& pbm) const; + + Direction direction () const; + + }; + +//Solution ---------------------------------------------------------------------------- + + requires class Solution + { + public: + Solution (const Problem& pbm); + Solution (const Solution& sol); + ~Solution(); + + friend ostream& operator<< (ostream& os, const Solution& sol); + friend istream& operator>> (istream& is, Solution& sol); + friend NetStream& operator << (NetStream& ns, const Solution& sol); + friend NetStream& operator >> (NetStream& ns, Solution& sol); + + const Problem& pbm() const; + + Solution& operator= (const Solution& sol); + bool operator== (const Solution& sol) const; + bool operator!= (const Solution& sol) const; + + char *to_String() const; + void to_Solution(char *_vertex_); + unsigned int size() const; + + void initialize(); + double fitness () const; + + private: + const Problem& _pbm; + }; + +// UserStatistics ---------------------------------------------------------------------------- + + requires class UserStatistics + { + private: + struct user_stat + { + unsigned int trial; + double initial_temperature; + double temperature_best_found_trial; + unsigned long nb_evaluation_best_found_trial; + double best_cost_trial; + float time_best_found_trial; + float time_spent_trial; + }; + + Rlist<struct user_stat> result_trials; + + public: + UserStatistics (); + ~UserStatistics(); + + friend ostream& operator<< (ostream& os, const UserStatistics& usertats); + + UserStatistics& operator= (const UserStatistics& userstats); + void update(const Solver& solver); + void clear(); + }; + +// Move ---------------------------------------------------------------------------------- + + provides class Move + { + public: + Move() {} + virtual ~Move() {} + + virtual void Apply(Solution& sol) const = 0; + }; + +// DefaultMove ---------------------------------------------------------------------------------- + + requires class DefaultMove: public Move + { + public: + DefaultMove(); + ~DefaultMove(); + + void Apply(Solution& sol) const; + }; + +// SetUpParams ------------------------------------------------------------------------------- + + provides class SetUpParams + { + private: + unsigned int _independent_runs; + unsigned long _max_evaluations; + unsigned int _MarkovChain_length; + double _temperature_decay; + bool _display_state; + + // for LAN execution configuration + unsigned long _refresh_global_state; + bool _synchronized; + unsigned int _cooperation; + + public: + SetUpParams (); + + friend ostream& operator<< (ostream& os, const SetUpParams& setup); + friend istream& operator>> (istream& is, SetUpParams& setup); + + const unsigned int independent_runs() const; + const unsigned long max_evaluations() const; + const unsigned int MarkovChain_length() const; + const double temperature_decay() const; + const bool display_state() const; + const unsigned long refresh_global_state() const; + const bool synchronized() const; + const unsigned int cooperation() const; + + void independent_runs(const unsigned int val); + void max_evaluations(const unsigned long val); + void MarkovChain_length(const unsigned int val); + void temperature_decay(const double val); + void display_state(const bool val); + void refresh_global_state(const unsigned long val); + void synchronized(const bool val); + void cooperation(const unsigned int val); + + ~SetUpParams(); + }; + +// Statistics --------------------------------------------------------------------------------- + + provides class Statistics + { + private: + struct stat + { + unsigned int trial; + unsigned long nb_evaluations; + double best_cost; + double current_cost; + }; + + Rlist<struct stat> stats_data; + + public: + Statistics(); + + friend ostream& operator<< (ostream& os, const Statistics& stats); + + Statistics& operator= (const Statistics& stats); + void update(const Solver& solver); + void clear(); + + ~Statistics(); + }; + +// Solver --------------------------------------------------------------------------------- + + provides class Solver + { + protected: + const Problem& problem; + const SetUpParams& params; + UserStatistics _userstat; + Statistics _stat; + Move* move; + Solution current; + double curfit; + Solution tentative; + double currentTemperature; + unsigned int k; // to control temperature update. + StateCenter _sc; + + float total_time_spent; + float time_spent_in_trial; + float start_trial; + float start_global; + + bool _end_trial; + + State_Vble _current_trial; + State_Vble _current_iteration; + State_Vble _current_best_solution; + State_Vble _current_best_cost; + State_Vble _current_solution; + State_Vble _current_cost; + + State_Vble _current_time_spent; + State_Vble _initial_temperature_trial; + State_Vble _time_best_found_trial; + State_Vble _iteration_best_found_trial; + State_Vble _temperature_best_found_trial; + State_Vble _time_spent_trial; + + State_Vble _trial_best_found; + State_Vble _iteration_best_found; + State_Vble _global_best_solution; + State_Vble _global_best_cost; + State_Vble _time_best_found; + + State_Vble _temperature; + State_Vble _display_state; + + const Direction _direction; + + bool AcceptQ(double tent, double cur, double temperature); + double Set_Initial_Temperature(const Problem& pbm); + void KeepHistory(const Solution& sol, const double curfit,const float time_spent_trial,const float total_time_spent); + + double UpdateT(double temp, int K); + + public: + // Constructor - Destructor ------------------------- + + Solver (const Problem& pbm, const SetUpParams& setup); + virtual ~Solver (); + virtual int pid() const; + bool end_trial() const; + + // Execution methods -------------------------------- + + // Full execution + virtual void run () =0; + virtual void run (unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol, unsigned long int nb_evaluations) =0; + + virtual void run (const double initialTemperature) =0; + virtual void run (const Solution& sol,const double initialTemperature) =0; + virtual void run (const double initialTemperature, unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations) =0; + + // Partial execution + virtual void StartUp () =0; + virtual void StartUp (const Solution& sol) =0; + virtual void StartUp (const double initialTemperature) =0; + virtual void StartUp (const Solution& sol, const double initialTemperature) =0; + virtual void DoStep () =0; + + // Statistics handling ------------------------------ + + const Statistics& statistics() const; + const UserStatistics& userstatistics () const; + const SetUpParams& setup() const; + const Problem& pbm() const; + + // State handling ----------------------------------- + + void RefreshState(); + void UpdateFromState(); + StateCenter* GetState(); + + unsigned int current_trial() const; + unsigned long current_iteration() const; + Solution current_best_solution() const; + Solution current_solution() const; + double current_best_cost() const; + double current_cost() const; + float current_time_spent() const; + float time_best_found_trial() const; + double initial_temperature_trial() const; + unsigned int iteration_best_found_trial() const; + double temperature_best_found_trial() const; + float time_spent_trial() const; + unsigned int trial_best_found() const; + unsigned int iteration_best_found() const; + Solution global_best_solution() const; + double global_best_cost() const; + float time_best_found() const; + double temperature() const; + int display_state() const; + + void current_trial(const unsigned int value); + void current_iteration(const unsigned long value); + void current_best_solution(const Solution& sol); + void current_best_cost(const double value); + void current_solution(const Solution& sol); + void current_cost(const double value); + void current_time_spent(const float value); + void time_best_found_trial(const float value); + void initial_temperature_trial(const double temperature); + void iteration_best_found_trial(const unsigned int value); + void temperature_best_found_trial(const double value); + void time_spent_trial(const float value); + void trial_best_found(const unsigned int value); + void iteration_best_found(const unsigned int value); + void global_best_solution(const Solution& sol); + void global_best_cost(const double value); + void time_best_found(const float value); + void temperature(const double value); + void display_state(const int value); + void show_state() const; + + // State handling ----------------------------------- + void SetMove(Move* mov); + }; + + provides class Solver_Seq: public Solver + { + public: + // Constructor - Destructor ------------------------- + + Solver_Seq ( const Problem& pbm, const SetUpParams& setup); + virtual ~Solver_Seq (); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + }; + + provides class Solver_Lan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + + public: + Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Lan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + + provides class Solver_Wan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + + public: + Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Wan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + +}; + +#endif diff --git a/ProyectoFinal/CHC/malva/rep/SA/SA.req.cc b/ProyectoFinal/CHC/malva/rep/SA/SA.req.cc new file mode 100644 index 0000000000000000000000000000000000000000..65328019b498310ed56b81f2ec58559fe54aa39f --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/SA.req.cc @@ -0,0 +1,222 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** User-required classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** *** +*** *** +************************************************/ + +#include <iostream.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "StopCondition.hh" + +skeleton SA { + + +// Problem --------------------------------------------------------------- + Problem::Problem () + {} + + ostream& operator<< (ostream& os, const Problem& pbm) + { + return os; + } + + istream& operator>> (istream& is, Problem& pbm) + { + return is; + } + + Problem& Problem::operator= (const Problem& pbm) + { + return *this; + } + + bool Problem::operator== (const Problem& pbm) const + { + return true; + } + + bool Problem::operator!= (const Problem& pbm) const + { + return !(*this == pbm); + } + + Direction Problem::direction() const + { + //return maximize; + return minimize; + } + + Problem::~Problem() + {} + +// Solution -------------------------------------------------------------- + Solution::Solution (const Problem& pbm):_pbm(pbm) + {} + + const Problem& Solution::pbm() const + { + return _pbm; + } + + Solution::Solution(const Solution& sol):_pbm(sol.pbm()) + { + *this=sol; + } + + istream& operator>> (istream& is, Solution& sol) + { + return is; + } + + ostream& operator<< (ostream& os, const Solution& sol) + { + return os; + } + + NetStream& operator << (NetStream& ns, const Solution& sol) + { + return ns; + } + + NetStream& operator >> (NetStream& ns, Solution& sol) + { + return ns; + } + + Solution& Solution::operator= (const Solution &sol) + { + return *this; + } + + bool Solution::operator== (const Solution& sol) const + { + if (sol.pbm() != _pbm) return false; + return true; + } + + bool Solution::operator!= (const Solution& sol) const + { + return !(*this == sol); + } + + void Solution::initialize() + {} + + double Solution::fitness () const + { + return 0.0; + } + + char *Solution::to_String() const + { + return NULL; + } + + void Solution::to_Solution(char *_routes_) + {} + + unsigned int Solution::size() const + { + return 0; + } + + Solution::~Solution() + {} + +// UserStatistics ------------------------------------------------------- + + UserStatistics::UserStatistics () + {} + + ostream& operator<< (ostream& os, const UserStatistics& userstat) + { + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF TRIALS " << endl; + os << "------------------------------------------------------------------" << endl; + + for (int i=0;i< userstat.result_trials.size();i++) + { + os << endl + << "\t" << userstat.result_trials[i].trial + << "\t" << userstat.result_trials[i].best_cost_trial + << "\t\t" << userstat.result_trials[i].nb_evaluation_best_found_trial + << "\t\t" << userstat.result_trials[i].initial_temperature + << "\t\t" << userstat.result_trials[i].temperature_best_found_trial + << "\t\t" << userstat.result_trials[i].time_best_found_trial + << "\t\t" << userstat.result_trials[i].time_spent_trial; + } + + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + + UserStatistics& UserStatistics::operator= (const UserStatistics& userstats) + { + result_trials=userstats.result_trials; + return (*this); + } + + + void UserStatistics::update(const Solver& solver) + { + if ((solver.pid()!=0) || (solver.end_trial()!=true) + || ((solver.current_iteration()!=solver.setup().max_evaluations()) + && !TerminateQ(solver.pbm(),solver,solver.setup()))) + return; + + struct user_stat *new_stat; + if ((new_stat=(struct user_stat *)malloc(sizeof(struct user_stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluation_best_found_trial= solver.iteration_best_found_trial(); + new_stat->initial_temperature=solver.initial_temperature_trial(); + new_stat->temperature_best_found_trial=solver.temperature_best_found_trial(); + new_stat->best_cost_trial = solver.current_best_cost(); + new_stat->time_best_found_trial= solver.time_best_found_trial(); + new_stat->time_spent_trial = solver.time_spent_trial(); + result_trials.append(*new_stat); + } + + void UserStatistics::clear() + { + result_trials.remove(); + } + + UserStatistics::~UserStatistics() + { + result_trials.remove(); + } + +// DefaultMove ------------------------------------------------------- + + + DefaultMove::DefaultMove() + {} + + DefaultMove::~DefaultMove() + {} + + void DefaultMove::Apply (Solution& sol) const + { + // Body of operator + } + + //------------------------------------------------------------------------ + // Specific methods ------------------------------------------------------ + //------------------------------------------------------------------------ + + bool TerminateQ (const Problem& pbm, const Solver& solver, + const SetUpParams& setup) + { + + StopCondition_1 stop; + return stop.EvaluateCondition(pbm,solver,setup); + } +} + + diff --git a/ProyectoFinal/CHC/malva/rep/SA/StopCondition.cc b/ProyectoFinal/CHC/malva/rep/SA/StopCondition.cc new file mode 100644 index 0000000000000000000000000000000000000000..79e3342a1e450975eede655a28080d3ec9d92f74 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/StopCondition.cc @@ -0,0 +1,52 @@ +#include "StopCondition.hh" +skeleton SA +{ + +// StopCondition ------------------------------------------------------------------------------------- + + StopCondition::StopCondition() + {} + + StopCondition::~StopCondition() + {} + +// StopCondition_1 ------------------------------------------------------------------------------------- + + StopCondition_1::StopCondition_1():StopCondition() + {} + + bool StopCondition_1::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return false; + } + + StopCondition_1::~StopCondition_1() + {} + +// StopCondition_2 ------------------------------------------------------------------------------------- + + StopCondition_2::StopCondition_2():StopCondition() + {} + + bool StopCondition_2::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return (solver.global_best_cost()>8.5); + } + + StopCondition_2::~StopCondition_2() + {} + +// StopCondition_3 ------------------------------------------------------------------------------------- + + StopCondition_3::StopCondition_3():StopCondition() + {} + + bool StopCondition_3::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return ((solver.current_trial()==setup.independent_runs()) && (solver.current_iteration()==setup.max_evaluations())); + } + + StopCondition_3::~StopCondition_3() + {} + +} diff --git a/ProyectoFinal/CHC/malva/rep/SA/StopCondition.hh b/ProyectoFinal/CHC/malva/rep/SA/StopCondition.hh new file mode 100644 index 0000000000000000000000000000000000000000..04ef770d9cac5bb9ef69aae7d085e3ae2166e187 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/StopCondition.hh @@ -0,0 +1,41 @@ +#ifndef stop_condition +#define stop_condition + +#include "SA.hh" +skeleton SA +{ + + provides class StopCondition + { + public: + StopCondition(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup)=0; + ~StopCondition(); + }; + + requires class StopCondition_1 : public StopCondition + { + public: + StopCondition_1(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_1(); + }; + + requires class StopCondition_2 : public StopCondition + { + public: + StopCondition_2(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_2(); + }; + + requires class StopCondition_3 : public StopCondition + { + public: + StopCondition_3(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_3(); + }; +} + +#endif diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/AdjKeys.cpp b/ProyectoFinal/CHC/malva/rep/SA/dnafa/AdjKeys.cpp new file mode 100644 index 0000000000000000000000000000000000000000..64d179a34f0fc3f11f987bb86813c46090fdeb4a --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/AdjKeys.cpp @@ -0,0 +1,286 @@ +/*********************************************************************** + * File: AdjKeys.cpp + * Author: Lishan Li + * Date: May, 2003 + * + * Description: It provides implementation of all the functions declared + * in the header file AdjKeys.h. + ***********************************************************************/ + +#include "AdjKeys.h" + +/********************************************* + * Purpose: allocate memory and initialization + *********************************************/ + +AdjKeys::AdjKeys(int * parent1, int * parent2, int nbOfFrag):nof(nbOfFrag) +{ + offSpring = new int[nof]; + share = new bool[nof]; + remaining = new int[nof]; + + aKeys = new int *[nof]; + for(int i = 0; i < nof; i++) + { + aKeys[i] = new int[4]; // [0] and [1] for parent1; [2] and [3] for parent2 + for(int j = 0; j < 4; j++) + aKeys[i][j] = -1; // initialize to -1 + } + + for(int k = 0; k < nof; k++) + { + offSpring[k] = -1; + share[k] = false; + remaining[k] = 0; + } + startKey = parent1[0]; // start key point to the first fragment of parent1 + makeAdjKeysTable(parent1, parent2); +} + +/************************* + * Purpose: release memory + *************************/ + +AdjKeys::~AdjKeys() +{ + for(int i = 0; i < nof; i++) + delete [] aKeys[i]; + + delete [] aKeys; + delete [] remaining; + delete [] share; + delete [] offSpring; +} + +/**************************************************** + * Purpose: create an adjacency table for two parents + ****************************************************/ + +void AdjKeys::makeAdjKeysTable(int * parent1, int * parent2) +{ + initAdjacentcy(parent1, 1); + initAdjacentcy(parent2, 2); + + setSharing(); +// printInfo(); +} + +/******************************************* + * Purpose: initialize a parent's adjacency + *******************************************/ + +void AdjKeys::initAdjacentcy(int * parent, int pid) +{ + int indStart; + if(pid == 1) + indStart = 0; // because aKeys[][0] and aKeys[][1] for parent1 + else + indStart = 2; // because aKeys[][2] and aKeys[][3] for parent2 + + int m = 0; + for(int i = 0; i < nof; i++) + { + int key = parent[m]; + + if(m == 0) // deal with the first fragment + { + aKeys[key][indStart] = parent[m+1]; + incrementRemaining(key); + } + else if(m == nof-1) // deal with the last fragment + { + aKeys[key][indStart] = parent[m-1]; + incrementRemaining(key); + } + else // deal with the middle fragments + { + aKeys[key][indStart] = parent[m-1]; + incrementRemaining(key); + aKeys[key][indStart+1] = parent[m+1]; + incrementRemaining(key); + } + m++; + } +} + +/*********************************************** + * Purpose: return number of remaining fragments + ***********************************************/ + +int AdjKeys::getRemaining(int id) +{ + return remaining[id]; +} + +/************************************************** + * Purpose: decrement number of remaining fragments + **************************************************/ + +void AdjKeys::decrementRemaining(int id) +{ + remaining[id]--; +} + +/************************************************** + * Purpose: increment number of remaining fragments + **************************************************/ + +void AdjKeys::incrementRemaining(int id) +{ + remaining[id]++; +} + +/**************************************************** + * Purpose: set the share to be true if the fragments + * are ajdacent to both parents. + ****************************************************/ + +void AdjKeys::setSharing() +{ + for(int i = 0; i < nof; i++) + { + if(aKeys[i][0] == aKeys[i][2] || aKeys[i][0] == aKeys[i][3]) + { + share[i] = true; + remaining[i]--; + } + if(aKeys[i][1] != -1) + { + if(aKeys[i][1] == aKeys[i][2] || aKeys[i][1] == aKeys[i][3]) + { + share[i] = true; + remaining[i]--; + } + } + } +} + +/************************************ + * Purpose: check the sharing status + ************************************/ + +bool AdjKeys::hasSharing(int id) +{ + return share[id]; +} + +/***************************************************** + * Purpose: print the detail information in this class + *****************************************************/ + +void AdjKeys::printInfo() +{ + for(int i = 0; i < nof; i++) + { + cout << aKeys[i][0] << ", " << aKeys[i][1] << ", " + << aKeys[i][2] << ", " << aKeys[i][3] << "\t"; + + cout << "sharing = " << share[i] << ", " << " remain = " << remaining[i] << endl; + } +} + +/***************************************************************** + * Purpose: reset the adjacent key to be -1 if it is already taken + *****************************************************************/ + +void AdjKeys::deleteTakenKey(int takenKey) +{ + int p, q; + for(p = 0; p < nof; p++) + { + if(takenKey != p) + { + bool exist = false; + for(q = 0; q < 4; q++) + { + if(aKeys[p][q] != -1 && aKeys[p][q] == takenKey) + { + aKeys[p][q] = -1; + exist = true; + } + } + if(exist) + decrementRemaining(p); + } + } +} + +/*********************************************************** + * Purpose: performs the actual edge-recombination operation + ***********************************************************/ + +void AdjKeys::recombine() +{ + int currKey = startKey; + offSpring[0] = currKey; + deleteTakenKey(currKey); + + int i; + // produce offspring based on adjacent keys + + for(i = 1; i < nof; i++) + { + int flag = false; + int tempKeys[4] = {-1, -1, -1, -1}; + int w = 0; + for(int j = 0; j < 4; j++) + { + int t = aKeys[currKey][j]; + if(t != -1 && hasSharing(t)) + { + currKey = t; + flag = true; + break; + } + else + { + if(t != -1) + tempKeys[w++] = t; + continue; + } + } + if(!flag) + { + if(w != 0) + { + int tk = tempKeys[0]; + int moreAdjLeft = getRemaining(tk); + currKey = tk; + for(int v = 1; v < w; v++) + { + tk = tempKeys[v]; + int adjLeft = getRemaining(tk); + if(adjLeft > moreAdjLeft) + { + moreAdjLeft = adjLeft; + currKey = tk; + } + } + } + else + break; + } + offSpring[i] = currKey; + deleteTakenKey(currKey); + } + + if(i < nof) // handle special case + { + for(int x = 0; x < nof; x++) + { + if(getRemaining(x) != 0) + { + for(int y = 0; y < 4; y++) + { + if(aKeys[x][y] != -1) + { + offSpring[i++] = aKeys[x][y]; + deleteTakenKey(aKeys[x][y]); + } + } + } + } + } +} + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/AdjKeys.h b/ProyectoFinal/CHC/malva/rep/SA/dnafa/AdjKeys.h new file mode 100644 index 0000000000000000000000000000000000000000..cf440b2e7612f37b2d6280b2ea1b3736d88a8d52 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/AdjKeys.h @@ -0,0 +1,45 @@ +/********************************************************************* + * File: AdjKeys.h + * Author: Lishan Li + * Date: May, 2003 + * + * Description: AdjKeys class is a helper class for Edge-recombination + * crossover operator + *********************************************************************/ + +#ifndef ADJKEYS_H +#define ADJKEYS_H + +#include <iostream> +#include <string> + +using namespace std; + +class AdjKeys +{ +public: + int startKey; + int * offSpring; // store offspring generate by crossover operator + + AdjKeys(int * parent1, int * parent2, int nbOfFrag); + ~AdjKeys(); + void makeAdjKeysTable(int * parent1, int * parent2); + void initAdjacentcy(int * parent, int pid); + void recombine(); + void deleteTakenKey(int takenKey); + int getRemaining(int id); + void setSharing(); + bool hasSharing(int id); + void decrementRemaining(int id); + void incrementRemaining(int id); + void printInfo(); +private: + int ** aKeys; // store adjacent keys for both parents + bool * share; // store sharing info for both parents + int * remaining; // store remaining fragments + int nof; +}; + +#endif + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/AlignedPair.h b/ProyectoFinal/CHC/malva/rep/SA/dnafa/AlignedPair.h new file mode 100644 index 0000000000000000000000000000000000000000..a5d087202c74e4e615f93e484e5da1823ced1cf7 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/AlignedPair.h @@ -0,0 +1,39 @@ +/********************************************************************* + * File: AlignedPair.h + * Author: Lishan Li + * Date: May, 2003 + * + * Description: AlignedPair class is a helper class that wraps an + * alignment of two sequences + *********************************************************************/ + +#ifndef ALIGNEDPAIR_H +#define ALIGNEDPAIR_H + +#include <iostream> +#include <string> + +using namespace std; + +class AlignedPair +{ +public: + string s; // to store sequence s after alignment + string t; // to store sequence t after alignment + + AlignedPair() {} + AlignedPair(const string &s, const string &t) + { + this->s = s; + this->t = t; + } + + void printAlign() + { + cout << s << "\n" << t << endl << endl; + } +}; + +#endif + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/Config.cfg b/ProyectoFinal/CHC/malva/rep/SA/dnafa/Config.cfg new file mode 100644 index 0000000000000000000000000000000000000000..8175e18307a3cb93a5f4d9cd80ea972a1fd6980b --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/Config.cfg @@ -0,0 +1,3 @@ +SA.cfg +../../../ProblemInstances/DNAFA-instances/pbm.txt +res/dna.sa.lan.txt diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/ConsensusBuilder.cpp b/ProyectoFinal/CHC/malva/rep/SA/dnafa/ConsensusBuilder.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ad8879ea58862e0c54e0d9fe56b11d65f0ffa267 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/ConsensusBuilder.cpp @@ -0,0 +1,286 @@ +/*********************************************************************** + * File: ConsensusBuilder.cpp + * Author: Lishan Li + * Date: May, 2003 + * + * Description: It provides implementation of all the functions declared + * in the header file ConsensusBuilder.h. + ***********************************************************************/ + +#include "ConsensusBuilder.h" + +int Global_cutoff; + +/***************************************************** + * Purpose: build the initial consensuses from contigs + *****************************************************/ + +ConsensusBuilder::ConsensusBuilder(vector<string> &SACons) +{ + consensus = SACons; + scpList = new List1<SubConsensusPair>(); +} + +/************************* + * Purpose: release memory + *************************/ + +ConsensusBuilder::~ConsensusBuilder() +{ + delete scpList; +} + +/********************************************** + * Purpose: postprocess four types of consensus + **********************************************/ + +void ConsensusBuilder::buildConsensus() +{ + if(consensus.size() > 1) + { +// cout << endl << "case FF" << endl; +/**/ cerr << "case FF" << endl; + buildSubConsensus(FF); // both from forward strand +/**/ cerr << "End case FF" << endl; + if(consensus.size() > 1) + { +// cout << endl << "case FR" << endl; +/**/ cerr << "case FR" << endl; + buildSubConsensus(FR); // first from forward, second from reverse complement +/**/ cerr << "End case FR" << endl; + if(consensus.size() > 1) + { +// cout << endl << "case RF" << endl; +/**/ cerr << "case RF" << endl; + buildSubConsensus(RF); // first from reverse complement, second from forward +/**/ cerr << "End case RF" << endl; + if(consensus.size() > 1) + { +// cout << endl << "case RR" << endl;; +/**/ cerr << "case RR" << endl; + buildSubConsensus(RR); // both from reverse complement +/**/ cerr << "End case RR" << endl; + } + } + } + } +} + +/********************************************** + * Purpose: initialize four types of consensus + **********************************************/ + +void ConsensusBuilder::initST(int type) +{ + vector<string> rc; + for(int k = 0; k < consensus.size(); k++) + rc.push_back(Util::rcSequence(consensus[k])); + + s.clear(); + t.clear(); + switch(type) + { + case FF: + s = t = consensus; + break; + case FR: + s = consensus; + t = rc; + break; + case RF: + s = rc; + t = consensus; + break; + case RR: + s = t = rc; + break; + } +} + +/******************************************************** + * Purpose: detects the overlap for all possible pair of + * consensus and stores the overlap score in a + * sorted linked list in descending order. + ********************************************************/ + +void ConsensusBuilder::buildSubConsensus(int type) +{ +// cout << "\nCurrent consensus (" << type << ")" << endl; + //print(); + initST(type); + + for(int i = 0; i < s.size(); i++) + { + for(int j = i+1; j < s.size(); j++) // compute half of pairs only + { + SGA *sga = new SGA(s[i], t[j]); // eg. w1 and w2 +/**/ cerr << "Building Matrix " << i << " " << j << endl; + sga->buildMatrix(); + sga->findBestScore(); + int score = sga->getBestScore(); + delete sga; +/**/ cerr << "End Building Matrix " << i << " " << j << endl; + + if(score >= Global_cutoff) + { + scpList->insert(SubConsensusPair(i, j, score)); + scpList->insert(SubConsensusPair(j, i, score)); + } + } + } +// scpList->printList(); +/**/ cerr << "Updating Consensus" << endl; + updateConsensus(type); +/**/ cerr << "End Updating Consensus" << endl; +} + +/************************************************************ + * Purpose: update consensus information by aligning possible + * overlapping consensuses. + ************************************************************/ + +void ConsensusBuilder::updateConsensus(int type) +{ + vector<string> tempLayout; + vector<string> tepCon = consensus; + consensus.clear(); + + ListNode<SubConsensusPair>* tempNode = scpList->header->next; + + while(tempNode != NULL) + { + int cid1 = tempNode->data.cid1; + int cid2 = tempNode->data.cid2; + char direction = 'F'; // forward + + tempLayout.push_back(s[cid1]); + tempLayout.push_back(t[cid2]); + if(type == FR) + direction = 'R'; // reverse complement + + tepCon.at(cid1) = ""; + tepCon.at(cid2) = ""; + remove(scpList, cid1); + bool found = true; + while(found) + { + ListNode<SubConsensusPair>* nextNode = search(scpList, cid2); + if(nextNode == NULL) + found = false; + else + { + cid1 = cid2; + cid2 = nextNode->data.cid2; + + if(type == FR && direction == 'R') + { + tempLayout.push_back(s[cid2]); // s[cid2] = Util::rcSequence(t[cid2]) + direction = 'F'; + } + else if (type == FR && direction == 'F') + { + tempLayout.push_back(t[cid2]); + direction = 'R'; + } + else if (type == RF && direction == 'F') + { + tempLayout.push_back(s[cid2]); + direction = 'R'; + } + else + { + tempLayout.push_back(t[cid2]); + direction = 'F'; + } + + tepCon.at(cid2) = ""; + remove(scpList, cid1); + } + } + + if(tempLayout.size() > 1) + { + LayoutBuilder layoutBuilder(tempLayout); + layoutBuilder.findAlignments(); + // layoutBuilder.printAlignments(); + layoutBuilder.buildLayout(); +// cout << endl << "Merging =>"<< endl << endl; + layoutBuilder.printLayout(); + layoutBuilder.findConsensus(); + layoutBuilder.printConsensus(); + consensus.push_back(layoutBuilder.getConsensus()); + } + else + consensus.push_back(tempLayout.at(0)); + + tempLayout.clear(); + tempNode = scpList->header->next; + } + + for(int m = 0; m < tepCon.size(); m++) + { + if(tepCon.at(m) != "") + consensus.push_back(tepCon.at(m)); + } +} + +/************************************************************ + * Purpose: removes SubConsensusPair objects that contain the + * given id from the linked list. + ************************************************************/ + +void ConsensusBuilder::remove(List1<SubConsensusPair>* list, int cid) +{ + List1<SubConsensusPair>* temp = list; + ListNode<SubConsensusPair>* tempCurr = temp->header->next; + ListNode<SubConsensusPair>* tempPrev = temp->header; + + while(tempCurr != NULL) + { + if(tempCurr->data.cid1 == cid || tempCurr->data.cid2 == cid ) + { + ListNode<SubConsensusPair>* oldNode = tempCurr; + tempPrev->next = tempCurr->next; + tempCurr = tempCurr->next; + delete oldNode; + (temp->len)--; + } + else + { + tempPrev = tempCurr; + if(tempCurr != NULL) + tempCurr = tempCurr->next; + } + } +} + +/************************************************************ + * Purpose: find the SubConsensusPair object that contain the + * given id in the linked list. + ************************************************************/ + +ListNode<SubConsensusPair>* ConsensusBuilder::search(List1<SubConsensusPair>* list, int cid) +{ + ListNode<SubConsensusPair>* curr; + + for(curr = list->header->next; curr != NULL; curr = curr->next) + { + if(curr->data.cid1 == cid) // found + return curr; + } + return NULL; +} + +/*********************************** + * Purpose: prints current consensus + ***********************************/ + +void ConsensusBuilder::print() +{ +/* for(int j = 0; j < consensus.size(); j++) + cout << endl << "Cons #" << j << " => " << consensus.at(j); + cout << endl; +*/} + +/************************************ End of File **************************************/ + diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/ConsensusBuilder.h b/ProyectoFinal/CHC/malva/rep/SA/dnafa/ConsensusBuilder.h new file mode 100644 index 0000000000000000000000000000000000000000..ea813d30173bbbac56ca291db5f4b424edbac019 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/ConsensusBuilder.h @@ -0,0 +1,53 @@ +/********************************************************************* + * File: ConsensusBuilder.h + * Author: Lishan Li + * Date: May, 2003 + * + * Description: This ConsensusBuilder class is used to determine the + * sequence for contigs. + *********************************************************************/ + +#ifndef CONSENSUSBUILDER_H +#define CONSENSUSBUILDER_H + +#pragma warning(disable: 4786) + +#include <iostream> +#include <string> +#include <vector> +#include "list.h" +#include "Util.h" +#include "ContigBuilder.h" +#include "LayoutBuilder.h" +#include "scp.h" + +using namespace std; + +class ConsensusBuilder +{ +public: + // F - forward; R - reverse complement + enum TableType { FF, FR, RF, RR }; + + ConsensusBuilder(vector<string> &SACons); + ~ConsensusBuilder(); + + void initLayout(); // initialize layout + void buildConsensus(); + void updateConsensus(int type); + void remove(List1<SubConsensusPair> * list, int cid); + ListNode<SubConsensusPair> * search(List1<SubConsensusPair> * list, int cid); + vector<string> getConsensus() { return consensus; } + void print(); +private: + void buildSubConsensus(int type); + void initST(int type); + + List1<SubConsensusPair>* scpList; // a list of SubConsensusPair objects + vector<string> consensus; + vector<string> s, t; +}; + +#endif + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/ContigBuilder.cpp b/ProyectoFinal/CHC/malva/rep/SA/dnafa/ContigBuilder.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dd7dc6f2cb48a1c26cfdb7775c80f8308ef9dd93 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/ContigBuilder.cpp @@ -0,0 +1,238 @@ +/*********************************************************************** + * File: ContigBuilder.cpp + * Author: Lishan Li + * Date: May, 2003 + * + * Description: It provides implementation of all the functions declared + * in the header file ContigBuilder.h. + ***********************************************************************/ + +#include "ContigBuilder.h" + +/****************************************************** + * Purpose: initialize fragment order and overlap score + ******************************************************/ + +ContigBuilder::ContigBuilder(int * order, int ** s, const SA::Problem *pbm):_pbm(pbm) +{ + fragOrder = order; + score = s; +} + +/******************************************************* + * Purpose: construct contigs based on the overlap score + * of adjacent fragments + *******************************************************/ + +void ContigBuilder::buildContigs() +{ + vector<int> tempOrder; + + int id1 = fragOrder[0]; + tempOrder.push_back(id1+1); // +1 because 0 has no negative number + int direction = 1; + + for(int i = 1; i < _pbm->numOfFragments; i++) + { + int id2 = fragOrder[i]; + // cout << "score[" << id1 << "][" << id2 << "] = " << score[id1][id2] << endl; + + int sign = direction * score[id1][id2]; + + if(abs(score[id1][id2]) >= _pbm->cutoff) // default cutoff = 30bps + { + if(sign > 0) // from same strand + { + tempOrder.push_back(id2+1); + direction = 1; + } + else // from different strand + { + tempOrder.push_back(-(id2+1)); + direction = -1; + } + id1 = id2; + } + else + { + allContigs.push_back(tempOrder); // a new contig is formed + tempOrder.clear(); + id1 = id2; + tempOrder.push_back(id1+1); + direction = 1; + } + } + allContigs.push_back(tempOrder); +} + +/******************************************************* + * Purpose: merge two contigs and update the orientation + * accordingly + *******************************************************/ + +void ContigBuilder::mergeTwoContig(int cid1, int cid2) +{ + vector<int> fids1 = allContigs.at(cid1); + vector<int> fids2 = allContigs.at(cid2); + + int fid1 = fids1.at(fids1.size()-1); + int fid2 = fids2.at(0); + int sign = fid1 * fid2; + + bool type = score[abs(fid1)-1][abs(fid2)-1] > 0; + + bool flag = (!type && sign < 0) || (type && sign > 0); // flag = true => not change + + for(int i = 0; i < fids2.size(); i++) + { + if(flag) // don't change + allContigs.at(cid1).push_back(fids2.at(i)); + else // change + allContigs.at(cid1).push_back(-fids2.at(i)); + } + + allContigs.erase(allContigs.begin() + cid2); +} + +/***************************************************** + * Purpose: merge contigs that satisfy the predefined + * threshold + *****************************************************/ + +void ContigBuilder::mergeContigs() +{ + while(allContigs.size() >= 2) + { + int bestScore = _pbm->cutoff; + int cid_i = -1; + int cid_j = -1; + + for(int i = 0; i < allContigs.size()-1; i++) + { + vector<int> tempi = allContigs.at(i); + int fidi_First = abs(tempi.at(0)) - 1; + int fidi_Last = abs(tempi.at(tempi.size()-1)) - 1; + + for(int j = i+1; j < allContigs.size(); j++) + { + vector<int> tempj = allContigs.at(j); + + int fidj_First = abs(tempj.at(0)) - 1; + int fidj_Last = abs(tempj.at(tempj.size()-1)) - 1; + + if(abs(score[fidi_Last][fidj_First]) >= bestScore) // put contig_j after contig_i + { + bestScore = abs(score[fidi_Last][fidj_First]); + cid_i = i; + cid_j = j; + } + if(abs(score[fidj_Last][fidi_First]) > bestScore) // put contig_j before contig_i + { + bestScore = abs(score[fidj_Last][fidi_First]); + cid_i = j; + cid_j = i; + } + } + } + + if(cid_i != -1 && cid_j != -1) + mergeTwoContig(cid_i, cid_j); + else + break; + } + cerr << endl << "*** *** *** *** SA Contigs ( " << allContigs.size() << " ) *** *** *** ***" << endl << endl; +} + +/******************************************* + * Purpose: build consensus for each contigs + *******************************************/ + +void ContigBuilder::buildConsensus() +{ + vector< vector<string> > fragLayouts; + for(int i = 0; i < allContigs.size(); i++) + fragLayouts.push_back(getPreLayoutFrags(allContigs.at(i))); + + vector<string> SACons; + cerr << endl << "*** *** *** *** SA Contigs ( " << fragLayouts.size() << " ) *** *** *** ***" << endl << endl; + + for(int j = 0; j < fragLayouts.size(); j++) + { + vector<string> layout = fragLayouts.at(j); + +// cout << endl << "Fragments Layout (" << j << ") =>" << endl << endl; + + if(layout.size() > 1) + { + LayoutBuilder layoutBuilder(layout); + layoutBuilder.findAlignments(); + // layoutBuilder.printAlignments(); + layoutBuilder.buildLayout(); + layoutBuilder.printLayout(); + layoutBuilder.findConsensus(); + layoutBuilder.printConsensus(); + SACons.push_back(layoutBuilder.getConsensus()); + } + else + { + SACons.push_back(layout.at(0)); +// cout << layout.at(0) << endl; + } + } + ConsensusBuilder * cb = new ConsensusBuilder(SACons); +/**/ cerr << "Building Consensus" << endl; + cb->buildConsensus(); +/**/ cerr << "End Building Consensus" << endl; + + vector<string> finalCons = cb->getConsensus(); + cerr << endl << "*** *** *** *** Final Contigs ( " << finalCons.size() << " ) *** *** *** ***" << endl << endl; +/* for(int k = 0; k < finalCons.size(); k++) + { + cout << ">Contig #" << k << endl; + cout << finalCons.at(k) << endl; + } + cout << endl << "*****************************************************" << endl; +*/ delete cb; +} + +/******************************************************** + * Purpose: returns a vector of fragments associated with + * the fragment order + ********************************************************/ + +vector<string> ContigBuilder::getPreLayoutFrags(vector<int> order) +{ + vector<string> preLayoutFrags; + + for(int i = 0; i < order.size(); i++) + { + int fid = order.at(i); + if( fid > 0) // -1 because +1 when insert + preLayoutFrags.push_back(_pbm->fragments->at(fid-1)); + else + preLayoutFrags.push_back(_pbm->rcFragments->at(abs(fid)-1)); + } +// cout << endl; + return preLayoutFrags; +} + +/*********************************************** + * Purpose: print fragment order for each contig + ***********************************************/ + +void ContigBuilder::printOrder() +{ +/* cout << endl << "Contig size = " << allContigs.size() << endl; + + for(int i = 0; i < allContigs.size(); i++) + { + vector<int> temp = allContigs.at(i); + for(int j = 0; j < temp.size(); j++) + cout << temp.at(j) << ", "; + cout << endl; + } + cout << endl; +*/} + +/************************************ End of File **************************************/ + diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/ContigBuilder.h b/ProyectoFinal/CHC/malva/rep/SA/dnafa/ContigBuilder.h new file mode 100644 index 0000000000000000000000000000000000000000..f169c0059fa9e6aa633aa1505b67f9176a6172bc --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/ContigBuilder.h @@ -0,0 +1,49 @@ +/********************************************************************* + * File: ContigBuilder.h + * Author: Lishan Li + * Date: May, 2003 + * + * Description: This ContigBuilder class is used to process contigs + * formed from SA. + *********************************************************************/ + +#ifndef CONTIGBUILDER_H +#define CONTIGBUILDER_H + +#pragma warning(disable: 4786) + +#include <iostream> +#include <string> +#include <vector> + +#include "Util.h" +#include "ConsensusBuilder.h" + +#include "SA.hh" + +using namespace std; + +class ContigBuilder +{ +public: + ContigBuilder(int * order, int ** s, const SA::Problem *pbm); // constructor + ~ContigBuilder() { } // destructor + + void buildContigs(); + void buildConsensus(); + void mergeContigs(); + void mergeTwoContig(int cid1, int cid2); + void print(); + void printOrder(); + vector<string> getPreLayoutFrags(vector<int> order); + vector< vector<int> > getAllContigs() { return allContigs; } +private: + int * fragOrder; // fragment order generated by SA + int ** score; // pointer to score in OverlapDetector class + vector< vector<int> > allContigs; // set of contigs + const SA::Problem *_pbm; +}; + +#endif + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/LayoutBuilder.cpp b/ProyectoFinal/CHC/malva/rep/SA/dnafa/LayoutBuilder.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d3ab188b6b90286399f9ef94d5379ea62b440849 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/LayoutBuilder.cpp @@ -0,0 +1,423 @@ +/*********************************************************************** + * File: LayoutBuilder.cpp + * Author: Lishan Li + * Date: May, 2003 + * + * Description: It provides implementation of all the functions declared + * in the header file LayoutBuilder.h. + ***********************************************************************/ + +#include "LayoutBuilder.h" + +/********************************************* + * Purpose: allocate memory and initialization + *********************************************/ + +LayoutBuilder::LayoutBuilder(const vector<string> & frags) +{ + preLayoutFrags = frags; + fragmentsLayout = new string[frags.size()]; + semiAlign = new AlignedPair[frags.size()-1]; +} + +/************************* + * Purpose: release memory + *************************/ + +LayoutBuilder::~LayoutBuilder() +{ + delete [] semiAlign; + delete [] fragmentsLayout; +} + +/************************************************************ + * Purpose: count number of gaps in front of a given fragment + ************************************************************/ + +int countStartGaps(const string &str) +{ + int count = 0; + for(int i = 0; i < str.length(); i++) + { + if(str.at(i) != '-') + break; + else + count++; + } + return count; +} + +/************************************************************** + * Purpose: count number of gaps at the end of a given fragment + **************************************************************/ + +int countEndGaps(const string &str) +{ + int count = 0; + for(int i = str.length() - 1; i >= 0; i--) + { + if(str.at(i) != '-') + break; + else + count++; + } + return count; +} + +/********************************************************** + * Purpose: count number of nucleotides in a given fragment + **********************************************************/ + +int countNonGapChar(const string &str) +{ + int count = 0; + for(int i = 0; i < str.length(); i++) + { + if(str.at(i) != '-') + count++; + } + return count; +} + +/**************************************** + * Purpose: create a given number of gaps + ****************************************/ + +string addGaps(int num) +{ + string gapStr = ""; + for(int i = 0; i < num; i++) + gapStr += "-"; + + return gapStr; +} + +/********************************************************** + * Purpose: count number of middle gaps in a given fragment + **********************************************************/ + +int* findMiddleGaps(const string &str, int count) +{ + int *midGapCounts = new int[count]; + int len = str.length(); + + for(int i = 0; i < count; i++) + { + midGapCounts[i] = 0; + } + + int k = 0; + for(int j = 0; j < len; j++) + { + if(str[j+1] == '-') + { + midGapCounts[k]++; + } + else + k++; + } + + return midGapCounts; +} + +/******************************************** + * Purpose: return the first non-gap position + ********************************************/ + +int findFirstNonGapPos(const string &str) +{ + for(int i = 0; i < str.length(); i++) + { + if(str.at(i) != '-') + return i; + } + return -1; +} + +/****************************************************************** + * Purpose: compute pairwise alignments for given ordered fragments + ******************************************************************/ + +void LayoutBuilder::findAlignments() +{ + for(int k = 0; k < preLayoutFrags.size()-1; k++) + { + string s = preLayoutFrags[k]; + string t = preLayoutFrags[k+1]; + SGA sga(s, t); + sga.buildMatrix(); + sga.findBestScore(); + sga.align(); + + AlignedPair aResult(sga.align_s, sga.align_t); + semiAlign[k] = aResult; + } +} + +/************************************************************* + * Purpose: insert number of gaps in front of a given fragment + *************************************************************/ + +void LayoutBuilder::insertStartGaps(int id, int numOfGaps) +{ + string temp = fragmentsLayout[id]; + string startGaps = ""; + for(int i = 0; i < numOfGaps; i++) + startGaps += "-"; + fragmentsLayout[id] = startGaps + temp; +} + +/*********************************************************** + * Purpose: insert number of gaps in the middle of fragments + ***********************************************************/ + +void LayoutBuilder::insertMiddleGaps(const string &str1, const string &str2, int k, int prev) +{ + int nonGapCount = countNonGapChar(str1); + int *midGapCounts1 = findMiddleGaps(str1, nonGapCount-1); + int *midGapCounts2 = findMiddleGaps(str2, nonGapCount-1); + + int pos = findFirstNonGapPos(fragmentsLayout[prev]); + + for(int w = 0; w < nonGapCount-1; w++) + { + pos += 1; + if(midGapCounts1[w] != 0 || midGapCounts2[w] != 0) + { + int gapDiff = abs(midGapCounts1[w] - midGapCounts2[w]); + int move = 0; + string gaps = ""; + for(int u = 0; u < gapDiff; u++) + gaps += "-"; + + if(midGapCounts1[w] > midGapCounts2[w]) + { + fragmentsLayout[k].insert(pos, gaps); + move = midGapCounts1[w]; + } + else if (midGapCounts1[w] < midGapCounts2[w]) + { + for(int v = 0; v < k; v++) + fragmentsLayout[v].insert(pos, gaps); + move = midGapCounts2[w]; + } + pos += move; + } + } + delete [] midGapCounts1; + delete [] midGapCounts2; +} + +/*************************************************************** + * Purpose: insert number of gaps at the end of a given fragment + ***************************************************************/ + +void LayoutBuilder::insertEndGaps(int id, int numOfGaps) +{ + string temp = fragmentsLayout[id]; + string endGaps = ""; + for(int i = 0; i < numOfGaps; i++) + endGaps += "-"; + fragmentsLayout[id] = temp + endGaps; +} + +/************************************************************** + * Purpose: extract fragment excluding starting and ending gaps + **************************************************************/ + +string LayoutBuilder::extractMiddleSeq(const string &str) +{ + int startGapCount = countStartGaps(str); + int endGapCount = countEndGaps(str); + int num = str.length() - startGapCount - endGapCount; + return str.substr(startGapCount, num); +} + +/************************************ + * Purpose: check if it is ending gap + ************************************/ + +bool LayoutBuilder::isEndGap(int i, int col) +{ + string middle = extractMiddleSeq(fragmentsLayout[i]); + int firstNonGap = findFirstNonGapPos(fragmentsLayout[i]); + + if(col < firstNonGap || col > firstNonGap + middle.length() - 1) + return true; + else + return false; +} + +/************************************************ + * Purpose: progressively build a fragment layout + ************************************************/ + +void LayoutBuilder::buildLayout() +{ + int j = 0; + fragmentsLayout[j++] = semiAlign[0].s; + fragmentsLayout[j++] = semiAlign[0].t; + + for(int i = 1; i < preLayoutFrags.size()-1; i++) + { + fragmentsLayout[j] = semiAlign[i].t; + + /* handle starting gaps */ + + string s_temp = semiAlign[i].s; + + int s_startGaps = countStartGaps(fragmentsLayout[j-1]); + int stemp_startGaps = countStartGaps(s_temp); + int startGapDiff = abs(s_startGaps - stemp_startGaps); + + if(startGapDiff > 0) + { + if(stemp_startGaps > s_startGaps) + { + for(int m = 0; m < j; m++) + insertStartGaps(m, startGapDiff); + } + else + insertStartGaps(j, startGapDiff); + } + + /* handle middle gaps */ + + string s_middle = extractMiddleSeq(fragmentsLayout[j-1]); + string stemp_middle = extractMiddleSeq(s_temp); + + insertMiddleGaps(s_middle, stemp_middle, j, j-1); + + /* handle end gaps */ + + int s_endGaps = countEndGaps(fragmentsLayout[j-1]); + int stemp_endGaps = countEndGaps(s_temp); + int endGapDiff = abs(s_endGaps - stemp_endGaps); + + if(endGapDiff > 0) + { + if(stemp_endGaps > s_endGaps) + { + for(int m = 0; m < j; m++) + insertEndGaps(m, endGapDiff); + } + else + insertEndGaps(j, endGapDiff); + } + j++; + } +} + +/*********************************************** + * Purpose: find majority of a particular column + ***********************************************/ + +char LayoutBuilder::majorityVote(int col) +{ + int count[5] = { 0, 0, 0, 0, 0 }; + char nucleotide[5] = {'A', 'T', 'C', 'G', '-'}; + char majority1 = 'A'; + char majority2 = 'A'; + + for(int i = 0; i < preLayoutFrags.size(); i++) + { + if(fragmentsLayout[i].at(col) == 'A') + count[0]++; + else if(fragmentsLayout[i].at(col) == 'T') + count[1]++; + else if(fragmentsLayout[i].at(col) == 'C') + count[2]++; + else if(fragmentsLayout[i].at(col) == 'G') + count[3]++; + else if(fragmentsLayout[i].at(col) == '-') + count[4]++; + } + int max = count[0]; + for(int j = 1; j < 5; j++) + { + if(count[j] > max) + { + majority2 = majority1; + max = count[j]; + majority1 = nucleotide[j]; + } + } + bool endGap = true; + if(majority1 == '-') + { + for(int i = 0; i < preLayoutFrags.size() && endGap; i++) + { + if(fragmentsLayout[i].at(col) == '-') + { + endGap = isEndGap(i, col); + } + } + + if(endGap) + return majority2; + } + return majority1; +} + +/*************************************** + * Purpose: find majority of all columns + ***************************************/ + +void LayoutBuilder::findMajority() +{ + int length = fragmentsLayout[0].length(); + + majority = ""; + for(int i = 0; i < length; i++) + { + char c = majorityVote(i); + majority += c; + } +} + +/******************************************** + * Purpose: determine sequence for the layout + ********************************************/ + +void LayoutBuilder::findConsensus() +{ + findMajority(); + consensus = ""; + for(int i = 0; i < majority.length(); i++) + { + if(majority.at(i) != '-') + consensus += majority.at(i); + } +} + +/*************************************************** + * Purpose: print info about all pairs of alignments + ***************************************************/ + +void LayoutBuilder::printAlignments() +{ + for(int j = 0; j < preLayoutFrags.size()-1; j++) + semiAlign[j].printAlign(); +} + +/*********************** + * Purpose: print layout + ***********************/ + +void LayoutBuilder::printLayout() +{ + for(int i = 0; i < preLayoutFrags.size(); i++) + cout << fragmentsLayout[i] << endl; + cout << endl; +} + +/************************** + * Purpose: print consensus + **************************/ + +void LayoutBuilder::printConsensus() +{ + cout << consensus << endl; +} + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/LayoutBuilder.h b/ProyectoFinal/CHC/malva/rep/SA/dnafa/LayoutBuilder.h new file mode 100644 index 0000000000000000000000000000000000000000..3e611f53952a7da75652d424400e0019beca0509 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/LayoutBuilder.h @@ -0,0 +1,53 @@ +/********************************************************************* + * File: LayoutBuilder.h + * Author: Lishan Li + * Date: May, 2003 + * + * Description: This LayoutBuilder class builds a layout for a contig. + * The contig consists of an ordered set of contiguous + * overlapping fragments. + *********************************************************************/ + +#ifndef LAYOUTBUILDER_H +#define LAYOUTBUILDER_H + +#pragma warning(disable: 4786) + +#include <iostream> +#include <string> +#include <vector> +#include "sga.h" +#include "AlignedPair.h" + +using namespace std; + +class LayoutBuilder +{ +public: + LayoutBuilder(const vector<string> & frags); // constructor + ~LayoutBuilder(); // destructor + void findAlignments(); // compute the alignments using SGA + void buildLayout(); // progressively build layout + void insertStartGaps(int id, int numOfGaps); // insert '-' at the beginning of fragments + void insertMiddleGaps(const string &str1, const string &str2, int k, int prev); + void insertEndGaps(int id, int numOfGaps); // insert '-' at the end of fragments + string extractMiddleSeq(const string &str); + bool isEndGap(int i, int col); + void findMajority(); // find majorities of the layout + char majorityVote(int col); // find majority of a particular column + void findConsensus(); + void printLayout(); + void printConsensus(); + void printAlignments(); + string getConsensus() { return consensus; } +private: + vector<string> preLayoutFrags; // ordered fragments + AlignedPair * semiAlign; // store pairwise alignment result + string * fragmentsLayout; // store layout + string majority; + string consensus; +}; + +#endif + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/MainLan.cc b/ProyectoFinal/CHC/malva/rep/SA/dnafa/MainLan.cc new file mode 100644 index 0000000000000000000000000000000000000000..2b937bd6a96b813bb2905d3ba431d1685b52ddf4 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/MainLan.cc @@ -0,0 +1,57 @@ +#include "SA.hh" +#include "ContigBuilder.h" +#include <iostream.h> +#include <fstream.h> + +extern int Global_cutoff; + +int main (int argc, char** argv) +{ + using skeleton SA; + char path[MAX_BUFFER]; + int len; + int longitud; + + system("clear"); + + get_path(argv[0],path); + len = strlen(path); + longitud = MAX_BUFFER - len; + + strcat(path,"Config.cfg"); + ifstream f(path); + if(!f) show_message(10); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f1(path); + if(!f1) show_message(11); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f2(path); + if(!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + Global_cutoff = pbm.cutoff; + + SetUpParams cfg; + f1 >> cfg; + + + Solver_Lan solver(pbm,cfg,argc,argv); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solucion: " << solver.global_best_solution() << " Fitness: " << solver.global_best_solution().fitness(); + + f.getline(&(path[len]),longitud,'\n'); + ofstream fexit(path); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + cout << endl << endl << " :( ---------------------- THE END --------------- :) " << endl; + } + return(0); +} diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/MainSeq.cc b/ProyectoFinal/CHC/malva/rep/SA/dnafa/MainSeq.cc new file mode 100644 index 0000000000000000000000000000000000000000..488096d30ae1e582256f58600c5ec2acdd236d67 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/MainSeq.cc @@ -0,0 +1,48 @@ +#include "SA.hh" +#include "ContigBuilder.h" +#include <iostream.h> +#include <fstream.h> + +extern int Global_cutoff; + +int main (int argc, char** argv) +{ + using skeleton SA; + + system("clear"); + + if(argc < 4) + show_message(1); + + ifstream f1(argv[1]); + if (!f1) show_message(11); + + ifstream f2(argv[2]); + if (!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + +//cout << pbm; + Global_cutoff = pbm.cutoff; + + SetUpParams cfg; + f1 >> cfg; + + Solver_Seq solver(pbm,cfg); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << solver.global_best_solution() + << " Fitness: " << solver.global_best_solution().fitness() << endl; + cout << "\n\n :( ---------------------- THE END --------------- :) "; + + ofstream fexit(argv[3]); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + } + return(0); +} diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/Makefile b/ProyectoFinal/CHC/malva/rep/SA/dnafa/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..275b8575ae0fe807091339652a9cc8f4ad0ddf40 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/Makefile @@ -0,0 +1,25 @@ +include ../../../environment + +all: MainSeq MainLan + +clean: + rm -f MainLan MainSeq *.o *% *~ + +MainLan: SA.req.o SA.pro.o StopCondition.o MainLan.o OverlapDetector.o sga.o AdjKeys.o ContigBuilder.o ConsensusBuilder.o LayoutBuilder.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainWan: SA.req.o SA.pro.o StopCondition.o MainWan.o OverlapDetector.o sga.o AdjKeys.o ContigBuilder.o ConsensusBuilder.o LayoutBuilder.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainSeq: SA.req.o SA.pro.o StopCondition.o MainSeq.o OverlapDetector.o sga.o AdjKeys.o ContigBuilder.o ConsensusBuilder.o LayoutBuilder.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainScore: SA.req.o SA.pro.o StopCondition.o MainScore.o OverlapDetector.o sga.o AdjKeys.o ContigBuilder.o ConsensusBuilder.o LayoutBuilder.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +LAN: + $(RUN) -v -p4pg pgfileLan MainLan +WAN: + $(RUN) -v -p4pg pgfileWan MainWan +SEQ: + ./MainSeq SA.cfg ../../../ProblemInstances/DNAFA-instances/pbm.txt res/dna.sa.seq.txt diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/OverlapDetector.cpp b/ProyectoFinal/CHC/malva/rep/SA/dnafa/OverlapDetector.cpp new file mode 100644 index 0000000000000000000000000000000000000000..49b81ec13a45fd66e46cd17e0fd1cef7b5bca870 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/OverlapDetector.cpp @@ -0,0 +1,130 @@ +/*********************************************************************** + * File: OverlapDetector.cpp + * Author: Lishan Li + * Date: May, 2003 + * + * Description: It provides implementation of all the functions declared + * in the header file OverlapDetector.h. + ***********************************************************************/ + +#include "OverlapDetector.h" + +/************************** + * Purpose: allocate memory + **************************/ + +OverlapDetector::OverlapDetector(int nof):nbOfFrag(nof) +{ + score = new int*[nof]; + for(int i = 0; i < nof; i++) + score[i] = new int[nof]; +} + +/************************** + * Purpose: release memory + **************************/ + +OverlapDetector::~OverlapDetector() +{ + for(int j = 0; j < nbOfFrag; j++) + delete [] score[j]; + delete [] score; +} + +/********************************************************** + * Purpose: construct a score table to store overlap length + * of all possible pair of fragments + **********************************************************/ + +void OverlapDetector::buildScoresTable(vector<string>* fragments, vector<string>* rcFragments) +{ + for(int i = 0; i < nbOfFrag; i++) + { + string rcFrags = rcFragments->at(i); + + for(int j = i+1; j < nbOfFrag; j++) + { + SGA sga1(fragments->at(i), fragments->at(j)); // eg. w1 and w2 + sga1.buildMatrix(); + sga1.findBestScore(); + int score1 = sga1.getBestScore(); + + SGA sga2(rcFrags, fragments->at(j)); // eg. rcw1 and w2 + sga2.buildMatrix(); + sga2.findBestScore(); + int score2 = sga2.getBestScore(); + + if(score2 > score1) // store the larger one + score[j][i] = score[i][j] = -score2; + else + score[j][i] = score[i][j] = score1; + } + } +} + +/*************************** + * Purpose: for testing use + ***************************/ + +void OverlapDetector::readScoreTable() +{ + string inputFile = string(getenv("HOME")) + "/Mallba/ProblemInstances/DNAFA-instances/score.txt"; + ifstream inFile(inputFile.c_str(), ios::in); + if( !inFile ) + { + cout << "\n\t\t*** The file " << inputFile + << " doesn't exist! ***" << endl << endl; + exit(1); + } + +/* char seps[] = " \t\n"; + char oneLine[2000]; + int i = 0; + inFile.getline(oneLine, 2000); + while(inFile.getline(oneLine, 2000)) + { + int j = 0; + char * token = strtok(oneLine, seps); + + while (token != NULL) + { + score[i][j] = atoi(token); + token = strtok(NULL, seps); + j++; + } + i++; + }*/ + for(int i = 0; i < nbOfFrag; i++) + for(int j= 0; j < nbOfFrag; j++) + inFile >> score[i][j]; + inFile.close(); +} + +/************************************ + * Purpose: print overlap score table + ************************************/ + +void OverlapDetector::printScoreTable() +{ +// cout << endl << "*** *** *** *** Overlap Score Table *** *** *** ***" << endl << endl; + +// cout << " "; +// for(int k = 0; k < nbOfFrag; k++) +// cout << setw(5) << setiosflags(ios::right) << "F" << k; + + for(int i = 0; i < nbOfFrag; i++) + { + cout << endl; +// cout << "F" << i << " "; + for(int j = 0; j < nbOfFrag; j++) + { + if(i == j) + cout << setw(5) << setiosflags(ios::right) << "0 "; + else + cout << setw(5) << setiosflags(ios::right) << score[i][j] << " "; + } + } +// cout << endl << endl << "*****************************************************" << endl; +} + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/OverlapDetector.h b/ProyectoFinal/CHC/malva/rep/SA/dnafa/OverlapDetector.h new file mode 100644 index 0000000000000000000000000000000000000000..a0a0594582c45a89b93fd955505748386cd7357d --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/OverlapDetector.h @@ -0,0 +1,45 @@ +/*************************************************************** + * File: OverlapDetector.h + * Author: Lishan Li + * Date: May, 2003 + * + * Description: This OverlapDetector class is used to detect the + * similarity of all possible pair of fragments. The + * overlap length between any two fragments is stored + * in a two dimentional array called score. + ***************************************************************/ + +#ifndef OVERLAPDETECTOR_H +#define OVERLAPDETECTOR_H + +#pragma warning(disable: 4786) + +#include <iostream> +#include <fstream> +#include <iomanip> +#include <stdlib.h> +#include <string> +#include <vector> + +#include "sga.h" + +using namespace std; + + +class OverlapDetector +{ +public: + OverlapDetector(int nof); // constructor + ~OverlapDetector(); // destructor + void buildScoresTable(vector<string>*, vector<string>*); // build overlap score table for fragments + void readScoreTable(); + void printScoreTable(); + int ** getScoreTable() { return score; } +private: + int ** score; // to store the overlap length of all possible pair of fragments + int nbOfFrag; // Number of Fragments +}; + +#endif + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/SA.cfg b/ProyectoFinal/CHC/malva/rep/SA/dnafa/SA.cfg new file mode 100644 index 0000000000000000000000000000000000000000..739dc527253b58bd7f99914ebf8e494823154c93 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/SA.cfg @@ -0,0 +1,9 @@ +10 // number of independent runs +25600 // number of evaluations +256 // Markov-Chain Length +.99 // temperature Decay +1 // display state ? +LAN-configuration +200000 // the global state is updated in this number of evaluations +0 // 0: asynchronized mode // 1: synchronized mode +200 // interval of iterations to cooperate ( if 0 no cooperation) diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/SA.hh b/ProyectoFinal/CHC/malva/rep/SA/dnafa/SA.hh new file mode 100644 index 0000000000000000000000000000000000000000..c8d691493345603aa20caebeadca031d235b62f8 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/SA.hh @@ -0,0 +1,494 @@ +#ifndef INC_SA +#define INC_SA + +#include "Mallba/mallba.hh" +#include "Mallba/States.hh" +#include "Mallba/Rarray.h" +#include "Mallba/time.hh" +#include "Mallba/netstream.hh" +#include <math.h> +#include <string.h> +#include <vector> +#include "OverlapDetector.h" + +using namespace std; + +skeleton SA +{ + + provides class SetUpParams; + provides class Statistics; + provides class Move; + provides class StopCondition; + provides class Solver; + provides class Solver_Seq; + provides class Solver_Lan; + provides class Solver_Wan; + + requires class Problem; + requires class Solution; + requires class StopCondition_1; + requires class StopCondition_2; + requires class StopCondition_3; + requires class DefaultMove; + requires class UserStatistics; + requires bool TerminateQ (const Problem& pbm, const Solver& solver, const SetUpParams& setup); + +// Problem ---------------------------------------------------------------------------- + + requires class Problem + { + public: + Problem (); + ~Problem (); + + friend ostream& operator<< (ostream& os, const Problem& pbm); + friend istream& operator>> (istream& is, Problem& pbm); + + Problem& operator= (const Problem& pbm); + bool operator== (const Problem& pbm) const; + bool operator!= (const Problem& pbm) const; + + Direction direction () const; + + int numOfFragments; // number of fragments^M + double avgLength; // average length of the input fragments^M + int cutoff; // overlap threshold^M + int * fragmentLength; // fragments' lengths^M + vector<string>* fragments; // forward direction of the fragments^M + vector<string>* description; // description of the fragments (Nombre Del Fragmento)^M + vector<string>* rcFragments; // reverse complement of the fragments + OverlapDetector *detector; + }; + +//Solution ---------------------------------------------------------------------------- + + requires class Solution + { + public: + Solution (const Problem& pbm); + Solution (const Solution& sol); + ~Solution(); + + friend ostream& operator<< (ostream& os, const Solution& sol); + friend istream& operator>> (istream& is, Solution& sol); + friend NetStream& operator << (NetStream& ns, const Solution& sol); + friend NetStream& operator >> (NetStream& ns, Solution& sol); + + const Problem& pbm() const; + + Solution& operator= (const Solution& sol); + bool operator== (const Solution& sol) const; + bool operator!= (const Solution& sol) const; + + char *to_String() const; + void to_Solution(char *_vertex_); + unsigned int size() const; + + void initialize(); + double fitness (); + int& fragment(const int index); + int* fragments(); + + private: + int * fragOrder; // an order of an individual ^M + const Problem& _pbm; + + }; + +// UserStatistics ---------------------------------------------------------------------------- + + requires class UserStatistics + { + private: + struct user_stat + { + unsigned int trial; + double initial_temperature; + double temperature_best_found_trial; + unsigned long nb_evaluation_best_found_trial; + double best_cost_trial; + float time_best_found_trial; + float time_spent_trial; + }; + + Rlist<struct user_stat> result_trials; + + public: + UserStatistics (); + ~UserStatistics(); + + friend ostream& operator<< (ostream& os, const UserStatistics& usertats); + + UserStatistics& operator= (const UserStatistics& userstats); + void update(const Solver& solver); + void clear(); + }; + +// Move ---------------------------------------------------------------------------------- + + provides class Move + { + public: + Move() {} + virtual ~Move() {} + + virtual void Apply(Solution& sol) const = 0; + }; + +// DefaultMove ---------------------------------------------------------------------------------- + + requires class DefaultMove: public Move + { + public: + DefaultMove(); + ~DefaultMove(); + + void Apply(Solution& sol) const; + }; + +// SetUpParams ------------------------------------------------------------------------------- + + provides class SetUpParams + { + private: + unsigned int _independent_runs; + unsigned long _max_evaluations; + unsigned int _MarkovChain_length; + double _temperature_decay; + bool _display_state; + + // for LAN execution configuration + unsigned long _refresh_global_state; + bool _synchronized; + unsigned int _cooperation; + + public: + SetUpParams (); + + friend ostream& operator<< (ostream& os, const SetUpParams& setup); + friend istream& operator>> (istream& is, SetUpParams& setup); + + const unsigned int independent_runs() const; + const unsigned long max_evaluations() const; + const unsigned int MarkovChain_length() const; + const double temperature_decay() const; + const bool display_state() const; + const unsigned long refresh_global_state() const; + const bool synchronized() const; + const unsigned int cooperation() const; + + void independent_runs(const unsigned int val); + void max_evaluations(const unsigned long val); + void MarkovChain_length(const unsigned int val); + void temperature_decay(const double val); + void display_state(const bool val); + void refresh_global_state(const unsigned long val); + void synchronized(const bool val); + void cooperation(const unsigned int val); + + ~SetUpParams(); + }; + +// Statistics --------------------------------------------------------------------------------- + + provides class Statistics + { + private: + struct stat + { + unsigned int trial; + unsigned long nb_evaluations; + double best_cost; + double current_cost; + }; + + Rlist<struct stat> stats_data; + + public: + Statistics(); + + friend ostream& operator<< (ostream& os, const Statistics& stats); + + Statistics& operator= (const Statistics& stats); + void update(const Solver& solver); + void clear(); + + ~Statistics(); + }; + +// Solver --------------------------------------------------------------------------------- + + provides class Solver + { + protected: + const Problem& problem; + const SetUpParams& params; + UserStatistics _userstat; + Statistics _stat; + Move* move; + Solution current; + double curfit; + Solution tentative; + double currentTemperature; + unsigned int k; // to control temperature update. + StateCenter _sc; + + float total_time_spent; + float time_spent_in_trial; + float start_trial; + float start_global; + + bool _end_trial; + + State_Vble _current_trial; + State_Vble _current_iteration; + State_Vble _current_best_solution; + State_Vble _current_best_cost; + State_Vble _current_solution; + State_Vble _current_cost; + + State_Vble _current_time_spent; + State_Vble _initial_temperature_trial; + State_Vble _time_best_found_trial; + State_Vble _iteration_best_found_trial; + State_Vble _temperature_best_found_trial; + State_Vble _time_spent_trial; + + State_Vble _trial_best_found; + State_Vble _iteration_best_found; + State_Vble _global_best_solution; + State_Vble _global_best_cost; + State_Vble _time_best_found; + + State_Vble _temperature; + State_Vble _display_state; + + const Direction _direction; + + bool AcceptQ(double tent, double cur, double temperature); + double Set_Initial_Temperature(const Problem& pbm); + void KeepHistory(const Solution& sol, const double curfit,const float time_spent_trial,const float total_time_spent); + + double UpdateT(double temp, int K); + + public: + // Constructor - Destructor ------------------------- + + Solver (const Problem& pbm, const SetUpParams& setup); + virtual ~Solver (); + virtual int pid() const; + bool end_trial() const; + + // Execution methods -------------------------------- + + // Full execution + virtual void run () =0; + virtual void run (unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol, unsigned long int nb_evaluations) =0; + + virtual void run (const double initialTemperature) =0; + virtual void run (const Solution& sol,const double initialTemperature) =0; + virtual void run (const double initialTemperature, unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations) =0; + + // Partial execution + virtual void StartUp () =0; + virtual void StartUp (const Solution& sol) =0; + virtual void StartUp (const double initialTemperature) =0; + virtual void StartUp (const Solution& sol, const double initialTemperature) =0; + virtual void DoStep () =0; + + // Statistics handling ------------------------------ + + const Statistics& statistics() const; + const UserStatistics& userstatistics () const; + const SetUpParams& setup() const; + const Problem& pbm() const; + + // State handling ----------------------------------- + + void RefreshState(); + void UpdateFromState(); + StateCenter* GetState(); + + unsigned int current_trial() const; + unsigned long current_iteration() const; + Solution current_best_solution() const; + Solution current_solution() const; + double current_best_cost() const; + double current_cost() const; + float current_time_spent() const; + float time_best_found_trial() const; + double initial_temperature_trial() const; + unsigned int iteration_best_found_trial() const; + double temperature_best_found_trial() const; + float time_spent_trial() const; + unsigned int trial_best_found() const; + unsigned int iteration_best_found() const; + Solution global_best_solution() const; + double global_best_cost() const; + float time_best_found() const; + double temperature() const; + int display_state() const; + + void current_trial(const unsigned int value); + void current_iteration(const unsigned long value); + void current_best_solution(const Solution& sol); + void current_best_cost(const double value); + void current_solution(const Solution& sol); + void current_cost(const double value); + void current_time_spent(const float value); + void time_best_found_trial(const float value); + void initial_temperature_trial(const double temperature); + void iteration_best_found_trial(const unsigned int value); + void temperature_best_found_trial(const double value); + void time_spent_trial(const float value); + void trial_best_found(const unsigned int value); + void iteration_best_found(const unsigned int value); + void global_best_solution(const Solution& sol); + void global_best_cost(const double value); + void time_best_found(const float value); + void temperature(const double value); + void display_state(const int value); + void show_state() const; + + // State handling ----------------------------------- + void SetMove(Move* mov); + }; + + provides class Solver_Seq: public Solver + { + public: + // Constructor - Destructor ------------------------- + + Solver_Seq ( const Problem& pbm, const SetUpParams& setup); + virtual ~Solver_Seq (); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + }; + + provides class Solver_Lan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + + public: + Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Lan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + + provides class Solver_Wan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + + public: + Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Wan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + +}; + +#endif diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/SA.pro.cc b/ProyectoFinal/CHC/malva/rep/SA/dnafa/SA.pro.cc new file mode 100644 index 0000000000000000000000000000000000000000..a89284b0f375e8968fdc58653931017d8798a8ba --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/SA.pro.cc @@ -0,0 +1,1808 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** Provided classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** *** +************************************************/ + +#include <iostream.h> +#include <math.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "Mallba/time.hh" + +skeleton SA +{ + +// SetUpParams ----------------------------------------------------------- + + SetUpParams::SetUpParams (): + _independent_runs(0), + _max_evaluations(0), + _MarkovChain_length(0), + _temperature_decay(0), + _refresh_global_state(0), + _synchronized(0), + _display_state(0), + _cooperation(0) + {} + + istream& operator>> (istream& is, SetUpParams& setup) + { + char buffer[MAX_BUFFER]; // current line in the setup file + char command[50]; + int op; + double dop; + short int nb_param=0; + short int nb_section=0; + short int nb_LAN_param=0; + + while (is.getline(buffer,MAX_BUFFER,'\n')) + { + sscanf(buffer," %s ",command); + + if (!(strcmp(command,"General"))) nb_section=0; + if (!(strcmp(command,"LAN-configuration"))) nb_section=1; + + if (nb_param==3 && nb_section==0) + { + dop=-1; + sscanf(buffer," %lf ",&dop); + if (dop<0) continue; + } + else + { + op=-1; + sscanf(buffer," %ld%*s ",&op); + if (op<0) continue; + } + + switch (nb_section) + { + case 0: switch (nb_param) + { + case 0: setup.independent_runs(op); break; + case 1: setup.max_evaluations(op); break; + case 2: setup.MarkovChain_length(op); break; + case 3: setup.temperature_decay(dop); break; + case 4: setup.display_state(op); break; + } + nb_param++; + break; + case 1: if (nb_LAN_param>=3) break; + if (nb_LAN_param==0) setup.refresh_global_state(op); + if (nb_LAN_param==1) setup.synchronized(op); + if (nb_LAN_param==2) setup.cooperation(op); + nb_LAN_param++; + break; + } // end switch + } // end while + return is; + } + + ostream& operator<< (ostream& os, const SetUpParams& setup) + { + os << "CONFIGURATION -------------------------------------------" << endl << endl; + os << "\t" << "Independent runs : " << setup.independent_runs() << endl + << "\t" << "Evaluation steps: " << setup.max_evaluations() << endl + << "\t" << "Markov-Chain Length: " << setup.MarkovChain_length() << endl + << "\t" << "Temperature Decay: " << setup.temperature_decay() << endl; + + if (setup.display_state()) + os << "\t" << "Display state" << endl; + else + os << "\t" << "Not display state" << endl; + os << endl << "\t" << "LAN configuration:" << endl + << "\t" << "----------------------" << endl << endl + << "\t" << "Refresh global state in number of generations: " << setup.refresh_global_state() << endl; + + if (setup.synchronized()) + os << "\t" << "Running in synchronous mode" << endl; + else + os << "\t" << "Running in asynchronous mode" << endl; + + if (!setup.cooperation()) + os << "\t" << "Running without cooperation" << endl << endl; + else + os << "\t" << "Running with cooperation in " << setup.cooperation() << " iterations. " << endl << endl; + + os << endl << endl << "END CONFIGURATION -------------------------------------------" << endl << endl; + return os; + } + + const unsigned int SetUpParams::independent_runs() const + { + return _independent_runs; + } + + const unsigned long SetUpParams::max_evaluations() const + { + return _max_evaluations; + } + + const unsigned int SetUpParams::MarkovChain_length() const + { + return _MarkovChain_length; + } + + const double SetUpParams::temperature_decay() const + { + return _temperature_decay; + } + + const bool SetUpParams::display_state() const + { + return _display_state; + } + + const unsigned long SetUpParams::refresh_global_state() const + { + return _refresh_global_state; + } + + const bool SetUpParams::synchronized() const + { + return _synchronized; + } + + const unsigned int SetUpParams::cooperation() const + { + return _cooperation; + } + + void SetUpParams::independent_runs(const unsigned int val) + { + _independent_runs = val; + } + + void SetUpParams::max_evaluations(const unsigned long val) + { + _max_evaluations= val; + } + void SetUpParams::MarkovChain_length(const unsigned int val) + { + _MarkovChain_length= val; + } + void SetUpParams::temperature_decay(const double val) + { + _temperature_decay= val; + } + + void SetUpParams::display_state(const bool val) + { + _display_state=val; + } + + void SetUpParams::refresh_global_state(const unsigned long val) + { + _refresh_global_state=val; + } + + void SetUpParams::synchronized(const bool val) + { + _synchronized=val; + } + + void SetUpParams::cooperation(const unsigned int val) + { + _cooperation=val; + } + + SetUpParams::~SetUpParams() + {} + +// Statistics ------------------------------------------------------ + + Statistics::Statistics() + {} + + ostream& operator<< (ostream& os, const Statistics& stats) + { + int j; + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF CURRENT TRIAL " << endl; + os << "------------------------------------------------------------------" << endl; + for (int i=0;i< stats.stats_data.size();i++) + { + os << endl + << " Evaluations: " << stats.stats_data[i].nb_evaluations + << " Best: " << stats.stats_data[i].best_cost + << " Current: " << stats.stats_data[i].current_cost; + } + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + Statistics& Statistics::operator= (const Statistics& stats) + { + stats_data = stats.stats_data; + return *this; + } + + void Statistics::update(const Solver& solver) + { + /* struct stat *new_stat; + if ((new_stat=(struct stat *)malloc(sizeof(struct stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluations= solver.current_iteration(); + new_stat->best_cost = solver.current_best_cost(); + new_stat->current_cost = solver.current_cost(); + stats_data.append(*new_stat); */ + } + + Statistics::~Statistics() + { + stats_data.remove(); + } + + void Statistics::clear() + { + stats_data.remove(); + } + +// Solver (superclass)--------------------------------------------------- + + Solver::Solver (const Problem& pbm, const SetUpParams& setup) + : problem(pbm), + params(setup), + _stat(), + _userstat(), + _sc(), + _direction(pbm.direction()), + current(pbm), + tentative(pbm), + currentTemperature(0.0), + time_spent_in_trial(0.0), + total_time_spent(0.0), + start_trial(0.0), + start_global(0.0), + _current_trial("_current_trial",_sc), + _current_iteration("_current_iteration",_sc), + _current_best_solution("_current_best_solution",_sc), + _current_best_cost("_current_best_cost",_sc), + _current_solution("_current_solution",_sc), + _current_cost("_current_cost",_sc), + _current_time_spent("_current_time_spent",_sc), + _initial_temperature_trial("_initial_temperature_trial",_sc), + _time_best_found_trial("_time_best_found_trial",_sc), + _iteration_best_found_trial("_iteration_best_found_trial",_sc), + _temperature_best_found_trial("_temperature_best_found_trial",_sc), + _time_spent_trial("_time_spent_trial",_sc), + _trial_best_found("_trial_best_found",_sc), + _iteration_best_found("_iteration_best_found;",_sc), + _global_best_solution("_global_best_solution",_sc), + _global_best_cost("_global_best_cost",_sc), + _time_best_found("_time_best_found",_sc), + _temperature("_temperature",_sc), + _display_state("_display_state",_sc) + { + current_trial(0); + current_iteration(0); + current_best_solution(current), + current_best_cost((-1) * pbm.direction() * infinity()); + current_solution(current); + current_cost((-1) * pbm.direction() * infinity()); + current_time_spent(total_time_spent); + initial_temperature_trial(0); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(0); + temperature_best_found_trial(0.0); + time_spent_trial(time_spent_in_trial); + trial_best_found(0); + iteration_best_found(0); + global_best_solution(current); + global_best_cost((-1) * pbm.direction() * infinity()); + time_best_found(total_time_spent); + temperature(currentTemperature); + display_state(setup.display_state()); + + move = new DefaultMove; + } + + int Solver::pid() const + { + return 0; + } + + bool Solver::end_trial() const + { + return _end_trial; + } + + unsigned int Solver::current_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_trial",(char *)&value, nitems, length); + return value; + } + + unsigned long Solver::current_iteration() const + { + unsigned long value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_iteration",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_best_solution() const + { + Solution sol(problem); + unsigned long nitems,length; + char data_stored[_current_best_solution.get_nitems() + _current_best_solution.get_length()]; + _sc.get_contents_state_variable("_current_best_solution", data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::current_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_best_cost",(char *)&value, nitems, length); + return value; + } + + double Solver::current_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_cost",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_solution() const + { + Solution sol(problem); + char data_stored[_current_solution.get_nitems() + _current_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_solution",data_stored, nitems, length); + sol.to_Solution((char *)data_stored); + return sol; + } + + float Solver::current_time_spent() const + { + float value=0.0; + unsigned long nitems,length; + _current_time_spent.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::initial_temperature_trial() const + { + double value=0.0; + unsigned long nitems,length; + _initial_temperature_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature_best_found_trial() const + { + double value=0.0; + unsigned long nitems,length; + _temperature_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_spent_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_spent_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::trial_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _trial_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::global_best_solution() const + { + Solution sol(problem); + char data_stored[_global_best_solution.get_nitems() + _global_best_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_solution",data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::global_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_cost",(char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_temperature",(char *)&value, nitems, length); + return value; + } + + int Solver::display_state() const + { + int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_display_state",(char *)&value, nitems, length); + return value; + } + + void Solver::current_trial(const unsigned int value) + { + _sc.set_contents_state_variable("_current_trial",(char *)&value,1,sizeof(int)); + } + + void Solver::current_iteration(const unsigned long value) + { + _sc.set_contents_state_variable("_current_iteration",(char *)&value,1,sizeof(long)); + } + + void Solver::current_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_best_cost(const double value) + { + _sc.set_contents_state_variable("_current_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_cost(const double value) + { + _sc.set_contents_state_variable("_current_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_time_spent(const float value) + { + _current_time_spent.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::time_best_found_trial(const float value) + { + _time_best_found_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::iteration_best_found_trial(const unsigned int value) + { + _iteration_best_found_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::initial_temperature_trial(const double value) + { + _initial_temperature_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::temperature_best_found_trial(const double value) + { + _temperature_best_found_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::time_spent_trial(const float value) + { + _time_spent_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::trial_best_found(const unsigned int value) + { + _trial_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::iteration_best_found(const unsigned int value) + { + _iteration_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::global_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_global_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::global_best_cost(const double value) + { + _sc.set_contents_state_variable("_global_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::time_best_found(const float value) + { + _time_best_found.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::temperature(const double value) + { + _sc.set_contents_state_variable("_temperature",(char *)&value,1,sizeof(double)); + } + + void Solver::display_state(const int value) + { + _sc.set_contents_state_variable("_display_state",(char *)&value,1,sizeof(int)); + } + + const Statistics& Solver::statistics() const + { + return _stat; + } + + const UserStatistics& Solver::userstatistics() const + { + return _userstat; + } + + const SetUpParams& Solver::setup() const + { + return params; + } + + const Problem& Solver::pbm() const + { + return problem; + } + + void Solver::KeepHistory(const Solution& sol, const double curfit,const float time_spent_in_trial,const float total_time_spent) + { + bool betterG=false; + bool betterT=false; + + switch (_direction) + { + case minimize: betterG = (curfit < global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit < current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + case maximize: betterG = (curfit > global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit > current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + } + + if (betterT) + { + current_best_solution(sol); + current_best_cost(curfit); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(current_iteration()); + temperature_best_found_trial(temperature()); + if (betterG) + { + trial_best_found(current_trial()); + iteration_best_found(current_iteration()); + global_best_solution(sol); + global_best_cost(curfit); + time_best_found(time_spent_in_trial); + } + } + } + + double Solver::UpdateT(double temp, int K) + { + return temp * params.temperature_decay(); // initial + + /* + if(K == 1) return temp/log(2); + else return temp * log(K) / log(K+1); + */ + /* + if(K == 1) return temp/2; + else return (temp * K) / (K + 1); + */ + + /* if(K == 1) return temp / exp(2); + else return (temp * exp(K)) / exp(K+1); + */ + + } + + StateCenter* Solver::GetState() + { + return &_sc; + } + + void Solver::RefreshState() + { + current_solution(current); + current_cost(curfit); + current_time_spent(total_time_spent); + time_spent_trial(time_spent_in_trial); + temperature(currentTemperature); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::UpdateFromState() + { + current = current_solution(); + curfit = current_cost(); + total_time_spent=current_time_spent(); + time_spent_in_trial=time_spent_trial(); + currentTemperature = temperature(); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::show_state() const + { + cout << endl << "Current trial: " << current_trial(); + cout << endl << "Current iteration: " << current_iteration(); + cout << endl << "Current Temperature: " << temperature (); + cout << endl << "Current cost: " << current_cost(); + cout << endl << "Best cost in trial: " << current_best_cost(); + cout << endl << "Time of best solution found in trial: " << time_best_found_trial(); + cout << endl << "Iteration of best solution found in trial: " << iteration_best_found_trial(); + cout << endl << "Initial temperature in trial: " << initial_temperature_trial(); + cout << endl << "Temperature of best solution found in trial: " << temperature_best_found_trial(); + cout << endl << "Time spent in trial: " << time_spent_trial(); + cout << endl << "Global best cost: " << global_best_cost(); + cout << endl << "Trial of best global solution found: " << trial_best_found(); + cout << endl << "Iteration of best global solution found: " << iteration_best_found(); + cout << endl << "Time of global best solution found: " << time_best_found(); + // cout << endl << "Current solution: " << current_solution(); + // cout << endl << "Best solution of trial: " << current_best_solution(); + // cout << endl << "Global solution: " << global_best_solution() << endl; + cout << endl << endl << "Current time spent (so far): " << current_time_spent() << endl; + } + + Solver::~Solver() + { + _sc.removeAll(); + delete move; + } + + bool Solver::AcceptQ (double tent, double cur, double temperature) + { + if (_direction==minimize) + + return (tent < cur) || + ((rand01()*(1+exp((tent-cur)/temperature)))<2.0); + + else + + return (tent > cur) || + ((rand01()*(1+exp((cur-tent)/temperature)))<2.0); + } + + double Solver::Set_Initial_Temperature(const Problem& pbm) + { + const double beta = 1.05; + const double test = 10; + const double acrat = .8; + const double T = 1.0; + + Solution current (pbm); + Solution newsol (pbm); + double ac; + double fit; + double temperature = T; + + do + { + temperature *= beta; + ac = 0; + current.initialize(); + fit = current.fitness(); + for (int i=0; i<test; i++) + { + newsol = current; + move->Apply(newsol); + if (AcceptQ(newsol.fitness(),fit,temperature)) + ac += 1.0/test; + } + } while (ac < acrat); + + initial_temperature_trial(temperature); + return temperature; + + } + + void Solver::SetMove (Move* mov) + { + delete move; + move = mov; + } + + // Solver sequencial ----------------------------------------------------- + + Solver_Seq::Solver_Seq (const Problem& pbm, const SetUpParams& setup) + : Solver(pbm,setup) + { + random_seed(time(0)); + _end_trial=true; + } + + Solver_Seq::~Solver_Seq () + {} + + void Solver_Seq::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Seq::StartUp(const Solution& sol, const double initialTemperature) + { + start_trial=_used_time(); + start_global=total_time_spent; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current = sol; + curfit = current.fitness(); + current_best_cost((-1) * problem.direction() * infinity()); + currentTemperature = initialTemperature; + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + void Solver_Seq::DoStep() + { + current_iteration(current_iteration()+1); + + tentative = current; + move->Apply(tentative); + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + + void Solver_Seq::run (unsigned long int max_evaluations) + { + StartUp(); + + while (current_iteration()<max_evaluations && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + // Solver LAN ----------------------------------------------------------- + + Solver_Lan::Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); + } + + Solver_Lan::~Solver_Lan () + { + NetStream::finalize(); + } + + int Solver_Lan::pid() const + { + return mypid; + } + + NetStream& Solver_Lan::netstream() + { + return _netstream; + } + + void Solver_Lan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Lan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + void update(Direction direction, Solution &solution_received,double cost_received, Solution &solution_to_send, double &best_cost) + { + switch (direction) + { + case minimize: if (cost_received < best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + case maximize: if (cost_received > best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + } + } + + int Solver_Lan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Lan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Lan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Lan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Lan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Lan::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + void Solver_Lan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } + + // Solver WAN ------------------------------------------------------------ + + Solver_Wan::Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); + } + + Solver_Wan::~Solver_Wan () + { + NetStream::finalize(); + } + + int Solver_Wan::pid() const + { + return mypid; + } + + NetStream& Solver_Wan::netstream() + { + return _netstream; + } + + void Solver_Wan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Wan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + int Solver_Wan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Wan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Wan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Wan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Wan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Wan::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + void Solver_Wan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } +}; + diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/SA.pro.cc1 b/ProyectoFinal/CHC/malva/rep/SA/dnafa/SA.pro.cc1 new file mode 100644 index 0000000000000000000000000000000000000000..3d95a77e472c61314ac087f8a415735030e5fa6e --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/SA.pro.cc1 @@ -0,0 +1,1837 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** Provided classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** *** +************************************************/ + +#include <iostream.h> +#include <math.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "Mallba/time.hh" +#include "ContigBuilder.h" + +skeleton SA +{ + +// SetUpParams ----------------------------------------------------------- + + SetUpParams::SetUpParams (): + _independent_runs(0), + _max_evaluations(0), + _MarkovChain_length(0), + _temperature_decay(0), + _refresh_global_state(0), + _synchronized(0), + _display_state(0), + _cooperation(0) + {} + + istream& operator>> (istream& is, SetUpParams& setup) + { + char buffer[MAX_BUFFER]; // current line in the setup file + char command[50]; + int op; + double dop; + short int nb_param=0; + short int nb_section=0; + short int nb_LAN_param=0; + + while (is.getline(buffer,MAX_BUFFER,'\n')) + { + sscanf(buffer," %s ",command); + + if (!(strcmp(command,"General"))) nb_section=0; + if (!(strcmp(command,"LAN-configuration"))) nb_section=1; + + if (nb_param==3 && nb_section==0) + { + dop=-1; + sscanf(buffer," %lf ",&dop); + if (dop<0) continue; + } + else + { + op=-1; + sscanf(buffer," %d ",&op); + if (op<0) continue; + } + + switch (nb_section) + { + case 0: switch (nb_param) + { + case 0: setup.independent_runs(op); break; + case 1: setup.max_evaluations(op); break; + case 2: setup.MarkovChain_length(op); break; + case 3: setup.temperature_decay(dop); break; + case 4: setup.display_state(op); break; + } + nb_param++; + break; + case 1: if (nb_LAN_param>=3) break; + if (nb_LAN_param==0) setup.refresh_global_state(op); + if (nb_LAN_param==1) setup.synchronized(op); + if (nb_LAN_param==2) setup.cooperation(op); + nb_LAN_param++; + break; + } // end switch + } // end while + return is; + } + + ostream& operator<< (ostream& os, const SetUpParams& setup) + { + os << "CONFIGURATION -------------------------------------------" << endl << endl; + os << "\t" << "Independent runs : " << setup.independent_runs() << endl + << "\t" << "Evaluation steps: " << setup.max_evaluations() << endl + << "\t" << "Markov-Chain Length: " << setup.MarkovChain_length() << endl + << "\t" << "Temperature Decay: " << setup.temperature_decay() << endl; + + if (setup.display_state()) + os << "\t" << "Display state" << endl; + else + os << "\t" << "Not display state" << endl; + os << endl << "\t" << "LAN configuration:" << endl + << "\t" << "----------------------" << endl << endl + << "\t" << "Refresh global state in number of generations: " << setup.refresh_global_state() << endl; + + if (setup.synchronized()) + os << "\t" << "Running in synchronous mode" << endl; + else + os << "\t" << "Running in asynchronous mode" << endl; + + if (!setup.cooperation()) + os << "\t" << "Running without cooperation" << endl << endl; + else + os << "\t" << "Running with cooperation in " << setup.cooperation() << " iterations. " << endl << endl; + + os << endl << endl << "END CONFIGURATION -------------------------------------------" << endl << endl; + return os; + } + + const unsigned int SetUpParams::independent_runs() const + { + return _independent_runs; + } + + const unsigned long SetUpParams::max_evaluations() const + { + return _max_evaluations; + } + + const unsigned int SetUpParams::MarkovChain_length() const + { + return _MarkovChain_length; + } + + const double SetUpParams::temperature_decay() const + { + return _temperature_decay; + } + + const bool SetUpParams::display_state() const + { + return _display_state; + } + + const unsigned long SetUpParams::refresh_global_state() const + { + return _refresh_global_state; + } + + const bool SetUpParams::synchronized() const + { + return _synchronized; + } + + const unsigned int SetUpParams::cooperation() const + { + return _cooperation; + } + + void SetUpParams::independent_runs(const unsigned int val) + { + _independent_runs = val; + } + + void SetUpParams::max_evaluations(const unsigned long val) + { + _max_evaluations= val; + } + void SetUpParams::MarkovChain_length(const unsigned int val) + { + _MarkovChain_length= val; + } + void SetUpParams::temperature_decay(const double val) + { + _temperature_decay= val; + } + + void SetUpParams::display_state(const bool val) + { + _display_state=val; + } + + void SetUpParams::refresh_global_state(const unsigned long val) + { + _refresh_global_state=val; + } + + void SetUpParams::synchronized(const bool val) + { + _synchronized=val; + } + + void SetUpParams::cooperation(const unsigned int val) + { + _cooperation=val; + } + + SetUpParams::~SetUpParams() + {} + +// Statistics ------------------------------------------------------ + + Statistics::Statistics() + {} + + ostream& operator<< (ostream& os, const Statistics& stats) + { + int j; + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF CURRENT TRIAL " << endl; + os << "------------------------------------------------------------------" << endl; + for (int i=0;i< stats.stats_data.size();i++) + { + os << endl + << " Evaluations: " << stats.stats_data[i].nb_evaluations + << " Best: " << stats.stats_data[i].best_cost + << " Current: " << stats.stats_data[i].current_cost; + } + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + Statistics& Statistics::operator= (const Statistics& stats) + { + stats_data = stats.stats_data; + return *this; + } + + void Statistics::update(const Solver& solver) + { + /* struct stat *new_stat; + if ((new_stat=(struct stat *)malloc(sizeof(struct stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluations= solver.current_iteration(); + new_stat->best_cost = solver.current_best_cost(); + new_stat->current_cost = solver.current_cost(); + stats_data.append(*new_stat); */ + } + + Statistics::~Statistics() + { + stats_data.remove(); + } + + void Statistics::clear() + { + stats_data.remove(); + } + +// Solver (superclass)--------------------------------------------------- + + Solver::Solver (const Problem& pbm, const SetUpParams& setup) + : problem(pbm), + params(setup), + _stat(), + _userstat(), + _sc(), + _direction(pbm.direction()), + current(pbm), + tentative(pbm), + currentTemperature(0.0), + time_spent_in_trial(0.0), + total_time_spent(0.0), + start_trial(0.0), + start_global(0.0), + _current_trial("_current_trial",_sc), + _current_iteration("_current_iteration",_sc), + _current_best_solution("_current_best_solution",_sc), + _current_best_cost("_current_best_cost",_sc), + _current_solution("_current_solution",_sc), + _current_cost("_current_cost",_sc), + _current_time_spent("_current_time_spent",_sc), + _initial_temperature_trial("_initial_temperature_trial",_sc), + _time_best_found_trial("_time_best_found_trial",_sc), + _iteration_best_found_trial("_iteration_best_found_trial",_sc), + _temperature_best_found_trial("_temperature_best_found_trial",_sc), + _time_spent_trial("_time_spent_trial",_sc), + _trial_best_found("_trial_best_found",_sc), + _iteration_best_found("_iteration_best_found;",_sc), + _global_best_solution("_global_best_solution",_sc), + _global_best_cost("_global_best_cost",_sc), + _time_best_found("_time_best_found",_sc), + _temperature("_temperature",_sc), + _display_state("_display_state",_sc) + { + current_trial(0); + current_iteration(0); + current_best_solution(current), + current_best_cost((-1) * pbm.direction() * infinity()); + current_solution(current); + current_cost((-1) * pbm.direction() * infinity()); + current_time_spent(total_time_spent); + initial_temperature_trial(0); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(0); + temperature_best_found_trial(0.0); + time_spent_trial(time_spent_in_trial); + trial_best_found(0); + iteration_best_found(0); + global_best_solution(current); + global_best_cost((-1) * pbm.direction() * infinity()); + time_best_found(total_time_spent); + temperature(currentTemperature); + display_state(setup.display_state()); + + move = new DefaultMove; + } + + int Solver::pid() const + { + return 0; + } + + bool Solver::end_trial() const + { + return _end_trial; + } + + unsigned int Solver::current_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_trial",(char *)&value, nitems, length); + return value; + } + + unsigned long Solver::current_iteration() const + { + unsigned long value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_iteration",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_best_solution() const + { + Solution sol(problem); + unsigned long nitems,length; + char data_stored[_current_best_solution.get_nitems() + _current_best_solution.get_length()]; + _sc.get_contents_state_variable("_current_best_solution", data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::current_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_best_cost",(char *)&value, nitems, length); + return value; + } + + double Solver::current_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_cost",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_solution() const + { + Solution sol(problem); + char data_stored[_current_solution.get_nitems() + _current_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_solution",data_stored, nitems, length); + sol.to_Solution((char *)data_stored); + return sol; + } + + float Solver::current_time_spent() const + { + float value=0.0; + unsigned long nitems,length; + _current_time_spent.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::initial_temperature_trial() const + { + double value=0.0; + unsigned long nitems,length; + _initial_temperature_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature_best_found_trial() const + { + double value=0.0; + unsigned long nitems,length; + _temperature_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_spent_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_spent_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::trial_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _trial_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::global_best_solution() const + { + Solution sol(problem); + char data_stored[_global_best_solution.get_nitems() + _global_best_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_solution",data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::global_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_cost",(char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_temperature",(char *)&value, nitems, length); + return value; + } + + int Solver::display_state() const + { + int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_display_state",(char *)&value, nitems, length); + return value; + } + + void Solver::current_trial(const unsigned int value) + { + _sc.set_contents_state_variable("_current_trial",(char *)&value,1,sizeof(int)); + } + + void Solver::current_iteration(const unsigned long value) + { + _sc.set_contents_state_variable("_current_iteration",(char *)&value,1,sizeof(long)); + } + + void Solver::current_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_best_cost(const double value) + { + _sc.set_contents_state_variable("_current_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_cost(const double value) + { + _sc.set_contents_state_variable("_current_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_time_spent(const float value) + { + _current_time_spent.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::time_best_found_trial(const float value) + { + _time_best_found_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::iteration_best_found_trial(const unsigned int value) + { + _iteration_best_found_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::initial_temperature_trial(const double value) + { + _initial_temperature_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::temperature_best_found_trial(const double value) + { + _temperature_best_found_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::time_spent_trial(const float value) + { + _time_spent_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::trial_best_found(const unsigned int value) + { + _trial_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::iteration_best_found(const unsigned int value) + { + _iteration_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::global_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_global_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::global_best_cost(const double value) + { + _sc.set_contents_state_variable("_global_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::time_best_found(const float value) + { + _time_best_found.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::temperature(const double value) + { + _sc.set_contents_state_variable("_temperature",(char *)&value,1,sizeof(double)); + } + + void Solver::display_state(const int value) + { + _sc.set_contents_state_variable("_display_state",(char *)&value,1,sizeof(int)); + } + + const Statistics& Solver::statistics() const + { + return _stat; + } + + const UserStatistics& Solver::userstatistics() const + { + return _userstat; + } + + const SetUpParams& Solver::setup() const + { + return params; + } + + const Problem& Solver::pbm() const + { + return problem; + } + + void Solver::KeepHistory(const Solution& sol, const double curfit,const float time_spent_in_trial,const float total_time_spent) + { + bool betterG=false; + bool betterT=false; + + switch (_direction) + { + case minimize: betterG = (curfit < global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit < current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + case maximize: betterG = (curfit > global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit > current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + } + + if (betterT) + { + current_best_solution(sol); + current_best_cost(curfit); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(current_iteration()); + temperature_best_found_trial(temperature()); + if (betterG) + { + trial_best_found(current_trial()); + iteration_best_found(current_iteration()); + global_best_solution(sol); + global_best_cost(curfit); + time_best_found(time_spent_in_trial); + } + } + } + + double Solver::UpdateT(double temp, int K) + { + return temp * params.temperature_decay(); // initial + + /* + if(K == 1) return temp/log(2); + else return temp * log(K) / log(K+1); + */ + /* + if(K == 1) return temp/2; + else return (temp * K) / (K + 1); + */ + +/* if(K == 1) return temp / exp(2); + else return (temp * exp(K)) / exp(K+1);*/ + + } + + StateCenter* Solver::GetState() + { + return &_sc; + } + + void Solver::RefreshState() + { + current_solution(current); + current_cost(curfit); + current_time_spent(total_time_spent); + time_spent_trial(time_spent_in_trial); + temperature(currentTemperature); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::UpdateFromState() + { + current = current_solution(); + curfit = current_cost(); + total_time_spent=current_time_spent(); + time_spent_in_trial=time_spent_trial(); + currentTemperature = temperature(); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::show_state() const + { + cout << endl << "Current trial: " << current_trial(); + cout << endl << "Current iteration: " << current_iteration(); + cout << endl << "Current Temperature: " << temperature (); + cout << endl << "Current cost: " << current_cost(); + cout << endl << "Best cost in trial: " << current_best_cost(); + cout << endl << "Time of best solution found in trial: " << time_best_found_trial(); + cout << endl << "Iteration of best solution found in trial: " << iteration_best_found_trial(); + cout << endl << "Initial temperature in trial: " << initial_temperature_trial(); + cout << endl << "Temperature of best solution found in trial: " << temperature_best_found_trial(); + cout << endl << "Time spent in trial: " << time_spent_trial(); + cout << endl << "Global best cost: " << global_best_cost(); + cout << endl << "Trial of best global solution found: " << trial_best_found(); + cout << endl << "Iteration of best global solution found: " << iteration_best_found(); + cout << endl << "Time of global best solution found: " << time_best_found(); + // cout << endl << "Current solution: " << current_solution(); + // cout << endl << "Best solution of trial: " << current_best_solution(); + // cout << endl << "Global solution: " << global_best_solution() << endl; + cout << endl << endl << "Current time spent (so far): " << current_time_spent() << endl; + } + + Solver::~Solver() + { + _sc.removeAll(); + delete move; + } + + bool Solver::AcceptQ (double tent, double cur, double temperature) + { + if (_direction==minimize) + + return (tent < cur) || + ((rand01()*(1+exp((tent-cur)/temperature)))<2.0); + + else + + return (tent > cur) || + ((rand01()*(1+exp((cur-tent)/temperature)))<2.0); + } + + double Solver::Set_Initial_Temperature(const Problem& pbm) + { + const double beta = 1.05; + const double test = 10; + const double acrat = .8; + const double T = 1.0; + + Solution current (pbm); + Solution newsol (pbm); + double ac; + double fit; + double temperature = T; + + do + { + temperature *= beta; + ac = 0; + current.initialize(); + fit = current.fitness(); + for (int i=0; i<test; i++) + { + newsol = current; + move->Apply(newsol); + if (AcceptQ(newsol.fitness(),fit,temperature)) + ac += 1.0/test; + } + } while (ac < acrat); + + initial_temperature_trial(temperature); + return temperature; + + } + + void Solver::SetMove (Move* mov) + { + delete move; + move = mov; + } + + // Solver sequencial ----------------------------------------------------- + + Solver_Seq::Solver_Seq (const Problem& pbm, const SetUpParams& setup) + : Solver(pbm,setup) + { + random_seed(time(0)); + _end_trial=true; + } + + Solver_Seq::~Solver_Seq () + {} + + void Solver_Seq::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Seq::StartUp(const Solution& sol, const double initialTemperature) + { + start_trial=_used_time(); + start_global=total_time_spent; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current = sol; + curfit = current.fitness(); + current_best_cost((-1) * problem.direction() * infinity()); + currentTemperature = initialTemperature; + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + void Solver_Seq::DoStep() + { + current_iteration(current_iteration()+1); + + tentative = current; + move->Apply(tentative); + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + +cerr << current_best_cost() << endl; + + if (display_state()) + show_state(); + } + + + void Solver_Seq::run (unsigned long int max_evaluations) + { + StartUp(); + + while (current_iteration()<max_evaluations && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run () + { + while (current_trial() < params.independent_runs()) + { + run(params.max_evaluations()); +// cerr << "Entrado" << endl; +// Solution s(current_best_solution()); +// cerr << s; +// ContigBuilder * builder = new ContigBuilder(s.fragments(), problem.detector->getScoreTable(),&problem); +// builder->buildContigs(); +// builder->mergeContigs(); +// // builder->buildConsensus(); +// delete builder; + + } + } + + // Solver LAN ----------------------------------------------------------- + + Solver_Lan::Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { +cout << "ConstructorA " << endl; + NetStream::init(argc,argv); +cout << "ConstructorB " << endl; + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); +cout << "Constructor " << endl; + } + + Solver_Lan::~Solver_Lan () + { + NetStream::finalize(); + } + + int Solver_Lan::pid() const + { + return mypid; + } + + NetStream& Solver_Lan::netstream() + { + return _netstream; + } + + void Solver_Lan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Lan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + void update(Direction direction, Solution &solution_received,double cost_received, Solution &solution_to_send, double &best_cost) + { + switch (direction) + { + case minimize: if (cost_received < best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + case maximize: if (cost_received > best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + } + } + + int Solver_Lan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Lan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Lan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Lan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Lan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Lan::run () + { + while (current_trial() < params.independent_runs()) + { + run(params.max_evaluations()); + if(mypid == 0) + { +// cerr << "Entrado" << endl; +// Solution s(current_solution()); +// cerr << s; +// ContigBuilder * builder = new ContigBuilder(s.fragments(), problem.detector->getScoreTable(),&problem); +// builder->buildContigs(); +// builder->mergeContigs(); +// // builder->buildConsensus(); +// delete builder; + } + } + } + + void Solver_Lan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } + + // Solver WAN ------------------------------------------------------------ + + Solver_Wan::Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); + } + + Solver_Wan::~Solver_Wan () + { + NetStream::finalize(); + } + + int Solver_Wan::pid() const + { + return mypid; + } + + NetStream& Solver_Wan::netstream() + { + return _netstream; + } + + void Solver_Wan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Wan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + int Solver_Wan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Wan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Wan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Wan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Wan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Wan::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + void Solver_Wan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } +}; + diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/SA.req.cc b/ProyectoFinal/CHC/malva/rep/SA/dnafa/SA.req.cc new file mode 100644 index 0000000000000000000000000000000000000000..153f37cf575f7b928df2b483af2710d9c5751bc7 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/SA.req.cc @@ -0,0 +1,437 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** User-required classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** Tab size = 4 *** +*** *** +*** *** +************************************************/ + +#include <iostream.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "StopCondition.hh" +#include <math.h> +#include "Util.h" +#include "AdjKeys.h" + +skeleton SA { + + // Problem --------------------------------------------------------------- + + Problem::Problem ():numOfFragments(0),avgLength(0.0),cutoff(0), + fragmentLength(NULL),fragments(NULL),rcFragments(NULL), + description(NULL) + { + } + + ostream& operator<< (ostream& os, const Problem& pbm) + { + return os; + } + + istream& operator>> (istream& is, Problem& pbm) + { + char buffer[MAX_BUFFER]; + int i; + + + is.getline(buffer,MAX_BUFFER,'\n'); + sscanf(buffer,"%d",&pbm.cutoff); + + is.getline(buffer,MAX_BUFFER,'\n'); +//cout << buffer; + ifstream f((string(getenv("HOME")) + buffer).c_str()); + + int seqCount = -1; + pbm.fragments = new vector<string>(); + pbm.description = new vector<string>(); + + /* read fragments from input file and store its description in descr[] + and its sequence in sequence[] */ + + char oneLine[2000]; + string sequence; + string upperSeq; + while(f.getline(oneLine, 2000)) + { +//cout << oneLine; + string temp = string(oneLine); + int rightArrow = temp.find_first_of(">"); + if(rightArrow != -1) //rightArrow is found + { + seqCount++; + if(seqCount != 0) + pbm.fragments->push_back(sequence); + int space = temp.find(" ", rightArrow); + pbm.description->push_back(temp.substr(rightArrow+1, space)); + sequence = ""; + } + else //line doesn't start with rightArrow + { + upperSeq = ""; + for(int i = 0; i < temp.length(); i++) + upperSeq += toupper(temp.at(i)); + + sequence.append(upperSeq); + } + } + pbm.fragments->push_back(sequence); + f.close(); + + pbm.numOfFragments = pbm.fragments->size(); + pbm.fragmentLength = new int[pbm.numOfFragments]; + + pbm.rcFragments = new vector<string>(); + + for(int j = 0; j < pbm.numOfFragments; j++) + { + pbm.rcFragments->push_back(Util::rcSequence(pbm.fragments->at(j))); +//cout << pbm.description->at(j) << " " << pbm.fragments->at(j) << " " << pbm.rcFragments->at(j) << endl; + } + + int sumLength = 0; + for(int i = 0; i < pbm.numOfFragments; i++) + { + pbm.fragmentLength[i] = pbm.fragments->at(i).length(); + sumLength += pbm.fragmentLength[i]; + } + pbm.avgLength = (double)sumLength / (double)pbm.numOfFragments; + + pbm.detector = new OverlapDetector(pbm.numOfFragments); +// pbm.detector->buildScoresTable(pbm.fragments, pbm.rcFragments); + pbm.detector->readScoreTable(); +// pbm.detector->printScoreTable(); + + return is; + } + + bool Problem::operator== (const Problem& pbm) const + { + // Falta terminar + return true; + } + + bool Problem::operator!= (const Problem& pbm) const + { + return !(*this == pbm); + } + + Direction Problem::direction() const + { + return maximize; // F1 +// return minimize; // F2 + } + + Problem::~Problem() + { + delete detector; + delete fragments; + delete rcFragments; + delete description; + delete [] fragmentLength; + } + + // Solution -------------------------------------------------------------- + + Solution::Solution (const Problem& pbm):_pbm(pbm),fragOrder(new int[pbm.numOfFragments]) + {} + + const Problem& Solution::pbm() const + { + return _pbm; + } + + Solution::Solution(const Solution& sol):_pbm(sol.pbm()) + { + if(fragOrder != NULL) delete [] fragOrder; + + fragOrder = new int [_pbm.numOfFragments]; + + for(int i = 0; i < _pbm.numOfFragments; i++) + fragOrder[i] = sol.fragOrder[i]; + } + + istream& operator>> (istream& is, Solution& sol) + { + for (int i=0;i<sol.pbm().numOfFragments;i++) + is >> sol.fragOrder[i]; + return is; + } + + ostream& operator<< (ostream& os, const Solution& sol) + { + for (int i=0;i<sol.pbm().numOfFragments;i++) + os << " " << sol.fragOrder[i]; + return os; + } + + NetStream& operator << (NetStream& ns, const Solution& sol) + { + for (int i=0;i<sol.pbm().numOfFragments;i++) + ns << sol.fragOrder[i]; + return ns; + } + + NetStream& operator >> (NetStream& ns, Solution& sol) + { + for (int i=0;i<sol.pbm().numOfFragments;i++) + ns >> sol.fragOrder[i]; + return ns; + } + + Solution& Solution::operator= (const Solution &sol) + { + if(fragOrder != NULL) delete [] fragOrder; + + fragOrder = new int [_pbm.numOfFragments]; + + for(int i = 0; i < _pbm.numOfFragments; i++) + fragOrder[i] = sol.fragOrder[i]; + + return *this; + } + + bool Solution::operator== (const Solution& sol) const + { + if (sol.pbm() != _pbm) return false; + for(int i = 0; i < _pbm.numOfFragments; i++) + if(fragOrder[i] != sol.fragOrder[i]) return false; + return true; + } + + bool Solution::operator!= (const Solution& sol) const + { + return !(*this == sol); + } + + void Solution::initialize() + { + int * randNum = new int[_pbm.numOfFragments]; + + for(int k = 0; k < _pbm.numOfFragments; k++) + { + int num = rand_int(0, _pbm.numOfFragments * 2); + randNum[k] = num; + fragOrder[k] = k; + } + + // sort value and store index as fragment order + for(int i = 0; i < _pbm.numOfFragments-1; i++) + { + for(int j = i+1; j < _pbm.numOfFragments; j++) + { + if( randNum[i] > randNum[j]) + { + int temp = randNum[i]; + randNum[i] = randNum[j]; + randNum[j] = temp; + + temp = fragOrder[i]; + fragOrder[i] = fragOrder[j]; + fragOrder[j] = temp; + } + } + } + delete [] randNum; + } + + double Solution::fitness () + { + int ** score = _pbm.detector->getScoreTable(); + // F1 maximization + int fit = 0; + + for(int k = 0; k < _pbm.numOfFragments-1; k++) + { + int i = fragOrder[k]; + int j = fragOrder[k+1]; + + fit += abs(score[i][j]); + } + return (double) fit; + // F2 minimization +/* int fit = 0; + int nof = _pbm.numOfFragments; + + for(int i = 0; i < nof; i++) + { + int m = fragOrder[i]; + for(int j = 0; j < nof; j++) + { + if(i != j) + { + int n = fragOrder[j]; + if((nof<m) || (nof<n) || (m<0) || (n<0)) + { + cout << "Error en indices" << endl; + return infinity(); + } + fit += abs(i-j) * abs(score[m][n]); + } + } + } + return (double)fit; +*/ } + + char *Solution::to_String() const + { + return (char *)fragOrder; + } + + void Solution::to_Solution(char *_string_) + { + int *ptr=(int *)_string_; + + for (int i=0;i<_pbm.numOfFragments;i++) + { + fragOrder[i]=*ptr; + ptr++; + } + } + + unsigned int Solution::size() const + { + return (_pbm.numOfFragments * sizeof(int)); + } + + + int& Solution::fragment(const int index) + { + return fragOrder[index]; + } + + + int* Solution::fragments() + { + return fragOrder; + } + + Solution::~Solution() + { + delete [] fragOrder; + } + + // UserStatistics ------------------------------------------------------- + + UserStatistics::UserStatistics () + {} + + ostream& operator<< (ostream& os, const UserStatistics& userstat) + { + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF TRIALS " << endl; + os << "------------------------------------------------------------------" << endl; + + for (int i=0;i< userstat.result_trials.size();i++) + { + os << endl + << "\t" << userstat.result_trials[i].trial + << "\t" << userstat.result_trials[i].best_cost_trial + << "\t\t" << userstat.result_trials[i].nb_evaluation_best_found_trial + << "\t\t" << userstat.result_trials[i].initial_temperature + << "\t\t" << userstat.result_trials[i].temperature_best_found_trial + << "\t\t" << userstat.result_trials[i].time_best_found_trial + << "\t\t" << userstat.result_trials[i].time_spent_trial; + } + + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + + UserStatistics& UserStatistics::operator= (const UserStatistics& userstats) + { + result_trials=userstats.result_trials; + return (*this); + } + + + void UserStatistics::update(const Solver& solver) + { + if ((solver.pid()!=0) || (solver.end_trial()!=true) + || ((solver.current_iteration()!=solver.setup().max_evaluations()) + && !TerminateQ(solver.pbm(),solver,solver.setup()))) + return; + + struct user_stat *new_stat; + if ((new_stat=(struct user_stat *)malloc(sizeof(struct user_stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluation_best_found_trial= solver.iteration_best_found_trial(); + new_stat->initial_temperature=solver.initial_temperature_trial(); + new_stat->temperature_best_found_trial=solver.temperature_best_found_trial(); + new_stat->best_cost_trial = solver.current_best_cost(); + new_stat->time_best_found_trial= solver.time_best_found_trial(); + new_stat->time_spent_trial = solver.time_spent_trial(); + result_trials.append(*new_stat); + } + + void UserStatistics::clear() + { + result_trials.remove(); + } + + UserStatistics::~UserStatistics() + { + result_trials.remove(); + } + +// DefaultMove ------------------------------------------------------- + + + DefaultMove::DefaultMove() + {} + + DefaultMove::~DefaultMove() + {} + + void DefaultMove::Apply (Solution& sol) const + { + int indsize = sol.pbm().numOfFragments; + int r1 = rand_int(0, indsize-1); + int r2 = rand_int(0, indsize-1); + + while(r2 == r1) + { + if(r1 == indsize-1) r2 = rand_int(0, indsize-2); + else r2 = rand_int(r1, indsize-1); + } + + /* // swap + int temp = sol.fragment(r1); + sol.fragment(r1) = sol.fragment(r2); + sol.fragment(r2) = temp; +*/ + // 2-opt + if(r2 < r1) + { + int temp = r1; + r1 = r2; + r2 = temp; + } + while(r2 > r1) + { + int temp = sol.fragment(r1); + sol.fragment(r1) = sol.fragment(r2); + sol.fragment(r2) = temp; + ++r1; + --r2; + } + } + + //------------------------------------------------------------------------ + // Specific methods ------------------------------------------------------ + //------------------------------------------------------------------------ + + bool TerminateQ (const Problem& pbm, const Solver& solver, + const SetUpParams& setup) + { + + StopCondition_3 stop; + return stop.EvaluateCondition(pbm,solver,setup); + } +} + + diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/StopCondition.cc b/ProyectoFinal/CHC/malva/rep/SA/dnafa/StopCondition.cc new file mode 100644 index 0000000000000000000000000000000000000000..2033972200be773a0ab34fc208d4cb4b54dcbe52 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/StopCondition.cc @@ -0,0 +1,52 @@ +#include "StopCondition.hh" +skeleton SA +{ + +// StopCondition ------------------------------------------------------------------------------------- + + StopCondition::StopCondition() + {} + + StopCondition::~StopCondition() + {} + +// StopCondition_1 ------------------------------------------------------------------------------------- + + StopCondition_1::StopCondition_1():StopCondition() + {} + + bool StopCondition_1::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return false; + } + + StopCondition_1::~StopCondition_1() + {} + +// StopCondition_2 ------------------------------------------------------------------------------------- + + StopCondition_2::StopCondition_2():StopCondition() + {} + + bool StopCondition_2::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return (solver.global_best_cost()>8.5); + } + + StopCondition_2::~StopCondition_2() + {} + +// StopCondition_3 ------------------------------------------------------------------------------------- + + StopCondition_3::StopCondition_3():StopCondition() + {} + + bool StopCondition_3::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return (false); + } + + StopCondition_3::~StopCondition_3() + {} + +} diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/StopCondition.hh b/ProyectoFinal/CHC/malva/rep/SA/dnafa/StopCondition.hh new file mode 100644 index 0000000000000000000000000000000000000000..04ef770d9cac5bb9ef69aae7d085e3ae2166e187 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/StopCondition.hh @@ -0,0 +1,41 @@ +#ifndef stop_condition +#define stop_condition + +#include "SA.hh" +skeleton SA +{ + + provides class StopCondition + { + public: + StopCondition(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup)=0; + ~StopCondition(); + }; + + requires class StopCondition_1 : public StopCondition + { + public: + StopCondition_1(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_1(); + }; + + requires class StopCondition_2 : public StopCondition + { + public: + StopCondition_2(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_2(); + }; + + requires class StopCondition_3 : public StopCondition + { + public: + StopCondition_3(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_3(); + }; +} + +#endif diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/Util.h b/ProyectoFinal/CHC/malva/rep/SA/dnafa/Util.h new file mode 100644 index 0000000000000000000000000000000000000000..fcea0d2d0d04098a16abf56b5b97da6c779cb053 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/Util.h @@ -0,0 +1,71 @@ +/************************************************************** + * File: Util.h + * Author: Lishan Li + * Date: May, 2003 + * + * Description: This Util class consists of utility functions + * used by other classes + **************************************************************/ + +#ifndef UTIL_H +#define UTIL_H + +#include <stdlib.h> +#include <vector> + +using namespace std; + +class Util +{ +public: + /* returns a randomly generated floating point number ranged [min, max] */ +// static double randDouble(double min, double max) +// { +// return (1.0*rand()*(max-min)/RAND_MAX + min); +// } + + /* returns a randomly generated interge number ranged [min, max] */ +// static int randInt(int min, int max) +// { +// return (int)randDouble(min, max); +// } + + /* returns a string that is the reverse of a given DNA sequence */ + static string revSequence(const string &s) + { + string revSeq = s; + int j = 0; + for(int i = s.length()-1; i >= 0; i--) + revSeq[j++] = s.at(i); + + return revSeq; + } + + /* returns a string that is the complement of a given DNA sequence */ + static string complSequence(const string &s) + { + string compSeq = s; + int j = 0; + for(unsigned int i = 0; i < s.length(); i++) + { + if(s.at(i) == 'A') + compSeq[j++] = 'T'; + else if(s.at(i) == 'T') + compSeq[j++] = 'A'; + else if(s.at(i) == 'C') + compSeq[j++] = 'G'; + else if(s.at(i) == 'G') + compSeq[j++] = 'C'; + else + compSeq[j++] = s.at(i); + } + return compSeq; + } + + /* returns a string that is the reverse complement of a given DNA sequence */ + static string rcSequence(const string &s) + { + return complSequence(revSequence(s)); + } +}; +#endif diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/list.h b/ProyectoFinal/CHC/malva/rep/SA/dnafa/list.h new file mode 100644 index 0000000000000000000000000000000000000000..46eff2e9f78b877a8488dbe648d45cc3ef473b16 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/list.h @@ -0,0 +1,300 @@ +/*************************************************************** + * File: list.h + * Author: Lishan Li + * Date: May, 2003 + * + * Description: This List class is a template class. It builds a + * single linked list of any type of objects. + ***************************************************************/ + +#ifndef LIST_H +#define LIST_H + +#include <assert.h> +#include <stdlib.h> +#include <iostream> +using namespace std; + +template <class T> +struct ListNode +{ + T data; // T could be any type of object + ListNode<T> *next; +}; + +template <class T> +class List1 +{ +public: + ListNode<T>* header; // header is a dummy node + ListNode<T>* current; + int len; // length of the linked list + + List1(); // constructor + ~List1(); // destructor + + List1(const List1<T> & source); // copy constructor + List1<T> & operator=(const List1<T> & source); + void append(const T); // append data at the end of list + void insert(const T); // insert data in order + void insertPtr(const T); // insert pointer type of object in order + void insertFront(const T); // insert data at the beginning of the list + void remove(const T); // delete data from list + void next(); + void prev(); + void reset(); + void clear(); + int length() const { return len; } + bool isEmpty() const; // check whether list is empty + bool isFull() const; // check whether memory is allocated + T value() const; // return content of the data + void printList(); + void printListPtr(); + ListNode<T>* findPrevious(const T); + ListNode<T>* search(const T); +}; + +template <class T> +List1<T>::List1() +{ + header = new ListNode<T>; + header->next = NULL; + current = header; + len = 0; +} + +template <class T> +List1<T>::List1(const List1<T> & source) +{ + header = NULL; + *this = source; +} + +template <class T> +List1<T> & List1<T>::operator=(const List1<T> & source) +{ + if(this != &source) + { + ListNode<T> * current = source.header; + while(current != NULL) + { + insert(current->data); + current = current->pnext; + } + } + return *this; +} + +template <class T> +void List1<T>::clear() +{ + ListNode<T> *tmp; + ListNode<T> *previous = header; + ListNode<T> *traverse = header->next; + + while(traverse != NULL) // release memory from list + { + tmp = traverse; + previous->next = traverse->next; + traverse = traverse->next; + delete tmp; + } + current = header; + len = 0; +} + +template <class T> +List1<T>::~List1() +{ + clear(); + delete header; +} + + +template <class T> +void List1<T>::insert(const T item) +{ + assert(!isFull()); + ListNode<T> * newNode = new ListNode<T>; + newNode->data = item; + newNode->next = NULL; + if(len == 0) // no need to traverse + { + newNode->next = current->next; + current->next = newNode; + } + else // need to traverse + { + ListNode<T> * temp = header; + while((temp->next != NULL) && (item < temp->next->data)) + temp = temp->next; + newNode->next = temp->next; + temp->next = newNode; + } + len++; +} + +template <class T> +void List1<T>::insertPtr(const T item) +{ + assert(!isFull()); + ListNode<T> * newNode = new ListNode<T>; + newNode->data = item; + newNode->next = NULL; + if(len == 0) // no need to traverse + { + newNode->next = current->next; + current->next = newNode; + } + else // need to traverse + { + ListNode<T> * temp = header; + while((temp->next != NULL) && (*item < *(temp->next->data))) // pointer need dereference + temp = temp->next; + newNode->next = temp->next; + temp->next = newNode; + } + len++; +} + +template <class T> +void List1<T>::insertFront(const T item) +{ + ListNode<T> * newNode = new ListNode<T>; + newNode->data = item; + newNode->next = header->next; + header->next = newNode; + len++; +} + +template <class T> +void List1<T>::append(const T item) +{ + assert(!isFull()); + ListNode<T> * newNode = new ListNode<T>; + newNode->data = item; + newNode->next = NULL; + ListNode<T> *traverse = header; + while(traverse->next != NULL) + traverse = traverse->next; + traverse->next = newNode; + len++; +} + +template <class T> +ListNode<T>* List1<T>::findPrevious(const T target) +{ + ListNode<T> *temp; + + for(temp = header; temp->next != NULL; temp = temp->next) + if(*(temp->next->data) == *target) + return temp; + + return NULL; +} + +template <class T> +void List1<T>::remove(const T target) +{ + if(len != 0) + { + ListNode<T> *p = findPrevious(target); + if(p->next != NULL) + { + ListNode<T> *oldNode = p->next; + p->next = p->next->next; + delete oldNode; + len--; + } + } +} + +template <class T> +void List1<T>::next() +{ + current = current->next; +} + +template <class T> +void List1<T>::prev() +{ + if(len > 1) + { + ListNode<T>* tmp = header; + while(tmp->next != current) + tmp = tmp->nect; + + current = tmp; + } +} + +template <class T> +void List1<T>::reset() +{ + current = header; +} + +template <class T> +bool List1<T>::isEmpty() const +{ + return (len == 0); +} + +template <class T> +bool List1<T>::isFull() const +{ + ListNode<T> *tmp = new ListNode<T>; + if(tmp == NULL) + return true; + else + { + delete tmp; + return false; + } +} + +template <class T> +T List1<T>::value() const +{ + return current->next->data; +} + +template <class T> +ListNode<T>* List1<T>::search(const T target) +{ + ListNode<T> *temp; + + for(temp = header->next; temp != NULL; temp = temp->next) + if((*target) == *(temp->data)) + return temp; + + return NULL; +} + +template <class T> +void List1<T>::printList() +{ + cout << endl; + for(int i = 0; i < len; i++) + { + cout << value(); + next(); + } + reset(); +} + +template <class T> +void List1<T>::printListPtr() +{ + cout << endl; + for(int i = 0; i < len; i++) + { + cout << *(value()); // pointer need dereference + next(); + } + reset(); +} + +#endif + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/pgfileLan b/ProyectoFinal/CHC/malva/rep/SA/dnafa/pgfileLan new file mode 100644 index 0000000000000000000000000000000000000000..d8a00110375f2cad056cb82ee4d938042e208f9e --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/pgfileLan @@ -0,0 +1,3 @@ +localhost 0 ~/Mallba/rep/SA/dnafa/MainLan +localhost 1 ~/Mallba/rep/SA/dnafa/MainLan +localhost 1 ~/Mallba/rep/SA/dnafa/MainLan diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/scp.h b/ProyectoFinal/CHC/malva/rep/SA/dnafa/scp.h new file mode 100644 index 0000000000000000000000000000000000000000..86960d68b9807b5477c99e38ffbb907aaacb00da --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/scp.h @@ -0,0 +1,53 @@ +/******************************************************************* + * File: scp.h + * Author: Lishan Li + * Date: May, 2003 + * + * Description: This SubConsensusPair class is used to create + * SubConsensusPair objects for ConsensusBuilder class + *******************************************************************/ + +#ifndef SCP_H +#define SCP_H + +#include <iostream> + +using namespace std; + +class SubConsensusPair +{ +public: + int cid1; // first consensus's ID + int cid2; // second consensus's ID + int score; // overlap score between two consensuses + + SubConsensusPair() { } // default constructor + SubConsensusPair(int id1, int id2, int s) // user defined constructor + { + cid1 = id1; + cid2 = id2; + score = s; + } + virtual ~SubConsensusPair() { } // destructor + + bool operator<(const SubConsensusPair& source) const + { + if(score < source.score) + return true; + else + return false; + } + /* overload operator<< for printing the contents of a SubConsensusPair object */ + friend ostream& operator<<(ostream& os, const SubConsensusPair &info) + { + os << "(" << info.cid1 << ", " << info.cid2 << ", " << info.score << ")" << endl; + return os; + } +}; + + /* overload operator<< for printing the contents of a SubConsensusPair object */ + //ostream& operator<<(ostream& os, const SubConsensusPair& info) + +#endif + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/sga.cpp b/ProyectoFinal/CHC/malva/rep/SA/dnafa/sga.cpp new file mode 100644 index 0000000000000000000000000000000000000000..29d740b668052d9a94319ae6a4f3854f98a7dc87 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/sga.cpp @@ -0,0 +1,256 @@ +/*********************************************************************** + * File: sga.cpp + * Author: Lishan Li + * Date: May, 2003 + * + * Description: It provides implementation of all the functions declared + * in the header file sga.h. + ***********************************************************************/ + +#include "sga.h" + +/********************************************* + * Purpose: allocate memory and initialization + *********************************************/ + +SGA::SGA(const string &is, const string &it) +{ + g = -2; // gap penalty = -2 + s = is; + t = it; + m = s.length(); + n = t.length(); +// /**/ cout << "\t size " << m+1 << " x " << n+1 << endl; + bestScore = 0; +} + +/************************* + * Purpose: release memory + *************************/ + +SGA::~SGA() +{ +} + + +/******************************************************* + * Purpose: Build a score matrix to store the scores of + * pairwise semiglobal alignment + *******************************************************/ + +void SGA::CalculateBest(int i, int j, int score) +{ +//cout << "(" << i<<","<< j<<","<<score<<")"<<endl; + if(j == n) + { + if((score == n) && (score > bestScore)) // ------- + { // --- + bestScore = score; + overlapType = 1; + } + else if((score == i) && (score > bestScore)) // ------- + { // ------- + bestScore = score; + overlapType = 2; + } + } + + if(i == m) + { + if((score == m) && (score > bestScore)) // --- + { // --------- + bestScore = score; + overlapType = 3; + } + else if((score == j) && (score > bestScore)) // ------- + { // ------- + bestScore = score; + overlapType = 4; + } + } +} + +void SGA::buildMatrix() +{ + // Primero la mitad superior + int i,j,k; + int score; + bestScore = 0; + overlapType = 3; + for(k = 1; k <= m; k++) + { + score = 0; + i = k; + j = 1; + while((j <=n) && (i <=m)) + { + if(p(i,j) == 1) + score = score + 1; + else + score = 0; + j++; + i++; + } + i--;j--; + CalculateBest(i,j,score); + } + + for(k = 2; k <= n; k++) + { + score = 0; + j = k; + i = 1; + while(j <=n && i <=m) + { + if(p(i,j) == 1) + score = score + 1; + else + score = 0; + j++; + i++; + } + i--;j--; + CalculateBest(i,j,score); + } +} + +/*************************** + * match score = 1 + * mismatch score = -1 + ***************************/ + +int SGA::p(int i, int j) +{ + if (s[i-1] == t[j-1]) // match + return 1; + else + return -1; +} + +/**************************************************** + * Purpose: find the maximum number of x, y, and z + ****************************************************/ + +int SGA::max(int x, int y, int z) +{ + int temp = x; + if (x < y) + temp = y; + if (temp < z) + temp = z; + return temp; +} + +/******************************************************************** + * Purpose: find the best score for the pairwise semiglobal alignment + ********************************************************************/ + +void SGA::findBestScore() +{ +} + + +/********************************************************************** + * Purpose: Align the two sequence starting from the the row and column + * with the best score + **********************************************************************/ + +void SGA::align() +{ + int i; + int start; +//cout << s << endl << t << endl << bestScore << " " << overlapType << endl; +//exit(-1); + string preGaps = ""; + string postGaps = ""; + if((start = s.find(t)) != string::npos) // t is substring of s + { + align_s = s; + for(i = 0; i < start; i++) + preGaps += "-"; + align_t = preGaps + t; + + for(i = start+bestScore; i < m; i++) + postGaps += "-"; + align_t += postGaps; + } + else if((start = t.find(s)) != string::npos) // s is substring of t + { + align_t = t; + for(i = 0; i < start; i++) + preGaps += "-"; + align_s = preGaps + s; + + for(i = start+bestScore; i < n; i++) + postGaps += "-"; + align_s += postGaps; + } + else if(overlapType == 4) + { + int preNumGaps = m - bestScore; + for(int i = 0; i < preNumGaps; i++) + preGaps += "-"; + align_t = preGaps + t; + + int postNumGaps = align_t.length() - m; + for(int j = 0; j < postNumGaps; j++) + postGaps += "-"; + align_s = s + postGaps; + } + else + { + int preNumGaps = n - bestScore; + for(int i = 0; i < preNumGaps; i++) + preGaps += "-"; + align_s = preGaps + s; + + int postNumGaps = align_s.length() - n; + for(int j = 0; j < postNumGaps; j++) + postGaps += "-"; + align_t = t + postGaps; + } +} + +/************************************************************ + * Purpose: Print the score matrix for the pairwise alignment + ************************************************************/ + +void SGA::printMatrix() +{ +/* for (int i = 0; i <= m; i++) + { + cout << endl; + for (int j = 0; j <= n; j++) + { + printf("%3d", score[i][j]); + } + } + cout << endl << endl; + cout << "The best score is: " << bestScore << endl << endl;*/ +} + +/*************************************** + * Purpose: Print the pairwise alignment + ***************************************/ + +void SGA::printAlign() +{ + cout << align_s << endl; + cout << align_t << endl << endl; +} + +/******************************* + * Purpose: Print Info for debug + *******************************/ +void SGA::printInfo() +{ + cout << "m = " << m << " n = " << n << " g = " << g + << " bestRow = " << bestRow << " bestCol = " << bestCol << " bestscore = " << bestScore + << endl; + cout << "s = " << align_s << " t = " << align_t << endl; + +// printMatrix(); +} + +/************************************ End of File **************************************/ + diff --git a/ProyectoFinal/CHC/malva/rep/SA/dnafa/sga.h b/ProyectoFinal/CHC/malva/rep/SA/dnafa/sga.h new file mode 100644 index 0000000000000000000000000000000000000000..1cf336dada75a9e2adb8ca309763b379943cac87 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/dnafa/sga.h @@ -0,0 +1,52 @@ +/*************************************************************** + * File: sga.h + * Author: Lishan Li + * Date: May, 2003 + * + * Description: This SGA class is used to do pairwise alignment + * between two fragments + ***************************************************************/ + +#ifndef SGA_H +#define SGA_H + +#include <iostream> +#include <string> +using namespace std; + +class SGA +{ +public: + string align_s; // to store sequence s after alignment + string align_t; // to store sequence t after alignment + + SGA() {} // default constructor + SGA(const string &is, const string &it); // user defined constructor + ~SGA(); // destructor + void buildMatrix(); + int p(int i, int j); + void align(); + void findBestScore(); + void printMatrix(); + void printAlign(); + void printInfo(); + int getBestRow() { return bestRow; } + int getBestCol() { return bestCol; } + int getBestScore() { return bestScore; } +private: + int max(int x, int y, int z); + void CalculateBest(int i, int j, int score); + string s, t; + int g; // gap + int m; // length of s + int n; // length of t + int bestRow; // the row containning best score + int bestCol; // the column containing best score + int bestScore; // the best score of the semiglobal alignment +// int ** score; // to store the scores for pairwise alignment + int overlapType; +}; + +#endif + +/************************************ End of File **************************************/ diff --git a/ProyectoFinal/CHC/malva/rep/SA/maxsat/Config.cfg b/ProyectoFinal/CHC/malva/rep/SA/maxsat/Config.cfg new file mode 100644 index 0000000000000000000000000000000000000000..2d6daf719378e680570b455a37d82b7ec818007f --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/maxsat/Config.cfg @@ -0,0 +1,3 @@ +SA.cfg +../../../ProblemInstances/MAXSAT-instances/sat1.txt +res/sat1.sa.lan.txt diff --git a/ProyectoFinal/CHC/malva/rep/SA/maxsat/MainLan.cc b/ProyectoFinal/CHC/malva/rep/SA/maxsat/MainLan.cc new file mode 100644 index 0000000000000000000000000000000000000000..8949422e10f93211d953aba1308c203d13f30f0a --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/maxsat/MainLan.cc @@ -0,0 +1,53 @@ +#include "SA.hh" +#include <iostream.h> +#include <fstream.h> + +int main (int argc, char** argv) +{ + using skeleton SA; + char path[MAX_BUFFER]; + int len; + int longitud; + + system("clear"); + + get_path(argv[0],path); + len = strlen(path); + longitud = MAX_BUFFER - len; + + strcat(path,"Config.cfg"); + ifstream f(path); + if(!f) show_message(10); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f1(path); + if(!f1) show_message(11); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f2(path); + if(!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + SetUpParams cfg; + f1 >> cfg; + + + Solver_Lan solver(pbm,cfg,argc,argv); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solucion: " << solver.global_best_solution() << " Fitness: " << solver.global_best_solution().fitness(); + + f.getline(&(path[len]),longitud,'\n'); + ofstream fexit(path); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + cout << endl << endl << " :( ---------------------- THE END --------------- :) " << endl; + } + return(0); +} diff --git a/ProyectoFinal/CHC/malva/rep/SA/maxsat/MainSeq.cc b/ProyectoFinal/CHC/malva/rep/SA/maxsat/MainSeq.cc new file mode 100644 index 0000000000000000000000000000000000000000..41d8a720793c0d10b14e1d5dfa05b7f11e9c4dda --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/maxsat/MainSeq.cc @@ -0,0 +1,42 @@ +#include "SA.hh" +#include <iostream.h> +#include <fstream.h> + +int main (int argc, char** argv) +{ + using skeleton SA; + + system("clear"); + + if(argc < 4) + show_message(1); + + ifstream f1(argv[1]); + if (!f1) show_message(11); + + ifstream f2(argv[2]); + if (!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + SetUpParams cfg; + f1 >> cfg; + + Solver_Seq solver(pbm,cfg); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << solver.global_best_solution() + << " Fitness: " << solver.global_best_solution().fitness() << endl; + cout << "\n\n :( ---------------------- THE END --------------- :) "; + + ofstream fexit(argv[3]); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + } + return(0); +} diff --git a/ProyectoFinal/CHC/malva/rep/SA/maxsat/Makefile b/ProyectoFinal/CHC/malva/rep/SA/maxsat/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..0ffc8d9c151fb9b922fcccfa68aa615941ac220e --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/maxsat/Makefile @@ -0,0 +1,22 @@ +include ../../../environment + +all: MainSeq MainLan + +clean: + rm -f MainLan MainSeq MainWan *.o *% *~ + +MainLan: SA.req.o SA.pro.o StopCondition.o MainLan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainWan: SA.req.o SA.pro.o StopCondition.o MainWan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainSeq: SA.req.o SA.pro.o StopCondition.o MainSeq.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +LAN: + $(RUN) -v -p4pg pgfileLan MainLan +WAN: + $(RUN) -v -p4pg pgfileWan MainWan +SEQ: + ./MainSeq SA.cfg ../../../ProblemInstances/MAXSAT-instances/sat1.txt res/sat1.sa.seq.txt diff --git a/ProyectoFinal/CHC/malva/rep/SA/maxsat/SA.cfg b/ProyectoFinal/CHC/malva/rep/SA/maxsat/SA.cfg new file mode 100644 index 0000000000000000000000000000000000000000..0aef72f34001678c87b53ac173ca9eb0050bd7f5 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/maxsat/SA.cfg @@ -0,0 +1,9 @@ +10 // number of independent runs +500 // number of evaluations +10 // Markov-Chain Length +.99 // temperature Decay +1 // display state ? +LAN-configuration +10 // the global state is updated in this number of evaluations +0 // 0: asynchronized mode // 1: synchronized mode +10 // interval of iterations to cooperate ( if 0 no cooperation) diff --git a/ProyectoFinal/CHC/malva/rep/SA/maxsat/SA.hh b/ProyectoFinal/CHC/malva/rep/SA/maxsat/SA.hh new file mode 100644 index 0000000000000000000000000000000000000000..26c7864e2a9fcae1ba394ae2e930018f4605df0a --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/maxsat/SA.hh @@ -0,0 +1,493 @@ +#ifndef INC_SA +#define INC_SA + +#include "Mallba/mallba.hh" +#include "Mallba/States.hh" +#include "Mallba/Rarray.h" +#include "Mallba/time.hh" +#include "Mallba/netstream.hh" +#include <math.h> +#include <string.h> + +skeleton SA +{ + + provides class SetUpParams; + provides class Statistics; + provides class Move; + provides class StopCondition; + provides class Solver; + provides class Solver_Seq; + provides class Solver_Lan; + provides class Solver_Wan; + + requires class Problem; + requires class Solution; + requires class StopCondition_1; + requires class StopCondition_2; + requires class StopCondition_3; + requires class DefaultMove; + requires class UserStatistics; + requires bool TerminateQ (const Problem& pbm, const Solver& solver, const SetUpParams& setup); + +// Problem ---------------------------------------------------------------------------- + + requires class Problem + { + public: + Problem(); + ~Problem(); + + friend ostream& operator<< (ostream& os, const Problem& pbm); + friend istream& operator>> (istream& is, Problem& pbm); + + Problem& operator= (const Problem& pbm); + bool operator== (const Problem& pbm) const; + bool operator!= (const Problem& pbm) const; + + Direction direction () const; + double infinity() const; + + int numvar() const; + int numclause() const; + int lenclause() const; + int *clause(const int i) const; + + + private: + + int _numvar; + int _numclause; + int _lenclause; + int ** _clauses; + }; + +//Solution ---------------------------------------------------------------------------- + + requires class Solution + { + public: + Solution (const Problem& pbm); + Solution (const Solution& sol); + ~Solution(); + + friend ostream& operator<< (ostream& os, const Solution& sol); + friend istream& operator>> (istream& is, Solution& sol); + friend NetStream& operator << (NetStream& ns, const Solution& sol); + friend NetStream& operator >> (NetStream& ns, Solution& sol); + + const Problem& pbm() const; + + Solution& operator= (const Solution& sol); + bool operator== (const Solution& sol) const; + bool operator!= (const Solution& sol) const; + + char *to_String() const; + void to_Solution(char *_cadena_); + + void initialize(); + double fitness (); + unsigned int size() const; + + int& var(const int index); + Rarray<int>& array_var(); + + private: + Rarray<int> _var; + const Problem& _pbm; + }; + +// UserStatistics ---------------------------------------------------------------------------- + + requires class UserStatistics + { + private: + struct user_stat + { + unsigned int trial; + double initial_temperature; + double temperature_best_found_trial; + unsigned long nb_evaluation_best_found_trial; + double best_cost_trial; + float time_best_found_trial; + float time_spent_trial; + }; + + Rlist<struct user_stat> result_trials; + + public: + UserStatistics (); + ~UserStatistics(); + + friend ostream& operator<< (ostream& os, const UserStatistics& usertats); + + UserStatistics& operator= (const UserStatistics& userstats); + void update(const Solver& solver); + void clear(); + }; + +// Move ---------------------------------------------------------------------------------- + + provides class Move + { + public: + Move() {} + virtual ~Move() {} + + virtual void Apply(Solution& sol) const = 0; + }; + +// DefaultMove ---------------------------------------------------------------------------------- + + requires class DefaultMove: public Move + { + public: + DefaultMove(); + ~DefaultMove(); + + void Apply(Solution& sol) const; + }; + +// SetUpParams ------------------------------------------------------------------------------- + + provides class SetUpParams + { + private: + unsigned int _independent_runs; + unsigned long _max_evaluations; + unsigned int _MarkovChain_length; + double _temperature_decay; + bool _display_state; + + // for LAN execution configuration + unsigned long _refresh_global_state; + bool _synchronized; + unsigned int _cooperation; + + public: + SetUpParams (); + + friend ostream& operator<< (ostream& os, const SetUpParams& setup); + friend istream& operator>> (istream& is, SetUpParams& setup); + + const unsigned int independent_runs() const; + const unsigned long max_evaluations() const; + const unsigned int MarkovChain_length() const; + const double temperature_decay() const; + const bool display_state() const; + const unsigned long refresh_global_state() const; + const bool synchronized() const; + const unsigned int cooperation() const; + + void independent_runs(const unsigned int val); + void max_evaluations(const unsigned long val); + void MarkovChain_length(const unsigned int val); + void temperature_decay(const double val); + void display_state(const bool val); + void refresh_global_state(const unsigned long val); + void synchronized(const bool val); + void cooperation(const unsigned int val); + + ~SetUpParams(); + }; + +// Statistics --------------------------------------------------------------------------------- + + provides class Statistics + { + private: + struct stat + { + unsigned int trial; + unsigned long nb_evaluations; + double best_cost; + double current_cost; + }; + + Rlist<struct stat> stats_data; + + public: + Statistics(); + + friend ostream& operator<< (ostream& os, const Statistics& stats); + + Statistics& operator= (const Statistics& stats); + void update(const Solver& solver); + void clear(); + + ~Statistics(); + }; + +// Solver --------------------------------------------------------------------------------- + + provides class Solver + { + protected: + const Problem& problem; + const SetUpParams& params; + UserStatistics _userstat; + Statistics _stat; + Move* move; + Solution current; + double curfit; + Solution tentative; + double currentTemperature; + unsigned int k; // to control temperature update. + StateCenter _sc; + + float total_time_spent; + float time_spent_in_trial; + float start_trial; + float start_global; + + bool _end_trial; + + State_Vble _current_trial; + State_Vble _current_iteration; + State_Vble _current_best_solution; + State_Vble _current_best_cost; + State_Vble _current_solution; + State_Vble _current_cost; + + State_Vble _current_time_spent; + State_Vble _initial_temperature_trial; + State_Vble _time_best_found_trial; + State_Vble _iteration_best_found_trial; + State_Vble _temperature_best_found_trial; + State_Vble _time_spent_trial; + + State_Vble _trial_best_found; + State_Vble _iteration_best_found; + State_Vble _global_best_solution; + State_Vble _global_best_cost; + State_Vble _time_best_found; + + State_Vble _temperature; + State_Vble _display_state; + + const Direction _direction; + + bool AcceptQ(double tent, double cur, double temperature); + double Set_Initial_Temperature(const Problem& pbm); + void KeepHistory(const Solution& sol, const double curfit,const float time_spent_trial,const float total_time_spent); + + double UpdateT(double temp, int K); + + public: + // Constructor - Destructor ------------------------- + + Solver (const Problem& pbm, const SetUpParams& setup); + virtual ~Solver (); + virtual int pid() const; + bool end_trial() const; + + // Execution methods -------------------------------- + + // Full execution + virtual void run () =0; + virtual void run (unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol, unsigned long int nb_evaluations) =0; + + virtual void run (const double initialTemperature) =0; + virtual void run (const Solution& sol,const double initialTemperature) =0; + virtual void run (const double initialTemperature, unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations) =0; + + // Partial execution + virtual void StartUp () =0; + virtual void StartUp (const Solution& sol) =0; + virtual void StartUp (const double initialTemperature) =0; + virtual void StartUp (const Solution& sol, const double initialTemperature) =0; + virtual void DoStep () =0; + + // Statistics handling ------------------------------ + + const Statistics& statistics() const; + const UserStatistics& userstatistics () const; + const SetUpParams& setup() const; + const Problem& pbm() const; + + // State handling ----------------------------------- + + void RefreshState(); + void UpdateFromState(); + StateCenter* GetState(); + + unsigned int current_trial() const; + unsigned long current_iteration() const; + Solution current_best_solution() const; + Solution current_solution() const; + double current_best_cost() const; + double current_cost() const; + float current_time_spent() const; + float time_best_found_trial() const; + double initial_temperature_trial() const; + unsigned int iteration_best_found_trial() const; + double temperature_best_found_trial() const; + float time_spent_trial() const; + unsigned int trial_best_found() const; + unsigned int iteration_best_found() const; + Solution global_best_solution() const; + double global_best_cost() const; + float time_best_found() const; + double temperature() const; + int display_state() const; + + void current_trial(const unsigned int value); + void current_iteration(const unsigned long value); + void current_best_solution(const Solution& sol); + void current_best_cost(const double value); + void current_solution(const Solution& sol); + void current_cost(const double value); + void current_time_spent(const float value); + void time_best_found_trial(const float value); + void initial_temperature_trial(const double temperature); + void iteration_best_found_trial(const unsigned int value); + void temperature_best_found_trial(const double value); + void time_spent_trial(const float value); + void trial_best_found(const unsigned int value); + void iteration_best_found(const unsigned int value); + void global_best_solution(const Solution& sol); + void global_best_cost(const double value); + void time_best_found(const float value); + void temperature(const double value); + void display_state(const int value); + void show_state() const; + + // State handling ----------------------------------- + void SetMove(Move* mov); + }; + + provides class Solver_Seq: public Solver + { + public: + // Constructor - Destructor ------------------------- + + Solver_Seq ( const Problem& pbm, const SetUpParams& setup); + virtual ~Solver_Seq (); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + }; + + provides class Solver_Lan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + public: + Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Lan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + + provides class Solver_Wan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + public: + Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Wan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + +}; + +#endif diff --git a/ProyectoFinal/CHC/malva/rep/SA/maxsat/SA.pro.cc b/ProyectoFinal/CHC/malva/rep/SA/maxsat/SA.pro.cc new file mode 100644 index 0000000000000000000000000000000000000000..43dcaf9ebda2aa5738f2982cb5f6441259ce44f5 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/maxsat/SA.pro.cc @@ -0,0 +1,1807 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** Provided classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** *** +************************************************/ + +#include <iostream.h> +#include <math.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "Mallba/time.hh" + +skeleton SA +{ + +// SetUpParams ----------------------------------------------------------- + + SetUpParams::SetUpParams (): + _independent_runs(0), + _max_evaluations(0), + _MarkovChain_length(0), + _temperature_decay(0), + _refresh_global_state(0), + _synchronized(0), + _display_state(0), + _cooperation(0) + {} + + istream& operator>> (istream& is, SetUpParams& setup) + { + char buffer[MAX_BUFFER]; // current line in the setup file + char command[50]; + int op; + double dop; + short int nb_param=0; + short int nb_section=0; + short int nb_LAN_param=0; + + while (is.getline(buffer,MAX_BUFFER,'\n')) + { + sscanf(buffer," %s ",command); + + if (!(strcmp(command,"General"))) nb_section=0; + if (!(strcmp(command,"LAN-configuration"))) nb_section=1; + + if (nb_param==3 && nb_section==0) + { + dop=-1; + sscanf(buffer," %lf ",&dop); + if (dop<0) continue; + } + else + { + op=-1; + sscanf(buffer," %ld%*s ",&op); + if (op<0) continue; + } + + switch (nb_section) + { + case 0: switch (nb_param) + { + case 0: setup.independent_runs(op); break; + case 1: setup.max_evaluations(op); break; + case 2: setup.MarkovChain_length(op); break; + case 3: setup.temperature_decay(dop); break; + case 4: setup.display_state(op); break; + } + nb_param++; + break; + case 1: if (nb_LAN_param>=3) break; + if (nb_LAN_param==0) setup.refresh_global_state(op); + if (nb_LAN_param==1) setup.synchronized(op); + if (nb_LAN_param==2) setup.cooperation(op); + nb_LAN_param++; + break; + } // end switch + } // end while + return is; + } + + ostream& operator<< (ostream& os, const SetUpParams& setup) + { + os << "CONFIGURATION -------------------------------------------" << endl << endl; + os << "\t" << "Independent runs : " << setup.independent_runs() << endl + << "\t" << "Evaluation steps: " << setup.max_evaluations() << endl + << "\t" << "Markov-Chain Length: " << setup.MarkovChain_length() << endl + << "\t" << "Temperature Decay: " << setup.temperature_decay() << endl; + + if (setup.display_state()) + os << "\t" << "Display state" << endl; + else + os << "\t" << "Not display state" << endl; + os << endl << "\t" << "LAN configuration:" << endl + << "\t" << "----------------------" << endl << endl + << "\t" << "Refresh global state in number of generations: " << setup.refresh_global_state() << endl; + + if (setup.synchronized()) + os << "\t" << "Running in synchronous mode" << endl; + else + os << "\t" << "Running in asynchronous mode" << endl; + + if (!setup.cooperation()) + os << "\t" << "Running without cooperation" << endl << endl; + else + os << "\t" << "Running with cooperation in " << setup.cooperation() << " iterations. " << endl << endl; + + os << endl << endl << "END CONFIGURATION -------------------------------------------" << endl << endl; + return os; + } + + const unsigned int SetUpParams::independent_runs() const + { + return _independent_runs; + } + + const unsigned long SetUpParams::max_evaluations() const + { + return _max_evaluations; + } + + const unsigned int SetUpParams::MarkovChain_length() const + { + return _MarkovChain_length; + } + + const double SetUpParams::temperature_decay() const + { + return _temperature_decay; + } + + const bool SetUpParams::display_state() const + { + return _display_state; + } + + const unsigned long SetUpParams::refresh_global_state() const + { + return _refresh_global_state; + } + + const bool SetUpParams::synchronized() const + { + return _synchronized; + } + + const unsigned int SetUpParams::cooperation() const + { + return _cooperation; + } + + void SetUpParams::independent_runs(const unsigned int val) + { + _independent_runs = val; + } + + void SetUpParams::max_evaluations(const unsigned long val) + { + _max_evaluations= val; + } + void SetUpParams::MarkovChain_length(const unsigned int val) + { + _MarkovChain_length= val; + } + void SetUpParams::temperature_decay(const double val) + { + _temperature_decay= val; + } + + void SetUpParams::display_state(const bool val) + { + _display_state=val; + } + + void SetUpParams::refresh_global_state(const unsigned long val) + { + _refresh_global_state=val; + } + + void SetUpParams::synchronized(const bool val) + { + _synchronized=val; + } + + void SetUpParams::cooperation(const unsigned int val) + { + _cooperation=val; + } + + SetUpParams::~SetUpParams() + {} + +// Statistics ------------------------------------------------------ + + Statistics::Statistics() + {} + + ostream& operator<< (ostream& os, const Statistics& stats) + { + int j; + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF CURRENT TRIAL " << endl; + os << "------------------------------------------------------------------" << endl; + for (int i=0;i< stats.stats_data.size();i++) + { + os << endl + << " Evaluations: " << stats.stats_data[i].nb_evaluations + << " Best: " << stats.stats_data[i].best_cost + << " Current: " << stats.stats_data[i].current_cost; + } + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + Statistics& Statistics::operator= (const Statistics& stats) + { + stats_data = stats.stats_data; + return *this; + } + + void Statistics::update(const Solver& solver) + { + /* struct stat *new_stat; + if ((new_stat=(struct stat *)malloc(sizeof(struct stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluations= solver.current_iteration(); + new_stat->best_cost = solver.current_best_cost(); + new_stat->current_cost = solver.current_cost(); + stats_data.append(*new_stat); */ + } + + Statistics::~Statistics() + { + stats_data.remove(); + } + + void Statistics::clear() + { + stats_data.remove(); + } + +// Solver (superclass)--------------------------------------------------- + + Solver::Solver (const Problem& pbm, const SetUpParams& setup) + : problem(pbm), + params(setup), + _stat(), + _userstat(), + _sc(), + _direction(pbm.direction()), + current(pbm), + tentative(pbm), + currentTemperature(0.0), + time_spent_in_trial(0.0), + total_time_spent(0.0), + start_trial(0.0), + start_global(0.0), + _current_trial("_current_trial",_sc), + _current_iteration("_current_iteration",_sc), + _current_best_solution("_current_best_solution",_sc), + _current_best_cost("_current_best_cost",_sc), + _current_solution("_current_solution",_sc), + _current_cost("_current_cost",_sc), + _current_time_spent("_current_time_spent",_sc), + _initial_temperature_trial("_initial_temperature_trial",_sc), + _time_best_found_trial("_time_best_found_trial",_sc), + _iteration_best_found_trial("_iteration_best_found_trial",_sc), + _temperature_best_found_trial("_temperature_best_found_trial",_sc), + _time_spent_trial("_time_spent_trial",_sc), + _trial_best_found("_trial_best_found",_sc), + _iteration_best_found("_iteration_best_found;",_sc), + _global_best_solution("_global_best_solution",_sc), + _global_best_cost("_global_best_cost",_sc), + _time_best_found("_time_best_found",_sc), + _temperature("_temperature",_sc), + _display_state("_display_state",_sc) + { + current_trial(0); + current_iteration(0); + current_best_solution(current), + current_best_cost((-1) * pbm.direction() * infinity()); + current_solution(current); + current_cost((-1) * pbm.direction() * infinity()); + current_time_spent(total_time_spent); + initial_temperature_trial(0); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(0); + temperature_best_found_trial(0.0); + time_spent_trial(time_spent_in_trial); + trial_best_found(0); + iteration_best_found(0); + global_best_solution(current); + global_best_cost((-1) * pbm.direction() * infinity()); + time_best_found(total_time_spent); + temperature(currentTemperature); + display_state(setup.display_state()); + + move = new DefaultMove; + } + + int Solver::pid() const + { + return 0; + } + + bool Solver::end_trial() const + { + return _end_trial; + } + + unsigned int Solver::current_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_trial",(char *)&value, nitems, length); + return value; + } + + unsigned long Solver::current_iteration() const + { + unsigned long value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_iteration",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_best_solution() const + { + Solution sol(problem); + unsigned long nitems,length; + char data_stored[_current_best_solution.get_nitems() + _current_best_solution.get_length()]; + _sc.get_contents_state_variable("_current_best_solution", data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::current_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_best_cost",(char *)&value, nitems, length); + return value; + } + + double Solver::current_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_cost",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_solution() const + { + Solution sol(problem); + char data_stored[_current_solution.get_nitems() + _current_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_solution",data_stored, nitems, length); + sol.to_Solution((char *)data_stored); + return sol; + } + + float Solver::current_time_spent() const + { + float value=0.0; + unsigned long nitems,length; + _current_time_spent.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::initial_temperature_trial() const + { + double value=0.0; + unsigned long nitems,length; + _initial_temperature_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature_best_found_trial() const + { + double value=0.0; + unsigned long nitems,length; + _temperature_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_spent_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_spent_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::trial_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _trial_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::global_best_solution() const + { + Solution sol(problem); + char data_stored[_global_best_solution.get_nitems() + _global_best_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_solution",data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::global_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_cost",(char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_temperature",(char *)&value, nitems, length); + return value; + } + + int Solver::display_state() const + { + int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_display_state",(char *)&value, nitems, length); + return value; + } + + void Solver::current_trial(const unsigned int value) + { + _sc.set_contents_state_variable("_current_trial",(char *)&value,1,sizeof(int)); + } + + void Solver::current_iteration(const unsigned long value) + { + _sc.set_contents_state_variable("_current_iteration",(char *)&value,1,sizeof(long)); + } + + void Solver::current_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_best_cost(const double value) + { + _sc.set_contents_state_variable("_current_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_cost(const double value) + { + _sc.set_contents_state_variable("_current_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_time_spent(const float value) + { + _current_time_spent.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::time_best_found_trial(const float value) + { + _time_best_found_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::iteration_best_found_trial(const unsigned int value) + { + _iteration_best_found_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::initial_temperature_trial(const double value) + { + _initial_temperature_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::temperature_best_found_trial(const double value) + { + _temperature_best_found_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::time_spent_trial(const float value) + { + _time_spent_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::trial_best_found(const unsigned int value) + { + _trial_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::iteration_best_found(const unsigned int value) + { + _iteration_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::global_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_global_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::global_best_cost(const double value) + { + _sc.set_contents_state_variable("_global_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::time_best_found(const float value) + { + _time_best_found.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::temperature(const double value) + { + _sc.set_contents_state_variable("_temperature",(char *)&value,1,sizeof(double)); + } + + void Solver::display_state(const int value) + { + _sc.set_contents_state_variable("_display_state",(char *)&value,1,sizeof(int)); + } + + const Statistics& Solver::statistics() const + { + return _stat; + } + + const UserStatistics& Solver::userstatistics() const + { + return _userstat; + } + + const SetUpParams& Solver::setup() const + { + return params; + } + + const Problem& Solver::pbm() const + { + return problem; + } + + void Solver::KeepHistory(const Solution& sol, const double curfit,const float time_spent_in_trial,const float total_time_spent) + { + bool betterG=false; + bool betterT=false; + + switch (_direction) + { + case minimize: betterG = (curfit < global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit < current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + case maximize: betterG = (curfit > global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit > current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + } + + if (betterT) + { + current_best_solution(sol); + current_best_cost(curfit); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(current_iteration()); + temperature_best_found_trial(temperature()); + if (betterG) + { + trial_best_found(current_trial()); + iteration_best_found(current_iteration()); + global_best_solution(sol); + global_best_cost(curfit); + time_best_found(time_spent_in_trial); + } + } + } + + double Solver::UpdateT(double temp, int K) + { + //return temp * params.temperature_decay(); // initial + + /* + if(K == 1) return temp/log(2); + else return temp * log(K) / log(K+1); + */ + /* + if(K == 1) return temp/2; + else return (temp * K) / (K + 1); + */ + + if(K == 1) return temp / exp(2); + else return (temp * exp(K)) / exp(K+1); + + } + + StateCenter* Solver::GetState() + { + return &_sc; + } + + void Solver::RefreshState() + { + current_solution(current); + current_cost(curfit); + current_time_spent(total_time_spent); + time_spent_trial(time_spent_in_trial); + temperature(currentTemperature); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::UpdateFromState() + { + current = current_solution(); + curfit = current_cost(); + total_time_spent=current_time_spent(); + time_spent_in_trial=time_spent_trial(); + currentTemperature = temperature(); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::show_state() const + { + cout << endl << "Current trial: " << current_trial(); + cout << endl << "Current iteration: " << current_iteration(); + cout << endl << "Current Temperature: " << temperature (); + cout << endl << "Current cost: " << current_cost(); + cout << endl << "Best cost in trial: " << current_best_cost(); + cout << endl << "Time of best solution found in trial: " << time_best_found_trial(); + cout << endl << "Iteration of best solution found in trial: " << iteration_best_found_trial(); + cout << endl << "Initial temperature in trial: " << initial_temperature_trial(); + cout << endl << "Temperature of best solution found in trial: " << temperature_best_found_trial(); + cout << endl << "Time spent in trial: " << time_spent_trial(); + cout << endl << "Global best cost: " << global_best_cost(); + cout << endl << "Trial of best global solution found: " << trial_best_found(); + cout << endl << "Iteration of best global solution found: " << iteration_best_found(); + cout << endl << "Time of global best solution found: " << time_best_found(); + // cout << endl << "Current solution: " << current_solution(); + // cout << endl << "Best solution of trial: " << current_best_solution(); + // cout << endl << "Global solution: " << global_best_solution() << endl; + cout << endl << endl << "Current time spent (so far): " << current_time_spent() << endl; + } + + Solver::~Solver() + { + _sc.removeAll(); + delete move; + } + + bool Solver::AcceptQ (double tent, double cur, double temperature) + { + if (_direction==minimize) + + return (tent < cur) || + ((rand01()*(1+exp((tent-cur)/temperature)))<2.0); + + else + + return (tent > cur) || + ((rand01()*(1+exp((cur-tent)/temperature)))<2.0); + } + + double Solver::Set_Initial_Temperature(const Problem& pbm) + { + const double beta = 1.05; + const double test = 10; + const double acrat = .8; + const double T = 1.0; + + Solution current (pbm); + Solution newsol (pbm); + double ac; + double fit; + double temperature = T; + + do + { + temperature *= beta; + ac = 0; + current.initialize(); + fit = current.fitness(); + for (int i=0; i<test; i++) + { + newsol = current; + move->Apply(newsol); + if (AcceptQ(newsol.fitness(),fit,temperature)) + ac += 1.0/test; + } + } while (ac < acrat); + + initial_temperature_trial(temperature); + return temperature; + + } + + void Solver::SetMove (Move* mov) + { + delete move; + move = mov; + } + + // Solver sequencial ----------------------------------------------------- + + Solver_Seq::Solver_Seq (const Problem& pbm, const SetUpParams& setup) + : Solver(pbm,setup) + { + random_seed(time(0)); + _end_trial=true; + } + + Solver_Seq::~Solver_Seq () + {} + + void Solver_Seq::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Seq::StartUp(const Solution& sol, const double initialTemperature) + { + start_trial=_used_time(); + start_global=total_time_spent; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current = sol; + curfit = current.fitness(); + current_best_cost((-1) * problem.direction() * infinity()); + currentTemperature = initialTemperature; + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + void Solver_Seq::DoStep() + { + current_iteration(current_iteration()+1); + + tentative = current; + move->Apply(tentative); + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + + void Solver_Seq::run (unsigned long int max_evaluations) + { + StartUp(); + + while (current_iteration()<max_evaluations && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + // Solver LAN ----------------------------------------------------------- + + Solver_Lan::Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); + } + + Solver_Lan::~Solver_Lan () + { + NetStream::finalize(); + } + + int Solver_Lan::pid() const + { + return mypid; + } + + NetStream& Solver_Lan::netstream() + { + return _netstream; + } + + void Solver_Lan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Lan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + void update(Direction direction, Solution &solution_received,double cost_received, Solution &solution_to_send, double &best_cost) + { + switch (direction) + { + case minimize: if (cost_received < best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + case maximize: if (cost_received > best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + } + } + + int Solver_Lan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Lan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Lan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Lan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Lan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Lan::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + void Solver_Lan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } + + // Solver WAN ------------------------------------------------------------ + + Solver_Wan::Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); + } + + Solver_Wan::~Solver_Wan () + { + NetStream::finalize(); + } + + int Solver_Wan::pid() const + { + return mypid; + } + + NetStream& Solver_Wan::netstream() + { + return _netstream; + } + + void Solver_Wan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Wan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + int Solver_Wan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Wan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Wan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Wan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Wan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Wan::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + void Solver_Wan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } +}; + diff --git a/ProyectoFinal/CHC/malva/rep/SA/maxsat/SA.req.cc b/ProyectoFinal/CHC/malva/rep/SA/maxsat/SA.req.cc new file mode 100644 index 0000000000000000000000000000000000000000..f3554e78d1d41df92f0395d8eb58136986f5bde4 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/maxsat/SA.req.cc @@ -0,0 +1,364 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** User-required classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** Tab size = 4 *** +*** *** +*** *** +************************************************/ + +#include <iostream.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "StopCondition.hh" + +skeleton SA { + + // Problem --------------------------------------------------------------- + + Problem::Problem ():_numvar(0),_numclause(0),_clauses(NULL),_lenclause(0) + {} + + ostream& operator<< (ostream& os, const Problem& pbm) + { + os << endl << endl << "Number of variables " << pbm._numvar + << endl << endl << "Number of clauses " << pbm._numclause + << endl << endl << "Length of clauses " << pbm._lenclause + << endl << endl + << " Clauses: " << endl; + + for (int i=0;i<pbm._numclause;i++) + { + os << "\t clause " << i << "\t "; + for(int j = 0; j < pbm._lenclause; j++) + os << pbm._clauses[i][j] << " "; + os << endl; + } + return os; + } + + istream& operator>> (istream& is, Problem& pbm) + { + int l; + int n; + is >> pbm._numvar >> pbm._numclause >> pbm._lenclause; + + n = pbm._lenclause; + // read clauses + pbm._clauses = new int*[pbm._numclause]; + + for (int i = 0; i < pbm._numclause; i++) + { + pbm._clauses[i] = new int[n]; + for(int j = 0; j < n;j++) + { + is >> l; + pbm._clauses[i][j] = l; + } + is >> l; + } + + return is; + } + + Problem& Problem::operator= (const Problem& pbm) + { + int n; + _numvar=pbm.numvar(); + for(int i = 0; i < _numclause;i++) + delete [] _clauses[i]; + delete [] _clauses; + + _numclause = pbm.numclause(); + n = _lenclause = pbm.lenclause(); + + _clauses = new int *[_numclause]; + + for(int i = 0; i < pbm._numclause;i++) + { + _clauses[i] = new int [n]; + for(int j = 0; j < n ; j++) + _clauses[i][j] = pbm._clauses[i][j]; + } + return *this; + } + + bool Problem::operator== (const Problem& pbm) const + { + if (_numvar!=pbm.numvar()) return false; + for (int i = 0; i < _numclause; i++) + for(int j = 0; j < _lenclause;j++) + if ( _clauses[i][j] != pbm._clauses[i][j]) + return false; + return true; + } + + bool Problem::operator!= (const Problem& pbm) const + { + return !(*this == pbm); + } + + Direction Problem::direction() const + { + return maximize; + //return minimize; + } + + double Problem::infinity() const + { + double one=1.0; + double zero=0.0; + return 0.0 - one/zero; + } + + int Problem::numvar() const + { + return _numvar; + } + + int Problem::numclause() const + { + return _numclause; + } + + int Problem::lenclause() const + { + return _lenclause; + } + + int *Problem::clause(const int i) const + { + return _clauses[i]; + } + + Problem::~Problem() + { + for(int i = 0;i < _numclause;i++) + delete [] _clauses[i]; + + delete [] _clauses; + } + + // Solution -------------------------------------------------------------- + + Solution::Solution (const Problem& pbm):_pbm(pbm),_var(pbm.numvar()) + {} + + const Problem& Solution::pbm() const + { + return _pbm; + } + + Solution::Solution(const Solution& sol):_pbm(sol.pbm()) + { + *this=sol; + } + + istream& operator>> (istream& is, Solution& sol) + { + for (int i=0;i<sol.pbm().numvar();i++) + is >> sol._var[i]; + return is; + } + + ostream& operator<< (ostream& os, const Solution& sol) + { + for (int i=0;i<sol.pbm().numvar();i++) + os << " " << sol._var[i]; + return os; + } + + NetStream& operator << (NetStream& ns, const Solution& sol) + { + for (int i=0;i<sol._var.size();i++) + ns << sol._var[i]; + return ns; + } + + NetStream& operator >> (NetStream& ns, Solution& sol) + { + for (int i=0;i<sol._var.size();i++) + ns >> sol._var[i]; + return ns; + } + + Solution& Solution::operator= (const Solution &sol) + { + _var = sol._var; + return *this; + } + + bool Solution::operator== (const Solution& sol) const + { + if (sol.pbm() != _pbm) return false; + return true; + } + + bool Solution::operator!= (const Solution& sol) const + { + return !(*this == sol); + } + + void Solution::initialize() + { + for (int i=0;i<_pbm.numvar();i++) + _var[i]=rand_int(0,1); + } + + double Solution::fitness () + { + double fitness = 0.0; + int acum = 0; + + for(int i = 0; i < _pbm.numclause(); i++) + { + int *rl = _pbm.clause(i); + acum = 0; + for(int j = 0; (j < _pbm.lenclause()) && (acum != 1);j++) + { + if( ((rl[j] < 0) && (_var[(int)abs(rl[j])-1] == 0)) + || ((rl[j] > 0) && (_var[rl[j]-1] == 1)) ) + acum = 1; + } + fitness += acum; + } + return fitness; + } + + char *Solution::to_String() const + { + return (char *)_var.get_first(); + } + + void Solution::to_Solution(char *_string_) + { + int *ptr=(int *)_string_; + for (int i=0;i<_pbm.numvar();i++) + { + _var[i]=*ptr; + ptr++; + } + } + + unsigned int Solution::size() const + { + return (_pbm.numvar() * sizeof(int)); + } + + + int& Solution::var(const int index) + { + return _var[index]; + } + + + Rarray<int>& Solution::array_var() + { + return _var; + } + + Solution::~Solution() + {} + +// UserStatistics ------------------------------------------------------- + + UserStatistics::UserStatistics () + {} + + ostream& operator<< (ostream& os, const UserStatistics& userstat) + { + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF TRIALS " << endl; + os << "------------------------------------------------------------------" << endl; + + for (int i=0;i< userstat.result_trials.size();i++) + { + os << endl + << "\t" << userstat.result_trials[i].trial + << "\t" << userstat.result_trials[i].best_cost_trial + << "\t\t" << userstat.result_trials[i].nb_evaluation_best_found_trial + << "\t\t" << userstat.result_trials[i].initial_temperature + << "\t\t" << userstat.result_trials[i].temperature_best_found_trial + << "\t\t" << userstat.result_trials[i].time_best_found_trial + << "\t\t" << userstat.result_trials[i].time_spent_trial; + } + + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + + UserStatistics& UserStatistics::operator= (const UserStatistics& userstats) + { + result_trials=userstats.result_trials; + return (*this); + } + + + void UserStatistics::update(const Solver& solver) + { + if ((solver.pid()!=0) || (solver.end_trial()!=true) + || ((solver.current_iteration()!=solver.setup().max_evaluations()) + && !TerminateQ(solver.pbm(),solver,solver.setup()))) + return; + struct user_stat *new_stat; + if ((new_stat=(struct user_stat *)malloc(sizeof(struct user_stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluation_best_found_trial= solver.iteration_best_found_trial(); + new_stat->initial_temperature=solver.initial_temperature_trial(); + new_stat->temperature_best_found_trial=solver.temperature_best_found_trial(); + new_stat->best_cost_trial = solver.current_best_cost(); + new_stat->time_best_found_trial= solver.time_best_found_trial(); + new_stat->time_spent_trial = solver.time_spent_trial(); + result_trials.append(*new_stat); + } + + void UserStatistics::clear() + { + result_trials.remove(); + } + + UserStatistics::~UserStatistics() + { + result_trials.remove(); + } + +// DefaultMove ------------------------------------------------------- + + + DefaultMove::DefaultMove() + {} + + DefaultMove::~DefaultMove() + {} + + void DefaultMove::Apply (Solution& sol) const + { + const float probability = 0.03; + + for (int i=0;i<sol.pbm().numvar();i++) + { + if (rand01()<=probability) + { + if (sol.var(i)==1) sol.var(i)=0; + else sol.var(i)=1; + } + } + } + + //------------------------------------------------------------------------ + // Specific methods ------------------------------------------------------ + //------------------------------------------------------------------------ + + bool TerminateQ (const Problem& pbm, const Solver& solver, + const SetUpParams& setup) + { + + StopCondition_3 stop; + return stop.EvaluateCondition(pbm,solver,setup); + } +} + + diff --git a/ProyectoFinal/CHC/malva/rep/SA/maxsat/StopCondition.cc b/ProyectoFinal/CHC/malva/rep/SA/maxsat/StopCondition.cc new file mode 100644 index 0000000000000000000000000000000000000000..dcd0513b3aa3efbd58c9aac87a7ae91e94585170 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/maxsat/StopCondition.cc @@ -0,0 +1,52 @@ +#include "StopCondition.hh" +skeleton SA +{ + +// StopCondition ------------------------------------------------------------------------------------- + + StopCondition::StopCondition() + {} + + StopCondition::~StopCondition() + {} + +// StopCondition_1 ------------------------------------------------------------------------------------- + + StopCondition_1::StopCondition_1():StopCondition() + {} + + bool StopCondition_1::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return false; + } + + StopCondition_1::~StopCondition_1() + {} + +// StopCondition_2 ------------------------------------------------------------------------------------- + + StopCondition_2::StopCondition_2():StopCondition() + {} + + bool StopCondition_2::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return (solver.global_best_cost()>8.5); + } + + StopCondition_2::~StopCondition_2() + {} + +// StopCondition_3 ------------------------------------------------------------------------------------- + + StopCondition_3::StopCondition_3():StopCondition() + {} + + bool StopCondition_3::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return ((int)solver.current_best_cost() == pbm.numclause()); + } + + StopCondition_3::~StopCondition_3() + {} + +} diff --git a/ProyectoFinal/CHC/malva/rep/SA/maxsat/StopCondition.hh b/ProyectoFinal/CHC/malva/rep/SA/maxsat/StopCondition.hh new file mode 100644 index 0000000000000000000000000000000000000000..04ef770d9cac5bb9ef69aae7d085e3ae2166e187 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/maxsat/StopCondition.hh @@ -0,0 +1,41 @@ +#ifndef stop_condition +#define stop_condition + +#include "SA.hh" +skeleton SA +{ + + provides class StopCondition + { + public: + StopCondition(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup)=0; + ~StopCondition(); + }; + + requires class StopCondition_1 : public StopCondition + { + public: + StopCondition_1(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_1(); + }; + + requires class StopCondition_2 : public StopCondition + { + public: + StopCondition_2(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_2(); + }; + + requires class StopCondition_3 : public StopCondition + { + public: + StopCondition_3(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_3(); + }; +} + +#endif diff --git a/ProyectoFinal/CHC/malva/rep/SA/maxsat/pgfileLan b/ProyectoFinal/CHC/malva/rep/SA/maxsat/pgfileLan new file mode 100644 index 0000000000000000000000000000000000000000..a681b216557346c572dd8531406475a201cd01b1 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/maxsat/pgfileLan @@ -0,0 +1,5 @@ +localhost 0 ~/Mallba/rep/SA/maxsat/MainLan +localhost 1 ~/Mallba/rep/SA/maxsat/MainLan +localhost 1 ~/Mallba/rep/SA/maxsat/MainLan +localhost 1 ~/Mallba/rep/SA/maxsat/MainLan +localhost 1 ~/Mallba/rep/SA/maxsat/MainLan diff --git a/ProyectoFinal/CHC/malva/rep/SA/onemax/Config.cfg b/ProyectoFinal/CHC/malva/rep/SA/onemax/Config.cfg new file mode 100644 index 0000000000000000000000000000000000000000..87d424d262edb6ee4764dadc24bd085dfe030248 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/onemax/Config.cfg @@ -0,0 +1,3 @@ +SA.cfg +../../../ProblemInstances/ONEMAX-instances/onemax10.txt +res/om10.sa.lan.txt diff --git a/ProyectoFinal/CHC/malva/rep/SA/onemax/MainLan.cc b/ProyectoFinal/CHC/malva/rep/SA/onemax/MainLan.cc new file mode 100644 index 0000000000000000000000000000000000000000..8949422e10f93211d953aba1308c203d13f30f0a --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/onemax/MainLan.cc @@ -0,0 +1,53 @@ +#include "SA.hh" +#include <iostream.h> +#include <fstream.h> + +int main (int argc, char** argv) +{ + using skeleton SA; + char path[MAX_BUFFER]; + int len; + int longitud; + + system("clear"); + + get_path(argv[0],path); + len = strlen(path); + longitud = MAX_BUFFER - len; + + strcat(path,"Config.cfg"); + ifstream f(path); + if(!f) show_message(10); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f1(path); + if(!f1) show_message(11); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f2(path); + if(!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + SetUpParams cfg; + f1 >> cfg; + + + Solver_Lan solver(pbm,cfg,argc,argv); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solucion: " << solver.global_best_solution() << " Fitness: " << solver.global_best_solution().fitness(); + + f.getline(&(path[len]),longitud,'\n'); + ofstream fexit(path); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + cout << endl << endl << " :( ---------------------- THE END --------------- :) " << endl; + } + return(0); +} diff --git a/ProyectoFinal/CHC/malva/rep/SA/onemax/MainSeq.cc b/ProyectoFinal/CHC/malva/rep/SA/onemax/MainSeq.cc new file mode 100644 index 0000000000000000000000000000000000000000..41d8a720793c0d10b14e1d5dfa05b7f11e9c4dda --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/onemax/MainSeq.cc @@ -0,0 +1,42 @@ +#include "SA.hh" +#include <iostream.h> +#include <fstream.h> + +int main (int argc, char** argv) +{ + using skeleton SA; + + system("clear"); + + if(argc < 4) + show_message(1); + + ifstream f1(argv[1]); + if (!f1) show_message(11); + + ifstream f2(argv[2]); + if (!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + SetUpParams cfg; + f1 >> cfg; + + Solver_Seq solver(pbm,cfg); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << solver.global_best_solution() + << " Fitness: " << solver.global_best_solution().fitness() << endl; + cout << "\n\n :( ---------------------- THE END --------------- :) "; + + ofstream fexit(argv[3]); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + } + return(0); +} diff --git a/ProyectoFinal/CHC/malva/rep/SA/onemax/Makefile b/ProyectoFinal/CHC/malva/rep/SA/onemax/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..82415bbd05b58056dc192ea02ba203de90048153 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/onemax/Makefile @@ -0,0 +1,22 @@ +include ../../../environment + +all: MainSeq MainLan + +clean: + rm -f MainLan MainSeq MainWan *.o *% *~ + +MainLan: SA.req.o SA.pro.o StopCondition.o MainLan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainWan: SA.req.o SA.pro.o StopCondition.o MainWan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainSeq: SA.req.o SA.pro.o StopCondition.o MainSeq.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +LAN: + $(RUN) -v -p4pg pgfileLan MainLan +WAN: + $(RUN) -v -p4pg pgfileWan MainWan +SEQ: + ./MainSeq SA.cfg ../../../ProblemInstances/ONEMAX-instances/onemax10.txt res/om10.sa.seq.txt diff --git a/ProyectoFinal/CHC/malva/rep/SA/onemax/SA.cfg b/ProyectoFinal/CHC/malva/rep/SA/onemax/SA.cfg new file mode 100644 index 0000000000000000000000000000000000000000..b6c93992066b9367d040e96d81efd590532238a3 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/onemax/SA.cfg @@ -0,0 +1,9 @@ +10 // number of independent runs +500 // number of evaluations +5 // Markov-Chain Length +.99 // temperature Decay +1 // display state ? +LAN-configuration +10 // the global state is updated in this number of evaluations +0 // 0: asynchronized mode // 1: synchronized mode +10 // interval of iterations to cooperate ( if 0 no cooperation) diff --git a/ProyectoFinal/CHC/malva/rep/SA/onemax/SA.hh b/ProyectoFinal/CHC/malva/rep/SA/onemax/SA.hh new file mode 100644 index 0000000000000000000000000000000000000000..6238f6de1290020e2dc587e829e825e0e7edb4ae --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/onemax/SA.hh @@ -0,0 +1,488 @@ +#ifndef INC_SA +#define INC_SA + +#include "Mallba/mallba.hh" +#include "Mallba/States.hh" +#include "Mallba/Rarray.h" +#include "Mallba/time.hh" +#include "Mallba/netstream.hh" +#include <math.h> +#include <string.h> + +skeleton SA +{ + + provides class SetUpParams; + provides class Statistics; + provides class Move; + provides class StopCondition; + provides class Solver; + provides class Solver_Seq; + provides class Solver_Lan; + provides class Solver_Wan; + + requires class Problem; + requires class Solution; + requires class StopCondition_1; + requires class StopCondition_2; + requires class StopCondition_3; + requires class DefaultMove; + requires class UserStatistics; + requires bool TerminateQ (const Problem& pbm, const Solver& solver, const SetUpParams& setup); + +// Problem ---------------------------------------------------------------------------- + + requires class Problem + { + public: + Problem (); + ~Problem (); + + friend ostream& operator<< (ostream& os, const Problem& pbm); + friend istream& operator>> (istream& is, Problem& pbm); + + Problem& operator= (const Problem& pbm); + bool operator== (const Problem& pbm) const; + bool operator!= (const Problem& pbm) const; + + Direction direction () const; + + int dimension() const; + double infinity() const; + + private: + + int _dimension; + }; + +//Solution ---------------------------------------------------------------------------- + + requires class Solution + { + public: + Solution (const Problem& pbm); + Solution (const Solution& sol); + ~Solution(); + + friend ostream& operator<< (ostream& os, const Solution& sol); + friend istream& operator>> (istream& is, Solution& sol); + friend NetStream& operator << (NetStream& ns, const Solution& sol); + friend NetStream& operator >> (NetStream& ns, Solution& sol); + + const Problem& pbm() const; + + Solution& operator= (const Solution& sol); + bool operator== (const Solution& sol) const; + bool operator!= (const Solution& sol) const; + + char *to_String() const; + void to_Solution(char *_vertex_); + unsigned int size() const; + + void initialize(); + double fitness () const; + + int& var(const int index); + Rarray<int>& array_var(); + + private: + Rarray<int> _var; + const Problem& _pbm; + }; + +// UserStatistics ---------------------------------------------------------------------------- + + requires class UserStatistics + { + private: + struct user_stat + { + unsigned int trial; + double initial_temperature; + double temperature_best_found_trial; + unsigned long nb_evaluation_best_found_trial; + double best_cost_trial; + float time_best_found_trial; + float time_spent_trial; + }; + + Rlist<struct user_stat> result_trials; + + public: + UserStatistics (); + ~UserStatistics(); + + friend ostream& operator<< (ostream& os, const UserStatistics& usertats); + + UserStatistics& operator= (const UserStatistics& userstats); + void update(const Solver& solver); + void clear(); + }; + +// Move ---------------------------------------------------------------------------------- + + provides class Move + { + public: + Move() {} + virtual ~Move() {} + + virtual void Apply(Solution& sol) const = 0; + }; + +// DefaultMove ---------------------------------------------------------------------------------- + + requires class DefaultMove: public Move + { + public: + DefaultMove(); + ~DefaultMove(); + + void Apply(Solution& sol) const; + }; + +// SetUpParams ------------------------------------------------------------------------------- + + provides class SetUpParams + { + private: + unsigned int _independent_runs; + unsigned long _max_evaluations; + unsigned int _MarkovChain_length; + double _temperature_decay; + bool _display_state; + + // for LAN execution configuration + unsigned long _refresh_global_state; + bool _synchronized; + unsigned int _cooperation; + + public: + SetUpParams (); + + friend ostream& operator<< (ostream& os, const SetUpParams& setup); + friend istream& operator>> (istream& is, SetUpParams& setup); + + const unsigned int independent_runs() const; + const unsigned long max_evaluations() const; + const unsigned int MarkovChain_length() const; + const double temperature_decay() const; + const bool display_state() const; + const unsigned long refresh_global_state() const; + const bool synchronized() const; + const unsigned int cooperation() const; + + void independent_runs(const unsigned int val); + void max_evaluations(const unsigned long val); + void MarkovChain_length(const unsigned int val); + void temperature_decay(const double val); + void display_state(const bool val); + void refresh_global_state(const unsigned long val); + void synchronized(const bool val); + void cooperation(const unsigned int val); + + ~SetUpParams(); + }; + +// Statistics --------------------------------------------------------------------------------- + + provides class Statistics + { + private: + struct stat + { + unsigned int trial; + unsigned long nb_evaluations; + double best_cost; + double current_cost; + }; + + Rlist<struct stat> stats_data; + + public: + Statistics(); + + friend ostream& operator<< (ostream& os, const Statistics& stats); + + Statistics& operator= (const Statistics& stats); + void update(const Solver& solver); + void clear(); + + ~Statistics(); + }; + +// Solver --------------------------------------------------------------------------------- + + provides class Solver + { + protected: + const Problem& problem; + const SetUpParams& params; + UserStatistics _userstat; + Statistics _stat; + Move* move; + Solution current; + double curfit; + Solution tentative; + double currentTemperature; + unsigned int k; // to control temperature update. + StateCenter _sc; + + float total_time_spent; + float time_spent_in_trial; + float start_trial; + float start_global; + + bool _end_trial; + + State_Vble _current_trial; + State_Vble _current_iteration; + State_Vble _current_best_solution; + State_Vble _current_best_cost; + State_Vble _current_solution; + State_Vble _current_cost; + + State_Vble _current_time_spent; + State_Vble _initial_temperature_trial; + State_Vble _time_best_found_trial; + State_Vble _iteration_best_found_trial; + State_Vble _temperature_best_found_trial; + State_Vble _time_spent_trial; + + State_Vble _trial_best_found; + State_Vble _iteration_best_found; + State_Vble _global_best_solution; + State_Vble _global_best_cost; + State_Vble _time_best_found; + + State_Vble _temperature; + State_Vble _display_state; + + const Direction _direction; + + bool AcceptQ(double tent, double cur, double temperature); + double Set_Initial_Temperature(const Problem& pbm); + void KeepHistory(const Solution& sol, const double curfit,const float time_spent_trial,const float total_time_spent); + + double UpdateT(double temp, int K); + + public: + // Constructor - Destructor ------------------------- + + Solver (const Problem& pbm, const SetUpParams& setup); + virtual ~Solver (); + virtual int pid() const; + bool end_trial() const; + + // Execution methods -------------------------------- + + // Full execution + virtual void run () =0; + virtual void run (unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol, unsigned long int nb_evaluations) =0; + + virtual void run (const double initialTemperature) =0; + virtual void run (const Solution& sol,const double initialTemperature) =0; + virtual void run (const double initialTemperature, unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations) =0; + + // Partial execution + virtual void StartUp () =0; + virtual void StartUp (const Solution& sol) =0; + virtual void StartUp (const double initialTemperature) =0; + virtual void StartUp (const Solution& sol, const double initialTemperature) =0; + virtual void DoStep () =0; + + // Statistics handling ------------------------------ + + const Statistics& statistics() const; + const UserStatistics& userstatistics () const; + const SetUpParams& setup() const; + const Problem& pbm() const; + + // State handling ----------------------------------- + + void RefreshState(); + void UpdateFromState(); + StateCenter* GetState(); + + unsigned int current_trial() const; + unsigned long current_iteration() const; + Solution current_best_solution() const; + Solution current_solution() const; + double current_best_cost() const; + double current_cost() const; + float current_time_spent() const; + float time_best_found_trial() const; + double initial_temperature_trial() const; + unsigned int iteration_best_found_trial() const; + double temperature_best_found_trial() const; + float time_spent_trial() const; + unsigned int trial_best_found() const; + unsigned int iteration_best_found() const; + Solution global_best_solution() const; + double global_best_cost() const; + float time_best_found() const; + double temperature() const; + int display_state() const; + + void current_trial(const unsigned int value); + void current_iteration(const unsigned long value); + void current_best_solution(const Solution& sol); + void current_best_cost(const double value); + void current_solution(const Solution& sol); + void current_cost(const double value); + void current_time_spent(const float value); + void time_best_found_trial(const float value); + void initial_temperature_trial(const double temperature); + void iteration_best_found_trial(const unsigned int value); + void temperature_best_found_trial(const double value); + void time_spent_trial(const float value); + void trial_best_found(const unsigned int value); + void iteration_best_found(const unsigned int value); + void global_best_solution(const Solution& sol); + void global_best_cost(const double value); + void time_best_found(const float value); + void temperature(const double value); + void display_state(const int value); + void show_state() const; + + // State handling ----------------------------------- + void SetMove(Move* mov); + }; + + provides class Solver_Seq: public Solver + { + public: + // Constructor - Destructor ------------------------- + + Solver_Seq ( const Problem& pbm, const SetUpParams& setup); + virtual ~Solver_Seq (); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + }; + + provides class Solver_Lan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + + public: + Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Lan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + + provides class Solver_Wan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + + public: + Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Wan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + +}; + +#endif diff --git a/ProyectoFinal/CHC/malva/rep/SA/onemax/SA.pro.cc b/ProyectoFinal/CHC/malva/rep/SA/onemax/SA.pro.cc new file mode 100644 index 0000000000000000000000000000000000000000..43dcaf9ebda2aa5738f2982cb5f6441259ce44f5 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/onemax/SA.pro.cc @@ -0,0 +1,1807 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** Provided classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** *** +************************************************/ + +#include <iostream.h> +#include <math.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "Mallba/time.hh" + +skeleton SA +{ + +// SetUpParams ----------------------------------------------------------- + + SetUpParams::SetUpParams (): + _independent_runs(0), + _max_evaluations(0), + _MarkovChain_length(0), + _temperature_decay(0), + _refresh_global_state(0), + _synchronized(0), + _display_state(0), + _cooperation(0) + {} + + istream& operator>> (istream& is, SetUpParams& setup) + { + char buffer[MAX_BUFFER]; // current line in the setup file + char command[50]; + int op; + double dop; + short int nb_param=0; + short int nb_section=0; + short int nb_LAN_param=0; + + while (is.getline(buffer,MAX_BUFFER,'\n')) + { + sscanf(buffer," %s ",command); + + if (!(strcmp(command,"General"))) nb_section=0; + if (!(strcmp(command,"LAN-configuration"))) nb_section=1; + + if (nb_param==3 && nb_section==0) + { + dop=-1; + sscanf(buffer," %lf ",&dop); + if (dop<0) continue; + } + else + { + op=-1; + sscanf(buffer," %ld%*s ",&op); + if (op<0) continue; + } + + switch (nb_section) + { + case 0: switch (nb_param) + { + case 0: setup.independent_runs(op); break; + case 1: setup.max_evaluations(op); break; + case 2: setup.MarkovChain_length(op); break; + case 3: setup.temperature_decay(dop); break; + case 4: setup.display_state(op); break; + } + nb_param++; + break; + case 1: if (nb_LAN_param>=3) break; + if (nb_LAN_param==0) setup.refresh_global_state(op); + if (nb_LAN_param==1) setup.synchronized(op); + if (nb_LAN_param==2) setup.cooperation(op); + nb_LAN_param++; + break; + } // end switch + } // end while + return is; + } + + ostream& operator<< (ostream& os, const SetUpParams& setup) + { + os << "CONFIGURATION -------------------------------------------" << endl << endl; + os << "\t" << "Independent runs : " << setup.independent_runs() << endl + << "\t" << "Evaluation steps: " << setup.max_evaluations() << endl + << "\t" << "Markov-Chain Length: " << setup.MarkovChain_length() << endl + << "\t" << "Temperature Decay: " << setup.temperature_decay() << endl; + + if (setup.display_state()) + os << "\t" << "Display state" << endl; + else + os << "\t" << "Not display state" << endl; + os << endl << "\t" << "LAN configuration:" << endl + << "\t" << "----------------------" << endl << endl + << "\t" << "Refresh global state in number of generations: " << setup.refresh_global_state() << endl; + + if (setup.synchronized()) + os << "\t" << "Running in synchronous mode" << endl; + else + os << "\t" << "Running in asynchronous mode" << endl; + + if (!setup.cooperation()) + os << "\t" << "Running without cooperation" << endl << endl; + else + os << "\t" << "Running with cooperation in " << setup.cooperation() << " iterations. " << endl << endl; + + os << endl << endl << "END CONFIGURATION -------------------------------------------" << endl << endl; + return os; + } + + const unsigned int SetUpParams::independent_runs() const + { + return _independent_runs; + } + + const unsigned long SetUpParams::max_evaluations() const + { + return _max_evaluations; + } + + const unsigned int SetUpParams::MarkovChain_length() const + { + return _MarkovChain_length; + } + + const double SetUpParams::temperature_decay() const + { + return _temperature_decay; + } + + const bool SetUpParams::display_state() const + { + return _display_state; + } + + const unsigned long SetUpParams::refresh_global_state() const + { + return _refresh_global_state; + } + + const bool SetUpParams::synchronized() const + { + return _synchronized; + } + + const unsigned int SetUpParams::cooperation() const + { + return _cooperation; + } + + void SetUpParams::independent_runs(const unsigned int val) + { + _independent_runs = val; + } + + void SetUpParams::max_evaluations(const unsigned long val) + { + _max_evaluations= val; + } + void SetUpParams::MarkovChain_length(const unsigned int val) + { + _MarkovChain_length= val; + } + void SetUpParams::temperature_decay(const double val) + { + _temperature_decay= val; + } + + void SetUpParams::display_state(const bool val) + { + _display_state=val; + } + + void SetUpParams::refresh_global_state(const unsigned long val) + { + _refresh_global_state=val; + } + + void SetUpParams::synchronized(const bool val) + { + _synchronized=val; + } + + void SetUpParams::cooperation(const unsigned int val) + { + _cooperation=val; + } + + SetUpParams::~SetUpParams() + {} + +// Statistics ------------------------------------------------------ + + Statistics::Statistics() + {} + + ostream& operator<< (ostream& os, const Statistics& stats) + { + int j; + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF CURRENT TRIAL " << endl; + os << "------------------------------------------------------------------" << endl; + for (int i=0;i< stats.stats_data.size();i++) + { + os << endl + << " Evaluations: " << stats.stats_data[i].nb_evaluations + << " Best: " << stats.stats_data[i].best_cost + << " Current: " << stats.stats_data[i].current_cost; + } + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + Statistics& Statistics::operator= (const Statistics& stats) + { + stats_data = stats.stats_data; + return *this; + } + + void Statistics::update(const Solver& solver) + { + /* struct stat *new_stat; + if ((new_stat=(struct stat *)malloc(sizeof(struct stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluations= solver.current_iteration(); + new_stat->best_cost = solver.current_best_cost(); + new_stat->current_cost = solver.current_cost(); + stats_data.append(*new_stat); */ + } + + Statistics::~Statistics() + { + stats_data.remove(); + } + + void Statistics::clear() + { + stats_data.remove(); + } + +// Solver (superclass)--------------------------------------------------- + + Solver::Solver (const Problem& pbm, const SetUpParams& setup) + : problem(pbm), + params(setup), + _stat(), + _userstat(), + _sc(), + _direction(pbm.direction()), + current(pbm), + tentative(pbm), + currentTemperature(0.0), + time_spent_in_trial(0.0), + total_time_spent(0.0), + start_trial(0.0), + start_global(0.0), + _current_trial("_current_trial",_sc), + _current_iteration("_current_iteration",_sc), + _current_best_solution("_current_best_solution",_sc), + _current_best_cost("_current_best_cost",_sc), + _current_solution("_current_solution",_sc), + _current_cost("_current_cost",_sc), + _current_time_spent("_current_time_spent",_sc), + _initial_temperature_trial("_initial_temperature_trial",_sc), + _time_best_found_trial("_time_best_found_trial",_sc), + _iteration_best_found_trial("_iteration_best_found_trial",_sc), + _temperature_best_found_trial("_temperature_best_found_trial",_sc), + _time_spent_trial("_time_spent_trial",_sc), + _trial_best_found("_trial_best_found",_sc), + _iteration_best_found("_iteration_best_found;",_sc), + _global_best_solution("_global_best_solution",_sc), + _global_best_cost("_global_best_cost",_sc), + _time_best_found("_time_best_found",_sc), + _temperature("_temperature",_sc), + _display_state("_display_state",_sc) + { + current_trial(0); + current_iteration(0); + current_best_solution(current), + current_best_cost((-1) * pbm.direction() * infinity()); + current_solution(current); + current_cost((-1) * pbm.direction() * infinity()); + current_time_spent(total_time_spent); + initial_temperature_trial(0); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(0); + temperature_best_found_trial(0.0); + time_spent_trial(time_spent_in_trial); + trial_best_found(0); + iteration_best_found(0); + global_best_solution(current); + global_best_cost((-1) * pbm.direction() * infinity()); + time_best_found(total_time_spent); + temperature(currentTemperature); + display_state(setup.display_state()); + + move = new DefaultMove; + } + + int Solver::pid() const + { + return 0; + } + + bool Solver::end_trial() const + { + return _end_trial; + } + + unsigned int Solver::current_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_trial",(char *)&value, nitems, length); + return value; + } + + unsigned long Solver::current_iteration() const + { + unsigned long value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_iteration",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_best_solution() const + { + Solution sol(problem); + unsigned long nitems,length; + char data_stored[_current_best_solution.get_nitems() + _current_best_solution.get_length()]; + _sc.get_contents_state_variable("_current_best_solution", data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::current_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_best_cost",(char *)&value, nitems, length); + return value; + } + + double Solver::current_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_cost",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_solution() const + { + Solution sol(problem); + char data_stored[_current_solution.get_nitems() + _current_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_solution",data_stored, nitems, length); + sol.to_Solution((char *)data_stored); + return sol; + } + + float Solver::current_time_spent() const + { + float value=0.0; + unsigned long nitems,length; + _current_time_spent.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::initial_temperature_trial() const + { + double value=0.0; + unsigned long nitems,length; + _initial_temperature_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature_best_found_trial() const + { + double value=0.0; + unsigned long nitems,length; + _temperature_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_spent_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_spent_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::trial_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _trial_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::global_best_solution() const + { + Solution sol(problem); + char data_stored[_global_best_solution.get_nitems() + _global_best_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_solution",data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::global_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_cost",(char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_temperature",(char *)&value, nitems, length); + return value; + } + + int Solver::display_state() const + { + int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_display_state",(char *)&value, nitems, length); + return value; + } + + void Solver::current_trial(const unsigned int value) + { + _sc.set_contents_state_variable("_current_trial",(char *)&value,1,sizeof(int)); + } + + void Solver::current_iteration(const unsigned long value) + { + _sc.set_contents_state_variable("_current_iteration",(char *)&value,1,sizeof(long)); + } + + void Solver::current_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_best_cost(const double value) + { + _sc.set_contents_state_variable("_current_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_cost(const double value) + { + _sc.set_contents_state_variable("_current_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_time_spent(const float value) + { + _current_time_spent.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::time_best_found_trial(const float value) + { + _time_best_found_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::iteration_best_found_trial(const unsigned int value) + { + _iteration_best_found_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::initial_temperature_trial(const double value) + { + _initial_temperature_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::temperature_best_found_trial(const double value) + { + _temperature_best_found_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::time_spent_trial(const float value) + { + _time_spent_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::trial_best_found(const unsigned int value) + { + _trial_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::iteration_best_found(const unsigned int value) + { + _iteration_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::global_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_global_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::global_best_cost(const double value) + { + _sc.set_contents_state_variable("_global_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::time_best_found(const float value) + { + _time_best_found.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::temperature(const double value) + { + _sc.set_contents_state_variable("_temperature",(char *)&value,1,sizeof(double)); + } + + void Solver::display_state(const int value) + { + _sc.set_contents_state_variable("_display_state",(char *)&value,1,sizeof(int)); + } + + const Statistics& Solver::statistics() const + { + return _stat; + } + + const UserStatistics& Solver::userstatistics() const + { + return _userstat; + } + + const SetUpParams& Solver::setup() const + { + return params; + } + + const Problem& Solver::pbm() const + { + return problem; + } + + void Solver::KeepHistory(const Solution& sol, const double curfit,const float time_spent_in_trial,const float total_time_spent) + { + bool betterG=false; + bool betterT=false; + + switch (_direction) + { + case minimize: betterG = (curfit < global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit < current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + case maximize: betterG = (curfit > global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit > current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + } + + if (betterT) + { + current_best_solution(sol); + current_best_cost(curfit); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(current_iteration()); + temperature_best_found_trial(temperature()); + if (betterG) + { + trial_best_found(current_trial()); + iteration_best_found(current_iteration()); + global_best_solution(sol); + global_best_cost(curfit); + time_best_found(time_spent_in_trial); + } + } + } + + double Solver::UpdateT(double temp, int K) + { + //return temp * params.temperature_decay(); // initial + + /* + if(K == 1) return temp/log(2); + else return temp * log(K) / log(K+1); + */ + /* + if(K == 1) return temp/2; + else return (temp * K) / (K + 1); + */ + + if(K == 1) return temp / exp(2); + else return (temp * exp(K)) / exp(K+1); + + } + + StateCenter* Solver::GetState() + { + return &_sc; + } + + void Solver::RefreshState() + { + current_solution(current); + current_cost(curfit); + current_time_spent(total_time_spent); + time_spent_trial(time_spent_in_trial); + temperature(currentTemperature); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::UpdateFromState() + { + current = current_solution(); + curfit = current_cost(); + total_time_spent=current_time_spent(); + time_spent_in_trial=time_spent_trial(); + currentTemperature = temperature(); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::show_state() const + { + cout << endl << "Current trial: " << current_trial(); + cout << endl << "Current iteration: " << current_iteration(); + cout << endl << "Current Temperature: " << temperature (); + cout << endl << "Current cost: " << current_cost(); + cout << endl << "Best cost in trial: " << current_best_cost(); + cout << endl << "Time of best solution found in trial: " << time_best_found_trial(); + cout << endl << "Iteration of best solution found in trial: " << iteration_best_found_trial(); + cout << endl << "Initial temperature in trial: " << initial_temperature_trial(); + cout << endl << "Temperature of best solution found in trial: " << temperature_best_found_trial(); + cout << endl << "Time spent in trial: " << time_spent_trial(); + cout << endl << "Global best cost: " << global_best_cost(); + cout << endl << "Trial of best global solution found: " << trial_best_found(); + cout << endl << "Iteration of best global solution found: " << iteration_best_found(); + cout << endl << "Time of global best solution found: " << time_best_found(); + // cout << endl << "Current solution: " << current_solution(); + // cout << endl << "Best solution of trial: " << current_best_solution(); + // cout << endl << "Global solution: " << global_best_solution() << endl; + cout << endl << endl << "Current time spent (so far): " << current_time_spent() << endl; + } + + Solver::~Solver() + { + _sc.removeAll(); + delete move; + } + + bool Solver::AcceptQ (double tent, double cur, double temperature) + { + if (_direction==minimize) + + return (tent < cur) || + ((rand01()*(1+exp((tent-cur)/temperature)))<2.0); + + else + + return (tent > cur) || + ((rand01()*(1+exp((cur-tent)/temperature)))<2.0); + } + + double Solver::Set_Initial_Temperature(const Problem& pbm) + { + const double beta = 1.05; + const double test = 10; + const double acrat = .8; + const double T = 1.0; + + Solution current (pbm); + Solution newsol (pbm); + double ac; + double fit; + double temperature = T; + + do + { + temperature *= beta; + ac = 0; + current.initialize(); + fit = current.fitness(); + for (int i=0; i<test; i++) + { + newsol = current; + move->Apply(newsol); + if (AcceptQ(newsol.fitness(),fit,temperature)) + ac += 1.0/test; + } + } while (ac < acrat); + + initial_temperature_trial(temperature); + return temperature; + + } + + void Solver::SetMove (Move* mov) + { + delete move; + move = mov; + } + + // Solver sequencial ----------------------------------------------------- + + Solver_Seq::Solver_Seq (const Problem& pbm, const SetUpParams& setup) + : Solver(pbm,setup) + { + random_seed(time(0)); + _end_trial=true; + } + + Solver_Seq::~Solver_Seq () + {} + + void Solver_Seq::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Seq::StartUp(const Solution& sol, const double initialTemperature) + { + start_trial=_used_time(); + start_global=total_time_spent; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current = sol; + curfit = current.fitness(); + current_best_cost((-1) * problem.direction() * infinity()); + currentTemperature = initialTemperature; + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + void Solver_Seq::DoStep() + { + current_iteration(current_iteration()+1); + + tentative = current; + move->Apply(tentative); + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + + void Solver_Seq::run (unsigned long int max_evaluations) + { + StartUp(); + + while (current_iteration()<max_evaluations && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + // Solver LAN ----------------------------------------------------------- + + Solver_Lan::Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); + } + + Solver_Lan::~Solver_Lan () + { + NetStream::finalize(); + } + + int Solver_Lan::pid() const + { + return mypid; + } + + NetStream& Solver_Lan::netstream() + { + return _netstream; + } + + void Solver_Lan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Lan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + void update(Direction direction, Solution &solution_received,double cost_received, Solution &solution_to_send, double &best_cost) + { + switch (direction) + { + case minimize: if (cost_received < best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + case maximize: if (cost_received > best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + } + } + + int Solver_Lan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Lan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Lan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Lan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Lan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Lan::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + void Solver_Lan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } + + // Solver WAN ------------------------------------------------------------ + + Solver_Wan::Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); + } + + Solver_Wan::~Solver_Wan () + { + NetStream::finalize(); + } + + int Solver_Wan::pid() const + { + return mypid; + } + + NetStream& Solver_Wan::netstream() + { + return _netstream; + } + + void Solver_Wan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Wan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + int Solver_Wan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Wan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Wan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Wan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Wan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Wan::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + void Solver_Wan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } +}; + diff --git a/ProyectoFinal/CHC/malva/rep/SA/onemax/SA.req.cc b/ProyectoFinal/CHC/malva/rep/SA/onemax/SA.req.cc new file mode 100644 index 0000000000000000000000000000000000000000..a327cb306d729022f5bb8908ec9d8932cb288f90 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/onemax/SA.req.cc @@ -0,0 +1,286 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** User-required classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** Tab size = 4 *** +*** *** +*** *** +************************************************/ + +#include <iostream.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "StopCondition.hh" + +skeleton SA { + + // Problem --------------------------------------------------------------- + + Problem::Problem ():_dimension(0) + {} + + ostream& operator<< (ostream& os, const Problem& pbm) + { + os << endl << endl << "Number of Variables " << pbm._dimension + << endl; + return os; + } + + istream& operator>> (istream& is, Problem& pbm) + { + char buffer[MAX_BUFFER]; + int i; + + is.getline(buffer,MAX_BUFFER,'\n'); + sscanf(buffer,"%d",&pbm._dimension); + + return is; + } + + bool Problem::operator== (const Problem& pbm) const + { + if (_dimension!=pbm.dimension()) return false; + return true; + } + + bool Problem::operator!= (const Problem& pbm) const + { + return !(*this == pbm); + } + + Direction Problem::direction() const + { + return maximize; + //return minimize; + } + + int Problem::dimension() const + { + return _dimension; + } + + double Problem::infinity() const + { + double one=1.0; + double zero=0.0; + return 0.0 - one/zero; + } + + Problem::~Problem() + { + } + + // Solution -------------------------------------------------------------- + + Solution::Solution (const Problem& pbm):_pbm(pbm),_var(pbm.dimension()) + {} + + const Problem& Solution::pbm() const + { + return _pbm; + } + + Solution::Solution(const Solution& sol):_pbm(sol.pbm()) + { + *this=sol; + } + + istream& operator>> (istream& is, Solution& sol) + { + for (int i=0;i<sol.pbm().dimension();i++) + is >> sol._var[i]; + return is; + } + + ostream& operator<< (ostream& os, const Solution& sol) + { + for (int i=0;i<sol.pbm().dimension();i++) + os << " " << sol._var[i]; + return os; + } + + NetStream& operator << (NetStream& ns, const Solution& sol) + { + for (int i=0;i<sol._var.size();i++) + ns << sol._var[i]; + return ns; + } + + NetStream& operator >> (NetStream& ns, Solution& sol) + { + for (int i=0;i<sol._var.size();i++) + ns >> sol._var[i]; + return ns; + } + + Solution& Solution::operator= (const Solution &sol) + { + _var=sol._var; + return *this; + } + + bool Solution::operator== (const Solution& sol) const + { + if (sol.pbm() != _pbm) return false; + return true; + } + + bool Solution::operator!= (const Solution& sol) const + { + return !(*this == sol); + } + + void Solution::initialize() + { + for (int i=0;i<_pbm.dimension();i++) + _var[i]=rand_int(0,1); + } + + double Solution::fitness () const + { + double fitness = 0.0; + + for (int i=0;i<_var.size();i++) + fitness += _var[i]; + + return fitness; + } + + char *Solution::to_String() const + { + return (char *)_var.get_first(); + } + + void Solution::to_Solution(char *_string_) + { + int *ptr=(int *)_string_; + for (int i=0;i<_pbm.dimension();i++) + { + _var[i]=*ptr; + ptr++; + } + } + + unsigned int Solution::size() const + { + return (_pbm.dimension() * sizeof(int)); + } + + + int& Solution::var(const int index) + { + return _var[index]; + } + + + Rarray<int>& Solution::array_var() + { + return _var; + } + + Solution::~Solution() + {} + +// UserStatistics ------------------------------------------------------- + + UserStatistics::UserStatistics () + {} + + ostream& operator<< (ostream& os, const UserStatistics& userstat) + { + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF TRIALS " << endl; + os << "------------------------------------------------------------------" << endl; + + for (int i=0;i< userstat.result_trials.size();i++) + { + os << endl + << "\t" << userstat.result_trials[i].trial + << "\t" << userstat.result_trials[i].best_cost_trial + << "\t\t" << userstat.result_trials[i].nb_evaluation_best_found_trial + << "\t\t" << userstat.result_trials[i].initial_temperature + << "\t\t" << userstat.result_trials[i].temperature_best_found_trial + << "\t\t" << userstat.result_trials[i].time_best_found_trial + << "\t\t" << userstat.result_trials[i].time_spent_trial; + } + + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + + UserStatistics& UserStatistics::operator= (const UserStatistics& userstats) + { + result_trials=userstats.result_trials; + return (*this); + } + + + void UserStatistics::update(const Solver& solver) + { + if ((solver.pid()!=0) || (solver.end_trial()!=true) + || ((solver.current_iteration()!=solver.setup().max_evaluations()) + && !TerminateQ(solver.pbm(),solver,solver.setup()))) + return; + + struct user_stat *new_stat; + if ((new_stat=(struct user_stat *)malloc(sizeof(struct user_stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluation_best_found_trial= solver.iteration_best_found_trial(); + new_stat->initial_temperature=solver.initial_temperature_trial(); + new_stat->temperature_best_found_trial=solver.temperature_best_found_trial(); + new_stat->best_cost_trial = solver.current_best_cost(); + new_stat->time_best_found_trial= solver.time_best_found_trial(); + new_stat->time_spent_trial = solver.time_spent_trial(); + result_trials.append(*new_stat); + } + + void UserStatistics::clear() + { + result_trials.remove(); + } + + UserStatistics::~UserStatistics() + { + result_trials.remove(); + } + +// DefaultMove ------------------------------------------------------- + + + DefaultMove::DefaultMove() + {} + + DefaultMove::~DefaultMove() + {} + + void DefaultMove::Apply (Solution& sol) const + { + const float probability = 0.03; + + for (int i=0;i<sol.pbm().dimension();i++) + { + if (rand01()<=probability) + { + if (sol.var(i)==1) sol.var(i)=0; + else sol.var(i)=1; + } + } + } + + //------------------------------------------------------------------------ + // Specific methods ------------------------------------------------------ + //------------------------------------------------------------------------ + + bool TerminateQ (const Problem& pbm, const Solver& solver, + const SetUpParams& setup) + { + + StopCondition_3 stop; + return stop.EvaluateCondition(pbm,solver,setup); + } +} + + diff --git a/ProyectoFinal/CHC/malva/rep/SA/onemax/StopCondition.cc b/ProyectoFinal/CHC/malva/rep/SA/onemax/StopCondition.cc new file mode 100644 index 0000000000000000000000000000000000000000..f9cfd89b1a6f5292633566664a6caa78815ea279 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/onemax/StopCondition.cc @@ -0,0 +1,52 @@ +#include "StopCondition.hh" +skeleton SA +{ + +// StopCondition ------------------------------------------------------------------------------------- + + StopCondition::StopCondition() + {} + + StopCondition::~StopCondition() + {} + +// StopCondition_1 ------------------------------------------------------------------------------------- + + StopCondition_1::StopCondition_1():StopCondition() + {} + + bool StopCondition_1::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return false; + } + + StopCondition_1::~StopCondition_1() + {} + +// StopCondition_2 ------------------------------------------------------------------------------------- + + StopCondition_2::StopCondition_2():StopCondition() + {} + + bool StopCondition_2::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return (solver.global_best_cost()>8.5); + } + + StopCondition_2::~StopCondition_2() + {} + +// StopCondition_3 ------------------------------------------------------------------------------------- + + StopCondition_3::StopCondition_3():StopCondition() + {} + + bool StopCondition_3::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return ((int)solver.current_best_cost() == pbm.dimension()); + } + + StopCondition_3::~StopCondition_3() + {} + +} diff --git a/ProyectoFinal/CHC/malva/rep/SA/onemax/StopCondition.hh b/ProyectoFinal/CHC/malva/rep/SA/onemax/StopCondition.hh new file mode 100644 index 0000000000000000000000000000000000000000..04ef770d9cac5bb9ef69aae7d085e3ae2166e187 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/onemax/StopCondition.hh @@ -0,0 +1,41 @@ +#ifndef stop_condition +#define stop_condition + +#include "SA.hh" +skeleton SA +{ + + provides class StopCondition + { + public: + StopCondition(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup)=0; + ~StopCondition(); + }; + + requires class StopCondition_1 : public StopCondition + { + public: + StopCondition_1(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_1(); + }; + + requires class StopCondition_2 : public StopCondition + { + public: + StopCondition_2(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_2(); + }; + + requires class StopCondition_3 : public StopCondition + { + public: + StopCondition_3(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_3(); + }; +} + +#endif diff --git a/ProyectoFinal/CHC/malva/rep/SA/onemax/pgfileLan b/ProyectoFinal/CHC/malva/rep/SA/onemax/pgfileLan new file mode 100644 index 0000000000000000000000000000000000000000..fa76afbfbf07aa7bda8b6c94d3c79b850b22342e --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/onemax/pgfileLan @@ -0,0 +1,5 @@ +localhost 0 ~/Mallba/rep/SA/onemax/MainLan +localhost 1 ~/Mallba/rep/SA/onemax/MainLan +localhost 1 ~/Mallba/rep/SA/onemax/MainLan +localhost 1 ~/Mallba/rep/SA/onemax/MainLan +localhost 1 ~/Mallba/rep/SA/onemax/MainLan diff --git a/ProyectoFinal/CHC/malva/rep/SA/pgfileLan b/ProyectoFinal/CHC/malva/rep/SA/pgfileLan new file mode 100644 index 0000000000000000000000000000000000000000..2c73753f745ee91a25a367aeaaeae00da9237c76 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/pgfileLan @@ -0,0 +1 @@ +machine_name number_of_process executable_path login diff --git a/ProyectoFinal/CHC/malva/rep/SA/pgfileWan b/ProyectoFinal/CHC/malva/rep/SA/pgfileWan new file mode 100644 index 0000000000000000000000000000000000000000..2c73753f745ee91a25a367aeaaeae00da9237c76 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/pgfileWan @@ -0,0 +1 @@ +machine_name number_of_process executable_path login diff --git a/ProyectoFinal/CHC/malva/rep/SA/rnd/Config.cfg b/ProyectoFinal/CHC/malva/rep/SA/rnd/Config.cfg new file mode 100644 index 0000000000000000000000000000000000000000..c8bac1a1bf02c9abdb8c509e47f01d8f5848f1e0 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/rnd/Config.cfg @@ -0,0 +1,3 @@ +SA.cfg +../../../ProblemInstances/RND-instances/rnd149.txt +res/rnd149.sa.lan.txt diff --git a/ProyectoFinal/CHC/malva/rep/SA/rnd/MainLan.cc b/ProyectoFinal/CHC/malva/rep/SA/rnd/MainLan.cc new file mode 100644 index 0000000000000000000000000000000000000000..8949422e10f93211d953aba1308c203d13f30f0a --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/rnd/MainLan.cc @@ -0,0 +1,53 @@ +#include "SA.hh" +#include <iostream.h> +#include <fstream.h> + +int main (int argc, char** argv) +{ + using skeleton SA; + char path[MAX_BUFFER]; + int len; + int longitud; + + system("clear"); + + get_path(argv[0],path); + len = strlen(path); + longitud = MAX_BUFFER - len; + + strcat(path,"Config.cfg"); + ifstream f(path); + if(!f) show_message(10); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f1(path); + if(!f1) show_message(11); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f2(path); + if(!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + SetUpParams cfg; + f1 >> cfg; + + + Solver_Lan solver(pbm,cfg,argc,argv); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solucion: " << solver.global_best_solution() << " Fitness: " << solver.global_best_solution().fitness(); + + f.getline(&(path[len]),longitud,'\n'); + ofstream fexit(path); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + cout << endl << endl << " :( ---------------------- THE END --------------- :) " << endl; + } + return(0); +} diff --git a/ProyectoFinal/CHC/malva/rep/SA/rnd/MainSeq.cc b/ProyectoFinal/CHC/malva/rep/SA/rnd/MainSeq.cc new file mode 100644 index 0000000000000000000000000000000000000000..41d8a720793c0d10b14e1d5dfa05b7f11e9c4dda --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/rnd/MainSeq.cc @@ -0,0 +1,42 @@ +#include "SA.hh" +#include <iostream.h> +#include <fstream.h> + +int main (int argc, char** argv) +{ + using skeleton SA; + + system("clear"); + + if(argc < 4) + show_message(1); + + ifstream f1(argv[1]); + if (!f1) show_message(11); + + ifstream f2(argv[2]); + if (!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + SetUpParams cfg; + f1 >> cfg; + + Solver_Seq solver(pbm,cfg); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << solver.global_best_solution() + << " Fitness: " << solver.global_best_solution().fitness() << endl; + cout << "\n\n :( ---------------------- THE END --------------- :) "; + + ofstream fexit(argv[3]); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + } + return(0); +} diff --git a/ProyectoFinal/CHC/malva/rep/SA/rnd/Makefile b/ProyectoFinal/CHC/malva/rep/SA/rnd/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..b15a6cd5f40fff6ee58229521da579010270af89 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/rnd/Makefile @@ -0,0 +1,22 @@ +include ../../../environment + +all: MainSeq MainLan + +clean: + rm -f MainLan MainSeq MainWan *.o *% *~ + +MainLan: SA.req.o SA.pro.o StopCondition.o MainLan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainWan: SA.req.o SA.pro.o StopCondition.o MainWan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainSeq: SA.req.o SA.pro.o StopCondition.o MainSeq.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +LAN: + $(RUN) -v -p4pg pgfileLan MainLan +WAN: + $(RUN) -v -p4pg pgfileWan MainWan +SEQ: + ./MainSeq SA.cfg ../../../ProblemInstances/RND-instances/rnd149.txt res/rnd149.sa.seq.txt diff --git a/ProyectoFinal/CHC/malva/rep/SA/rnd/SA.cfg b/ProyectoFinal/CHC/malva/rep/SA/rnd/SA.cfg new file mode 100644 index 0000000000000000000000000000000000000000..1dbac85cb0d3cf28e87175c640e6f9d53e5988f5 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/rnd/SA.cfg @@ -0,0 +1,9 @@ +10 // number of independent runs +5000 // number of evaluations +50 // Markov-Chain Length +.99 // temperature Decay +1 // display state ? +LAN-configuration +10 // the global state is updated in this number of evaluations +0 // 0: asynchronized mode // 1: synchronized mode +10 // interval of iterations to cooperate ( if 0 no cooperation) diff --git a/ProyectoFinal/CHC/malva/rep/SA/rnd/SA.hh b/ProyectoFinal/CHC/malva/rep/SA/rnd/SA.hh new file mode 100644 index 0000000000000000000000000000000000000000..6238f6de1290020e2dc587e829e825e0e7edb4ae --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/rnd/SA.hh @@ -0,0 +1,488 @@ +#ifndef INC_SA +#define INC_SA + +#include "Mallba/mallba.hh" +#include "Mallba/States.hh" +#include "Mallba/Rarray.h" +#include "Mallba/time.hh" +#include "Mallba/netstream.hh" +#include <math.h> +#include <string.h> + +skeleton SA +{ + + provides class SetUpParams; + provides class Statistics; + provides class Move; + provides class StopCondition; + provides class Solver; + provides class Solver_Seq; + provides class Solver_Lan; + provides class Solver_Wan; + + requires class Problem; + requires class Solution; + requires class StopCondition_1; + requires class StopCondition_2; + requires class StopCondition_3; + requires class DefaultMove; + requires class UserStatistics; + requires bool TerminateQ (const Problem& pbm, const Solver& solver, const SetUpParams& setup); + +// Problem ---------------------------------------------------------------------------- + + requires class Problem + { + public: + Problem (); + ~Problem (); + + friend ostream& operator<< (ostream& os, const Problem& pbm); + friend istream& operator>> (istream& is, Problem& pbm); + + Problem& operator= (const Problem& pbm); + bool operator== (const Problem& pbm) const; + bool operator!= (const Problem& pbm) const; + + Direction direction () const; + + int dimension() const; + double infinity() const; + + private: + + int _dimension; + }; + +//Solution ---------------------------------------------------------------------------- + + requires class Solution + { + public: + Solution (const Problem& pbm); + Solution (const Solution& sol); + ~Solution(); + + friend ostream& operator<< (ostream& os, const Solution& sol); + friend istream& operator>> (istream& is, Solution& sol); + friend NetStream& operator << (NetStream& ns, const Solution& sol); + friend NetStream& operator >> (NetStream& ns, Solution& sol); + + const Problem& pbm() const; + + Solution& operator= (const Solution& sol); + bool operator== (const Solution& sol) const; + bool operator!= (const Solution& sol) const; + + char *to_String() const; + void to_Solution(char *_vertex_); + unsigned int size() const; + + void initialize(); + double fitness () const; + + int& var(const int index); + Rarray<int>& array_var(); + + private: + Rarray<int> _var; + const Problem& _pbm; + }; + +// UserStatistics ---------------------------------------------------------------------------- + + requires class UserStatistics + { + private: + struct user_stat + { + unsigned int trial; + double initial_temperature; + double temperature_best_found_trial; + unsigned long nb_evaluation_best_found_trial; + double best_cost_trial; + float time_best_found_trial; + float time_spent_trial; + }; + + Rlist<struct user_stat> result_trials; + + public: + UserStatistics (); + ~UserStatistics(); + + friend ostream& operator<< (ostream& os, const UserStatistics& usertats); + + UserStatistics& operator= (const UserStatistics& userstats); + void update(const Solver& solver); + void clear(); + }; + +// Move ---------------------------------------------------------------------------------- + + provides class Move + { + public: + Move() {} + virtual ~Move() {} + + virtual void Apply(Solution& sol) const = 0; + }; + +// DefaultMove ---------------------------------------------------------------------------------- + + requires class DefaultMove: public Move + { + public: + DefaultMove(); + ~DefaultMove(); + + void Apply(Solution& sol) const; + }; + +// SetUpParams ------------------------------------------------------------------------------- + + provides class SetUpParams + { + private: + unsigned int _independent_runs; + unsigned long _max_evaluations; + unsigned int _MarkovChain_length; + double _temperature_decay; + bool _display_state; + + // for LAN execution configuration + unsigned long _refresh_global_state; + bool _synchronized; + unsigned int _cooperation; + + public: + SetUpParams (); + + friend ostream& operator<< (ostream& os, const SetUpParams& setup); + friend istream& operator>> (istream& is, SetUpParams& setup); + + const unsigned int independent_runs() const; + const unsigned long max_evaluations() const; + const unsigned int MarkovChain_length() const; + const double temperature_decay() const; + const bool display_state() const; + const unsigned long refresh_global_state() const; + const bool synchronized() const; + const unsigned int cooperation() const; + + void independent_runs(const unsigned int val); + void max_evaluations(const unsigned long val); + void MarkovChain_length(const unsigned int val); + void temperature_decay(const double val); + void display_state(const bool val); + void refresh_global_state(const unsigned long val); + void synchronized(const bool val); + void cooperation(const unsigned int val); + + ~SetUpParams(); + }; + +// Statistics --------------------------------------------------------------------------------- + + provides class Statistics + { + private: + struct stat + { + unsigned int trial; + unsigned long nb_evaluations; + double best_cost; + double current_cost; + }; + + Rlist<struct stat> stats_data; + + public: + Statistics(); + + friend ostream& operator<< (ostream& os, const Statistics& stats); + + Statistics& operator= (const Statistics& stats); + void update(const Solver& solver); + void clear(); + + ~Statistics(); + }; + +// Solver --------------------------------------------------------------------------------- + + provides class Solver + { + protected: + const Problem& problem; + const SetUpParams& params; + UserStatistics _userstat; + Statistics _stat; + Move* move; + Solution current; + double curfit; + Solution tentative; + double currentTemperature; + unsigned int k; // to control temperature update. + StateCenter _sc; + + float total_time_spent; + float time_spent_in_trial; + float start_trial; + float start_global; + + bool _end_trial; + + State_Vble _current_trial; + State_Vble _current_iteration; + State_Vble _current_best_solution; + State_Vble _current_best_cost; + State_Vble _current_solution; + State_Vble _current_cost; + + State_Vble _current_time_spent; + State_Vble _initial_temperature_trial; + State_Vble _time_best_found_trial; + State_Vble _iteration_best_found_trial; + State_Vble _temperature_best_found_trial; + State_Vble _time_spent_trial; + + State_Vble _trial_best_found; + State_Vble _iteration_best_found; + State_Vble _global_best_solution; + State_Vble _global_best_cost; + State_Vble _time_best_found; + + State_Vble _temperature; + State_Vble _display_state; + + const Direction _direction; + + bool AcceptQ(double tent, double cur, double temperature); + double Set_Initial_Temperature(const Problem& pbm); + void KeepHistory(const Solution& sol, const double curfit,const float time_spent_trial,const float total_time_spent); + + double UpdateT(double temp, int K); + + public: + // Constructor - Destructor ------------------------- + + Solver (const Problem& pbm, const SetUpParams& setup); + virtual ~Solver (); + virtual int pid() const; + bool end_trial() const; + + // Execution methods -------------------------------- + + // Full execution + virtual void run () =0; + virtual void run (unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol, unsigned long int nb_evaluations) =0; + + virtual void run (const double initialTemperature) =0; + virtual void run (const Solution& sol,const double initialTemperature) =0; + virtual void run (const double initialTemperature, unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations) =0; + + // Partial execution + virtual void StartUp () =0; + virtual void StartUp (const Solution& sol) =0; + virtual void StartUp (const double initialTemperature) =0; + virtual void StartUp (const Solution& sol, const double initialTemperature) =0; + virtual void DoStep () =0; + + // Statistics handling ------------------------------ + + const Statistics& statistics() const; + const UserStatistics& userstatistics () const; + const SetUpParams& setup() const; + const Problem& pbm() const; + + // State handling ----------------------------------- + + void RefreshState(); + void UpdateFromState(); + StateCenter* GetState(); + + unsigned int current_trial() const; + unsigned long current_iteration() const; + Solution current_best_solution() const; + Solution current_solution() const; + double current_best_cost() const; + double current_cost() const; + float current_time_spent() const; + float time_best_found_trial() const; + double initial_temperature_trial() const; + unsigned int iteration_best_found_trial() const; + double temperature_best_found_trial() const; + float time_spent_trial() const; + unsigned int trial_best_found() const; + unsigned int iteration_best_found() const; + Solution global_best_solution() const; + double global_best_cost() const; + float time_best_found() const; + double temperature() const; + int display_state() const; + + void current_trial(const unsigned int value); + void current_iteration(const unsigned long value); + void current_best_solution(const Solution& sol); + void current_best_cost(const double value); + void current_solution(const Solution& sol); + void current_cost(const double value); + void current_time_spent(const float value); + void time_best_found_trial(const float value); + void initial_temperature_trial(const double temperature); + void iteration_best_found_trial(const unsigned int value); + void temperature_best_found_trial(const double value); + void time_spent_trial(const float value); + void trial_best_found(const unsigned int value); + void iteration_best_found(const unsigned int value); + void global_best_solution(const Solution& sol); + void global_best_cost(const double value); + void time_best_found(const float value); + void temperature(const double value); + void display_state(const int value); + void show_state() const; + + // State handling ----------------------------------- + void SetMove(Move* mov); + }; + + provides class Solver_Seq: public Solver + { + public: + // Constructor - Destructor ------------------------- + + Solver_Seq ( const Problem& pbm, const SetUpParams& setup); + virtual ~Solver_Seq (); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + }; + + provides class Solver_Lan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + + public: + Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Lan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + + provides class Solver_Wan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + + public: + Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Wan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + +}; + +#endif diff --git a/ProyectoFinal/CHC/malva/rep/SA/rnd/SA.pro.cc b/ProyectoFinal/CHC/malva/rep/SA/rnd/SA.pro.cc new file mode 100644 index 0000000000000000000000000000000000000000..43dcaf9ebda2aa5738f2982cb5f6441259ce44f5 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/rnd/SA.pro.cc @@ -0,0 +1,1807 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** Provided classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** *** +************************************************/ + +#include <iostream.h> +#include <math.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "Mallba/time.hh" + +skeleton SA +{ + +// SetUpParams ----------------------------------------------------------- + + SetUpParams::SetUpParams (): + _independent_runs(0), + _max_evaluations(0), + _MarkovChain_length(0), + _temperature_decay(0), + _refresh_global_state(0), + _synchronized(0), + _display_state(0), + _cooperation(0) + {} + + istream& operator>> (istream& is, SetUpParams& setup) + { + char buffer[MAX_BUFFER]; // current line in the setup file + char command[50]; + int op; + double dop; + short int nb_param=0; + short int nb_section=0; + short int nb_LAN_param=0; + + while (is.getline(buffer,MAX_BUFFER,'\n')) + { + sscanf(buffer," %s ",command); + + if (!(strcmp(command,"General"))) nb_section=0; + if (!(strcmp(command,"LAN-configuration"))) nb_section=1; + + if (nb_param==3 && nb_section==0) + { + dop=-1; + sscanf(buffer," %lf ",&dop); + if (dop<0) continue; + } + else + { + op=-1; + sscanf(buffer," %ld%*s ",&op); + if (op<0) continue; + } + + switch (nb_section) + { + case 0: switch (nb_param) + { + case 0: setup.independent_runs(op); break; + case 1: setup.max_evaluations(op); break; + case 2: setup.MarkovChain_length(op); break; + case 3: setup.temperature_decay(dop); break; + case 4: setup.display_state(op); break; + } + nb_param++; + break; + case 1: if (nb_LAN_param>=3) break; + if (nb_LAN_param==0) setup.refresh_global_state(op); + if (nb_LAN_param==1) setup.synchronized(op); + if (nb_LAN_param==2) setup.cooperation(op); + nb_LAN_param++; + break; + } // end switch + } // end while + return is; + } + + ostream& operator<< (ostream& os, const SetUpParams& setup) + { + os << "CONFIGURATION -------------------------------------------" << endl << endl; + os << "\t" << "Independent runs : " << setup.independent_runs() << endl + << "\t" << "Evaluation steps: " << setup.max_evaluations() << endl + << "\t" << "Markov-Chain Length: " << setup.MarkovChain_length() << endl + << "\t" << "Temperature Decay: " << setup.temperature_decay() << endl; + + if (setup.display_state()) + os << "\t" << "Display state" << endl; + else + os << "\t" << "Not display state" << endl; + os << endl << "\t" << "LAN configuration:" << endl + << "\t" << "----------------------" << endl << endl + << "\t" << "Refresh global state in number of generations: " << setup.refresh_global_state() << endl; + + if (setup.synchronized()) + os << "\t" << "Running in synchronous mode" << endl; + else + os << "\t" << "Running in asynchronous mode" << endl; + + if (!setup.cooperation()) + os << "\t" << "Running without cooperation" << endl << endl; + else + os << "\t" << "Running with cooperation in " << setup.cooperation() << " iterations. " << endl << endl; + + os << endl << endl << "END CONFIGURATION -------------------------------------------" << endl << endl; + return os; + } + + const unsigned int SetUpParams::independent_runs() const + { + return _independent_runs; + } + + const unsigned long SetUpParams::max_evaluations() const + { + return _max_evaluations; + } + + const unsigned int SetUpParams::MarkovChain_length() const + { + return _MarkovChain_length; + } + + const double SetUpParams::temperature_decay() const + { + return _temperature_decay; + } + + const bool SetUpParams::display_state() const + { + return _display_state; + } + + const unsigned long SetUpParams::refresh_global_state() const + { + return _refresh_global_state; + } + + const bool SetUpParams::synchronized() const + { + return _synchronized; + } + + const unsigned int SetUpParams::cooperation() const + { + return _cooperation; + } + + void SetUpParams::independent_runs(const unsigned int val) + { + _independent_runs = val; + } + + void SetUpParams::max_evaluations(const unsigned long val) + { + _max_evaluations= val; + } + void SetUpParams::MarkovChain_length(const unsigned int val) + { + _MarkovChain_length= val; + } + void SetUpParams::temperature_decay(const double val) + { + _temperature_decay= val; + } + + void SetUpParams::display_state(const bool val) + { + _display_state=val; + } + + void SetUpParams::refresh_global_state(const unsigned long val) + { + _refresh_global_state=val; + } + + void SetUpParams::synchronized(const bool val) + { + _synchronized=val; + } + + void SetUpParams::cooperation(const unsigned int val) + { + _cooperation=val; + } + + SetUpParams::~SetUpParams() + {} + +// Statistics ------------------------------------------------------ + + Statistics::Statistics() + {} + + ostream& operator<< (ostream& os, const Statistics& stats) + { + int j; + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF CURRENT TRIAL " << endl; + os << "------------------------------------------------------------------" << endl; + for (int i=0;i< stats.stats_data.size();i++) + { + os << endl + << " Evaluations: " << stats.stats_data[i].nb_evaluations + << " Best: " << stats.stats_data[i].best_cost + << " Current: " << stats.stats_data[i].current_cost; + } + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + Statistics& Statistics::operator= (const Statistics& stats) + { + stats_data = stats.stats_data; + return *this; + } + + void Statistics::update(const Solver& solver) + { + /* struct stat *new_stat; + if ((new_stat=(struct stat *)malloc(sizeof(struct stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluations= solver.current_iteration(); + new_stat->best_cost = solver.current_best_cost(); + new_stat->current_cost = solver.current_cost(); + stats_data.append(*new_stat); */ + } + + Statistics::~Statistics() + { + stats_data.remove(); + } + + void Statistics::clear() + { + stats_data.remove(); + } + +// Solver (superclass)--------------------------------------------------- + + Solver::Solver (const Problem& pbm, const SetUpParams& setup) + : problem(pbm), + params(setup), + _stat(), + _userstat(), + _sc(), + _direction(pbm.direction()), + current(pbm), + tentative(pbm), + currentTemperature(0.0), + time_spent_in_trial(0.0), + total_time_spent(0.0), + start_trial(0.0), + start_global(0.0), + _current_trial("_current_trial",_sc), + _current_iteration("_current_iteration",_sc), + _current_best_solution("_current_best_solution",_sc), + _current_best_cost("_current_best_cost",_sc), + _current_solution("_current_solution",_sc), + _current_cost("_current_cost",_sc), + _current_time_spent("_current_time_spent",_sc), + _initial_temperature_trial("_initial_temperature_trial",_sc), + _time_best_found_trial("_time_best_found_trial",_sc), + _iteration_best_found_trial("_iteration_best_found_trial",_sc), + _temperature_best_found_trial("_temperature_best_found_trial",_sc), + _time_spent_trial("_time_spent_trial",_sc), + _trial_best_found("_trial_best_found",_sc), + _iteration_best_found("_iteration_best_found;",_sc), + _global_best_solution("_global_best_solution",_sc), + _global_best_cost("_global_best_cost",_sc), + _time_best_found("_time_best_found",_sc), + _temperature("_temperature",_sc), + _display_state("_display_state",_sc) + { + current_trial(0); + current_iteration(0); + current_best_solution(current), + current_best_cost((-1) * pbm.direction() * infinity()); + current_solution(current); + current_cost((-1) * pbm.direction() * infinity()); + current_time_spent(total_time_spent); + initial_temperature_trial(0); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(0); + temperature_best_found_trial(0.0); + time_spent_trial(time_spent_in_trial); + trial_best_found(0); + iteration_best_found(0); + global_best_solution(current); + global_best_cost((-1) * pbm.direction() * infinity()); + time_best_found(total_time_spent); + temperature(currentTemperature); + display_state(setup.display_state()); + + move = new DefaultMove; + } + + int Solver::pid() const + { + return 0; + } + + bool Solver::end_trial() const + { + return _end_trial; + } + + unsigned int Solver::current_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_trial",(char *)&value, nitems, length); + return value; + } + + unsigned long Solver::current_iteration() const + { + unsigned long value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_iteration",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_best_solution() const + { + Solution sol(problem); + unsigned long nitems,length; + char data_stored[_current_best_solution.get_nitems() + _current_best_solution.get_length()]; + _sc.get_contents_state_variable("_current_best_solution", data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::current_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_best_cost",(char *)&value, nitems, length); + return value; + } + + double Solver::current_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_cost",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_solution() const + { + Solution sol(problem); + char data_stored[_current_solution.get_nitems() + _current_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_solution",data_stored, nitems, length); + sol.to_Solution((char *)data_stored); + return sol; + } + + float Solver::current_time_spent() const + { + float value=0.0; + unsigned long nitems,length; + _current_time_spent.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::initial_temperature_trial() const + { + double value=0.0; + unsigned long nitems,length; + _initial_temperature_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature_best_found_trial() const + { + double value=0.0; + unsigned long nitems,length; + _temperature_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_spent_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_spent_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::trial_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _trial_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::global_best_solution() const + { + Solution sol(problem); + char data_stored[_global_best_solution.get_nitems() + _global_best_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_solution",data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::global_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_cost",(char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_temperature",(char *)&value, nitems, length); + return value; + } + + int Solver::display_state() const + { + int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_display_state",(char *)&value, nitems, length); + return value; + } + + void Solver::current_trial(const unsigned int value) + { + _sc.set_contents_state_variable("_current_trial",(char *)&value,1,sizeof(int)); + } + + void Solver::current_iteration(const unsigned long value) + { + _sc.set_contents_state_variable("_current_iteration",(char *)&value,1,sizeof(long)); + } + + void Solver::current_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_best_cost(const double value) + { + _sc.set_contents_state_variable("_current_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_cost(const double value) + { + _sc.set_contents_state_variable("_current_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_time_spent(const float value) + { + _current_time_spent.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::time_best_found_trial(const float value) + { + _time_best_found_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::iteration_best_found_trial(const unsigned int value) + { + _iteration_best_found_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::initial_temperature_trial(const double value) + { + _initial_temperature_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::temperature_best_found_trial(const double value) + { + _temperature_best_found_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::time_spent_trial(const float value) + { + _time_spent_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::trial_best_found(const unsigned int value) + { + _trial_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::iteration_best_found(const unsigned int value) + { + _iteration_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::global_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_global_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::global_best_cost(const double value) + { + _sc.set_contents_state_variable("_global_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::time_best_found(const float value) + { + _time_best_found.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::temperature(const double value) + { + _sc.set_contents_state_variable("_temperature",(char *)&value,1,sizeof(double)); + } + + void Solver::display_state(const int value) + { + _sc.set_contents_state_variable("_display_state",(char *)&value,1,sizeof(int)); + } + + const Statistics& Solver::statistics() const + { + return _stat; + } + + const UserStatistics& Solver::userstatistics() const + { + return _userstat; + } + + const SetUpParams& Solver::setup() const + { + return params; + } + + const Problem& Solver::pbm() const + { + return problem; + } + + void Solver::KeepHistory(const Solution& sol, const double curfit,const float time_spent_in_trial,const float total_time_spent) + { + bool betterG=false; + bool betterT=false; + + switch (_direction) + { + case minimize: betterG = (curfit < global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit < current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + case maximize: betterG = (curfit > global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit > current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + } + + if (betterT) + { + current_best_solution(sol); + current_best_cost(curfit); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(current_iteration()); + temperature_best_found_trial(temperature()); + if (betterG) + { + trial_best_found(current_trial()); + iteration_best_found(current_iteration()); + global_best_solution(sol); + global_best_cost(curfit); + time_best_found(time_spent_in_trial); + } + } + } + + double Solver::UpdateT(double temp, int K) + { + //return temp * params.temperature_decay(); // initial + + /* + if(K == 1) return temp/log(2); + else return temp * log(K) / log(K+1); + */ + /* + if(K == 1) return temp/2; + else return (temp * K) / (K + 1); + */ + + if(K == 1) return temp / exp(2); + else return (temp * exp(K)) / exp(K+1); + + } + + StateCenter* Solver::GetState() + { + return &_sc; + } + + void Solver::RefreshState() + { + current_solution(current); + current_cost(curfit); + current_time_spent(total_time_spent); + time_spent_trial(time_spent_in_trial); + temperature(currentTemperature); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::UpdateFromState() + { + current = current_solution(); + curfit = current_cost(); + total_time_spent=current_time_spent(); + time_spent_in_trial=time_spent_trial(); + currentTemperature = temperature(); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::show_state() const + { + cout << endl << "Current trial: " << current_trial(); + cout << endl << "Current iteration: " << current_iteration(); + cout << endl << "Current Temperature: " << temperature (); + cout << endl << "Current cost: " << current_cost(); + cout << endl << "Best cost in trial: " << current_best_cost(); + cout << endl << "Time of best solution found in trial: " << time_best_found_trial(); + cout << endl << "Iteration of best solution found in trial: " << iteration_best_found_trial(); + cout << endl << "Initial temperature in trial: " << initial_temperature_trial(); + cout << endl << "Temperature of best solution found in trial: " << temperature_best_found_trial(); + cout << endl << "Time spent in trial: " << time_spent_trial(); + cout << endl << "Global best cost: " << global_best_cost(); + cout << endl << "Trial of best global solution found: " << trial_best_found(); + cout << endl << "Iteration of best global solution found: " << iteration_best_found(); + cout << endl << "Time of global best solution found: " << time_best_found(); + // cout << endl << "Current solution: " << current_solution(); + // cout << endl << "Best solution of trial: " << current_best_solution(); + // cout << endl << "Global solution: " << global_best_solution() << endl; + cout << endl << endl << "Current time spent (so far): " << current_time_spent() << endl; + } + + Solver::~Solver() + { + _sc.removeAll(); + delete move; + } + + bool Solver::AcceptQ (double tent, double cur, double temperature) + { + if (_direction==minimize) + + return (tent < cur) || + ((rand01()*(1+exp((tent-cur)/temperature)))<2.0); + + else + + return (tent > cur) || + ((rand01()*(1+exp((cur-tent)/temperature)))<2.0); + } + + double Solver::Set_Initial_Temperature(const Problem& pbm) + { + const double beta = 1.05; + const double test = 10; + const double acrat = .8; + const double T = 1.0; + + Solution current (pbm); + Solution newsol (pbm); + double ac; + double fit; + double temperature = T; + + do + { + temperature *= beta; + ac = 0; + current.initialize(); + fit = current.fitness(); + for (int i=0; i<test; i++) + { + newsol = current; + move->Apply(newsol); + if (AcceptQ(newsol.fitness(),fit,temperature)) + ac += 1.0/test; + } + } while (ac < acrat); + + initial_temperature_trial(temperature); + return temperature; + + } + + void Solver::SetMove (Move* mov) + { + delete move; + move = mov; + } + + // Solver sequencial ----------------------------------------------------- + + Solver_Seq::Solver_Seq (const Problem& pbm, const SetUpParams& setup) + : Solver(pbm,setup) + { + random_seed(time(0)); + _end_trial=true; + } + + Solver_Seq::~Solver_Seq () + {} + + void Solver_Seq::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Seq::StartUp(const Solution& sol, const double initialTemperature) + { + start_trial=_used_time(); + start_global=total_time_spent; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current = sol; + curfit = current.fitness(); + current_best_cost((-1) * problem.direction() * infinity()); + currentTemperature = initialTemperature; + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + void Solver_Seq::DoStep() + { + current_iteration(current_iteration()+1); + + tentative = current; + move->Apply(tentative); + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + + void Solver_Seq::run (unsigned long int max_evaluations) + { + StartUp(); + + while (current_iteration()<max_evaluations && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + // Solver LAN ----------------------------------------------------------- + + Solver_Lan::Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); + } + + Solver_Lan::~Solver_Lan () + { + NetStream::finalize(); + } + + int Solver_Lan::pid() const + { + return mypid; + } + + NetStream& Solver_Lan::netstream() + { + return _netstream; + } + + void Solver_Lan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Lan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + void update(Direction direction, Solution &solution_received,double cost_received, Solution &solution_to_send, double &best_cost) + { + switch (direction) + { + case minimize: if (cost_received < best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + case maximize: if (cost_received > best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + } + } + + int Solver_Lan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Lan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Lan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Lan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Lan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Lan::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + void Solver_Lan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } + + // Solver WAN ------------------------------------------------------------ + + Solver_Wan::Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); + } + + Solver_Wan::~Solver_Wan () + { + NetStream::finalize(); + } + + int Solver_Wan::pid() const + { + return mypid; + } + + NetStream& Solver_Wan::netstream() + { + return _netstream; + } + + void Solver_Wan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Wan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + int Solver_Wan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Wan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Wan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Wan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Wan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Wan::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + void Solver_Wan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } +}; + diff --git a/ProyectoFinal/CHC/malva/rep/SA/rnd/SA.req.cc b/ProyectoFinal/CHC/malva/rep/SA/rnd/SA.req.cc new file mode 100644 index 0000000000000000000000000000000000000000..1702a43465ebe97fa3160f868220d72a0b5d96c8 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/rnd/SA.req.cc @@ -0,0 +1,385 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** User-required classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** Tab size = 4 *** +*** *** +*** *** +************************************************/ + +#include <iostream.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "StopCondition.hh" + +//Parámetros para RND ------------------------------------------------------------- + +#define GRID_SIZE_X 287 //Artificial grid horizontal size. +#define GRID_SIZE_Y 287 //Artificial grid vertical size. +#define GRID_SIZE 82369 //Total grid size. +#define TRANS_NUMB 59 //Number of transmiters used. +#define TRANS_TOTAL 349 //Number of total transmiters. + //49 transmiters distributed regulary... + //... the rest is distributed randomly. + +#define RANGE 20 //Transmiter cover range (square area) + +//------------------------------------------------------------------------------------------------------- +#define TARGET_FITNESS 204.08 //Fitness to be achieved in current trial +//------------------------------------------------------------------------------------------------------- + + +#define MAX_FIT 204.08 //Fitness for optimum solution. +#define AVG_B -4.878 //Coef. for linear penalty of fitness value ... +#define AVG_A 4.878 // ... depending on avg. and dev. overlapping. +#define DEV_B 0.0 +#define DEV_A 2.404 + +//--------------------------------------------------------------------------------- + +skeleton SA { + + + + + //Array ------------------------------------------------------------------ + + static short int trans_location[TRANS_TOTAL*2]= + {20,20, 61,20, 102,20, 143,20, 184,20, 225,20, 266,20, + 20,61, 61,61, 102,61, 143,61, 184,61, 225,61, 266,61, + 20,102, 61,102, 102,102, 143,102, 184,102, 225,102, 266,102, + 20,143, 61,143, 102,143, 143,143, 184,143, 225,143, 266,143, + 20,184, 61,184, 102,184, 143,184, 184,184, 225,184, 266,184, + 20,225, 61,225, 102,225, 143,225, 184,225, 225,225, 266,225, + 20,266, 61,266, 102,266, 143,266, 184,266, 225,266, 266,266, + + 169,180, 180,161, 160,233, 57,156, 158,145, 138,151, 160,32, + 165,36, 228,111, 251,181, 110,130, 286,19, 96,183, 91,133, + 88,74, 93,56, 35,273, 152,198, 142,181, 37,117, 271,193, + 49,109, 104,119, 110,54, 58,160, 135,204, 220,172, 4,141, + 160,244, 210,14, 36,37, 98,3, 134,226, 197,109, 101,17, + 112,230, 169,126, 215,44, 206,27, 18,90, 14,272, 40,134, + 160,150, 58,216, 170,37, 252,185, 246,142, 154,247, 180,128, + 188,55, 207,201, 134,15, 31,111, 166,34, 206,116, 223,261, + 94,48, 227,179, 24,250, 46,26, 159,245, 279,56, 235,43, + 195,166, 165,241, 203,9, 190,73, 20,91, 25,200, 211,255, + 260,199, 262,66, 283,120, 16,76, 38,112, 201,172, 144,1, + 273,282, 230,285, 222,240, 70,132, 240,40, 202,147, 35,175, + 24,41, 4,120, 88,114, 23,104, 274,142, 83,230, 281,265, + 248,58, 140,42, 136,185, 17,2, 9,42, 156,115, 216,32, + 242,104, 221,224, +241,113,224,229,261,56,96,220,79,158,137,180,104,147,273,262,182,205,40,174, +4,69,39,230,44,115,37,31,286,62,147,240,175,84,182,150,141,279,83,221, +151,220,114,255,81,101,231,263,20,272,150,24,55,190,255,100,18,5,131,18, +68,278,258,244,76,154,107,218,147,191,152,11,125,267,267,206,81,211,183,101, +197,47,126,252,237,94,65,256,100,197,274,168,188,246,126,265,114,233,196,261, +138,61,272,264,42,252,183,123,177,80,225,88,128,64,53,79,159,119,48,260, +29,36,142,218,282,268,196,109,215,105,84,66,167,70,43,210,36,227,47,213, +21,272,15,149,50,68,228,210,188,277,183,218,26,38,149,22,20,58,132,235, +164,216,14,45,286,58,255,36,286,15,249,20,1,264,170,51,46,112,262,235, +103,158,166,129,197,28,152,217,87,284,165,251,214,180,10,214,239,265,250,238, +281,213,259,282,191,142,47,238,255,22,186,71,180,65,201,90,94,66,21,181, +64,186,146,278,80,156,206,32,135,170,271,129,96,243,124,0,98,171,239,67, +193,138,138,87,204,52,178,11,118,199,193,183,99,52,174,179,209,94,212,58, +264,196,187,73,152,25,74,251,196,26,31,103,165,170,191,82,222,82,94,54, +282,1,237,95,54,125,275,263,219,200,34,196,110,222,270,262,247,58,227,157, +85,259,261,250,142,165,46,78,248,141,133,243,142,83,51,196,208,39,173,141, +240,207,51,63,143,34,39,103,93,267,260,178,240,234,142,96,113,189,174,74, +43,20,30,185,104,82,95,26,122,268,167,76,189,218,139,45,253,179,148,59, +160,122,238,113,70,93,209,183,282,97,257,39,117,1,224,222,84,32,248,206, +14,128,283,203,60,136,248,26,28,109,86,188,232,37,14,15,131,224,198,127}; + //Transmiters location array + + static short int grid[GRID_SIZE]; + + // Problem --------------------------------------------------------------- + + Problem::Problem ():_dimension(0) + {} + + ostream& operator<< (ostream& os, const Problem& pbm) + { + os << endl << endl << "Number of Variables " << pbm._dimension + << endl; + return os; + } + + istream& operator>> (istream& is, Problem& pbm) + { + char buffer[MAX_BUFFER]; + int i; + + is.getline(buffer,MAX_BUFFER,'\n'); + sscanf(buffer,"%d",&pbm._dimension); + + return is; + } + + Problem& Problem::operator= (const Problem& pbm) + { + return *this; + } + + bool Problem::operator== (const Problem& pbm) const + { + if (_dimension!=pbm.dimension()) return false; + return true; + } + + bool Problem::operator!= (const Problem& pbm) const + { + return !(*this == pbm); + } + + Direction Problem::direction() const + { + return maximize; + //return minimize; + } + + int Problem::dimension() const + { + return _dimension; + } + + Problem::~Problem() + {} + + // Solution -------------------------------------------------------------- + + Solution::Solution (const Problem& pbm):_pbm(pbm),_var(pbm.dimension()) + {} + + const Problem& Solution::pbm() const + { + return _pbm; + } + + Solution::Solution(const Solution& sol):_pbm(sol.pbm()) + { + *this=sol; + } + + istream& operator>> (istream& is, Solution& sol) + { + for (int i=0;i<sol.pbm().dimension();i++) + is >> sol._var[i]; + return is; + } + + ostream& operator<< (ostream& os, const Solution& sol) + { + for (int i=0;i<sol.pbm().dimension();i++) + os << " " << sol._var[i]; + return os; + } + + NetStream& operator << (NetStream& ns, const Solution& sol) + { + for (int i=0;i<sol._var.size();i++) + ns << sol._var[i]; + return ns; + } + + NetStream& operator >> (NetStream& ns, Solution& sol) + { + for (int i=0;i<sol._var.size();i++) + ns >> sol._var[i]; + return ns; + } + + Solution& Solution::operator= (const Solution &sol) + { + _var=sol._var; + return *this; + } + + bool Solution::operator== (const Solution& sol) const + { + if (sol.pbm() != _pbm) return false; + return true; + } + + bool Solution::operator!= (const Solution& sol) const + { + return !(*this == sol); + } + + void Solution::initialize() + { + for (int i=0;i<_pbm.dimension();i++) + _var[i]=rand_int(0,1); + } + + double Solution::fitness () const + { + register int x,y,x1,y1,k; + double covered_points=0.0, cover_rate=0.0, fitness=0.0,alfa=2.0; + int used_trans; + + for (k=0;k<GRID_SIZE;k++) // Initializing the grid + grid[k]=0; + + + used_trans=0; // Updating covered points in the grid according ... + for (k=0;k<_var.size();k++) // with transmiter locations and calculating ... + { // covered points. + if (_var[k]!=0.0) + { + used_trans++; + x=trans_location[k*2]; + y=trans_location[k*2+1]; + for (x1=x-RANGE;x1<=x+RANGE;x1++) + for (y1=y-RANGE;y1<=y+RANGE;y1++) + if ((x1>=0)&(y1>=0)&(x1<GRID_SIZE_X)&(y1<GRID_SIZE_Y)) + { + grid[x1*GRID_SIZE_X+y1]++; + if (grid[x1*GRID_SIZE_X+y1]==1) covered_points++; + } + } + } + + cover_rate =(double) (100.0 * covered_points) / (GRID_SIZE); + fitness = (cover_rate * cover_rate )/used_trans; + + return fitness; + } + + char *Solution::to_String() const + { + return (char *)_var.get_first(); + } + + void Solution::to_Solution(char *_string_) + { + int *ptr=(int *)_string_; + for (int i=0;i<_pbm.dimension();i++) + { + _var[i]=*ptr; + ptr++; + } + } + + unsigned int Solution::size() const + { + return (_pbm.dimension() * sizeof(int)); + } + + + int& Solution::var(const int index) + { + return _var[index]; + } + + + Rarray<int>& Solution::array_var() + { + return _var; + } + + Solution::~Solution() + {} + +// UserStatistics ------------------------------------------------------- + + UserStatistics::UserStatistics () + {} + + ostream& operator<< (ostream& os, const UserStatistics& userstat) + { + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF TRIALS " << endl; + os << "------------------------------------------------------------------" << endl; + + for (int i=0;i< userstat.result_trials.size();i++) + { + os << endl + << "\t" << userstat.result_trials[i].trial + << "\t" << userstat.result_trials[i].best_cost_trial + << "\t\t" << userstat.result_trials[i].nb_evaluation_best_found_trial + << "\t\t" << userstat.result_trials[i].initial_temperature + << "\t\t" << userstat.result_trials[i].temperature_best_found_trial + << "\t\t" << userstat.result_trials[i].time_best_found_trial + << "\t\t" << userstat.result_trials[i].time_spent_trial; + } + + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + + UserStatistics& UserStatistics::operator= (const UserStatistics& userstats) + { + result_trials=userstats.result_trials; + return (*this); + } + + + void UserStatistics::update(const Solver& solver) + { + if ((solver.pid()!=0) || (solver.end_trial()!=true) + || ((solver.current_iteration()!=solver.setup().max_evaluations()) + && !TerminateQ(solver.pbm(),solver,solver.setup()))) + return; + + struct user_stat *new_stat; + if ((new_stat=(struct user_stat *)malloc(sizeof(struct user_stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluation_best_found_trial= solver.iteration_best_found_trial(); + new_stat->initial_temperature=solver.initial_temperature_trial(); + new_stat->temperature_best_found_trial=solver.temperature_best_found_trial(); + new_stat->best_cost_trial = solver.current_best_cost(); + new_stat->time_best_found_trial= solver.time_best_found_trial(); + new_stat->time_spent_trial = solver.time_spent_trial(); + result_trials.append(*new_stat); + } + + void UserStatistics::clear() + { + result_trials.remove(); + } + + UserStatistics::~UserStatistics() + { + result_trials.remove(); + } + +// DefaultMove ------------------------------------------------------- + + + DefaultMove::DefaultMove() + {} + + DefaultMove::~DefaultMove() + {} + + void DefaultMove::Apply (Solution& sol) const + { + const float probability = 0.03; + + for (int i=0;i<sol.pbm().dimension();i++) + { + if (rand01()<=probability) + { + if (sol.var(i)==1) sol.var(i)=0; + else sol.var(i)=1; + } + } + } + + //------------------------------------------------------------------------ + // Specific methods ------------------------------------------------------ + //------------------------------------------------------------------------ + + bool TerminateQ (const Problem& pbm, const Solver& solver, + const SetUpParams& setup) + { + + StopCondition_3 stop; + return stop.EvaluateCondition(pbm,solver,setup); + } +} + + diff --git a/ProyectoFinal/CHC/malva/rep/SA/rnd/StopCondition.cc b/ProyectoFinal/CHC/malva/rep/SA/rnd/StopCondition.cc new file mode 100644 index 0000000000000000000000000000000000000000..f9cfd89b1a6f5292633566664a6caa78815ea279 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/rnd/StopCondition.cc @@ -0,0 +1,52 @@ +#include "StopCondition.hh" +skeleton SA +{ + +// StopCondition ------------------------------------------------------------------------------------- + + StopCondition::StopCondition() + {} + + StopCondition::~StopCondition() + {} + +// StopCondition_1 ------------------------------------------------------------------------------------- + + StopCondition_1::StopCondition_1():StopCondition() + {} + + bool StopCondition_1::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return false; + } + + StopCondition_1::~StopCondition_1() + {} + +// StopCondition_2 ------------------------------------------------------------------------------------- + + StopCondition_2::StopCondition_2():StopCondition() + {} + + bool StopCondition_2::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return (solver.global_best_cost()>8.5); + } + + StopCondition_2::~StopCondition_2() + {} + +// StopCondition_3 ------------------------------------------------------------------------------------- + + StopCondition_3::StopCondition_3():StopCondition() + {} + + bool StopCondition_3::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return ((int)solver.current_best_cost() == pbm.dimension()); + } + + StopCondition_3::~StopCondition_3() + {} + +} diff --git a/ProyectoFinal/CHC/malva/rep/SA/rnd/StopCondition.hh b/ProyectoFinal/CHC/malva/rep/SA/rnd/StopCondition.hh new file mode 100644 index 0000000000000000000000000000000000000000..04ef770d9cac5bb9ef69aae7d085e3ae2166e187 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/rnd/StopCondition.hh @@ -0,0 +1,41 @@ +#ifndef stop_condition +#define stop_condition + +#include "SA.hh" +skeleton SA +{ + + provides class StopCondition + { + public: + StopCondition(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup)=0; + ~StopCondition(); + }; + + requires class StopCondition_1 : public StopCondition + { + public: + StopCondition_1(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_1(); + }; + + requires class StopCondition_2 : public StopCondition + { + public: + StopCondition_2(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_2(); + }; + + requires class StopCondition_3 : public StopCondition + { + public: + StopCondition_3(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_3(); + }; +} + +#endif diff --git a/ProyectoFinal/CHC/malva/rep/SA/rnd/pgfileLan b/ProyectoFinal/CHC/malva/rep/SA/rnd/pgfileLan new file mode 100644 index 0000000000000000000000000000000000000000..d85e66e2fa7c529318184a2a5c96bfaeae7541d7 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/rnd/pgfileLan @@ -0,0 +1,5 @@ +localhost 0 ~/Mallba/rep/SA/rnd/MainLan +localhost 1 ~/Mallba/rep/SA/rnd/MainLan +localhost 1 ~/Mallba/rep/SA/rnd/MainLan +localhost 1 ~/Mallba/rep/SA/rnd/MainLan +localhost 1 ~/Mallba/rep/SA/rnd/MainLan diff --git a/ProyectoFinal/CHC/malva/rep/SA/vrp/Config.cfg b/ProyectoFinal/CHC/malva/rep/SA/vrp/Config.cfg new file mode 100644 index 0000000000000000000000000000000000000000..510e26da3a108155d6e73d191716818c909969eb --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/vrp/Config.cfg @@ -0,0 +1,3 @@ +SA.cfg +../../../ProblemInstances/VRP-instances/vrpnc1.txt +res/vrp1.sa.lan.txt diff --git a/ProyectoFinal/CHC/malva/rep/SA/vrp/MainLan.cc b/ProyectoFinal/CHC/malva/rep/SA/vrp/MainLan.cc new file mode 100644 index 0000000000000000000000000000000000000000..8949422e10f93211d953aba1308c203d13f30f0a --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/vrp/MainLan.cc @@ -0,0 +1,53 @@ +#include "SA.hh" +#include <iostream.h> +#include <fstream.h> + +int main (int argc, char** argv) +{ + using skeleton SA; + char path[MAX_BUFFER]; + int len; + int longitud; + + system("clear"); + + get_path(argv[0],path); + len = strlen(path); + longitud = MAX_BUFFER - len; + + strcat(path,"Config.cfg"); + ifstream f(path); + if(!f) show_message(10); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f1(path); + if(!f1) show_message(11); + + f.getline(&(path[len]),longitud,'\n'); + ifstream f2(path); + if(!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + SetUpParams cfg; + f1 >> cfg; + + + Solver_Lan solver(pbm,cfg,argc,argv); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << "Solucion: " << solver.global_best_solution() << " Fitness: " << solver.global_best_solution().fitness(); + + f.getline(&(path[len]),longitud,'\n'); + ofstream fexit(path); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + cout << endl << endl << " :( ---------------------- THE END --------------- :) " << endl; + } + return(0); +} diff --git a/ProyectoFinal/CHC/malva/rep/SA/vrp/MainSeq.cc b/ProyectoFinal/CHC/malva/rep/SA/vrp/MainSeq.cc new file mode 100644 index 0000000000000000000000000000000000000000..41d8a720793c0d10b14e1d5dfa05b7f11e9c4dda --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/vrp/MainSeq.cc @@ -0,0 +1,42 @@ +#include "SA.hh" +#include <iostream.h> +#include <fstream.h> + +int main (int argc, char** argv) +{ + using skeleton SA; + + system("clear"); + + if(argc < 4) + show_message(1); + + ifstream f1(argv[1]); + if (!f1) show_message(11); + + ifstream f2(argv[2]); + if (!f2) show_message(12); + + Problem pbm; + f2 >> pbm; + + SetUpParams cfg; + f1 >> cfg; + + Solver_Seq solver(pbm,cfg); + solver.run(); + + if (solver.pid()==0) + { + solver.show_state(); + cout << solver.global_best_solution() + << " Fitness: " << solver.global_best_solution().fitness() << endl; + cout << "\n\n :( ---------------------- THE END --------------- :) "; + + ofstream fexit(argv[3]); + if(!fexit) show_message(13); + fexit << solver.userstatistics(); + + } + return(0); +} diff --git a/ProyectoFinal/CHC/malva/rep/SA/vrp/Makefile b/ProyectoFinal/CHC/malva/rep/SA/vrp/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..cb3ba14e21ee15fc02d05ce6aebc08d3d68d7c50 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/vrp/Makefile @@ -0,0 +1,22 @@ +include ../../../environment + +all: MainSeq MainLan + +clean: + rm -f MainLan MainSeq MainWan *.o *% *~ + +MainLan: SA.req.o SA.pro.o StopCondition.o MainLan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainWan: SA.req.o SA.pro.o StopCondition.o MainWan.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +MainSeq: SA.req.o SA.pro.o StopCondition.o MainSeq.o + $(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(CPPFLAGS) -o $@ + +LAN: + $(RUN) -v -p4pg pgfileLan MainLan +WAN: + $(RUN) -v -p4pg pgfileWan MainWan +SEQ: + ./MainSeq SA.cfg ../../../ProblemInstances/VRP-instances/vrpnc1.txt res/vrp1.sa.seq.txt diff --git a/ProyectoFinal/CHC/malva/rep/SA/vrp/SA.cfg b/ProyectoFinal/CHC/malva/rep/SA/vrp/SA.cfg new file mode 100644 index 0000000000000000000000000000000000000000..eed67390e35f1f52eb2aa2b46bb6394ac80ed143 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/vrp/SA.cfg @@ -0,0 +1,9 @@ +10 // number of independent runs +1000 // number of evaluations +10 // Markov-Chain Length +.99 // temperature Decay +1 // display state ? +LAN-configuration +1001 // the global state is updated in this number of evaluations +0 // 0: asynchronized mode // 1: synchronized mode +10 // interval of iterations to cooperate ( if 0 no cooperation) diff --git a/ProyectoFinal/CHC/malva/rep/SA/vrp/SA.hh b/ProyectoFinal/CHC/malva/rep/SA/vrp/SA.hh new file mode 100644 index 0000000000000000000000000000000000000000..845bb53b54a0727cf7524ab217729f766a8fe577 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/vrp/SA.hh @@ -0,0 +1,499 @@ +#ifndef INC_SA +#define INC_SA + +#include "Mallba/mallba.hh" +#include "Mallba/States.hh" +#include "Mallba/Rarray.h" +#include "Mallba/time.hh" +#include "Mallba/netstream.hh" +#include <math.h> +#include <string.h> + +skeleton SA +{ + + provides class SetUpParams; + provides class Statistics; + provides class Move; + provides class StopCondition; + provides class Solver; + provides class Solver_Seq; + provides class Solver_Lan; + provides class Solver_Wan; + + requires class Problem; + requires class Solution; + requires class StopCondition_1; + requires class StopCondition_2; + requires class StopCondition_3; + requires class DefaultMove; + requires class UserStatistics; + requires bool TerminateQ (const Problem& pbm, const Solver& solver, const SetUpParams& setup); + +// Problem ---------------------------------------------------------------------------- + + requires class Problem + { + public: + Problem (); + ~Problem (); + + friend ostream& operator<< (ostream& os, const Problem& pbm); + friend istream& operator>> (istream& is, Problem& pbm); + + Problem& operator= (const Problem& pbm); + bool operator== (const Problem& pbm) const; + bool operator!= (const Problem& pbm) const; + + Direction direction () const; + + int nCustomers() const; + int capacity() const; + double maxRouteTime() const; + double bestCost() const; + double distance(const int i, const int j) const; + int demand(const int i) const; + int service_time() const; + + private: + void genDistances(int *x,int *y); + + int _nCustomers; + int _capacity; + double **_distance; + int _service_time; + double _maxRouteTime; + double _bestCost; + int *_demand; + }; + +//Solution ---------------------------------------------------------------------------- + + requires class Solution + { + public: + Solution (const Problem& pbm); + Solution (const Solution& sol); + ~Solution(); + + friend ostream& operator<< (ostream& os, const Solution& sol); + friend istream& operator>> (istream& is, Solution& sol); + friend NetStream& operator << (NetStream& ns, const Solution& sol); + friend NetStream& operator >> (NetStream& ns, Solution& sol); + + const Problem& pbm() const; + + Solution& operator= (const Solution& sol); + bool operator== (const Solution& sol) const; + bool operator!= (const Solution& sol) const; + + char *to_String() const; + void to_Solution(char *_vertex_); + unsigned int size() const; + + void initialize(); + double fitness () const; + + int & pos(const int index); + Rarray<int> & routes(); + void print(); + + private: + Rarray<int> _routes; + const Problem& _pbm; + }; + +// UserStatistics ---------------------------------------------------------------------------- + + requires class UserStatistics + { + private: + struct user_stat + { + unsigned int trial; + double initial_temperature; + double temperature_best_found_trial; + unsigned long nb_evaluation_best_found_trial; + double best_cost_trial; + float time_best_found_trial; + float time_spent_trial; + }; + + Rlist<struct user_stat> result_trials; + + public: + UserStatistics (); + ~UserStatistics(); + + friend ostream& operator<< (ostream& os, const UserStatistics& usertats); + + UserStatistics& operator= (const UserStatistics& userstats); + void update(const Solver& solver); + void clear(); + }; + +// Move ---------------------------------------------------------------------------------- + + provides class Move + { + public: + Move() {} + virtual ~Move() {} + + virtual void Apply(Solution& sol) const = 0; + }; + +// DefaultMove ---------------------------------------------------------------------------------- + + requires class DefaultMove: public Move + { + public: + DefaultMove(); + ~DefaultMove(); + + void Apply(Solution& sol) const; + }; + +// SetUpParams ------------------------------------------------------------------------------- + + provides class SetUpParams + { + private: + unsigned int _independent_runs; + unsigned long _max_evaluations; + unsigned int _MarkovChain_length; + double _temperature_decay; + bool _display_state; + + // for LAN execution configuration + unsigned long _refresh_global_state; + bool _synchronized; + unsigned int _cooperation; + + public: + SetUpParams (); + + friend ostream& operator<< (ostream& os, const SetUpParams& setup); + friend istream& operator>> (istream& is, SetUpParams& setup); + + const unsigned int independent_runs() const; + const unsigned long max_evaluations() const; + const unsigned int MarkovChain_length() const; + const double temperature_decay() const; + const bool display_state() const; + const unsigned long refresh_global_state() const; + const bool synchronized() const; + const unsigned int cooperation() const; + + void independent_runs(const unsigned int val); + void max_evaluations(const unsigned long val); + void MarkovChain_length(const unsigned int val); + void temperature_decay(const double val); + void display_state(const bool val); + void refresh_global_state(const unsigned long val); + void synchronized(const bool val); + void cooperation(const unsigned int val); + + ~SetUpParams(); + }; + +// Statistics --------------------------------------------------------------------------------- + + provides class Statistics + { + private: + struct stat + { + unsigned int trial; + unsigned long nb_evaluations; + double best_cost; + double current_cost; + }; + + Rlist<struct stat> stats_data; + + public: + Statistics(); + + friend ostream& operator<< (ostream& os, const Statistics& stats); + + Statistics& operator= (const Statistics& stats); + void update(const Solver& solver); + void clear(); + + ~Statistics(); + }; + +// Solver --------------------------------------------------------------------------------- + + provides class Solver + { + protected: + const Problem& problem; + const SetUpParams& params; + UserStatistics _userstat; + Statistics _stat; + Move* move; + Solution current; + double curfit; + Solution tentative; + double currentTemperature; + unsigned int k; // to control temperature update. + StateCenter _sc; + + float total_time_spent; + float time_spent_in_trial; + float start_trial; + float start_global; + + bool _end_trial; + + State_Vble _current_trial; + State_Vble _current_iteration; + State_Vble _current_best_solution; + State_Vble _current_best_cost; + State_Vble _current_solution; + State_Vble _current_cost; + + State_Vble _current_time_spent; + State_Vble _initial_temperature_trial; + State_Vble _time_best_found_trial; + State_Vble _iteration_best_found_trial; + State_Vble _temperature_best_found_trial; + State_Vble _time_spent_trial; + + State_Vble _trial_best_found; + State_Vble _iteration_best_found; + State_Vble _global_best_solution; + State_Vble _global_best_cost; + State_Vble _time_best_found; + + State_Vble _temperature; + State_Vble _display_state; + + const Direction _direction; + + bool AcceptQ(double tent, double cur, double temperature); + double Set_Initial_Temperature(const Problem& pbm); + void KeepHistory(const Solution& sol, const double curfit,const float time_spent_trial,const float total_time_spent); + + double UpdateT(double temp, int K); + + public: + // Constructor - Destructor ------------------------- + + Solver (const Problem& pbm, const SetUpParams& setup); + virtual ~Solver (); + virtual int pid() const; + bool end_trial() const; + + // Execution methods -------------------------------- + + // Full execution + virtual void run () =0; + virtual void run (unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol, unsigned long int nb_evaluations) =0; + + virtual void run (const double initialTemperature) =0; + virtual void run (const Solution& sol,const double initialTemperature) =0; + virtual void run (const double initialTemperature, unsigned long int nb_evaluations) =0; + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations) =0; + + // Partial execution + virtual void StartUp () =0; + virtual void StartUp (const Solution& sol) =0; + virtual void StartUp (const double initialTemperature) =0; + virtual void StartUp (const Solution& sol, const double initialTemperature) =0; + virtual void DoStep () =0; + + // Statistics handling ------------------------------ + + const Statistics& statistics() const; + const UserStatistics& userstatistics () const; + const SetUpParams& setup() const; + const Problem& pbm() const; + + // State handling ----------------------------------- + + void RefreshState(); + void UpdateFromState(); + StateCenter* GetState(); + + unsigned int current_trial() const; + unsigned long current_iteration() const; + Solution current_best_solution() const; + Solution current_solution() const; + double current_best_cost() const; + double current_cost() const; + float current_time_spent() const; + float time_best_found_trial() const; + double initial_temperature_trial() const; + unsigned int iteration_best_found_trial() const; + double temperature_best_found_trial() const; + float time_spent_trial() const; + unsigned int trial_best_found() const; + unsigned int iteration_best_found() const; + Solution global_best_solution() const; + double global_best_cost() const; + float time_best_found() const; + double temperature() const; + int display_state() const; + + void current_trial(const unsigned int value); + void current_iteration(const unsigned long value); + void current_best_solution(const Solution& sol); + void current_best_cost(const double value); + void current_solution(const Solution& sol); + void current_cost(const double value); + void current_time_spent(const float value); + void time_best_found_trial(const float value); + void initial_temperature_trial(const double temperature); + void iteration_best_found_trial(const unsigned int value); + void temperature_best_found_trial(const double value); + void time_spent_trial(const float value); + void trial_best_found(const unsigned int value); + void iteration_best_found(const unsigned int value); + void global_best_solution(const Solution& sol); + void global_best_cost(const double value); + void time_best_found(const float value); + void temperature(const double value); + void display_state(const int value); + void show_state() const; + + // State handling ----------------------------------- + void SetMove(Move* mov); + }; + + provides class Solver_Seq: public Solver + { + public: + // Constructor - Destructor ------------------------- + + Solver_Seq ( const Problem& pbm, const SetUpParams& setup); + virtual ~Solver_Seq (); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + }; + + provides class Solver_Lan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + public: + Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Lan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + + provides class Solver_Wan: public Solver + { + private: + NetStream _netstream; + int mypid; + + void send_local_state_to(int _mypid); + int receive_local_state_from(int source_pid); + + void check_for_refresh_global_state(); + + unsigned int _current_trial; + unsigned int _current_iteration; + double _best_cost_trial; + Solution _best_solution_trial; + float _time_best_found_in_trial; + unsigned int _iteration_best_found_in_trial; + double _temperature_best_found_in_trial; + + int cooperation(); + // Termination phase // + bool final_phase; + int acum_evaluations; + public: + Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv); + virtual ~Solver_Wan (); + virtual int pid() const; + NetStream& netstream(); + + // Execution methods -------------------------------- + + // Full execution + void run (); + virtual void run (unsigned long int max_evaluations); + virtual void run (const Solution& sol, unsigned long int max_evaluations); + + virtual void run (const double initialTemperature); + virtual void run (const Solution& sol,const double initialTemperature); + virtual void run (const double initialTemperature, unsigned long int nb_evaluations); + virtual void run (const Solution& sol,const double initialTemperature, unsigned long int nb_evaluations); + + // Partial execution + virtual void StartUp (); + virtual void StartUp (const Solution& sol); + virtual void StartUp (const double initialTemperature); + virtual void StartUp (const Solution& sol, const double initialTemperature); + virtual void DoStep (); + + void reset(); + }; + +}; + +#endif diff --git a/ProyectoFinal/CHC/malva/rep/SA/vrp/SA.pro.cc b/ProyectoFinal/CHC/malva/rep/SA/vrp/SA.pro.cc new file mode 100644 index 0000000000000000000000000000000000000000..43dcaf9ebda2aa5738f2982cb5f6441259ce44f5 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/vrp/SA.pro.cc @@ -0,0 +1,1807 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** Provided classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** *** +************************************************/ + +#include <iostream.h> +#include <math.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "Mallba/time.hh" + +skeleton SA +{ + +// SetUpParams ----------------------------------------------------------- + + SetUpParams::SetUpParams (): + _independent_runs(0), + _max_evaluations(0), + _MarkovChain_length(0), + _temperature_decay(0), + _refresh_global_state(0), + _synchronized(0), + _display_state(0), + _cooperation(0) + {} + + istream& operator>> (istream& is, SetUpParams& setup) + { + char buffer[MAX_BUFFER]; // current line in the setup file + char command[50]; + int op; + double dop; + short int nb_param=0; + short int nb_section=0; + short int nb_LAN_param=0; + + while (is.getline(buffer,MAX_BUFFER,'\n')) + { + sscanf(buffer," %s ",command); + + if (!(strcmp(command,"General"))) nb_section=0; + if (!(strcmp(command,"LAN-configuration"))) nb_section=1; + + if (nb_param==3 && nb_section==0) + { + dop=-1; + sscanf(buffer," %lf ",&dop); + if (dop<0) continue; + } + else + { + op=-1; + sscanf(buffer," %ld%*s ",&op); + if (op<0) continue; + } + + switch (nb_section) + { + case 0: switch (nb_param) + { + case 0: setup.independent_runs(op); break; + case 1: setup.max_evaluations(op); break; + case 2: setup.MarkovChain_length(op); break; + case 3: setup.temperature_decay(dop); break; + case 4: setup.display_state(op); break; + } + nb_param++; + break; + case 1: if (nb_LAN_param>=3) break; + if (nb_LAN_param==0) setup.refresh_global_state(op); + if (nb_LAN_param==1) setup.synchronized(op); + if (nb_LAN_param==2) setup.cooperation(op); + nb_LAN_param++; + break; + } // end switch + } // end while + return is; + } + + ostream& operator<< (ostream& os, const SetUpParams& setup) + { + os << "CONFIGURATION -------------------------------------------" << endl << endl; + os << "\t" << "Independent runs : " << setup.independent_runs() << endl + << "\t" << "Evaluation steps: " << setup.max_evaluations() << endl + << "\t" << "Markov-Chain Length: " << setup.MarkovChain_length() << endl + << "\t" << "Temperature Decay: " << setup.temperature_decay() << endl; + + if (setup.display_state()) + os << "\t" << "Display state" << endl; + else + os << "\t" << "Not display state" << endl; + os << endl << "\t" << "LAN configuration:" << endl + << "\t" << "----------------------" << endl << endl + << "\t" << "Refresh global state in number of generations: " << setup.refresh_global_state() << endl; + + if (setup.synchronized()) + os << "\t" << "Running in synchronous mode" << endl; + else + os << "\t" << "Running in asynchronous mode" << endl; + + if (!setup.cooperation()) + os << "\t" << "Running without cooperation" << endl << endl; + else + os << "\t" << "Running with cooperation in " << setup.cooperation() << " iterations. " << endl << endl; + + os << endl << endl << "END CONFIGURATION -------------------------------------------" << endl << endl; + return os; + } + + const unsigned int SetUpParams::independent_runs() const + { + return _independent_runs; + } + + const unsigned long SetUpParams::max_evaluations() const + { + return _max_evaluations; + } + + const unsigned int SetUpParams::MarkovChain_length() const + { + return _MarkovChain_length; + } + + const double SetUpParams::temperature_decay() const + { + return _temperature_decay; + } + + const bool SetUpParams::display_state() const + { + return _display_state; + } + + const unsigned long SetUpParams::refresh_global_state() const + { + return _refresh_global_state; + } + + const bool SetUpParams::synchronized() const + { + return _synchronized; + } + + const unsigned int SetUpParams::cooperation() const + { + return _cooperation; + } + + void SetUpParams::independent_runs(const unsigned int val) + { + _independent_runs = val; + } + + void SetUpParams::max_evaluations(const unsigned long val) + { + _max_evaluations= val; + } + void SetUpParams::MarkovChain_length(const unsigned int val) + { + _MarkovChain_length= val; + } + void SetUpParams::temperature_decay(const double val) + { + _temperature_decay= val; + } + + void SetUpParams::display_state(const bool val) + { + _display_state=val; + } + + void SetUpParams::refresh_global_state(const unsigned long val) + { + _refresh_global_state=val; + } + + void SetUpParams::synchronized(const bool val) + { + _synchronized=val; + } + + void SetUpParams::cooperation(const unsigned int val) + { + _cooperation=val; + } + + SetUpParams::~SetUpParams() + {} + +// Statistics ------------------------------------------------------ + + Statistics::Statistics() + {} + + ostream& operator<< (ostream& os, const Statistics& stats) + { + int j; + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF CURRENT TRIAL " << endl; + os << "------------------------------------------------------------------" << endl; + for (int i=0;i< stats.stats_data.size();i++) + { + os << endl + << " Evaluations: " << stats.stats_data[i].nb_evaluations + << " Best: " << stats.stats_data[i].best_cost + << " Current: " << stats.stats_data[i].current_cost; + } + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + Statistics& Statistics::operator= (const Statistics& stats) + { + stats_data = stats.stats_data; + return *this; + } + + void Statistics::update(const Solver& solver) + { + /* struct stat *new_stat; + if ((new_stat=(struct stat *)malloc(sizeof(struct stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluations= solver.current_iteration(); + new_stat->best_cost = solver.current_best_cost(); + new_stat->current_cost = solver.current_cost(); + stats_data.append(*new_stat); */ + } + + Statistics::~Statistics() + { + stats_data.remove(); + } + + void Statistics::clear() + { + stats_data.remove(); + } + +// Solver (superclass)--------------------------------------------------- + + Solver::Solver (const Problem& pbm, const SetUpParams& setup) + : problem(pbm), + params(setup), + _stat(), + _userstat(), + _sc(), + _direction(pbm.direction()), + current(pbm), + tentative(pbm), + currentTemperature(0.0), + time_spent_in_trial(0.0), + total_time_spent(0.0), + start_trial(0.0), + start_global(0.0), + _current_trial("_current_trial",_sc), + _current_iteration("_current_iteration",_sc), + _current_best_solution("_current_best_solution",_sc), + _current_best_cost("_current_best_cost",_sc), + _current_solution("_current_solution",_sc), + _current_cost("_current_cost",_sc), + _current_time_spent("_current_time_spent",_sc), + _initial_temperature_trial("_initial_temperature_trial",_sc), + _time_best_found_trial("_time_best_found_trial",_sc), + _iteration_best_found_trial("_iteration_best_found_trial",_sc), + _temperature_best_found_trial("_temperature_best_found_trial",_sc), + _time_spent_trial("_time_spent_trial",_sc), + _trial_best_found("_trial_best_found",_sc), + _iteration_best_found("_iteration_best_found;",_sc), + _global_best_solution("_global_best_solution",_sc), + _global_best_cost("_global_best_cost",_sc), + _time_best_found("_time_best_found",_sc), + _temperature("_temperature",_sc), + _display_state("_display_state",_sc) + { + current_trial(0); + current_iteration(0); + current_best_solution(current), + current_best_cost((-1) * pbm.direction() * infinity()); + current_solution(current); + current_cost((-1) * pbm.direction() * infinity()); + current_time_spent(total_time_spent); + initial_temperature_trial(0); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(0); + temperature_best_found_trial(0.0); + time_spent_trial(time_spent_in_trial); + trial_best_found(0); + iteration_best_found(0); + global_best_solution(current); + global_best_cost((-1) * pbm.direction() * infinity()); + time_best_found(total_time_spent); + temperature(currentTemperature); + display_state(setup.display_state()); + + move = new DefaultMove; + } + + int Solver::pid() const + { + return 0; + } + + bool Solver::end_trial() const + { + return _end_trial; + } + + unsigned int Solver::current_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_trial",(char *)&value, nitems, length); + return value; + } + + unsigned long Solver::current_iteration() const + { + unsigned long value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_iteration",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_best_solution() const + { + Solution sol(problem); + unsigned long nitems,length; + char data_stored[_current_best_solution.get_nitems() + _current_best_solution.get_length()]; + _sc.get_contents_state_variable("_current_best_solution", data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::current_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_best_cost",(char *)&value, nitems, length); + return value; + } + + double Solver::current_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_cost",(char *)&value, nitems, length); + return value; + } + + Solution Solver::current_solution() const + { + Solution sol(problem); + char data_stored[_current_solution.get_nitems() + _current_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_current_solution",data_stored, nitems, length); + sol.to_Solution((char *)data_stored); + return sol; + } + + float Solver::current_time_spent() const + { + float value=0.0; + unsigned long nitems,length; + _current_time_spent.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found_trial() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::initial_temperature_trial() const + { + double value=0.0; + unsigned long nitems,length; + _initial_temperature_trial.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature_best_found_trial() const + { + double value=0.0; + unsigned long nitems,length; + _temperature_best_found_trial.get_contents((char *)&value, nitems, length); + return value; + } + + float Solver::time_spent_trial() const + { + float value=0.0; + unsigned long nitems,length; + _time_spent_trial.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::trial_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _trial_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + unsigned int Solver::iteration_best_found() const + { + unsigned int value=0; + unsigned long nitems,length; + _iteration_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + Solution Solver::global_best_solution() const + { + Solution sol(problem); + char data_stored[_global_best_solution.get_nitems() + _global_best_solution.get_length()]; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_solution",data_stored, nitems, length); + sol.to_Solution(data_stored); + return sol; + } + + double Solver::global_best_cost() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_global_best_cost",(char *)&value, nitems, length); + return value; + } + + float Solver::time_best_found() const + { + float value=0.0; + unsigned long nitems,length; + _time_best_found.get_contents((char *)&value, nitems, length); + return value; + } + + double Solver::temperature() const + { + double value=0.0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_temperature",(char *)&value, nitems, length); + return value; + } + + int Solver::display_state() const + { + int value=0; + unsigned long nitems,length; + _sc.get_contents_state_variable("_display_state",(char *)&value, nitems, length); + return value; + } + + void Solver::current_trial(const unsigned int value) + { + _sc.set_contents_state_variable("_current_trial",(char *)&value,1,sizeof(int)); + } + + void Solver::current_iteration(const unsigned long value) + { + _sc.set_contents_state_variable("_current_iteration",(char *)&value,1,sizeof(long)); + } + + void Solver::current_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_best_cost(const double value) + { + _sc.set_contents_state_variable("_current_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_cost(const double value) + { + _sc.set_contents_state_variable("_current_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::current_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_current_solution",sol.to_String(),1,sol.size()); + } + + void Solver::current_time_spent(const float value) + { + _current_time_spent.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::time_best_found_trial(const float value) + { + _time_best_found_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::iteration_best_found_trial(const unsigned int value) + { + _iteration_best_found_trial.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::initial_temperature_trial(const double value) + { + _initial_temperature_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::temperature_best_found_trial(const double value) + { + _temperature_best_found_trial.set_contents((char *)&value,1,sizeof(double)); + } + + void Solver::time_spent_trial(const float value) + { + _time_spent_trial.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::trial_best_found(const unsigned int value) + { + _trial_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::iteration_best_found(const unsigned int value) + { + _iteration_best_found.set_contents((char *)&value,1,sizeof(int)); + } + + void Solver::global_best_solution(const Solution& sol) + { + _sc.set_contents_state_variable("_global_best_solution",sol.to_String(),1,sol.size()); + } + + void Solver::global_best_cost(const double value) + { + _sc.set_contents_state_variable("_global_best_cost",(char *)&value,1,sizeof(double)); + } + + void Solver::time_best_found(const float value) + { + _time_best_found.set_contents((char *)&value,1,sizeof(float)); + } + + void Solver::temperature(const double value) + { + _sc.set_contents_state_variable("_temperature",(char *)&value,1,sizeof(double)); + } + + void Solver::display_state(const int value) + { + _sc.set_contents_state_variable("_display_state",(char *)&value,1,sizeof(int)); + } + + const Statistics& Solver::statistics() const + { + return _stat; + } + + const UserStatistics& Solver::userstatistics() const + { + return _userstat; + } + + const SetUpParams& Solver::setup() const + { + return params; + } + + const Problem& Solver::pbm() const + { + return problem; + } + + void Solver::KeepHistory(const Solution& sol, const double curfit,const float time_spent_in_trial,const float total_time_spent) + { + bool betterG=false; + bool betterT=false; + + switch (_direction) + { + case minimize: betterG = (curfit < global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit < current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + case maximize: betterG = (curfit > global_best_cost() || (curfit == global_best_cost() && time_spent_in_trial < time_best_found())); + betterT = (curfit > current_best_cost() || (curfit == current_best_cost() && time_spent_in_trial < time_best_found_trial())); + break; + } + + if (betterT) + { + current_best_solution(sol); + current_best_cost(curfit); + time_best_found_trial(time_spent_in_trial); + iteration_best_found_trial(current_iteration()); + temperature_best_found_trial(temperature()); + if (betterG) + { + trial_best_found(current_trial()); + iteration_best_found(current_iteration()); + global_best_solution(sol); + global_best_cost(curfit); + time_best_found(time_spent_in_trial); + } + } + } + + double Solver::UpdateT(double temp, int K) + { + //return temp * params.temperature_decay(); // initial + + /* + if(K == 1) return temp/log(2); + else return temp * log(K) / log(K+1); + */ + /* + if(K == 1) return temp/2; + else return (temp * K) / (K + 1); + */ + + if(K == 1) return temp / exp(2); + else return (temp * exp(K)) / exp(K+1); + + } + + StateCenter* Solver::GetState() + { + return &_sc; + } + + void Solver::RefreshState() + { + current_solution(current); + current_cost(curfit); + current_time_spent(total_time_spent); + time_spent_trial(time_spent_in_trial); + temperature(currentTemperature); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::UpdateFromState() + { + current = current_solution(); + curfit = current_cost(); + total_time_spent=current_time_spent(); + time_spent_in_trial=time_spent_trial(); + currentTemperature = temperature(); + + KeepHistory(current,curfit,time_spent_in_trial,total_time_spent); + } + + void Solver::show_state() const + { + cout << endl << "Current trial: " << current_trial(); + cout << endl << "Current iteration: " << current_iteration(); + cout << endl << "Current Temperature: " << temperature (); + cout << endl << "Current cost: " << current_cost(); + cout << endl << "Best cost in trial: " << current_best_cost(); + cout << endl << "Time of best solution found in trial: " << time_best_found_trial(); + cout << endl << "Iteration of best solution found in trial: " << iteration_best_found_trial(); + cout << endl << "Initial temperature in trial: " << initial_temperature_trial(); + cout << endl << "Temperature of best solution found in trial: " << temperature_best_found_trial(); + cout << endl << "Time spent in trial: " << time_spent_trial(); + cout << endl << "Global best cost: " << global_best_cost(); + cout << endl << "Trial of best global solution found: " << trial_best_found(); + cout << endl << "Iteration of best global solution found: " << iteration_best_found(); + cout << endl << "Time of global best solution found: " << time_best_found(); + // cout << endl << "Current solution: " << current_solution(); + // cout << endl << "Best solution of trial: " << current_best_solution(); + // cout << endl << "Global solution: " << global_best_solution() << endl; + cout << endl << endl << "Current time spent (so far): " << current_time_spent() << endl; + } + + Solver::~Solver() + { + _sc.removeAll(); + delete move; + } + + bool Solver::AcceptQ (double tent, double cur, double temperature) + { + if (_direction==minimize) + + return (tent < cur) || + ((rand01()*(1+exp((tent-cur)/temperature)))<2.0); + + else + + return (tent > cur) || + ((rand01()*(1+exp((cur-tent)/temperature)))<2.0); + } + + double Solver::Set_Initial_Temperature(const Problem& pbm) + { + const double beta = 1.05; + const double test = 10; + const double acrat = .8; + const double T = 1.0; + + Solution current (pbm); + Solution newsol (pbm); + double ac; + double fit; + double temperature = T; + + do + { + temperature *= beta; + ac = 0; + current.initialize(); + fit = current.fitness(); + for (int i=0; i<test; i++) + { + newsol = current; + move->Apply(newsol); + if (AcceptQ(newsol.fitness(),fit,temperature)) + ac += 1.0/test; + } + } while (ac < acrat); + + initial_temperature_trial(temperature); + return temperature; + + } + + void Solver::SetMove (Move* mov) + { + delete move; + move = mov; + } + + // Solver sequencial ----------------------------------------------------- + + Solver_Seq::Solver_Seq (const Problem& pbm, const SetUpParams& setup) + : Solver(pbm,setup) + { + random_seed(time(0)); + _end_trial=true; + } + + Solver_Seq::~Solver_Seq () + {} + + void Solver_Seq::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Seq::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Seq::StartUp(const Solution& sol, const double initialTemperature) + { + start_trial=_used_time(); + start_global=total_time_spent; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current = sol; + curfit = current.fitness(); + current_best_cost((-1) * problem.direction() * infinity()); + currentTemperature = initialTemperature; + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + void Solver_Seq::DoStep() + { + current_iteration(current_iteration()+1); + + tentative = current; + move->Apply(tentative); + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + if (display_state()) + show_state(); + } + + + void Solver_Seq::run (unsigned long int max_evaluations) + { + StartUp(); + + while (current_iteration()<max_evaluations && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Seq::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + + while ((current_iteration()<max_evaluations) && !TerminateQ(problem, *this, params)) + DoStep(); + } + + void Solver_Seq::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + // Solver LAN ----------------------------------------------------------- + + Solver_Lan::Solver_Lan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); + } + + Solver_Lan::~Solver_Lan () + { + NetStream::finalize(); + } + + int Solver_Lan::pid() const + { + return mypid; + } + + NetStream& Solver_Lan::netstream() + { + return _netstream; + } + + void Solver_Lan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Lan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Lan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + void update(Direction direction, Solution &solution_received,double cost_received, Solution &solution_to_send, double &best_cost) + { + switch (direction) + { + case minimize: if (cost_received < best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + case maximize: if (cost_received > best_cost) + { + solution_to_send=solution_received; + best_cost=cost_received; + } + } + } + + int Solver_Lan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Lan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Lan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Lan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Lan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Lan::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + void Solver_Lan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Lan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Lan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } + + // Solver WAN ------------------------------------------------------------ + + Solver_Wan::Solver_Wan (const Problem& pbm, const SetUpParams& setup,int argc,char **argv): + _best_solution_trial(pbm), + Solver(pbm,setup),_netstream(), + // Termination phase // + final_phase(false),acum_evaluations(0) + { + NetStream::init(argc,argv); + mypid=_netstream.my_pid(); + random_seed(time(0) + (mypid+1)); + if (mypid!=0) + _netstream << set_source(0) << set_target(0); + } + + Solver_Wan::~Solver_Wan () + { + NetStream::finalize(); + } + + int Solver_Wan::pid() const + { + return mypid; + } + + NetStream& Solver_Wan::netstream() + { + return _netstream; + } + + void Solver_Wan::StartUp() + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const Solution& sol) + { + StartUp(sol, Set_Initial_Temperature(problem)); + } + + void Solver_Wan::StartUp(const double initialTemperature) + { + Solution sol(problem); + + sol.initialize(); + + StartUp(sol, initialTemperature); + } + + void Solver_Wan::StartUp(const Solution& sol, const double initialTemperature) + { + + _netstream << barrier; + + start_trial=_used_time(); + start_global=total_time_spent; + // Termination phase // + final_phase = false; + acum_evaluations = 0; + + _end_trial=false; + + current_trial(current_trial()+1); + current_iteration(0); + + k = 0; + time_spent_in_trial=0.0; + current_best_cost((-1) * problem.direction() * infinity()); + iteration_best_found_trial(0); + temperature_best_found_trial(0); + time_best_found_trial(0.0); + time_spent_trial(0.0); + + if (mypid!=0) + { + current = sol; + curfit = current.fitness(); + currentTemperature = initialTemperature; + + RefreshState(); + + send_local_state_to(mypid); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) show_state(); + } + } + + int Solver_Wan::cooperation() + { + int received=false; + Solution solution_received(problem), solution_to_send(problem); + double cost_received=0, cost_to_send=0; + int pending=false; + int pid_source,pid_target; + + if (mypid!=0) + { + if (((int)current_iteration() % params.refresh_global_state()) ==0) // isnot the server + { + _netstream << set_target(0); + send_local_state_to(mypid); + } + + if (params.cooperation()==0) return received; + pid_target=mypid+1; + if (pid_target==_netstream.pnumber()) pid_target=1; + _netstream << set_target(pid_target); + + pid_source=mypid-1; + if (pid_source==0) pid_source=_netstream.pnumber()-1; + _netstream << set_source(pid_source); + + if ((((int)current_iteration() % params.cooperation())==0) && (params.max_evaluations()!=current_iteration())) + { + if (mypid==1) + _netstream << current_best_cost() << current_best_solution(); + + if (params.synchronized()) + { + _netstream << wait(regular); + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (!params.synchronized()) + { + int pending=false; + _netstream._probe(regular,pending); + if (pending) + { + _netstream >> cost_received >> solution_received; + received=true; + } + } + + if (mypid!=1 && received) + { + solution_to_send = current_best_solution(); + cost_to_send=current_best_cost(); + + if (received) + { + update(problem.direction(),solution_received, cost_received, solution_to_send,cost_to_send); + } + _netstream << cost_to_send << solution_to_send; + } + + if (received) + { + tentative=solution_received; + curfit=cost_received; + } + + _netstream << set_target(0); + } + + return received; + } + + void Solver_Wan::DoStep() + { + current_iteration(current_iteration()+1); + // Termination phase // + _netstream << set_source(0); + int pending; + _netstream._probe(packed, pending); + if(pending) + { + Solution sol(problem); + _netstream << pack_begin >> sol << pack_end; + final_phase = true; + } + //////////////////////// + + int received=cooperation(); + + if (!received) + { + tentative = current; + move->Apply(tentative); + } + + double tentfit = tentative.fitness(); + + if (AcceptQ(tentfit,curfit, currentTemperature)) + { + current = tentative; + curfit = tentfit; + } + + k++; + if (k>=params.MarkovChain_length()) + { + currentTemperature = UpdateT(currentTemperature,current_iteration()/params.MarkovChain_length()); + k = 0; + } + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // if (display_state()) + // show_state(); + } + + void Solver_Wan::send_local_state_to(int _mypid) + { + _netstream << set_target(0); + _netstream << pack_begin + << _mypid + << current_trial() + << current_iteration() + << current_solution() + << current_cost() + << current_best_solution() + << current_best_cost() + << time_best_found_trial() + << iteration_best_found_trial() + << temperature_best_found_trial() + << temperature() + << pack_end; + } + + int Solver_Wan::receive_local_state_from(int source_pid) + { + _netstream << set_source(source_pid); + int received_pid=0; + + _netstream._wait(packed); + _netstream << pack_begin + >> received_pid + >> _current_trial + >> _current_iteration + >> current + >> curfit + >> _best_solution_trial + >> _best_cost_trial + >> _time_best_found_in_trial + >> _iteration_best_found_in_trial + >> _temperature_best_found_in_trial + >> currentTemperature + << pack_end; + + return received_pid; + } + + void Solver_Wan::check_for_refresh_global_state() // Executed in process with pid 0 + { + unsigned int nb_finalized_processes=0; + int received_pid; + int nb_proc=_netstream.pnumber(); + + while (!_end_trial) + { + // checking for all processes + + received_pid=0; + received_pid=receive_local_state_from(MPI_ANY_SOURCE); + + // refresh the global state with received data ( a local state ) + current_trial(_current_trial); + current_iteration(_iteration_best_found_in_trial); + temperature(_temperature_best_found_in_trial); + + KeepHistory(_best_solution_trial,_best_cost_trial,_time_best_found_in_trial,start_global + _time_best_found_in_trial); + + if (received_pid==-1) + { + // Termination phase // + if(!final_phase && TerminateQ(problem,*this,params)) + { + Solution sol(problem); + acum_evaluations = params.max_evaluations() * nb_finalized_processes; + for(int i = 1; i < _netstream.pnumber(); i++) + { + _netstream << set_target(i); + _netstream << pack_begin << sol << pack_end; + } + final_phase = true; + } + nb_finalized_processes++; + acum_evaluations += _iteration_best_found_in_trial; + } + + if (nb_finalized_processes==nb_proc-1) _end_trial=true; + + current_iteration(_current_iteration); + temperature(currentTemperature); + + time_spent_in_trial = _used_time(start_trial); + total_time_spent = start_global + time_spent_in_trial; + + RefreshState(); + + _stat.update(*this); + //_userstat.update(*this); + + // display current global state + if (display_state()) show_state(); + } // end while + + // Actualización de las estadísticas // Termination phase // + iteration_best_found_trial(acum_evaluations/(_netstream.pnumber()-1)); + + bool betterG=false; + double best_cost = current_best_cost(); + switch (problem.direction()) + { + case minimize: betterG = (best_cost < global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + case maximize: betterG = (best_cost > global_best_cost() || (best_cost == global_best_cost() && time_best_found_trial() <= time_best_found())); + break; + } + + if (betterG) + iteration_best_found(iteration_best_found_trial()); + + RefreshState(); + + _stat.update(*this); + _userstat.update(*this); + + // display the global state at the end of the current trial + if (display_state()) show_state(); + } + + void Solver_Wan::run () + { + while (current_trial() < params.independent_runs()) + run(params.max_evaluations()); + } + + void Solver_Wan::run (const unsigned long int max_evaluations) + { + StartUp(); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol, unsigned long int max_evaluations) + { + StartUp(sol); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature) + { + while (current_trial() < params.independent_runs()) + run(sol,initialTemperature,params.max_evaluations()); + } + + void Solver_Wan::run (const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::run (const Solution& sol,const double initialTemperature, unsigned long int max_evaluations) + { + StartUp(sol,initialTemperature); + if (mypid!=0) + { + while (!final_phase && (current_iteration() < max_evaluations) && !(TerminateQ(problem,*this,params))) + DoStep(); + send_local_state_to(-1); + } + else + { + check_for_refresh_global_state(); + } + + _netstream << barrier; + reset(); + } + + void Solver_Wan::reset() + { + Solution left_solution(problem); + double left_cost; + _netstream << set_source(MPI_ANY_SOURCE); + if (mypid!=0) + { + int pendingr = false; + int pendingp = false; + do + { + pendingr = false; + pendingp = false; + _netstream._probe(regular,pendingr); + _netstream._probe(packed,pendingp); + if (pendingr) _netstream >> left_cost >> left_solution; + if (pendingp) _netstream << pack_begin >> left_solution << pack_end; + } while (pendingr || pendingp); + } + _netstream << barrier; + } +}; + diff --git a/ProyectoFinal/CHC/malva/rep/SA/vrp/SA.req.cc b/ProyectoFinal/CHC/malva/rep/SA/vrp/SA.req.cc new file mode 100644 index 0000000000000000000000000000000000000000..c14f23a5386c9beadab6a7a497ef34ae141e2929 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/vrp/SA.req.cc @@ -0,0 +1,527 @@ +/************************************************ +*** *** +*** Simulated Annealing Skeleton v1.0 *** +*** User-required classes and methods *** +*** Developed by: Carlos Cotta Porras *** +*** *** +*** *** +************************************************/ + +#include <iostream.h> +#include "SA.hh" +#include "Mallba/random.hh" +#include "StopCondition.hh" + +skeleton SA { + + +// Problem --------------------------------------------------------------- + Problem::Problem ():_nCustomers(0),_capacity(0),_distance(NULL), + _demand(NULL),_service_time(0),_maxRouteTime(0.0) + {} + + ostream& operator<< (ostream& os, const Problem& pbm) + { + os << endl << endl << " Vehicle capacity: " << pbm._capacity + << endl << " Number of Customers: " << pbm._nCustomers << endl + << " Service time: " << pbm._service_time << endl + << " Max Time for any route: " << pbm._maxRouteTime << endl + << " Distances: " << endl; + + for(int i = 0; i < (pbm._nCustomers + 1) ; i++) + { + for(int j = 0; j < pbm._nCustomers; j++) + os << " " << pbm.distance(i,j); + os << endl; + } + + os << endl << " Demand for each customer: " << endl; + + for(int i = 0; i < (pbm._nCustomers + 1) ; i++) + { + os << " " << i << "\t" << pbm._demand[i] << endl; + } + + return os; + } + + istream& operator>> (istream& is, Problem& pbm) + { + char buffer[MAX_BUFFER]; + int *x; + int *y; + + is.getline(buffer,MAX_BUFFER,'\n'); + sscanf(buffer," %d %d %lf %d %lf",&pbm._nCustomers,&pbm._capacity,&pbm._maxRouteTime,&pbm._service_time,&pbm._bestCost); + + if( ((pbm._distance = new double *[pbm._nCustomers + 1]) == NULL) + || ((pbm._demand = new int[pbm._nCustomers + 1]) == NULL) + || ((x = new int[pbm._nCustomers + 1]) == NULL) + || ((y = new int[pbm._nCustomers + 1]) == NULL)) + show_message(7); + + // Read depot coordenates + if( ((pbm._distance[0] = new double[pbm._nCustomers+1]) == NULL)) + show_message(7); + + is.getline(buffer,MAX_BUFFER,'\n'); + sscanf(buffer," %d %d",&(x[0]),&(y[0])); + pbm._demand[0] = 0; + + // Read customers coordenates + for(int i = 1; i < (pbm._nCustomers + 1); i++) + { + if( ((pbm._distance[i] = new double[pbm._nCustomers+1]) == NULL)) + show_message(7); + + is.getline(buffer,MAX_BUFFER,'\n'); + sscanf(buffer," %d %d %d", &(x[i]),&(y[i]),&(pbm._demand[i])); + } + + pbm.genDistances(x,y); + + delete [] x; + delete [] y; + + return is; + } + + void Problem::genDistances(int *x,int *y) + { + for(int i = 0; i < (_nCustomers + 1); i++) + for(int j = 0; j < (_nCustomers +1) ; j++) + _distance[i][j] = sqrt( pow( (double) (x[j] - x[i]),2 ) + + pow( (double) (y[j] - y[i]),2 ) ) + _service_time ; + } + + Problem& Problem::operator= (const Problem& pbm) + { + if(_distance != NULL) + { + for(int i= 0;i < (_nCustomers+1); i++) + if(_distance[i] != NULL) delete [] _distance[i]; + delete [] _distance; + } + + if(_demand != NULL) delete [] _demand; + + if( ((_distance = new double*[pbm._nCustomers]) == NULL) + || ((_demand = new int[pbm._nCustomers + 1]) == NULL)) + show_message(7); + + _nCustomers = pbm.nCustomers(); + _capacity = pbm.capacity(); + _service_time = pbm.service_time(); + _maxRouteTime = pbm.maxRouteTime(); + + for(int i = 0; i < (_nCustomers+1); i++) + { + _demand[i] = pbm.demand(i); + + if( ((_distance[i] = new double[_nCustomers+1]) == NULL)) + show_message(7); + + for(int j = 0; j < (_nCustomers+1); i++) + { + _distance[i][j] = pbm.distance(i,j); + } + } + + return *this; + } + + bool Problem::operator== (const Problem& pbm) const + { + if( (_maxRouteTime != pbm.maxRouteTime()) || (_nCustomers != pbm.nCustomers()) + || (_capacity != pbm.capacity()) || (_service_time != pbm.service_time())) + return false; + + for(int i = 0; i < (_nCustomers+1); i++) + { + if(_demand[i] != pbm.demand(i)) + return false; + + for(int j = 0; j < (_nCustomers+1); i++) + { + if(distance(i,j) != pbm.distance(i,j)) return false; + } + } + + return true; + } + + bool Problem::operator!= (const Problem& pbm) const + { + return !(*this == pbm); + } + + Direction Problem::direction() const + { + //return maximize; + return minimize; + } + + double Problem::maxRouteTime() const + { + return _maxRouteTime; + } + + double Problem::bestCost() const + { + return _bestCost; + } + + int Problem::nCustomers() const + { + return _nCustomers; + } + + int Problem::capacity() const + { + return _capacity; + } + + double Problem::distance(const int i, const int j) const + { + return _distance[i][j]; + } + + int Problem::demand(const int i) const + { + return _demand[i]; + } + + int Problem::service_time() const + { + return _service_time; + } + + Problem::~Problem() + { + if(_distance != NULL) + { + for(int i= 0;i < (_nCustomers+1); i++) + if(_distance[i] != NULL) delete [] _distance[i]; + delete [] _distance; + } + + if(_demand != NULL) delete [] _demand; + + } + +// Solution -------------------------------------------------------------- + Solution::Solution (const Problem& pbm):_pbm(pbm),_routes(pbm.nCustomers()) + {} + + const Problem& Solution::pbm() const + { + return _pbm; + } + + Solution::Solution(const Solution& sol):_pbm(sol.pbm()) + { + *this=sol; + } + + istream& operator>> (istream& is, Solution& sol) + { + for (int i=0;i<sol.pbm().nCustomers(); i++) + { + is >> sol._routes[i]; + } + return is; + } + + ostream& operator<< (ostream& os, const Solution& sol) + { + for (int i=0;i<sol.pbm().nCustomers(); i++) + { + os << (sol._routes[i]<10?" ":"") << sol._routes[i] << " "; + } + + return os; + } + + void Solution::print() + { + int ultimo = 0; + double dist = 0.0; + int cap = _pbm.capacity(); + + register int c_actual; + register int i = 0; + + int nRoute = 1; + + cout << " Ruta " << nRoute << " = 0 "; + while(i < _pbm.nCustomers()) + { + c_actual = _routes[i]; + + if( ((dist + _pbm.distance(ultimo,c_actual) + _pbm.distance(c_actual,0)) > _pbm.maxRouteTime()) + || (( cap - _pbm.demand(c_actual)) < 0) + // add in version 1.0.1 + || ((_pbm.distance(ultimo,0) + _pbm.distance(0,c_actual)) < _pbm.distance(ultimo,c_actual)) + ) + { + nRoute++; + cout << "0 -> dist = " << (dist + _pbm.distance(ultimo,0)) << " capacidad sobra = " << cap + << endl << "Ruta " << nRoute << " = 0 "; + ultimo = 0; + dist = 0.0; + cap = _pbm.capacity(); + } + else + { + dist += _pbm.distance(ultimo,c_actual); + cap -= _pbm.demand(c_actual); + ultimo = c_actual; + cout << ultimo << " "; + i++; + } + } + + cout << "0 -> dist = " << (dist + _pbm.distance(ultimo,0)) << " capacidad sobra = " << cap + << endl; + } + + NetStream& operator << (NetStream& ns, const Solution& sol) + { + for (int i=0;i<sol.pbm().nCustomers();i++) + ns << sol._routes[i]; + return ns; + } + + NetStream& operator >> (NetStream& ns, Solution& sol) + { + for (int i=0;i<sol.pbm().nCustomers();i++) + ns >> sol._routes[i]; + return ns; + } + + Solution& Solution::operator= (const Solution &sol) + { + _routes = sol._routes; + return *this; + } + + bool Solution::operator== (const Solution& sol) const + { + if (sol.pbm() != _pbm) return false; + return true; + } + + bool Solution::operator!= (const Solution& sol) const + { + return !(*this == sol); + } + + void Solution::initialize() + { + int aux,ind1,ind2; + + int max = _pbm.nCustomers(); + + for(int i = 0; i < max; i++) + _routes[i] = i+1; + + cout << endl; + + for(int i=0;i< (max*5) ; i++) + { + ind1 = rand_int(0,max-1); + ind2 = rand_int(0,max-1); + + aux = _routes[ind1]; + _routes[ind1] = _routes[ind2]; + _routes[ind2] = aux; + } + } + + double Solution::fitness () const + { + double fitness = 0.0; + int ultimo = 0; + double dist = 0.0; + int cap = _pbm.capacity(); + + register int c_actual; + register int i = 0; + + while(i < _pbm.nCustomers()) + { + c_actual = _routes[i]; + + if( ((dist + _pbm.distance(ultimo,c_actual) + _pbm.distance(c_actual,0)) > _pbm.maxRouteTime()) + || (( cap - _pbm.demand(c_actual)) < 0) + // Add on version 1.0.1 + // New constrains: cost( Route + actual) < cost( new Route(actual)) + || ((_pbm.distance(ultimo,0) + _pbm.distance(0,c_actual)) < _pbm.distance(ultimo,c_actual)) + ) + { + fitness += dist + _pbm.distance(ultimo,0); + ultimo = 0; + dist = 0.0; + cap = _pbm.capacity(); + } + else + { + dist += _pbm.distance(ultimo,c_actual); + cap -= _pbm.demand(c_actual); + ultimo = c_actual; + i++; + } + } + + fitness += dist + _pbm.distance(ultimo,0); + + return fitness; + } + + char *Solution::to_String() const + { + return (char *)_routes.get_first(); + } + + void Solution::to_Solution(char *_routes_) + { + int *ptr=(int *)_routes_; + + for (int i=0;i<_pbm.nCustomers();i++) + { + _routes[i]=*ptr; + ptr++; + } + } + + unsigned int Solution::size() const + { + return ( _pbm.nCustomers() * sizeof(int)); + } + + int & Solution::pos(const int index) + { + return _routes[index]; + } + + + Rarray<int>& Solution::routes() + { + return _routes; + } + + Solution::~Solution() + {} + +// UserStatistics ------------------------------------------------------- + + UserStatistics::UserStatistics () + {} + + ostream& operator<< (ostream& os, const UserStatistics& userstat) + { + os << "\n---------------------------------------------------------------" << endl; + os << " STATISTICS OF TRIALS " << endl; + os << "------------------------------------------------------------------" << endl; + + for (int i=0;i< userstat.result_trials.size();i++) + { + os << endl + << "\t" << userstat.result_trials[i].trial + << "\t" << userstat.result_trials[i].best_cost_trial + << "\t\t" << userstat.result_trials[i].nb_evaluation_best_found_trial + << "\t\t" << userstat.result_trials[i].initial_temperature + << "\t\t" << userstat.result_trials[i].temperature_best_found_trial + << "\t\t" << userstat.result_trials[i].time_best_found_trial + << "\t\t" << userstat.result_trials[i].time_spent_trial; + } + + os << endl << "------------------------------------------------------------------" << endl; + return os; + } + + + UserStatistics& UserStatistics::operator= (const UserStatistics& userstats) + { + result_trials=userstats.result_trials; + return (*this); + } + + + void UserStatistics::update(const Solver& solver) + { + if ((solver.pid()!=0) || (solver.end_trial()!=true) + || ((solver.current_iteration()!=solver.setup().max_evaluations()) + && !TerminateQ(solver.pbm(),solver,solver.setup()))) + return; + struct user_stat *new_stat; + if ((new_stat=(struct user_stat *)malloc(sizeof(struct user_stat)))==NULL) + show_message(7); + new_stat->trial = solver.current_trial(); + new_stat->nb_evaluation_best_found_trial= solver.iteration_best_found_trial(); + new_stat->initial_temperature=solver.initial_temperature_trial(); + new_stat->temperature_best_found_trial=solver.temperature_best_found_trial(); + new_stat->best_cost_trial = solver.current_best_cost(); + new_stat->time_best_found_trial= solver.time_best_found_trial(); + new_stat->time_spent_trial = solver.time_spent_trial(); + result_trials.append(*new_stat); + } + + void UserStatistics::clear() + { + result_trials.remove(); + } + + UserStatistics::~UserStatistics() + { + result_trials.remove(); + } + +// DefaultMove ------------------------------------------------------- + + + DefaultMove::DefaultMove() + {} + + DefaultMove::~DefaultMove() + {} + + void DefaultMove::Apply (Solution& sol) const + { + Solution aux(sol); + const int max = sol.pbm().nCustomers(); + float fit = sol.fitness(); + float fit_a; + Direction d = sol.pbm().direction(); + + for(int i = 0; i < max; i++) + for(int j = i+1; j < max; j++) + { + aux.routes().invert(i,j); + fit_a = aux.fitness(); + if( ((d == minimize) && (fit_a < fit)) + || ((d == minimize) && (fit_a > fit) && (rand01() < 0.3)) + || ((d == maximize) && (fit_a > fit)) + || ((d == maximize) && (fit_a < fit) && (rand01() < 0.3))) + { + fit = fit_a; + sol = aux; + } + else aux = sol; + } + } + + //------------------------------------------------------------------------ + // Specific methods ------------------------------------------------------ + //------------------------------------------------------------------------ + + bool TerminateQ (const Problem& pbm, const Solver& solver, + const SetUpParams& setup) + { + + StopCondition_3 stop; + return stop.EvaluateCondition(pbm,solver,setup); + } +} + + diff --git a/ProyectoFinal/CHC/malva/rep/SA/vrp/StopCondition.cc b/ProyectoFinal/CHC/malva/rep/SA/vrp/StopCondition.cc new file mode 100644 index 0000000000000000000000000000000000000000..e5a2279a6bb41b1041feb49142a46d1c0c72a52e --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/vrp/StopCondition.cc @@ -0,0 +1,52 @@ +#include "StopCondition.hh" +skeleton SA +{ + +// StopCondition ------------------------------------------------------------------------------------- + + StopCondition::StopCondition() + {} + + StopCondition::~StopCondition() + {} + +// StopCondition_1 ------------------------------------------------------------------------------------- + + StopCondition_1::StopCondition_1():StopCondition() + {} + + bool StopCondition_1::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return false; + } + + StopCondition_1::~StopCondition_1() + {} + +// StopCondition_2 ------------------------------------------------------------------------------------- + + StopCondition_2::StopCondition_2():StopCondition() + {} + + bool StopCondition_2::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return (solver.global_best_cost()>8.5); + } + + StopCondition_2::~StopCondition_2() + {} + +// StopCondition_3 ------------------------------------------------------------------------------------- + + StopCondition_3::StopCondition_3():StopCondition() + {} + + bool StopCondition_3::EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup) + { + return ((double)solver.current_best_cost()==pbm.bestCost()); + } + + StopCondition_3::~StopCondition_3() + {} + +} diff --git a/ProyectoFinal/CHC/malva/rep/SA/vrp/StopCondition.hh b/ProyectoFinal/CHC/malva/rep/SA/vrp/StopCondition.hh new file mode 100644 index 0000000000000000000000000000000000000000..04ef770d9cac5bb9ef69aae7d085e3ae2166e187 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/vrp/StopCondition.hh @@ -0,0 +1,41 @@ +#ifndef stop_condition +#define stop_condition + +#include "SA.hh" +skeleton SA +{ + + provides class StopCondition + { + public: + StopCondition(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup)=0; + ~StopCondition(); + }; + + requires class StopCondition_1 : public StopCondition + { + public: + StopCondition_1(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_1(); + }; + + requires class StopCondition_2 : public StopCondition + { + public: + StopCondition_2(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_2(); + }; + + requires class StopCondition_3 : public StopCondition + { + public: + StopCondition_3(); + virtual bool EvaluateCondition(const Problem& pbm,const Solver& solver,const SetUpParams& setup); + ~StopCondition_3(); + }; +} + +#endif diff --git a/ProyectoFinal/CHC/malva/rep/SA/vrp/pgfileLan b/ProyectoFinal/CHC/malva/rep/SA/vrp/pgfileLan new file mode 100644 index 0000000000000000000000000000000000000000..1c419a1ec3c19506364c4b8024570096296426c8 --- /dev/null +++ b/ProyectoFinal/CHC/malva/rep/SA/vrp/pgfileLan @@ -0,0 +1,5 @@ +localhost 0 ~/Mallba/rep/SA/vrp/MainLan +localhost 1 ~/Mallba/rep/SA/vrp/MainLan +localhost 1 ~/Mallba/rep/SA/vrp/MainLan +localhost 1 ~/Mallba/rep/SA/vrp/MainLan +localhost 1 ~/Mallba/rep/SA/vrp/MainLan diff --git a/ProyectoFinal/CHC/malva/src/Makefile b/ProyectoFinal/CHC/malva/src/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..b6d64fba4ba48d6a207029d215eedf5df8a69730 --- /dev/null +++ b/ProyectoFinal/CHC/malva/src/Makefile @@ -0,0 +1,14 @@ +include ../environment + +OBJS = States.o netstream.o + +all: $(OBJS) + +States.o: States.cc States.hh + $(CXX) $(CPPFLAGS) States.cc -c + +netstream.o: netstream.cc netstream.hh + $(CXX) $(CPPFLAGS) netstream.cc -c + +clean: + rm -f *.o *~ *% diff --git a/ProyectoFinal/CHC/malva/src/Matrix.hh b/ProyectoFinal/CHC/malva/src/Matrix.hh new file mode 100644 index 0000000000000000000000000000000000000000..cc30ae7e23189594a197d99982205dac483fd37b --- /dev/null +++ b/ProyectoFinal/CHC/malva/src/Matrix.hh @@ -0,0 +1,337 @@ +/***************************************************************************** +*** *** +*** Este fichero decribe el template Matrix, para el manejo de matrices. *** +*** Tambien permite el manejo de vectores, los que trata como matrices cuya*** +*** primera dimension es 1. *** +*** *** +*****************************************************************************/ +#ifndef _MATRIX +#define _MATRIX + +#include "Messages.h" +#include <assert.h> + +template <class T> class Matrix +{ + private: + T *_matrix; + T nulo,neutro,inverso; + int _dimX,_dimY; + + public: + Matrix() + { + _dimX = _dimY = 0; + _matrix = NULL; + } + + Matrix(const int x,const int y,const T nulo = 0.0,const T neutro = 1.0,const T inverso = -1.0) + { + assert(x >= 1); + assert(y >= 1); + + int k = 0; + + _dimX = x; + _dimY = y; + + this->nulo = nulo; + this->neutro = neutro; + this->inverso = inverso; + + _matrix = new T [_dimX*_dimY]; + if(!_matrix) show_message(7); + + for(int i = 0; i < x; i++) + { + for(int j = 0; j < y ; j++) + { + _matrix[k] = (i!=j?nulo:neutro); + k++; + } + + } + } + + Matrix(const int y,const T nulo = 0.0,const T neutro = 1.0,const T inverso = -1.0) + { + assert(y >= 1); + + _dimX = 1; + _dimY = y; + + this->nulo = nulo; + this->neutro = neutro; + this->inverso = inverso; + + _matrix = new T [_dimY]; + if(!_matrix) show_message(7); + + _matrix[0] = neutro; + for(int j = 1; j < y ; j++) + _matrix[j] = nulo; + } + + Matrix(const Matrix<T> &m) + { + + _dimX = m.dimX(); + _dimY = m.dimY(); + + nulo = m.nulo; + neutro = m.neutro; + inverso = m.inverso; + + _matrix = new T [_dimX*_dimY]; + if(!_matrix) show_message(7); + + for(int i = 0; i < (_dimX*_dimY); i++) + { + _matrix[i] = m[i]; + } + } + + + ~Matrix() + { + remove(); + } + + T &operator()(const int x,const int y) const + { + if((x >= _dimX) || (y >= _dimY)) + show_message(14); + + return (T&)(*(_matrix + (x*_dimX) + y)); + } + + T &operator[](const int y) const + { + if(y >= (_dimX*_dimY)) + show_message(14); + + return (T&)(*(_matrix + y)); + } + + T &operator()(const int y) const + { + if(y >= (_dimX*_dimY)) + show_message(14); + + return (T&)(*(_matrix + y)); + } + + Matrix<T> &operator=(const Matrix<T> &m) + { + remove(); + + _dimX = m.dimX(); + _dimY = m.dimY(); + + _matrix = new T [_dimX*_dimY]; + if(!_matrix) show_message(7); + + for(int i = 0; i < (_dimX*_dimY); i++) + { + _matrix[i] = m[i]; + } + + return (*this); + } + + bool operator==(const Matrix<T> &m) const + { + if((_dimX != m.dimX()) || (_dimY != m.dimY())) + return false; + + for(int i = 0; i < (_dimX*_dimY); i++) + if(_matrix[i] != m[i]) return false; + + return true; + } + + bool operator!=(const Matrix<T> &m) const + { + return !((*this) == m); + } + + Matrix<T> operator*(const Matrix<T> &m) + { + int x = (m.dimX()!=_dimY?0:_dimX); + int y = (x!=0?m.dimY():0); + T acum = nulo; + + Matrix<T> res(x,y); + + for(int i = 0; i < _dimX; i++) + for(int j = 0; j < m.dimY(); j++) + { + acum = nulo; + for( int k = 0; k < _dimY; k++) + acum += (*this)(i,k)* m(k,j); + res(i,j) = acum; + } + + return Matrix<T>(res); + + } + + Matrix<T> &operator*=(const Matrix<T> &m) + { + int x = (m.dimX()!=_dimY?0:_dimX); + int y = (x!=0?0:m.dimY()); + T acum = nulo; + + Matrix<T> res(x,y); + + for(int i = 0; i < _dimX; i++) + for(int j = 0; j < m.dimY(); j++) + { + acum = nulo; + for( int k = 0; k < _dimY; k++) + acum += (*this)(i,k)*m(k,j); + res(i,j) = acum; + } + + (*this) = res; + + return (*this); + + } + + Matrix<T> operator*(const T &elem) + { + Matrix<T> res(_dimX,_dimY); + + for(int i = 0; i < (_dimX*_dimY); i++) + res[i] = _matrix[i] * elem; + + return Matrix(res); + } + + Matrix<T> &operator*=(const T &elem) + { + for(int i = 0; i < (_dimX*_dimY); i++) + _matrix[i] *= elem; + + return (*this); + } + + Matrix<T> operator+(const Matrix<T> &m) + { + int x = (m.dimX()!=_dimX?0:_dimX); + int y = (m.dimY()!=_dimY?0:_dimY); + + Matrix<T> res(x,y); + + for(int i = 0; i < (x*y); i++) + res[i] = _matrix[i] + m[i]; + + return Matrix<T>(res); + } + + Matrix<T> &operator+=(const Matrix<T> &m) + { + int x = (m.dimX()!=_dimX?0:_dimX); + int y = (m.dimY()!=_dimY?0:_dimY); + + for(int i = 0; i < (x*y); i++) + _matrix[i] += m[i]; + + return (*this); + } + + Matrix<T> operator-(const Matrix<T> &m) + { + Matrix<T> res(); + + res = m * inverso; + return (*this) + res; + } + + + Matrix<T> &operator-=(const Matrix<T> &m) + { + Matrix<T> res(); + + res = m * inverso; + (*this) += res; + + return (*this); + } + + Matrix<T> Traspuesta() + { + Matrix<T> res(_dimY,_dimX); + + for(int i = 0; i < _dimX; i++) + for(int j = 0; j < _dimY; j++) + res(j,i) = (*this)(i,j); + + return Matrix<T>(res); + } + + Matrix<T> &nula() + { + for(int i = 0; i < (_dimX*dimY); i++) + _matrix[i] = nulo; + + return (*this); + } + + Matrix<T> &identity() + { + register int k = 0; + + for(int i = 0; i < _dimX; i++) + for(int j = 0; j < _dimY; j++) + { + _matrix[k] = (i!=j?nulo:neutro); + k++; + } + + return (*this); + } + + unsigned int size() const + { + return (sizeof(T)*_dimX*_dimY); + } + + char *to_string() const + { + return (char *) _matrix; + } + + Matrix<T> &to_Matrix(char *_cadena) + { + T *ptr = (T *)_cadena; + + for(int i = 0; i < (_dimX*_dimY) ; i++) + { + _matrix[i] = *ptr; + ptr++; + } + + return (*this); + } + + + int dimX() const + { + return _dimX; + } + + int dimY() const + { + return _dimY; + } + + void remove() + { + if(_matrix != NULL) + delete [] _matrix; + } +}; + +#endif diff --git a/ProyectoFinal/CHC/malva/src/Messages.h b/ProyectoFinal/CHC/malva/src/Messages.h new file mode 100644 index 0000000000000000000000000000000000000000..e46b1d823977e76b1c942dda51104206102cc62f --- /dev/null +++ b/ProyectoFinal/CHC/malva/src/Messages.h @@ -0,0 +1,112 @@ +/*****************************************************************************/ +/*** ***/ +/*** Modificado por G.J.L.P. ***/ +/*** Añadidos nuevos mensajes que indican falta de algún ***/ +/*** Fichero de Configuración (No específico para ningún ***/ +/*** problema) o nuevos errores. ***/ +/*** ***/ +/*****************************************************************************/ + +#ifndef RLFAP_MESSAGES +#define RLFAP_MESSAGES + +#ifndef MAX_BUFFER +#define MAX_BUFFER 200 +#endif + +#include <iostream> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +using namespace std; + +inline void show_message(int value) +{ + switch (value) + { + case 1: cout << endl << "Error: number of arguments in the execution call is incorrect !!" + << endl; break; + case 2: cout << endl << "Error: It's imposible find Configuration file !!" << endl; + break; + /* Específicos de RLFAP */ + case 3: cout << endl << "Error: It is imposible find the Celar problem definition file (cst.txt) !!" + << endl; break; + case 4: cout << endl << "Error: It is imposible find the Celar domains file (dom.txt) !!" + << endl; break; + case 5: cout << endl << "Error: It is imposible find the Celar links file (var.txt) !!" + << endl; break; + case 6: cout << endl << "Error: It is imposible find the Celar constraints file (ctr.txt) !!" + << endl; break; + /* Fallos de Memoria */ + case 7: cout << endl << "Error: No avalible memory for \"malloc\" operation !!" << endl; + break; + case 8: cout << endl << "Error: in \"free\" operation !!" << endl; + break; + /* Específicos del MaxCut */ + case 9: cout << endl << "Error: It is imposible find the Maxcut file (Maxcut.txt) !!" + << endl; break; + /* Genéricos de Falta de ficheros de configuracion adicionales al mensaje 2 */ + case 10: cout << endl << "Error: It's imposible find Configuration file (Config.cfg) !!" + << endl; break; + case 11: cout << endl << "Error: It's imposible find Skeleton Configuration File (Ske.cfg) !!" + << endl; break; + case 12: cout << endl << "Error: It's imposible find Instance Problem File !!" << endl; + break; + case 13: cout << endl << "Error: It's imposible find Resultate File !!" << endl; + break; + case 14: cout << endl << "Error: Index out of Range !!" << endl; + break; + default: cout << endl << "Unkown Error !!" << endl; + } + + cout << endl << " " << endl; + exit(-1); +} + +inline void continue_question() +{ + fflush(stdout); + cout << endl << "Press any key to continue..." << endl; + fflush(stdin); + getc(stdin); +} + +inline void get_path(const char *source,char *target) +{ + int last = 0; + + for(int i = 0; i < strlen(source); i++) + { + target[i] = source[i]; + if(target[i] == '/') + last = i; + } + target[last+1] = '\0'; +} + +inline unsigned count_lines(char *file_name) // returns the number of lines of a file +{ + char line[MAX_BUFFER]; + FILE *file; + int count=0; + + if ((file=fopen(file_name,"r"))==NULL) + { + fflush(stdout); + printf("File not found !"); + } + + while (!feof(file)) + { + if (fgets(line,MAX_BUFFER,file)) count++; + else + { + fclose(file); + break; + } + } + return count; +} + +#endif diff --git a/ProyectoFinal/CHC/malva/src/Rarray.h b/ProyectoFinal/CHC/malva/src/Rarray.h new file mode 100644 index 0000000000000000000000000000000000000000..5d1a1c24919e00e84e1c1bf889021e2c04054dba --- /dev/null +++ b/ProyectoFinal/CHC/malva/src/Rarray.h @@ -0,0 +1,145 @@ +/****************************************************************************** +*** *** +*** Template para el manejo dinámico de arrays *** +*** Añadido métodos para invertir todo o parte del array. *** +*** *** +******************************************************************************/ + +#ifndef ARRAY_INC +#define ARRAY_INC 1 +#include <iostream> +#include <assert.h> + +using namespace std; + +template<class E1> class Rarray +{ + private: + E1 *first; + int count; + + public: + Rarray() + { + first = NULL; + count = 0; + } + + ~Rarray() + { + remove(); + } + + E1* get_first() const + { + return first; + } + + void message_a(int cod) const + { + switch (cod) + { + case 1: cout << endl << "The size of array must be upper that 0 !!!" ; + } + } + + Rarray(const int size_a) + { + if (size_a<0) message_a(1); + first = new E1[size_a]; + count=size_a; + } + + void remove() + { + if (count!=0) + delete [] first; + } + + int size() const + { + return count; + } + + E1& operator[](int pos) const + { + return (E1&)(*(first + pos)); + } + + friend ostream& operator<< (ostream& os,const Rarray<E1>& a) + { + for (int i=0;i<a.size();i++) + os << endl << a[i]; + return os; + } + + Rarray<E1>& operator=(const Rarray<E1>& source) + { + remove(); + count = source.size(); + first = new E1[count]; + + for (int i=0;i<count;i++) + (*this)[i] = source[i]; + + return (*this); + } + + + Rarray<E1>& invert() + { + return invert(0,count-1); + } + + Rarray<E1>& invert(const int pos1, const int pos2) + { + int max,min,half,i,j; + E1 aux; + + if(pos1 > pos2) + { + max = pos1; + min = pos2; + } + else + { + max = pos2; + min = pos1; + } + + assert((min > 0) || (min < count-1)); + half = ((max-min)/2) + 1; + + for(i = min,j=max; i< half; i++,j--) + { + aux = first[min]; + first[min] = first[max]; + first[max] = aux; + } + + return (*this); + } + + Rarray<E1>& sort(int (*comp)(const E1 &,const E1 &)) + { + E1 aux; + int j; + + for (int i=1; i < count ; i++) + { + aux = first[i]; + j = i - 1; + while ( (comp(aux,first[j])) && (j >= 0) ) + { + first[j+1]= first[j]; + j--; + } + first[j+1] = aux; + } + + return (*this); + } + +}; // end of class + +#endif diff --git a/ProyectoFinal/CHC/malva/src/Rlist.h b/ProyectoFinal/CHC/malva/src/Rlist.h new file mode 100644 index 0000000000000000000000000000000000000000..f561d0bcd49bbffc7fe449f74252df988343f2ff --- /dev/null +++ b/ProyectoFinal/CHC/malva/src/Rlist.h @@ -0,0 +1,415 @@ +/****************************************************************************** +*** *** +*** Este template sirve para el manejo de listas din�micas *** +*** *** +******************************************************************************/ + +#ifndef LIST_INC +#define LIST_INC 1 +#include <iostream> +#include <stdlib.h> +#include <Messages.h> + +using namespace std; + +template<class E> class Rlist_item +{ + public: + E *useful_data; // pointer to the structure stored in the list + Rlist_item<E> *next; + Rlist_item<E> *previous; + + Rlist_item(E& new_data) + { + useful_data=&new_data; + next=NULL; + previous=NULL; + } + + Rlist_item(E *new_data) + { + useful_data=new_data; + next=NULL; + previous=NULL; + } + + ~Rlist_item() + { + } + + Rlist_item<E>& next_item() + { + return *(next); + } + + Rlist_item<E>& previous_item() + { + return *(previous); + } + + bool is_last() + { + return (next==NULL); + } + + bool is_first() + { + return (previous==NULL); + } + + E& data() + { + return *(useful_data); + } +}; + +template<class E> class Rlist +{ + private: + Rlist_item<E> *first; // first item in the list + Rlist_item<E> *last; // last item un the list + int count; // number of items in the list + + public: + // constructor + Rlist() + { + first=NULL; + last=NULL; + count=0; + } + + // destructor + ~Rlist() + { + remove(); + } + + // Return the size of the list + int size() const + { return count; } + + // Go back to the initial state of the list + void reset() + { + first=NULL; + last=NULL; + count=0; + } + + // Add a item at the final of the list + Rlist<E>& append(E& new_item) + { + Rlist_item<E> *new_Rlist_item=new Rlist_item<E>(new_item); + if (first==NULL) + { + first=new_Rlist_item; + new_Rlist_item->next=NULL; + new_Rlist_item->previous=NULL; + } + else + { + last->next=new_Rlist_item; + new_Rlist_item->previous=last; + } + last=new_Rlist_item; + count++; + return *this; + } + + Rlist<E>& append(E *new_item) + { + append(*new_item); + return (*this); + } + + // Add a item in a position ( pos ) of the list + Rlist<E>& add_pos(E& new_item, const int pos) + { + if (pos==size()-1) + return append(new_item); + + if (pos==-1) + return add(new_item,NULL); + else + return add(new_item,get_at(pos).useful_data); + } + + // Add a item in the list in the position next to "previous item" + Rlist<E>& add(E& new_item,E *previous_item) + { + if (first==NULL) + return append(new_item); + + Rlist_item<E> *new_Rlist_item=new Rlist_item<E>(new_item); + + if (previous_item==NULL) // Add the item like the first of the list + { + new_Rlist_item->next=first; + new_Rlist_item->previous=NULL; + first->previous=new_Rlist_item; + first=new_Rlist_item; + } + else + { + int previous_position=get_position(*previous_item); + if (previous_position==-1) return(*this); + Rlist_item<E> *previous_Rlist_item = &( get_at(previous_position)); + new_Rlist_item->next=previous_Rlist_item->next; + new_Rlist_item->previous=previous_Rlist_item; + if (previous_Rlist_item->next!=NULL) + (previous_Rlist_item->next)->previous=new_Rlist_item; + else last=new_Rlist_item; + previous_Rlist_item->next=new_Rlist_item; + } + count++; + return *this; + } + + // Return a pointer to the first item of the list + Rlist_item<E> *get_first() const + { return first; } + + // Assign a item like the first item in the list + void set_first(Rlist_item<E> *new_first) + { first=new_first; } + + // Return a pointer to the last item of the list + Rlist_item<E> *get_last() const + { return last; } + + // Assign a item like the last item in the list + void set_last(Rlist_item<E> *new_last) + { last=new_last; } + + // Return the item at position "pos" + E& operator[](int pos) const + { + return *(get_at(pos).useful_data); + } + + // Return the Rlist_item at position "pos" + Rlist_item<E>& get_at(int pos) const + { + Rlist_item<E> *present=first; + for (int k=0;k<size();k++) + if (k==pos) return *present; + else present=present->next; + } + + // Return the item position in the list + int get_position(const E& item) const // probado + { + Rlist_item<E> *present=first; + int i=0; + + while(present!=NULL) + { + if (present->useful_data==&item) return i; + i++; + present=present->next; + } + return -1; // the object has not been found + } + + // Delete a item of the list + Rlist<E>& delete_item(E& item) + { + int position = get_position(item); + + if (position==-1) return *this; + Rlist_item<E> *present=&(get_at(position)); + + if (&item==first->useful_data) // is the first + { + if (&item==last->useful_data) + { + delete(first->useful_data); + delete(first); + first=NULL; + last=NULL; + count=0; + } + else + { + first=first->next; + first->previous=NULL; + delete(present->useful_data); + delete(present); + count--; + } + } + else + { + if (&item==last->useful_data) + { + last=present->previous; + last->next=NULL; + delete(present->useful_data); + delete(present); + count--; + } + else + { + (present->next)->previous=present->previous; + (present->previous)->next=present->next; + delete(present->useful_data); + delete(present); + count--; + } + } + return *this; + } + + // Delete a item of the list without free the useful_data + Rlist<E>& delete_item_1(E& item) + { + int position = get_position(item); + + if (position==-1) return *this; + Rlist_item<E> *present=&(get_at(position)); + + if (&item==first->useful_data) // is the first + { + if (&item==last->useful_data) + { + delete(first); + first=NULL; + last=NULL; + count=0; + } + else + { + first=first->next; + first->previous=NULL; + delete(present); + count--; + } + } + else + { + if (&item==last->useful_data) + { + last=present->previous; + last->next=NULL; + delete(present); + count--; + } + else + { + (present->next)->previous=present->previous; + (present->previous)->next=present->next; + delete(present); + count--; + } + } + return *this; + } + + // Delete item at position "pos" + Rlist<E>& delete_item_by_position(const int pos) + { return delete_item(*(get_at(pos).useful_data)); } + + // Delete the last item in the list + Rlist<E>& delete_last() + { return delete_item(*(last->useful_data)); } + + // delete all items in the list + Rlist<E>& remove() + { + Rlist_item<E> *next,*present=first; + while (present!=NULL) + { + next=present->next; + delete(present->useful_data); + delete(present); + present=next; + } + first=NULL; + last=NULL; + count=0; + return *this; + } + + // Join a new list to this list + Rlist<E>& join(Rlist<E>& new_list) + { + if (new_list.size()==0) + return *this; + + if (first==NULL) + { + first=new_list.get_first(); + last=new_list.get_last(); + } + else + { + last->next=new_list.get_first(); + (new_list.get_first())->previous=last; + last = new_list.get_last(); + } + count += new_list.size(); + new_list.reset(); + return *this; + } + + // Show items of the list + friend ostream& operator<<(ostream& os, const Rlist<E>& list) + { + Rlist_item<E> *present=list.get_first(); + if (list.get_first()==NULL) os << endl << "THE LIST IS EMPTY !!"; + while (present!=NULL) + { + os << endl << (*(present->useful_data)); + // Falta el operador para stat. + // (habra que ver) + present=present->next; + } + return os; + } + + // Copy the list passed + Rlist<E>& operator=(const Rlist<E>& source) + { + E *new_item; + remove(); + if (source.first==NULL && source.last==NULL) + { + first=NULL; + last=NULL; + count=0; + } + else + { + for (int i=0;i<source.size();i++) + { + if ((new_item=(E *)malloc(sizeof(E)))==NULL) + show_message(7); + (*new_item)=*(source.get_at(i).useful_data); + append(*new_item); + } + } + return *this; + } + + // Invert the order of items in the list + Rlist<E>& invert() + { + Rlist_item<E> *present,*interchange; + + present=first; + + for (int i=0;i<size();i++) + { + interchange=present->next; + present->next=present->previous; + present->previous=interchange; + present=interchange; + } + interchange=first; + first=last; + last=interchange; + return (*this); + } +}; // end of class +#endif diff --git a/ProyectoFinal/CHC/malva/src/States.cc b/ProyectoFinal/CHC/malva/src/States.cc new file mode 100644 index 0000000000000000000000000000000000000000..f36d1979373c40068088fb6951f13a126bc033fe --- /dev/null +++ b/ProyectoFinal/CHC/malva/src/States.cc @@ -0,0 +1,228 @@ +/****************************************************************************** + Modified by Carlos Cotta Porras + April 2001 + + Modified by G.J.L.P +******************************************************************************/ + + +#include <string.h> +#include "States.hh" + +// Methods of class State_Vble + + // constructors + State_Vble ::State_Vble () + { + name=NULL; + nitems=0; + length=0; + content=NULL; + } + + State_Vble ::State_Vble (const char *st_name) + { + name=strdup(st_name); + nitems=0; + length=0; + content=NULL; + } + + State_Vble::State_Vble (const char *st_name,StateCenter& sc) + { + name=strdup(st_name); + nitems=0; + length=0; + content=NULL; + sc.add(*this); + } + + State_Vble ::State_Vble (const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length) + { + name=strdup(st_name); + nitems=0; + length=0; + content=NULL; + set_contents(new_contents,new_nitems,new_length); + } + + State_Vble ::State_Vble (const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length,StateCenter& sc) + { + name=strdup(st_name); + nitems=0; + length=0; + content=NULL; + set_contents(new_contents,new_nitems,new_length); + sc.add(*this); + } + + + // Set the name of a state vble. + void State_Vble ::set_name (const char* st_name) // Set the name of a state vble. + { + if (name!=NULL) + free(name); + name=strdup(st_name); + } + + // Get the name of a state vble. + char* State_Vble ::get_name () const // Get the name of a state vble. + { + return name; + } + + // Number of basic items + unsigned long State_Vble ::get_nitems() const // Number of basic items + { + return nitems; + } + + // Get the total number of bytes + unsigned long State_Vble ::get_length () const // Get the total number of bytes + { + return length; + } + + // Fill up a state vble. + void State_Vble ::set_contents (const char *new_contents, unsigned long new_nitems, unsigned long new_length) + { + if (content!=NULL) + free(content); + content=(char *)malloc(new_nitems * new_length); + memcpy(content,new_contents,(new_nitems*new_length)); + nitems=new_nitems; + length=new_length; + } + + // Obtain the contents of a state vble. + void *State_Vble ::get_contents (char *read_contents, unsigned long& read_nitems, unsigned long& read_length) const + { + memcpy(read_contents,content,nitems * length); + read_nitems=nitems; + read_length=length; + return NULL; + } + + ostream& operator<< (ostream& os,const State_Vble& st) + { + os << endl << st.name + << endl << st.nitems + << endl << st.length + << endl << st.content; + + return os; + } + + State_Vble ::~State_Vble () + { + free(content); + free(name); + } + +// Methods of class StateCenter + + StateCenter::StateCenter():state_variables() + {} + + // searchs a state variable + State_Vble *StateCenter::find(const char *st_name) const + { + Rlist_item<State_Vble> *current_state=state_variables.get_first(); + + for (int i=0;i<state_variables.size();i++) + { + if (!(strcmp(current_state->data().get_name(),st_name))) + return &(current_state->data()); + current_state=¤t_state->next_item(); + } + return NULL; + } + + // Add one state variable + void StateCenter::add(State_Vble& st) + { + State_Vble *found_state=find(st.get_name()); + if (found_state==NULL) + state_variables.append(st); + else + cout << endl << "You are trying to introduce a state variable that is yet used in the skeleton !!" << st.get_name(); + } + + void StateCenter::add(State_Vble *st) + { + State_Vble *found_state=find(st->get_name()); + if (found_state==NULL) + state_variables.append(*st); + else + cout << endl << "You are trying to introduce a state variable that is yet used in the skeleton !!" << st->get_name(); + } + + // Remove one state variable + void StateCenter::remove(const char* st_name) + { + State_Vble *found_state=find(st_name); + if (found_state!=NULL) + state_variables.delete_item_1(*found_state); + } + + // Update the contents of one vble. + void StateCenter::update(const char* st_name, const State_Vble& st) const // Update the contents of one vble. + { + State_Vble *found_state=find(st_name); + if (found_state!=NULL) + { + char *a=(char *)malloc(found_state->get_nitems() * found_state->get_length()); + unsigned long nitems,length; + st.get_contents(a,nitems,length); + found_state->set_contents(a,nitems,length); + free(a); + } + } + + // Get a vble. with a given name + State_Vble& StateCenter::get(const char* st_name) const // Get a vble. with a given name + { + State_Vble *found_state=find(st_name); + return *found_state; + } + + // Allows an easy iterated extraction + State_Vble* StateCenter::get_next(const State_Vble& st) const + { + State_Vble *found_state=find(st.get_name()); + if (found_state==NULL) return NULL; + if ( state_variables.get_at(state_variables.get_position(*found_state)).is_last()) return NULL; + else return &(state_variables.get_at(state_variables.get_position(*found_state)).next_item().data()); + } + + // returns the number of state variables + unsigned int StateCenter::size() const + { + return state_variables.size(); + } + + // Obtain the contents of a state vble. of name st_name + void StateCenter::get_contents_state_variable(const char *st_name,char *read_contents, unsigned long& read_nitems, unsigned long& read_length) const + { + get(st_name).get_contents(read_contents,read_nitems,read_length); + } + + // Fill up a state vble.of name st_name + void StateCenter::set_contents_state_variable(const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length) const + { + get(st_name).set_contents(new_contents,new_nitems,new_length); + } + + void StateCenter::removeAll() + { + while(state_variables.get_first()) + { + Rlist_item<State_Vble>* v = state_variables.get_first(); + remove(v->useful_data->get_name()); + } + } + + StateCenter::~StateCenter() + { + removeAll(); + } diff --git a/ProyectoFinal/CHC/malva/src/States.hh b/ProyectoFinal/CHC/malva/src/States.hh new file mode 100644 index 0000000000000000000000000000000000000000..e3a215f5066608ec161882d5ae0c1273944ceaa1 --- /dev/null +++ b/ProyectoFinal/CHC/malva/src/States.hh @@ -0,0 +1,64 @@ +/******************************************************************************************************** +*** *** +*** Class StateCenter: Pool of state variables for skeletons *** +*** *** +*** Class State_Vble: State Variable of a skeleton *** +*** *** +*********************************************************************************************************/ + +#ifndef STATE_CENTER +#define STATE_CENTER 1 + +#include "Rlist.h" +#include <iostream> + +class StateCenter; + +class State_Vble +{ + private: + char *name; + unsigned long nitems; + unsigned long length; + char *content; + + public: + // constructors + State_Vble (); + State_Vble (const char *st_name); + State_Vble (const char *st_name,StateCenter& sc); + State_Vble (const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length); + State_Vble (const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length,StateCenter& sc); + + void set_name (const char* st_name); // Set the name of a state vble. + char* get_name () const; // Get the name of a state vble. + unsigned long get_nitems() const; + unsigned long get_length () const; // Get the total number of bytes + void set_contents (const char *new_contents, unsigned long new_nitems, unsigned long new_length); // Fill up a state vble. + void *get_contents (char *read_contents, unsigned long& read_nitems, unsigned long& read_length) const; // Obtain the contents of a state vble. + friend ostream& operator<< (ostream& os,const State_Vble& st); + ~State_Vble (); +}; + +class StateCenter +{ + private: + Rlist<State_Vble> state_variables; + + public: + StateCenter(); + State_Vble *find(const char *st_name) const; // search a state variable + void add(State_Vble& st); // Add one state variable + void add(State_Vble *st); // Add one state variable + void remove(const char* st_name); // Remove one state variable + void removeAll(); // Removes all variables + void update(const char* st_name, const State_Vble& st) const; // Update the contents of one vble. + State_Vble& get(const char* st_name) const; // Get a vble. with a given name + State_Vble* get_next(const State_Vble& st) const; // Allows an easy iterated extraction + unsigned int size() const; // returns the number of state variables + void get_contents_state_variable(const char *st_name,char *read_contents, unsigned long& read_nitems, unsigned long& read_length) const; // Obtain the contents of a state vble. of name st_name + void set_contents_state_variable(const char *st_name,const char *new_contents, unsigned long new_nitems, unsigned long new_length) const; // Fill up a state vble.of name st_name + ~StateCenter(); +}; + +#endif diff --git a/ProyectoFinal/CHC/malva/src/States.o b/ProyectoFinal/CHC/malva/src/States.o new file mode 100644 index 0000000000000000000000000000000000000000..f5e95c8928fb22e26363c12820d0e56fd98709d2 Binary files /dev/null and b/ProyectoFinal/CHC/malva/src/States.o differ diff --git a/ProyectoFinal/CHC/malva/src/mallba.hh b/ProyectoFinal/CHC/malva/src/mallba.hh new file mode 100644 index 0000000000000000000000000000000000000000..e4a35c07363b0c19d91cf9d5f03f352d0550fd83 --- /dev/null +++ b/ProyectoFinal/CHC/malva/src/mallba.hh @@ -0,0 +1,26 @@ +/***************************************************************************** +*** *** +*** Este fichero hace algunas declaraciones y declara algunos tipos comu- *** +*** nes a todos los algoritmos implementados. *** +*** *** +*****************************************************************************/ + +#ifndef INC_mallba_hh +#define INC_mallba_hh + +#define skeleton namespace +#define requires +#define provides +#define hybridizes(x) +#define inherits typedef +#define as + +enum Direction { minimize=-1,maximize=1}; + +extern const double plus_infinity; +extern const double minus_infinity; + +#define false 0 +#define true 1 + +#endif diff --git a/ProyectoFinal/CHC/malva/src/netstream.cc b/ProyectoFinal/CHC/malva/src/netstream.cc new file mode 100644 index 0000000000000000000000000000000000000000..932e89e56ab5eff64306137bd0ae97b1380a05e2 --- /dev/null +++ b/ProyectoFinal/CHC/malva/src/netstream.cc @@ -0,0 +1,380 @@ +/*************************************************************************** + *** netstream.cc *** + *** v1.6 - July 2001 *** + ** *** + *** v1.5 - March 2001 *** + *** v1.0 - November 2000 *** + *** *** + *** v1.5 extends v1.0: *** + *** .- Changes metods init() and finalize() to be static *** + *** .- Incorporates process group management *** + *** .- Do not consider LEDA anymore *** + *** .- Contains a method "int my_pid()" for easy invokations *** + *** .- Adds "unsigned" and "long double" input/output *** + *** *** + *** v1.6 extends v1.5: *** + ** .- Internal in/out buffers for packed separated *** + *** *** + *** Communication services for LAN/WAN use following the message *** + *** passing paradigm. *** + *** STREAM C++ VERSION *** + *** MPI implementation *** + *** Developed by Erique Alba *** + ***************************************************************************/ +#include "netstream.hh" +// Default constructor +NetStream::NetStream() +{ + this->reset(); // Reset to default values member variables + packin_buffer = new char[MAX_PACK_BUFFER_SIZE]; + packout_buffer = new char[MAX_PACK_BUFFER_SIZE]; +} +// Init the underlying communication library (MPI) +NetStream::NetStream (int argc, char ** argv) +{ + init(argc,argv); + this->reset(); + packin_buffer = new char[MAX_PACK_BUFFER_SIZE]; + packout_buffer = new char[MAX_PACK_BUFFER_SIZE]; +} +// Default destructor +NetStream::~NetStream() +{ + delete [] packin_buffer; delete [] packout_buffer; + this->reset(); +} +// Give default values to member variables +void NetStream::reset(void) +{ + default_target = default_source = 0; + pack_in_progress = false; + packin_index = packout_index = 0; + pending_input_packet = false; + pack_in = pack_out = false; + broadcast = false; + my_communicator = MPI_COMM_WORLD; +} +// Init the communication system. Invoke it only ONCE +void NetStream::init(int argc, char** argv) +{ + static bool system_up = false; // Is MPI already running? + if (!system_up) + { MPI_Init(&argc,&argv); + system_up = true; + } +} +// Shutdown the communication system. Invoke it ONCE +void NetStream::finalize(void) +{ + MPI_Finalize(); // Unconditional Finalization +} +// BASIC INPUT/OUTPUT SERVICES +// =================================================================================== + +NetStream& NetStream::operator>> (bool& d) +{ rcv(&d,1,NET_BOOL,default_source); return(*this); } + +NetStream& NetStream::operator<< (bool d) +{ send(&d,1,NET_BOOL,default_target); return(*this); } +NetStream& NetStream::operator>> (char& d) +{ rcv(&d,1,NET_CHAR,default_source); return(*this); } +NetStream& NetStream::operator<< (char d) +{ send(&d,1,NET_CHAR,default_target); return(*this); } +NetStream& NetStream::operator>> (short& d) +{ rcv(&d,1,NET_SHORT,default_source); return(*this); } +NetStream& NetStream::operator<< (short d) +{ send(&d,1,NET_SHORT,default_target); return(*this); } +NetStream& NetStream::operator>> (int& d) +{ rcv(&d,1,NET_INT,default_source); return(*this); } +NetStream& NetStream::operator<< (int d) +{ send(&d,1,NET_INT,default_target); return(*this); } +NetStream& NetStream::operator>> (long& d) +{ rcv(&d,1,NET_LONG,default_source); return(*this); } +NetStream& NetStream::operator<< (long d) +{ send(&d,1,NET_LONG,default_target); return(*this); } +NetStream& NetStream::operator>> (float& d) +{ rcv(&d,1,NET_FLOAT,default_source); return(*this); } +NetStream& NetStream::operator<< (float d) +{ send(&d,1,NET_FLOAT,default_target); return(*this); } +NetStream& NetStream::operator>> (double& d) +{ rcv(&d,1,NET_DOUBLE,default_source); return(*this); } +NetStream& NetStream::operator<< (double d) +{ send(&d,1,NET_DOUBLE,default_target); return(*this); } +NetStream& NetStream::operator>> (char* d) +{ rcv(d,MAX_MSG_LENGTH,NET_CHAR,default_source); return(*this); } +NetStream& NetStream::operator<< (char* d) +{ send(d,strlen(d)+1,NET_CHAR,default_target); return(*this); } +NetStream& NetStream::operator>> (void* d) +{ rcv(d,MAX_MSG_LENGTH,NET_CHAR,default_source); return(*this); } +NetStream& NetStream::operator<< (void* d) +{ send(d,strlen((char*)d)+1,NET_CHAR,default_target); return(*this); } +// Extended data types from version 1.5 on +NetStream& NetStream::operator>> (unsigned char& d) +{ rcv(&d,MAX_MSG_LENGTH,NET_UNSIGNED_CHAR,default_source);return(*this); } + +NetStream& NetStream::operator<< (unsigned char d) +{ send(&d,1,NET_UNSIGNED_CHAR,default_target); return(*this); } +NetStream& NetStream::operator>> (unsigned short int& d) +{ rcv(&d,MAX_MSG_LENGTH,NET_UNSIGNED_SHORT,default_source);return(*this); } +NetStream& NetStream::operator<< (unsigned short int d) +{ send(&d,1,NET_UNSIGNED_SHORT,default_target); return(*this); } +NetStream& NetStream::operator>> (unsigned int& d) +{ rcv(&d,MAX_MSG_LENGTH,NET_UNSIGNED,default_source); return(*this); } + +NetStream& NetStream::operator<< (unsigned int d) +{ send(&d,1,NET_UNSIGNED,default_target); return(*this); } +NetStream& NetStream::operator>> (unsigned long int& d) +{ rcv(&d,MAX_MSG_LENGTH,NET_UNSIGNED_LONG,default_source);return(*this); } + +NetStream& NetStream::operator<< (unsigned long int d) +{ send(&d,1,NET_UNSIGNED_LONG,default_target); return(*this); } +NetStream& NetStream::operator>> (long double& d) +{ rcv(&d,MAX_MSG_LENGTH,NET_LONG_DOUBLE,default_source); return(*this); } + +NetStream& NetStream::operator<< (long double d) +{ send(&d,1,NET_LONG_DOUBLE,default_target); return(*this); } +// SET-GET TARGET AND SOURCE PROCESSES +NetStream& __set_target(NetStream& n, const int p) { return n._set_target(p); } +NetStream& NetStream::_set_target(const int p) +{ assert(p>=0); default_target = p; return (*this); } +NetStream& __get_target(NetStream& n, int* p) { return n._get_target(p); } +NetStream& NetStream::_get_target(int* p) +{ *p = default_target; return (*this); } +NetStream& __set_source(NetStream& n, const int p) { return n._set_source(p); } +NetStream& NetStream::_set_source(const int p) +{ /*assert(p>=0);*/ default_source = p; return (*this); } +NetStream& __get_source(NetStream& n, int* p) { return n._get_source(p); } +NetStream& NetStream::_get_source(int* p) +{ *p = default_source; return (*this); } +// Get the number of processes involved in the communications +int NetStream::pnumber(void) +{ int numprocs, rvalue; + rvalue = MPI_Comm_size(my_communicator,&numprocs); + assert(rvalue==MPI_SUCCESS); + return numprocs; +} +// MANIPULATORS: SYNCHRONIZATION AND PACKING SERVICES +// =================================================================================== +// Get the process ID [0, 1, 2, ...] fro the calling process +NetStream& __my_pid(NetStream& n, int* pid) +{ + return n._my_pid(pid); +} +NetStream& NetStream::_my_pid(int* pid) +{ + MPI_Comm_rank(my_communicator,pid); + return (*this); +} +// EASY access to rank - Returns the process ID of the calling process +int NetStream::my_pid(void) +{ int pid; + this->_my_pid(&pid); + return pid; +} +// Sit and wait until all processes are in the same barrier +// Can be used as a MANIPULATOR +NetStream& barrier(NetStream& n) +{ + return n._barrier(); +} +NetStream& NetStream::_barrier(void) +{ int status; + status = MPI_Barrier(my_communicator); + assert(status==MPI_SUCCESS); + return (*this); +} +// Wait for an incoming message in any input stream +NetStream& NetStream::_wait(const int stream_type) // class +{ + int rvalue; + MPI_Status status; + assert(stream_type==regular||stream_type==packed||stream_type==any); + if( ((stream_type==packed) || (stream_type==any) )&& (pending_input_packet) ) + //if( (stream_type==packed) && (pending_input_packet) ) + return (*this); // wait befor packet_begin when already received + rvalue = MPI_Probe(default_source,stream_type,my_communicator,&status); + assert(rvalue==MPI_SUCCESS); + return (*this); +} + +NetStream& NetStream::_wait2(const int stream_type, int& tipo) // class +{ + int rvalue; + MPI_Status status; + assert(stream_type==regular||stream_type==packed||stream_type==any); + if( ((stream_type==packed) || (stream_type==any) )&& (pending_input_packet) ) + //if( (stream_type==packed) && (pending_input_packet) ) + return (*this); // wait befor packet_begin when already received + rvalue = MPI_Probe(default_source,stream_type,my_communicator,&status); + assert(rvalue==MPI_SUCCESS); + if (status.MPI_SOURCE == 0){ + tipo = 1; + } + return (*this); +} +NetStream& __wait(NetStream& n, const int stream_type) // helper +{ + return n._wait(stream_type); +} +// Marks the beginning of a packed information +NetStream& pack_begin(NetStream& n) +{ + return n._pack_begin(); +} +NetStream& NetStream::_pack_begin(void) +{ + int rvalue=MPI_SUCCESS; + MPI_Status status; + if(!pack_in_progress) + { pack_in_progress = true; + packin_index = packout_index = 0; + pack_in = false; + pack_out = false; + if (!pending_input_packet) + { _probe(packed,pending_input_packet); + if(pending_input_packet) + rvalue = MPI_Recv(packin_buffer, MAX_PACK_BUFFER_SIZE, NET_PACKED, + default_source, PACKED_STREAM_TAG, my_communicator, &status); + } + } + return (*this); +} +// Marks the end of a packed and flush it to the net +NetStream& pack_end(NetStream& n) +{ + return n._pack_end(); +} +NetStream& NetStream::_pack_end(void) +{ + int rvalue, mypid; + if (pack_in_progress) + { + if(pack_out) + { if(broadcast) // Packet broadcast + { broadcast = false; + _my_pid(&mypid); + rvalue = MPI_Bcast(packout_buffer,packout_index,NET_PACKED, + mypid,my_communicator); + assert(rvalue==MPI_SUCCESS); + } + else + { rvalue = MPI_Send(packout_buffer, packout_index, NET_PACKED, + default_target,PACKED_STREAM_TAG,my_communicator); + assert(rvalue==MPI_SUCCESS); + } + } + pack_in_progress = false; + pack_in = pack_out = false; + packin_index = packout_index = 0 ; + } + return (*this); +} +// Check whether there are awaiting data +NetStream& probe(NetStream& n, const int stream_type, int& pending) +{ + return n._probe(stream_type, pending); +} +NetStream& NetStream::_probe(const int stream_type, int& pending) +{ + MPI_Status status; + int rvalue; + assert(stream_type==regular||stream_type==packed||stream_type==any); + rvalue = MPI_Iprobe(default_source,stream_type,my_communicator,&pending,&status); + assert(rvalue==MPI_SUCCESS); + return (*this); +} +// Broadcast a message to all the processes +NetStream& broadcast(NetStream& n) +{ + return n._broadcast(); +} +NetStream& NetStream::_broadcast(void) +{ + broadcast = true; + return (*this); +} +// PRIVATE SERVICES +// =================================================================================== +// Usually, the length is the number of bytes for every net type +// When packing we must use in the pack calls the numer of items (length divided by type size) +// Any char is encoded with a leading field of length +void NetStream::send(void* d, const int len, const NET_TYPE type, const int target) +{ + int rvalue = MPI_SUCCESS, length = len; + // PACKING SERVICE + if(pack_in_progress) + { + pack_out = true; + assert(pack_out!=pack_in); // Error condition + if(type==NET_CHAR) + send(&length,sizeof(NET_INT),NET_INT,target); // Recursive call to store string length + else + length = 1; + rvalue = MPI_Pack(d,length,type,packout_buffer,MAX_PACK_BUFFER_SIZE,&packout_index,my_communicator); + assert(rvalue==MPI_SUCCESS); + return; + } + if(broadcast) // Regular broadcast, packed broadcast managed in _pack_end() + { int mypid; + + broadcast = false; + _my_pid(&mypid); + rvalue = MPI_Bcast(d,len,type,mypid,my_communicator); + assert(rvalue==MPI_SUCCESS); + return; + } + rvalue = MPI_Send(d,len,type,target,REGULAR_STREAM_TAG,my_communicator); + assert(rvalue==MPI_SUCCESS); +} +void NetStream::rcv (void* d, const int len, const NET_TYPE type, const int source) +{ MPI_Status status; + int rvalue = MPI_SUCCESS, length=len; + if(pack_in_progress) + { +// if(!pack_in && !pending_input_packet) +// rvalue = MPI_Recv(packin_buffer, MAX_PACK_BUFFER_SIZE, NET_PACKED, +// default_source, PACKED_STREAM_TAG, my_communicator, &status); + pack_in = true; + pending_input_packet = false; + assert(pack_out!=pack_in); + if(type==NET_CHAR) + rcv(&length,sizeof(NET_INT),NET_INT,source); // Gets the string length + else + length = 1; + rvalue = MPI_Unpack(packin_buffer, MAX_PACK_BUFFER_SIZE, &packin_index, d, + length, type, my_communicator); + assert(rvalue==MPI_SUCCESS); + return; + } + + rvalue=MPI_Recv(d,len,type,source,REGULAR_STREAM_TAG,my_communicator,&status); + assert(status.MPI_ERROR==MPI_SUCCESS); + assert(rvalue==MPI_SUCCESS); +} +/////////////////////////////////////// GROUP MANAGEMENT //////////////////////////////// +// Set the netstream to a new communicator +void NetStream::set_communicator(NET_Comm comm) +{ + my_communicator = comm; +} +// Get the present communicator in this netstream +NET_Comm NetStream::get_communicator(void) +{ + return my_communicator; +} +// Create a new group inside the present communicator +NET_Comm NetStream::create_group(NET_Comm comm, int color, int key) +{ int rvalue; + NET_Comm newcomm; + rvalue=MPI_Comm_split(comm,color,key,&newcomm); + assert(rvalue==MPI_SUCCESS); + return newcomm; +} +// Create a bridge between local and remote MATCHING call +NET_Comm NetStream::create_inter_group(NET_Comm lcomm, int lrank, NET_Comm bcomm, int rrank, int strtype) +{ int rvalue; + NET_Comm newcomm; + rvalue=MPI_Intercomm_create(lcomm,lrank,bcomm,rrank,strtype,&newcomm); + assert(rvalue==MPI_SUCCESS); + return newcomm; +} diff --git a/ProyectoFinal/CHC/malva/src/netstream.hh b/ProyectoFinal/CHC/malva/src/netstream.hh new file mode 100644 index 0000000000000000000000000000000000000000..5c24a3dc072e2d1dbed9ebecef2b7d6190e51683 --- /dev/null +++ b/ProyectoFinal/CHC/malva/src/netstream.hh @@ -0,0 +1,161 @@ +/*************************************************************************** + *** netstream.cc *** + *** v1.6 - July 2001 *** + ** *** + *** v1.5 - March 2001 *** + *** v1.0 - November 2000 *** + *** *** + *** v1.5 extends v1.0: *** + *** .- Changes metods init() and finalize() to be static *** + *** .- Incorporates process group management *** + *** .- Do not consider LEDA anymore *** + *** .- Contains a method "int my_pid()" for easy invokations *** + *** .- Adds "unsigned" and "long double" input/output *** + *** *** + *** v1.6 extends v1.5: *** + ** .- Internal in/out buffers for packed separated *** + *** *** + *** Communication services for LAN/WAN use following the message *** + *** passing paradigm. *** + *** STREAM C++ VERSION *** + *** MPI implementation *** + *** Developed by Erique Alba *** + ***************************************************************************/ +#ifndef INC_netstream +#define INC_netstream +#include "mpi.h" +#include <assert.h> +#include <string.h> +// Class NetStream allows to define and use network streams trhough LAN and WAN +#define REGULAR_STREAM_TAG 0 // Used for tagging MPI regular messages +#define PACKED_STREAM_TAG 1 // Used for tagging MPI packet messages +#define NET_TYPE MPI_Datatype // Network allowable data types +#define NET_BOOL MPI_CHAR // Bools like chars +#define NET_CHAR MPI_CHAR +#define NET_SHORT MPI_SHORT +#define NET_INT MPI_INT +#define NET_LONG MPI_LONG +#define NET_UNSIGNED_CHAR MPI_UNSIGNED_CHAR +#define NET_UNSIGNED_SHORT MPI_UNSIGNED_SHORT +#define NET_UNSIGNED MPI_UNSIGNED +#define NET_UNSIGNED_LONG MPI_UNSIGNED_LONG +#define NET_FLOAT MPI_FLOAT +#define NET_DOUBLE MPI_DOUBLE +#define NET_LONG_DOUBLE MPI_LONG_DOUBLE +#define NET_BYTE MPI_BYTE +#define NET_PACKED MPI_PACKED +#define NET_Comm MPI_Comm +#define MAX_MSG_LENGTH 204800 // Max length of a message +#define MAX_PACK_BUFFER_SIZE 204800 // Max length of a packed message +// Help structure for manipulators having one int& argument +class NetStream; +struct smanip1c // "const int" +{ NetStream& (*f)(NetStream&, const int); // The ONE argument function + int i; // The argument + smanip1c( NetStream&(*ff)(NetStream&,const int), int ii) : f(ff), i(ii) {} // Constuctor +}; +struct smanip1 // "int*" note: references do not work! "int&" +{ NetStream& (*f)(NetStream&, int*); // The ONE argument function + int* i; // The argument + smanip1( NetStream&(*ff)(NetStream&, int*), int* ii) : f(ff), i(ii) {} // Constuctor +}; +// Tags for the available streams +const int any = MPI_ANY_TAG; // Tag value valid for any stream +const int regular = REGULAR_STREAM_TAG; // Tag value for regular stream of data +const int packed = PACKED_STREAM_TAG; // Tag value for packed stream of data +// Tags for sources +const int any_source = MPI_ANY_SOURCE; // Tag value valid for any source +class NetStream +{ + public: + NetStream (); // Default constructor + // Constructor with source integer left unchanged + NetStream (int, char **); // Init the communications + ~NetStream (); // Default destructor + static void init(int,char**); // Init the communication system. Invoke it only ONCE + static void finalize(void); // Shutdown the communication system. Invoke it ONCE + // GROUP management + void set_communicator(NET_Comm comm); // Set the netstream to a new communicator + NET_Comm get_communicator(void); // Get the present communicator in this netstream + static NET_Comm create_group(NET_Comm comm, int color, int key); // Create a new group inside the present communicator + // Create a bridge between local and remote MATCHING call + static NET_Comm create_inter_group(NET_Comm lcomm, int lrank, NET_Comm bcomm, int rrank, int strtrype); + +// BASIC INPUT SERVICES <comments> BASIC OUTPUT SERVICES +// ============================================================================================================ + NetStream& operator>> (bool& d); NetStream& operator<< (bool d); + NetStream& operator>> (char& d); NetStream& operator<< (char d); + NetStream& operator>> (short& d); NetStream& operator<< (short d); + NetStream& operator>> (int& d); NetStream& operator<< (int d); + NetStream& operator>> (long& d); NetStream& operator<< (long d); + NetStream& operator>> (float& d); NetStream& operator<< (float d); + NetStream& operator>> (double& d); NetStream& operator<< (double d); + NetStream& operator>> (char* d); /*NULL terminated*/ NetStream& operator<< (char* d); + NetStream& operator>> (void* d); /*NULL terminated*/ NetStream& operator<< (void* d); + // Extended data types from version 1.5 on + NetStream& operator>> (unsigned char& d); NetStream& operator<< (unsigned char d); + NetStream& operator>> (unsigned short int& d); NetStream& operator<< (unsigned short int d); + NetStream& operator>> (unsigned int& d); NetStream& operator<< (unsigned int d); + NetStream& operator>> (unsigned long int& d); NetStream& operator<< (unsigned long int d); + NetStream& operator>> (long double& d); NetStream& operator<< (long double d); + int pnumber(void); // Returns the number of processes + bool broadcast; // Determines whether the next sent message is for broadcasting + // Input MANIPULATORS for modifying the behavior of the channel on the fly + // NO ARGUMENTS + NetStream& operator<< (NetStream& (*f)(NetStream& n)) { return f(*this); } // NO arguments + NetStream& _barrier(void); // Sit and wait until all processes are in barrier + NetStream& _pack_begin(void); // Marks the beginning of a packed information + NetStream& _pack_end(void); // Marks the end of a packed and flush it to the net + NetStream& _probe(const int stream_type, int& pending); // Check whether there are awaiting data + NetStream& _broadcast(void); // Broadcast a message to all the processes + // ONE ARGUMENT + // "const int" + NetStream& operator<< (smanip1c m) { return m.f((*this),m.i); }// ONE int& argument constant + // "int*" + NetStream& operator<< (smanip1 m) { return m.f((*this),m.i); }// ONE int& argument + // BASIC CLASS METHODS FOR MANIPULATORS + NetStream& _my_pid(int* pid); // Returns the process ID of the calling process + NetStream& _wait(const int stream_type); // Wait for an incoming message in the specified stream + NetStream& _wait2(const int stream_type, int& tipo); + NetStream& _set_target(const int p); // Stablish "p" as the default receiver + NetStream& _get_target(int* p); // Get into "p" the default receiver + NetStream& _set_source(const int p); // Stablish "p" as the default transmitter + NetStream& _get_source(int* p); // Get into "p" the default transmitter + // AUXILIAR PUBLIC METHODS FOR ALLOWING EASY MANAGEMENTS OF NETSTREAMS + int my_pid(void); // Returns the process ID of the calling process + private: + int default_target, default_source; // Default process IDs to send-recv data to-from + bool pack_in_progress; // Defines whether a packet is being defined with "pack_begin-pack_end" + int packin_index; // Index to be used for extracting from a IN packed message - v1.6 + int packout_index; // Index to be used for adding to an OUT packed message - v1.6 + int pending_input_packet;//Is there a pending packet already read into the IN buffer? - v1.6 + char* packin_buffer; // Buffer to temporary storage of the IN packed being defined - v1.6 + char* packout_buffer; // Buffer to temporary storage of the OUT packed being defined - v1.6 + bool pack_in, pack_out; // Define whether input-output packed message is being used + void reset(void); // Reset member variables of this class + NET_Comm my_communicator; // Communicator of this netstream + void send(void* d, const int len, const NET_TYPE type, const int target); + void rcv (void* d, const int len, const NET_TYPE type, const int source); +}; // class NetStream + // MANIPULATORS (must be static or non-member methods in C++ -mpiCC only allows non-member!-) + // NO ARGUMENTS + NetStream& barrier(NetStream& n); // Sit and wait until all processes are in barrier + NetStream& broadcast(NetStream& n); // Broadcast a message to all the processes + NetStream& pack_begin(NetStream& n); // Marks the beginning of a packed information + NetStream& pack_end(NetStream& n); // Marks the end of a packed and flush it to the net + // ONE ARGUMENT + NetStream& __my_pid(NetStream& n, int* pid); // Returns the process ID of the calling process + inline smanip1 my_pid(int* pid){ return smanip1(__my_pid,pid); } // manipulator + NetStream& __wait(NetStream& n, const int stream_type);// Wait for an incoming message - helper + inline smanip1c wait(const int stream_type){ return smanip1c(__wait,stream_type); } // manipulator + NetStream& __set_target(NetStream& n, const int p); // Stablish "p" as the default receiver + inline smanip1c set_target(const int p){ return smanip1c(__set_target,p); } // manipulator + NetStream& __get_target(NetStream& n, int* p); // Get into "p" the default receiver + inline smanip1 get_target(int* p){ return smanip1(__get_target,p); } // manipulator + NetStream& __set_source(NetStream& n, const int p); // Stablish "p" as the default transmitter + inline smanip1c set_source(const int p){ return smanip1c(__set_source,p); } // manipulator + NetStream& __get_source(NetStream& n, int* p); // Get into "p" the default transmitter + inline smanip1 get_source(int* p){ return smanip1(__get_source,p); } // manipulator + // TWO ARGUMENTS - not used yet + NetStream& probe(NetStream& n, const int stream_type, int& pending); // Check whether there are awaiting data +#endif diff --git a/ProyectoFinal/CHC/malva/src/netstream.o b/ProyectoFinal/CHC/malva/src/netstream.o new file mode 100644 index 0000000000000000000000000000000000000000..fb40ece360fb739d83d40beffbf1b01c031a15aa Binary files /dev/null and b/ProyectoFinal/CHC/malva/src/netstream.o differ diff --git a/ProyectoFinal/CHC/malva/src/random.hh b/ProyectoFinal/CHC/malva/src/random.hh new file mode 100644 index 0000000000000000000000000000000000000000..ae6bde6ae8230c733aeb341be926e21fc5648d94 --- /dev/null +++ b/ProyectoFinal/CHC/malva/src/random.hh @@ -0,0 +1,50 @@ +/****************************************************************************** +*** *** +*** Este fichero contiene funciones (en general inlines) para generar núme- *** +*** ros aleatorios y otras funciones relacionadas con ello *** +*** *** +*******************************************************************************/ + +#ifndef INC_random_hh +#define INC_random_hh + +#include <stdlib.h> + + +inline double undefined () +{ + double zero = 0; + return zero/zero; +} + +// Returns a valeu greater than any other +inline double infinity () +{ + double one=1.0; + double zero=0.0; + return one/zero; +} + +// Returns a random number in [0,1]. +inline double rand01 () +{ + return drand48(); +} + +// Returns a random number +inline int rand_int (float min,float max) +{ + int value=rand(); + int range= (int)(max - min); + int order = value % (range+1); + return ((int)min + order); +} + +// selects a seed +inline void random_seed(long int seed) +{ + srand48(seed); + srand(seed); +} + +#endif diff --git a/ProyectoFinal/CHC/malva/src/time.hh b/ProyectoFinal/CHC/malva/src/time.hh new file mode 100644 index 0000000000000000000000000000000000000000..088f4d5ea51f4a597ec1f0609ae5e175eae0a055 --- /dev/null +++ b/ProyectoFinal/CHC/malva/src/time.hh @@ -0,0 +1,43 @@ +/****************************************************************************** +*** *** +*** Este fichero incluye algunas funciones útiles para la medicion de tiem- *** +*** pos. *** +*** *** +******************************************************************************/ + +#ifndef INC_time_hh +#define INC_time_hh + +#define MAXTIME 4294 + +#include <time.h> +#include <sys/time.h> +#include <unistd.h> + +// return time in microseconds +inline float _used_time() +{ + struct timeval tv ; + static long tiempo = -1; + float u_clock; + + gettimeofday(&tv,NULL); + + if(tiempo < 0) tiempo = tv.tv_sec; + + u_clock = ((float)(tv.tv_sec - tiempo)*1000000.0) + ((float)tv.tv_usec); + return u_clock; + +} + + +inline float _used_time(float time) +{ + float dif=_used_time() - time; + if (dif<0) dif = 0; + return dif; +} + + + +#endif diff --git a/ProyectoFinal/CHC/malva/stat/file_stat_aco b/ProyectoFinal/CHC/malva/stat/file_stat_aco new file mode 100644 index 0000000000000000000000000000000000000000..8426ce41ac5119b9755a1efa3fb86f0dbffa2076 --- /dev/null +++ b/ProyectoFinal/CHC/malva/stat/file_stat_aco @@ -0,0 +1,12 @@ +#!/bin/bash + +lines=`cat $1 | wc -l` +head_op=$(($lines - 1)) +tail_op=$(($head_op - 5)) + +head -n $head_op $1 | tail -n $tail_op | gawk '{print $2}' > $1.best_fit +head -n $head_op $1 | tail -n $tail_op | gawk '{print $3}' > $1.worse_fit +head -n $head_op $1 | tail -n $tail_op | gawk '{print $5}' > $1.iter +head -n $head_op $1 | tail -n $tail_op | gawk '{print $6}' > $1.time +head -n $head_op $1 | tail -n $tail_op | gawk '{print $7}' > $1.total_time +echo $tail_op > $1.num_exec diff --git a/ProyectoFinal/CHC/malva/stat/file_stat_pop b/ProyectoFinal/CHC/malva/stat/file_stat_pop new file mode 100644 index 0000000000000000000000000000000000000000..8512575c9d1b84198ff3c895d26986950acf5591 --- /dev/null +++ b/ProyectoFinal/CHC/malva/stat/file_stat_pop @@ -0,0 +1,13 @@ +#!/bin/bash + +lines=`cat $1 | wc -l` +head_op=$(($lines - 1)) +tail_op=$(($head_op - 5)) + +head -n $head_op $1 | tail -n $tail_op | gawk '{print $2}' > $1.best_fit +head -n $head_op $1 | tail -n $tail_op | gawk '{print $3}' > $1.worse_fit +head -n $head_op $1 | tail -n $tail_op | gawk '{print $3}' > $1.eval +head -n $head_op $1 | tail -n $tail_op | gawk '{print $5}' > $1.iter +head -n $head_op $1 | tail -n $tail_op | gawk '{print $6}' > $1.time +head -n $head_op $1 | tail -n $tail_op | gawk '{print $7}' > $1.total_time +echo $tail_op > $1.num_exec diff --git a/ProyectoFinal/CHC/malva/stat/file_stat_pso b/ProyectoFinal/CHC/malva/stat/file_stat_pso new file mode 100644 index 0000000000000000000000000000000000000000..672f85797195fd2fa2ec8a64a4c869d40afba124 --- /dev/null +++ b/ProyectoFinal/CHC/malva/stat/file_stat_pso @@ -0,0 +1,12 @@ +#!/bin/bash + +lines=`cat $1 | wc -l` +head_op=$(($lines - 1)) +tail_op=$(($head_op - 5)) + +head -n $head_op $1 | tail -n $tail_op | gawk '{print $2}' > $1.best_fit +head -n $head_op $1 | tail -n $tail_op | gawk '{print $3}' > $1.worse_fit +head -n $head_op $1 | tail -n $tail_op | gawk '{print $4}' > $1.iter +head -n $head_op $1 | tail -n $tail_op | gawk '{print $5}' > $1.time +head -n $head_op $1 | tail -n $tail_op | gawk '{print $6}' > $1.total_time +echo $tail_op > $1.num_exec diff --git a/ProyectoFinal/CHC/malva/stat/file_stat_sa b/ProyectoFinal/CHC/malva/stat/file_stat_sa new file mode 100644 index 0000000000000000000000000000000000000000..d006462e8b7445d4c971805fd6706bd104ef12d6 --- /dev/null +++ b/ProyectoFinal/CHC/malva/stat/file_stat_sa @@ -0,0 +1,13 @@ +#!/bin/bash + +lines=`cat $1 | wc -l` +head_op=$(($lines - 1)) +tail_op=$(($head_op - 5)) + +head -n $head_op $1 | tail -n $tail_op | gawk '{print $2}' > $1.best_fit +head -n $head_op $1 | tail -n $tail_op | gawk '{print $3}' > $1.eval +head -n $head_op $1 | tail -n $tail_op | gawk '{print $4}' > $1.init_temp +head -n $head_op $1 | tail -n $tail_op | gawk '{print $5}' > $1.best_temp +head -n $head_op $1 | tail -n $tail_op | gawk '{print $6}' > $1.time +head -n $head_op $1 | tail -n $tail_op | gawk '{print $7}' > $1.total_time +echo $tail_op > $1.num_exec diff --git a/ProyectoFinal/CHC/malva/uml-comun.gif b/ProyectoFinal/CHC/malva/uml-comun.gif new file mode 100644 index 0000000000000000000000000000000000000000..e86a0eb3c9795f45438a28d1e81e8e0b6ec2b90b Binary files /dev/null and b/ProyectoFinal/CHC/malva/uml-comun.gif differ