{ "cells": [ { "cell_type": "markdown", "id": "171e1a75-257f-4ef5-a98c-667b9460663d", "metadata": {}, "source": [ "# 3.6.3 Taylor et al 2023" ] }, { "cell_type": "markdown", "id": "c2c6a4f3-7a9f-417d-b8c7-c9215da5f142", "metadata": {}, "source": [ "This is used in the paper **Flexible cable routing framework for wind farm collection system optimization**." ] }, { "cell_type": "code", "execution_count": 1, "id": "bdf5ac5d-ce06-4425-94be-2793edcbf33e", "metadata": {}, "outputs": [], "source": [ "import pickle\n", "from importlib.resources import files" ] }, { "cell_type": "code", "execution_count": 2, "id": "ff8b4268-f6cd-4f4a-82d1-200f208fe9c2", "metadata": {}, "outputs": [], "source": [ "from optiwindnet.interarraylib import G_from_S\n", "from optiwindnet.svg import svgplot\n", "from optiwindnet.mesh import make_planar_embedding\n", "from optiwindnet.baselines.hgs import hgs_cvrp\n", "from optiwindnet.importer import L_from_yaml\n", "from optiwindnet.pathfinding import PathFinder\n", "from optiwindnet.MILP import solver_factory, ModelOptions\n", "from optiwindnet.heuristics import EW_presolver\n", "from optiwindnet.interarraylib import as_normalized" ] }, { "cell_type": "code", "execution_count": 3, "id": "35bb73d8-26c0-4132-bfae-d9438f94e6fe", "metadata": {}, "outputs": [], "source": [ "solver = solver_factory('gurobi')" ] }, { "cell_type": "markdown", "id": "e2c8bb22-2a1f-4fb1-bafd-bbc3528057f4", "metadata": {}, "source": [ "## Reference solution" ] }, { "cell_type": "markdown", "id": "e8ec0a99-6d06-4d36-9da8-ed28a8831646", "metadata": {}, "source": [ "Taylor, P., Yue, H., Campos-Gaona, D., Anaya-Lara, O., & Jia, C. (2023). Wind farm array cable layout optimisation for complex offshore sites—A decomposition based heuristic approach. IET Renewable Power Generation, 17(2), 243–259. https://doi.org/10.1049/rpg2.12593" ] }, { "cell_type": "code", "execution_count": 4, "id": "2b6f398d-6333-4090-a329-cd5a0d7a2b47", "metadata": {}, "outputs": [], "source": [ "G_ref = pickle.load(open('data/taylor_2023_paper_routeset.pkl', 'rb'))" ] }, { "cell_type": "code", "execution_count": 5, "id": "37fbe442-9722-4d7f-918f-c97a7e9ed5e1", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "Σλ = 104 312 m(+2) [-1]: 7, [-2]: 6κ = 12, T = 122" ], "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "svgplot(G_ref)" ] }, { "cell_type": "markdown", "id": "8308f53d-4b45-4c3d-9b71-26ff4b4ef519", "metadata": {}, "source": [ "## Start here" ] }, { "cell_type": "code", "execution_count": 6, "id": "ed9067bb-250e-4a1a-981b-f586bc7f5985", "metadata": {}, "outputs": [], "source": [ "L = L_from_yaml(files('optiwindnet.data') / 'Taylor-2023.yaml')" ] }, { "cell_type": "code", "execution_count": 7, "id": "b6fab52e-aa7a-4b9b-bedd-9735db54e982", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "" ], "text/plain": [ "" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "svgplot(L)" ] }, { "cell_type": "code", "execution_count": 8, "id": "d2ae9456-39d5-41c9-9677-d3a280301142", "metadata": {}, "outputs": [], "source": [ "P, A = make_planar_embedding(L)" ] }, { "cell_type": "code", "execution_count": 9, "id": "c65ec31b-4789-4440-b341-df62f28e9f19", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "Σλ = 105 984 m(+3) [-1]: 7, [-2]: 7κ = 12, T = 122" ], "text/plain": [ "" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Sʹ = EW_presolver(A, 12)\n", "Gʹ = G_from_S(Sʹ, A)\n", "Hʹ = PathFinder(Gʹ, planar=P, A=A).create_detours()\n", "svgplot(Hʹ)" ] }, { "cell_type": "code", "execution_count": 10, "id": "22837d22-08fb-402c-b1f9-5d07fd2b7766", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(0.18, 0.17)" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Sʹ = hgs_cvrp(as_normalized(A), capacity=12, time_limit=0.6)\n", "Sʹ.graph['solution_time']" ] }, { "cell_type": "code", "execution_count": 11, "id": "858e13dc-814d-4a79-8d13-f46300659c49", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "Σλ = 103 512 m(+2) [-1]: 6, [-2]: 7κ = 12, T = 122" ], "text/plain": [ "" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Gʹ = G_from_S(Sʹ, A)\n", "Hʹ = PathFinder(Gʹ, planar=P, A=A).create_detours()\n", "svgplot(Hʹ)" ] }, { "cell_type": "code", "execution_count": 12, "id": "9216760f-8edc-4d79-bab0-4baab6a5ce41", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.007668344152415463" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 - Hʹ.size(weight='length')/G_ref.size(weight='length')" ] }, { "cell_type": "code", "execution_count": 13, "id": "1d961d96-a63c-43c4-a283-78e40b6e8d66", "metadata": {}, "outputs": [], "source": [ "solver.set_problem(\n", " P, A,\n", " capacity=Sʹ.graph['capacity'],\n", " model_options=ModelOptions(\n", " topology=\"branched\",\n", " feeder_route=\"segmented\",\n", " feeder_limit=\"unlimited\",\n", " ),\n", " warmstart=Sʹ,\n", ")" ] }, { "cell_type": "code", "execution_count": 14, "id": "d4deede9-2051-4318-b240-f0e790a38daf", "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Gurobi Optimizer version 13.0.1 build v13.0.1rc0 (linux64 - \"Debian GNU/Linux forky/sid\")\n", "\n", "CPU model: 11th Gen Intel(R) Core(TM) i7-11850H @ 2.50GHz, instruction set [SSE2|AVX|AVX2|AVX512]\n", "Thread count: 8 physical cores, 16 logical processors, using up to 16 threads\n", "\n", "Non-default parameters:\n", "TimeLimit 8\n", "MIPGap 0.001\n", "MIPFocus 1\n", "RINS 100\n", "CutPasses 4\n", "\n", "Academic license 937681 - for non-commercial use only - registered to ma___@dtu.dk\n", "Optimize a model with 4316 rows, 2892 columns and 16300 nonzeros (Min)\n", "Model fingerprint: 0x77b4b97b\n", "Model has 1446 linear objective coefficients\n", "Variable types: 0 continuous, 2892 integer (1446 binary)\n", "Coefficient statistics:\n", " Matrix range [1e+00, 1e+01]\n", " Objective range [4e+02, 9e+03]\n", " Bounds range [1e+00, 1e+01]\n", " RHS range [1e+00, 1e+02]\n", "\n", "Loaded user MIP start with objective 103512\n", "\n", "Presolve removed 529 rows and 0 columns\n", "Presolve time: 0.02s\n", "Presolved: 3787 rows, 2892 columns, 13798 nonzeros\n", "Variable types: 0 continuous, 2892 integer (1446 binary)\n", "\n", "Root relaxation: objective 9.983546e+04, 2782 iterations, 0.05 seconds (0.07 work units)\n", "\n", " Nodes | Current Node | Objective Bounds | Work\n", " Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time\n", "\n", " 0 0 99835.4625 0 133 103512.235 99835.4625 3.55% - 0s\n", "H 0 0 103200.55910 99835.4625 3.26% - 0s\n", "H 0 0 103166.06622 99835.4625 3.23% - 0s\n", "H 0 0 103013.05991 99835.4625 3.08% - 0s\n", "H 0 0 102978.56703 99835.4625 3.05% - 0s\n", "H 0 0 102978.48906 99835.4625 3.05% - 0s\n", "H 0 0 102973.41212 99835.4625 3.05% - 0s\n", "H 0 0 102971.33465 99835.4625 3.05% - 0s\n", "H 0 0 102698.63828 99835.4625 2.79% - 0s\n", "H 0 0 102687.22923 99835.4625 2.78% - 0s\n", "H 0 0 102685.15176 99835.4625 2.78% - 0s\n", "H 0 0 102677.99735 99835.4625 2.77% - 0s\n", "H 0 0 102266.22193 99835.4625 2.38% - 0s\n", "H 0 0 102022.70468 99835.4625 2.14% - 0s\n", " 0 0 100368.185 0 236 102022.705 100368.185 1.62% - 0s\n", "H 0 0 101728.83004 100368.185 1.34% - 0s\n", "H 0 0 100953.95751 100368.185 0.58% - 0s\n", "H 0 0 100953.46423 100368.185 0.58% - 0s\n", "H 0 0 100939.92989 100368.185 0.57% - 0s\n", "H 0 0 100932.27453 100368.185 0.56% - 0s\n", "H 0 0 100916.86258 100368.185 0.54% - 0s\n", " 0 0 100389.423 0 229 100916.863 100389.423 0.52% - 0s\n", " 0 0 100390.106 0 230 100916.863 100390.106 0.52% - 0s\n", " 0 0 100434.413 0 252 100916.863 100434.413 0.48% - 0s\n", " 0 0 100434.413 0 139 100916.863 100434.413 0.48% - 0s\n", " 0 0 100483.339 0 229 100916.863 100483.339 0.43% - 0s\n", " 0 0 100484.023 0 204 100916.863 100484.023 0.43% - 0s\n", " 0 0 100484.030 0 216 100916.863 100484.030 0.43% - 0s\n", " 0 0 100490.604 0 244 100916.863 100490.604 0.42% - 0s\n", " 0 0 100491.550 0 274 100916.863 100491.550 0.42% - 0s\n", " 0 0 100491.675 0 288 100916.863 100491.675 0.42% - 0s\n", " 0 0 100491.723 0 286 100916.863 100491.723 0.42% - 0s\n", "H 0 0 100874.89356 100491.723 0.38% - 0s\n", " 0 0 100511.086 0 258 100874.894 100511.086 0.36% - 0s\n", " 0 0 100512.393 0 243 100874.894 100512.393 0.36% - 0s\n", " 0 0 100512.764 0 243 100874.894 100512.764 0.36% - 0s\n", " 0 0 100512.880 0 299 100874.894 100512.880 0.36% - 0s\n", " 0 0 100512.893 0 252 100874.894 100512.893 0.36% - 0s\n", "H 0 0 100863.60197 100512.893 0.35% - 0s\n", " 0 0 100517.112 0 297 100863.602 100517.112 0.34% - 0s\n", " 0 0 100517.112 0 181 100863.602 100517.112 0.34% - 0s\n", " 0 0 100517.112 0 225 100863.602 100517.112 0.34% - 0s\n", " 0 0 100518.560 0 294 100863.602 100518.560 0.34% - 0s\n", " 0 0 100518.913 0 295 100863.602 100518.913 0.34% - 1s\n", " 0 0 100518.916 0 295 100863.602 100518.916 0.34% - 1s\n", " 0 0 100521.181 0 314 100863.602 100521.181 0.34% - 1s\n", " 0 0 100521.540 0 318 100863.602 100521.540 0.34% - 1s\n", " 0 0 100521.675 0 297 100863.602 100521.675 0.34% - 1s\n", " 0 0 100521.675 0 297 100863.602 100521.675 0.34% - 1s\n", " 0 0 100526.194 0 291 100863.602 100526.194 0.33% - 1s\n", " 0 0 100527.535 0 306 100863.602 100527.535 0.33% - 1s\n", " 0 0 100528.106 0 319 100863.602 100528.106 0.33% - 1s\n", " 0 0 100528.412 0 314 100863.602 100528.412 0.33% - 1s\n", " 0 0 100528.548 0 319 100863.602 100528.548 0.33% - 1s\n", " 0 0 100528.593 0 321 100863.602 100528.593 0.33% - 1s\n", " 0 0 100531.773 0 303 100863.602 100531.773 0.33% - 1s\n", " 0 0 100531.773 0 303 100863.602 100531.773 0.33% - 1s\n", " 0 0 100531.773 0 303 100863.602 100531.773 0.33% - 1s\n", " 0 2 100531.873 0 303 100863.602 100531.873 0.33% - 1s\n", "H 12 16 100855.16790 100536.793 0.32% 132 1s\n", "H 221 200 100852.07827 100536.793 0.31% 62.4 2s\n", "H 304 236 100796.21047 100539.731 0.25% 56.5 2s\n", "H 375 263 100794.97109 100539.731 0.25% 55.1 2s\n", " 2051 1193 100681.706 22 326 100794.971 100561.078 0.23% 42.9 5s\n", "\n", "Cutting planes:\n", " Gomory: 22\n", " Lift-and-project: 1\n", " Implied bound: 22\n", " MIR: 194\n", " StrongCG: 6\n", " Flow cover: 167\n", " Flow path: 19\n", " GUB cover: 2\n", " Inf proof: 16\n", " Zero half: 3\n", " Network: 15\n", " RLT: 2\n", " Relax-and-lift: 4\n", "\n", "Explored 6190 nodes (310870 simplex iterations) in 8.01 seconds (7.27 work units)\n", "Thread count was 16 (of 16 available processors)\n", "\n", "Solution count 10: 100795 100796 100852 ... 100953\n", "\n", "Time limit reached\n", "Best objective 1.007949710936e+05, best bound 1.005978296869e+05, gap 0.1956%\n" ] }, { "data": { "text/plain": [ "SolutionInfo(runtime=8.01302695274353, bound=100597.82968686293, objective=100794.97109360031, relgap=0.001955865502003218, termination='maxTimeLimit')" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "solver.solve(\n", " mip_gap=0.001,\n", " time_limit=8,\n", " verbose=True,\n", " options=dict(\n", " mipfocus=1,\n", " RINS=100,\n", " CutPasses=4,\n", " # VarBranch=1,\n", " )\n", ")" ] }, { "cell_type": "code", "execution_count": 15, "id": "9100aab2-2b32-415b-aa17-89031eea3d92", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "Σλ = 100 795 m(+1) [-1]: 6, [-2]: 6κ = 12, T = 122" ], "text/plain": [ "" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "S, G = solver.get_solution()\n", "\n", "svgplot(G)" ] }, { "cell_type": "code", "execution_count": 16, "id": "08f5b4da-6779-459e-acf3-10eb45a5d307", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.03371769751959075" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 - G.size(weight='length')/G_ref.size(weight='length')" ] }, { "cell_type": "code", "execution_count": 18, "id": "582d5e10-904c-4619-992d-a7c5f5bae5c8", "metadata": {}, "outputs": [], "source": [ "pickle.dump(G, open('Taylor_comparison_κ_12_branched_our.pkl', 'wb'))" ] } ], "metadata": { "language_info": { "name": "python" } }, "nbformat": 4, "nbformat_minor": 5 }