From b6753b5b24710f1a0de26e21548bebf809789296 Mon Sep 17 00:00:00 2001 From: arzba <arzba> Date: Tue, 12 Nov 2024 16:33:18 +0100 Subject: [PATCH] serie2 --- .vscode/launch.json | 2 +- README.md | 6 +- bin/Algorithms.class | Bin 8613 -> 12179 bytes bin/Ant.class | Bin 0 -> 4271 bytes bin/Node.class | Bin 1298 -> 1306 bytes bin/Solution.class | Bin 2953 -> 4529 bytes bin/cvrp_ls.class | Bin 3268 -> 4206 bytes src/Algorithms.class | Bin 5088 -> 9489 bytes src/Algorithms.java | 267 +++++++++++++++++++++++++++++++++++-------- src/Ant.class | Bin 0 -> 3271 bytes src/Ant.java | 140 +++++++++++++++++++++++ src/Node.java | 2 +- src/Solution.class | Bin 2155 -> 3634 bytes src/Solution.java | 53 ++++++++- src/cvrp_ls.class | Bin 2593 -> 3850 bytes src/cvrp_ls.java | 32 ++++-- 16 files changed, 438 insertions(+), 64 deletions(-) create mode 100644 bin/Ant.class create mode 100644 src/Ant.class create mode 100644 src/Ant.java diff --git a/.vscode/launch.json b/.vscode/launch.json index 19b9e6e..2d3f6be 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -16,7 +16,7 @@ "request": "launch", "mainClass": "cvrp_ls", "projectName": "optialgos_92db6011", - "args": ["C:\\Users\\Jule Behrens\\Documents\\JonahAlgos\\optialgos\\src\\instances\\Loggi-n401-k23.vrp", "taboo_search", "3600", "50"] + "args": ["C:\\Users\\Jule Behrens\\Documents\\JonahAlgos\\optialgos\\src\\instances\\Loggi-n401-k23.vrp", "taboo_search", "14400"] } ] } \ No newline at end of file diff --git a/README.md b/README.md index c78d38a..91abf4d 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ zeigen muss. Das Programm gibt die Kosten für die Initial ermittelte Lösung mit einem Greedy-Approach und die mit basic local search ohne Zeitlimit optimierte Lösung und anschließend die Lösungen selbst im .sol Format aus. Alternativ kann ein Algorithmus spezifiziert werden mit "java cvrp_ls *absolutePath* *algorithm*". Dabei sind die Optionen für *algorithm* "basic_local_serach", "taboo_search" und "ant_colony". -Für "taboo_search" und "ant_colony" muss zudem eine maximale Laufzeit für die Optimierung in vollen Sekunden angegeben werden ("java cvrp_ls *absolutePath* *algorithm* *maxTimeInSeconds*"). Für "basic_local_serach" ist das optional. +Für "taboo_search" und "ant_colony" muss zudem eine maximale Laufzeit (integer) für die Optimierung in vollen Sekunden angegeben werden ("java cvrp_ls *absolutePath* *algorithm* *maxTimeInSeconds*"). Für "basic_local_search" ist das optional. -"taboo_search" kann optional ein weiterer Parameter mitgegeben werden: Die Anzahl der Taboos. Der Standardwert liegt bei *Anzahl der Knoten/3* abgerundet. Ein möglicher Aufruf wäre: "java cvrp_ls *absolutePath* taboo_search *maxTimeInSeconds* *numberOfTaboos*". \ No newline at end of file +"taboo_search" kann optional ein weiterer Parameter mitgegeben werden: Die Anzahl der Taboos (integer). Der Standardwert liegt bei *Anzahl der Knoten/2* abgerundet. Ein möglicher Aufruf wäre: "java cvrp_ls *absolutePath* taboo_search *maxTimeInSeconds* *numberOfTaboos*". + +"ant_colony" können optional weitere Parameter mitgegeben werden: Die Anzahl der Ameisen (Standardwert: *Anzahl der Knoten x 5*), Anzahl der Pheromone, die eine Ameise zu einer Kante addiert (Standardwert: 10, integer), Anzahl der Pheromone, die in einer minor round verloren gehen (Standardwert: 1, integer), ob die Pheromone zwischen major rounds zurückgesetzt werden sollen (Standard: 0 (nein), integer[0 = nein, alles andere = ja]) und die Strategie zur Auswahl des ersten Knotens der Ameisen ("depot" oder "even", mit Standard "even"). Dabei bedeutet "depot", dass alle Ameisen vom Depot aus starten, während "even" bedeutet, dass die Ameisen gleichmäßig verteilt auf den Knoten starten, wobei ein erster Weg vom Depot aus impliziert ist. Ein möglicher Aufruf wäre: "java cvrp_ls *absolutePath* ant_colony *maxTimeInSeconds* *numberOfAnts* *numberOfPheromonesAdded* *numberOfPheromonesDecayes* *resetPheromonesBetweenMajorRounds* *antDeployStrategy*". \ No newline at end of file diff --git a/bin/Algorithms.class b/bin/Algorithms.class index b6ae11b222029b818ae7893b44664a06c8973154..35d59ae45df963d6188d6319629084a5f37e3b36 100644 GIT binary patch literal 12179 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 RU|;~vLC$2H%{Z4q5&&gSYI^_x literal 8613 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 G43YqT7AU3w diff --git a/bin/Ant.class b/bin/Ant.class new file mode 100644 index 0000000000000000000000000000000000000000..3de4d524734dece42485a07e8a9cb06237c50480 GIT binary patch literal 4271 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 literal 0 HcmV?d00001 diff --git a/bin/Node.class b/bin/Node.class index 05e69ee717aba2ef28568fa6305e7e5f8f7250fa..42144557dfcd10696d3f49782dc4f89c50bb3dbe 100644 GIT binary patch delta 83 zcmbQlHH&M*9Y$s`4bRQ@7$q24Sr|1KH8=lY+RJEc!NA18$iTqBr?rJaMr#X$#x4dO h28Im`3=B*R3JeSkY+zYI21N!21|Be*Z}JlsJpkMT4f_B9 delta 47 zcmbQmHHmA(9Y!Wmjm`HNB^a3)88`o7+RMmm!obMD$iTqBrL~1YX7VW(MMkd4Z&>sI DEFBB6 diff --git a/bin/Solution.class b/bin/Solution.class index 2cf9957a6dd60cf27a03de8ecc06e93c2f4377c3..89ae1e30c6e273bfdc0d9a6b53c5c1867ac05895 100644 GIT binary patch literal 4529 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 literal 2953 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 NMurB4CWaOUNdQH7Nvr?> diff --git a/bin/cvrp_ls.class b/bin/cvrp_ls.class index b881a47e3112097351bffd1753ab79d4097b2e25..0be1a074a6884820ab71538bbe23f451418625d5 100644 GIT binary patch delta 1847 zcmX>i`A&iB)W2Q(7#J9A8Ln*PTEJY-!4Sg8z?GO+5}%x(lb=_~#URcQ#={WK5W&d6 zmReYvm{ZKiAgbY$l~|UjpOcuEuJ50em6}{)tr^A1V8al_!w}67!^j|<n^+N4npcvU zo9dYtoSK}Umr~5g!00K&z`zj4!w}Dqz{nt;o0y&IoS&DRSQ4IDlHr`6S6njr9kYRa z5+ehXt|13Q3L^t&X<kldZe~ep3dkX8JPhd!8Ix^U0_#DRW$`d%gDm68E6q(xE%Hxu z%quAdN#yb{<bfoF3NliQ@^ka^Qj3F2ic<5^OEN&x1w0IeAZc-gv`cDoVkNSgVjhMP zh9E`;fyBI$;F83mlHih}#FEtXN{|6%JaG)=3>AzF{6(q7sU-n$TNoJ_ql6e38LB{D ztY&1;((v^3L<+0mlA_GKbn7ThOfew_CWcy&wmL=zwaJdG!jsprh_f~DFf=kWO+L*c z&DO%h(8|y@`3;M*Q3pd8J3}WU14nRvPH9PIejX1)H$xL61ABUEiF1B&35(MS1_mJp zW`;hHf&GjOnv)$_#T2mG%EB-aq-YW&gT`b>R*}iQtYVrS3{!X*rZTiKGO(892j}Mq zF|ab!3Nf%T#0fF5gIF94vp||=Pqt$<;N@hPD8#@866R*8oxGRzCgXz1)7cE!HZyEx zXV^0N9GfObJi|6dh8Y?@lNC7SCd;x{^K9Z^*vZJ?$Q7KQQ#Sb+yIuWmMusF%^jRq| z>L`E$6dY>`jwvarDR41JR4RZY3o7iAT9A`psQ`-|u+kt<q$nh&m82Fa_$FrM7bz6w zm*#<t;b7Ry$l&6cS6q^qmz=7QmzbNXpr)XppjNK{3O9vfXm~1UFls8OLBvW63Q~&{ zl0YUXXc!t8sA?)GD8$5YFzjb!5NCvFS721oU{nQZVT4K^WMmKoNy0Ex_%I^_FP8!= z+N`)3IT(&IG9+_NUcjEha-5MNX)*_gw+&7!PckydKum;N2WLPWb$aq@4k^a7laFy| zvs_?gP=$s#J2N}OrOC3Kom|Y18Q2*(85o!}CU4-JS1-xFg~4AacpF3LECvAx$8H-# z=uCz~n;7K5d=L@2iy@YQK`2ouc^gCOHU?FY7(~}h26d>yOpss>h{y*KMIfSd7egfj z!!`z0s2cxW3^icBB+E92`gsfn^&knBZ4Awl9NQS$!9*Kat}RcfCkxEl#n21ZvYbH{ zu9yv`co)M2up~%^V;jTdT@2H}{N)UrK|&zUf!q<fi(xvl`(bjs>KSH$)q`!C$KVQ* z06Pb41BgI&4jwno1RI0HjdQ?~AhX%PZk!9}vqKy`Z}Lwrb>>A38k3c|W9xS?7%*I6 zFk*PfV9dzMV8STMV9F@VV8-ahV8NKeV98j*V8vL@V9hw0!G>`$gDvA~20O;L3=T}} z4313V3{Fhy46Y2^3=9la3_PHCW|+^gfPsO5nMsvlAwv)YBLf?g62l^fAO<D|J|-!K z#S9A=m>JX<I2e{NEM;I}Ft2C)$gqrIIRguW8-pNNkd+~s@hF2m!wLpgh8)H{3@aH{ zF|aYzGOlJ=&9H)jouL=1nS)^-V;933hE)t43~Lz}7&007{xhgBu&^_%V`mTtqje07 z><ogO{~1IXSdoR<8MMJNLjM`+jTt!5q}Um3*cm$58En96IR7vxu`_i1X7KsV;36sX zo1s)vo`IQRJp%&+6T=3EjSLJ7UJN`8+Zh-cc7VxUU~&(b+y^EPfXPE(@(7qb1}0B1 gY-f;XWPnJY0t=mCILE-iz{SAGaGv2J!(|3Z0KL@7_W%F@ delta 964 zcmaE-a72>p)W2Q(7#J9A8CGrNTENW3$za0}!ov{C5H|Tevm9Fl4?`qF)MQ~6H~APw z1}0rY4u&{J2F}vFoXp(JlGGF~262W29)?7Qq{$U5fm}iij0`CtEvb_iv+Am+^DtyE zWHK`FrKgto7nEe?CgwQj7nd+HFl%UfaxrK#Wb-iOFyv1D&Z=yb&rrzDP{7E*5uBe> zT9TQc$HPzr(#xKnS_0C<;&g(6L5P8gp%i3(86$)CWCIqF$#2*sIhYwLKw_1X>)CXr z@)@dm7-|@D85vkh@`Lkpgcw*DQiK>-8B!(-vEO8DnEZy_kZm%<RCb0bla)C%nIjpd zP4?%Q$1;h7Vdi8*t_+shj11|M=W==1=R;hqPz-gDf`*}ifvTp0f<jCT2g6)O1{p>L zH3dcm4MtT>R0c%Fd`1RAhzgJ@H3g`~g^UcMTne6fnI)NtIdH?RxEMJY7Be!4b18sB zDzj>`H@7_FvdP)pS}ZFV8RRDCam!8K&Yi)<bd7<Xfs=uO(SNcg&%F9g4DyofTNwO7 zMDQ+#a0UjUXrb6`4Ds6-RAF+v7?K$nwlSzmvTS2Wo5$b^5@*@QkR{2sjUf+Aw1K7C z@`Q@BBsoBWAOcwsq;nTT3D}tB46<+&bihV{RPSOa2g`z_*tRiL?P92f^Etr$y2;*r z>daLPa+6E>V(WJ?7%-e-Fl4yIV8kfGV8W=!V9IF6V8-ajV9vnJz`#(&zytCmLp?(S z0|NsyqYpzPLl6Ta0~@0!LlZ*~0}}%uqa#BzLjwadgBk+|LkmMI0}F#WqXa`6LpuWt zgByb&Sd5h+nc)qCJwpcrD?<*$V}?$KE(SJ++Iogd4BZSJ4D1ZOP|X|+^B6WV^e}WW za4_^TFfhb2aQtUbVPIir=woLP2ctd)Ms@~4&i@Re46Mk)><rpq8KM6S#ta;2GVBaC z><szr3^rgToPQYV*ctLA-58h|`WYA)m>4E7Ok`kSP-9?Yn9jh+Fau1^0+VyV<UBCB Y08B1oSi-=-z{SAGu#{mr!%7B80Q+pto&W#< diff --git a/src/Algorithms.class b/src/Algorithms.class index fb297dc91aaf997c811fb976fbe8cf4dc18fc6f2..c69bede3dd854a0925a39002e23dfdc2475cb6b4 100644 GIT binary patch literal 9489 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 delta 3449 zcmbQ}^+28L)W2Q(7#J8F8J<t%^5)}B%t_BL$}Gvq4XG?ho!Bqw#mB?I&mh3aAe@_6 z5mcI2l9`+8nHQXzoS&Cc%*ep#$-yAR$iR}9pO?zTAi^NZ&LGCaAkHAc$RLoFSeB@t zlbDyTA6!zDnU_9Uj!9WXijhIApeQppvm~=DH9jXlIWZ@`I5n{-IfILVgF%LeL6$*o zvLK7KvIv6$4}&6u5+eggMq+V>bAC!HBLlOBrYA_93J-%SgWBXrEb7|q3>u6K9KrcH zr6rm9d0Y(Y3|c%4tPI+W47?gXo_WP3iFwJX)|z4L47!ugvPy*NFfem57%&*JGZ^tO z7=z7+sbXZ{Nlz_t$;?g7D+Zfo%3#LMV9vu}!C=YAAc*jfXI@EadTJ3P1AAFwPHC!t z+GKq;X$c($YaRw0kk^?LQ&K>d*zqvfGdN7X$01?n#Nf=%;KIY;3JOaWKd^7u@=9}) zQj544bQs)u7(763VJXh6N(Bjc@i2HZ_)I>^uEy=h;Lpwwz{3#85H$H4yE=y-LkJH; zC_~s}RSpGNQ-%m0hDeZBj?BE0FpzUVHb?U?#4yB8mgbb^Fkp!1VMt&|oNUJ_Y3;<2 z%)^iZasyjRYHng4*qLcO4Cx>f1kzJWLW)Y0vz-$Q5|cAaDmfW48M4?JvUwPC7;-0f zGZ_ozGcqt{b1@V$6tOcD^DvY!lurK5WWgoGz`#(>!%)FcIe8kVE{6_7H4j4#L+#|# zoQBpq4E3N0X<%fK)bIg^VQEQbj=pn#PEKkvD9*r<)5OTY9_<4P7i*CBTX+~+8QLbB zbD3ImGN?0j@Gx{TbTKlpmgJWf6*Dq$M8nmpGxYE<^n#qvo}OCboL^i5N+A6_3=<e8 zPM*W6m&L`9$uOCRVG6@kMh3y;(xRf&ypoX2+*IGpoSe*JaGLTGVqj#L&ciT+VJ0Jk zcy3~Ls&jr`a$-q%W=V!~J~$1P6f-i2YItfwe1Mdy!S0*Q!!U<o?qo$)DQ$Iz`8*5@ z7#1=zuq5XfR5CK~XlVMtlBYEn!(xUd><mkJ7?v?CpS+sOjhBgGB`DxlF)}D=L{DDG zsl?;Num%)hYZ)1AG$z|~t4+4&78U~~;4Th^4U7zoiJ$=51WIa~Cs%Vz+OjijWn>Tr zhb-7#t`*6t1)zZCVA#&cz`(^|${@<fAO;P5uo6gywD!~tn>>?ST9Y@pBr!SLH?bfj zF)1gNkwG9mH7~U&u_P7dZgz(Kj0{ZCo|7GU=9>sGNbs{UoCF2)DISJH42K06&Y+nO z%^=pAQ5+2C7#SqfCd=?j=<%~LTmb31$ir}e;h+G+Wkv>04M?18M)9*TT;*c8#&DgT z;RX-GO@>>WllYhz1^L++?r<^OWw^)Aa32&w4<`5X9-5rOFTl$1n2|ws@&`Wg$rJeb znHZi<UdV4;&&0sMz|FwJ00R6B0t^fc91M&MtPDFD7#VgkFfgPtFflMQFfb@-ZD(NA z(%#Czt|haTfmiz&1CO?l;5G)~nGBp-LXuk<*f%mTFfcLfW?*2DVqjxnVBln6Vc=rm zWZ-7tW8h(sX5eK|WZ-Am!@$5G$iVcUL7IV?oq?mCok4_=fq|8Qkzp@`9Mn!Z1||lO zyV$g}w=qa>U|?Wi1e?poz{tSB07`m$8PuR^%NUp#SQr=>T(q_@u=_IE>1<<=U(LY4 zAOq4>;bj;CvQI}y66{h|W;<DsB-o80QyJ<({$>yXS){yy5o8s_3w&Tti-Aff1}6q7 zu(Np>SpG7|fE>&v!pgt|DtIA|V3uHDW#D6AV7#-NK|NA?JA<b0ZU&vm?F@Q;P}+)x z)r?h?ReKwQK1;$P1`$aXQPv#{CfgY5t-@Pa8JGWm4pRtHW4ndH(Tt7BjGe`dgV~Hz zl4To%+dM{T5bbHjCCRmu!IzO?CPOud70k$RfWg#?TatSlL%1m0A_fytcBc6ZqT1US zqD0w@z`}Z>?28z@P(;kw!7^s`9LpID5jwzvMxtzB9g-j&a1odej^+OwMLD&%F~o^- z7;RxlO3>cMkh+K=2t~{crr<aO-zJ6(p}cJj1<M%(BtgCd>D$I&6)wtQ#wA(LBFeRk zp^SlH8$%UH1nTSM|M_)6AtK4TouLk-7{uAmpl8L(3^p1$gqHt%jH*_58-v?khDIwc zW;1TxZ491PJd!-nATt56z(J;C#Vg4r%3UwX3s&tE4B|<G#f-KwG#_AS3~u3OT>k%r zjwIJshIXB84Bg>6i1cxc!H|K0L4kpjL6Jd_L5V?%L772=L50DXL7BmlL5;zQL7l;y zL4(1ML6aenL5m@TL7O3lL5HD|L6@PKL62cJgFeG51_OrrEeysCXBbQvZZnuNJYuk5 zc*<bO@RPxck%PgSQHa5YQI^4uQH#NmQIEli(VD@T(VoGD(TTy8(UrlC(SyOAF^s{3 zF`mJbF^R#OF`L1MF^|EQv4kOzv56swv6~^7v5z5yaTP--<93EH#*+-;jAs}k7|%0A zGG1kfV!Xu=T@Oy#aSZ(b8DtsQ*cmw384TDN)Y%zy*co&f85n*sNdIS$V&FoP0ZB44 zGBPmyVc=tD@cYAH&dy*eA^wX&^cMq@IghONKL&YrhINeW41T{DtQeR;jSom(VO-0= z!obbI!0<!cmwgY{WJd)t!#*n(W;50u43o^+#Mrd9Fz^a8zsP7!H0O|HImU1RBruPG ze+R=PF^(zo7}%CGtereTL8rdYie(c+Mhh#WDC;hUX`mETu>Ai@UFH})mIQxYW<8xP z470W|=r3XL(Pd`!*JXu>vx3Ciby@U`_OYZaVKC5TW%k!)fyl9d<-p<+x-888x@-_} zHa*q_Aba_=bal2d^jWbi|L>?%k4Owv3~~$%3<(TO42cY43`q=f49N_N3@Hq145<tz z3>gfT4A~5x3^@!w40#L@4EYSv3<V4Y422BE3`Gpp48;uH3?&SG3}p;c8Oj+JF;p@v zW2j<S%TUd*kD->~5JMfqNrrlcYYdGHw-}lj9x}8rykKZ$c<sl~#qf<`0yzGZ8Cd@_ zn1CXW0~~qk><s(Z8PpkBSQr?@e=|7#W{BZpU;<U}kVs(SXJBLCWME)4)7i!_&rf#? zL;K_yC8>IyNJ;h`42!li)LC&za%k^jSOE&ws&GjTNp?u4uwrjvV_g3K<ZcG1NTwYO zCNR96VYL;DBn#7421iJ^$62vTvhFiuV>V+KWe1f@>XNLY>_#ASk1>c!a%^F6)MnOO zz`!NRVa2kXfwP63ae4j!8`^AoEDIPcLD?PTDyU;vS@tqGMKVjW1Y5C5vP!anN(5a= zR*(v?v({~8XkX3{2Gga@qGtrtDaisYg4TnJASp>!ZB{){NxE@41FsbusBqf0jiCT! zly*If9>h?P0bqk0gLOABFfy_-@-qrCY=Ks9c?{AF3=Gp4SQ%z8C^F1s&}W#%V9hX_ z!JT0SgD=B8h9rjh3>gdy7}^;YGW0MkVwlIUfME&4QijzG%NTYuEN3{zu!7+n!%BvG z467I(GOT9!%CLsv7sFac)_R5wjQk8+7=;)%GKw&4W|U#r!Dzy;2OP!T3|#*igc;bu z84(n@;D}xa%7Z@`EdMiTLt`H<<;2d=2$EI#!N6+she4U0LC1%kVGHLk25|u{P;&y3 z6d24In8B5;i1x9120`sD431i$cwuK*&cMRF241H_>fTvkx3DrW2{|wdaDkdKP*W74 zRW_%#6u4g70n&+FYdbM8GaLb%c9h{5xPE44xWd59aGc=;!)b=w42%qC86+VB=NT?B TJY)d1!x$MJF+5>-#vlm*FDCN~ diff --git a/src/Algorithms.java b/src/Algorithms.java index 590b7d1..37db335 100644 --- a/src/Algorithms.java +++ b/src/Algorithms.java @@ -3,8 +3,13 @@ import java.util.Arrays; public class Algorithms { + int pheromonesStrength = -1; + String antStartStrategy = ""; + int pheromonesDecayStrength = -1; String algorithmType; + boolean resetPheromones = false; int maxRuntimeInSeconds = -1; + int numberOfAnts = -1; int numberOfTaboos = -1; public Algorithms(){} public Algorithms(String algorithmType, String[] optionalParams) throws Exception{ @@ -20,8 +25,29 @@ public class Algorithms { this.algorithmType = "basic_local_search"; break; case "ant_colony": + try { + this.numberOfAnts = Integer.valueOf(optionalParams[1]); + this.pheromonesStrength = Integer.valueOf(optionalParams[2]); + this.pheromonesDecayStrength = Integer.valueOf(optionalParams[3]); + if(Integer.valueOf(optionalParams[4]) == 0){ + this.resetPheromones = false; + } else { + this.resetPheromones = true; + } + this.antStartStrategy = optionalParams[4]; + } catch (Exception e) { + + } if(maxRuntimeInSeconds <= 0) throw new Exception(); + if(this.pheromonesStrength <= 0) + System.out.println("Using standard value for pheromone strength."); + if(this.antStartStrategy.equals("")) + System.out.println("Using standard value for ant start strategy."); + if(this.pheromonesDecayStrength <= 0) + System.out.println("Using standard value for pheromone decay strength."); + if(this.numberOfAnts <= 0) + System.out.println("Using standard value for number of ants."); break; case "taboo_search": try { @@ -45,6 +71,15 @@ public class Algorithms { case "greedy": return generateInitialSolutionGreedy(instance); case "ant_colony": + //setting default parameters if needed + if(this.numberOfAnts <= 0) + numberOfAnts = Math.multiplyExact(instance.getDimension(),5); + if(this.pheromonesDecayStrength <= 0) + pheromonesDecayStrength = 1; + if(this.pheromonesStrength <= 0) + pheromonesStrength = 10; + if(this.antStartStrategy.equals("")) + antStartStrategy = "even"; return generateInitialSolutionAnt(instance); default: return null; @@ -58,20 +93,21 @@ public class Algorithms { case "greedy": return generateInitialSolutionGreedy(solution.instance); case "taboo_search": + //setting default parameters if needed if(this.numberOfTaboos <= 0) numberOfTaboos = solution.instance.getDimension()/3; return tabooSearch(solution); case "ant_colony": - return generateInitialSolutionAnt(solution.instance); + return generateSolution(solution.instance); default: - return null; + return localSearch(solution); } } private Solution tabooSearch(Solution solution) { int[] state = {2,0,0,0}; int newBestCount = 0; - + int time =0; Solution currentSolution = solution; Solution bestSolutionSeen = solution; @@ -86,10 +122,28 @@ public class Algorithms { while(maxRuntimeInSeconds > 0 && System.currentTimeMillis()<end){ - if(possibleBetterNeighbor.getCost() < currentBestNeighbor.getCost()){ - currentBestNeighbor = possibleBetterNeighbor; - currentBestNeighborNodeChanged = state[0]; + if(System.currentTimeMillis()>start+1000 && time == 0){ + try{System.out.println("1 Sekunde: " + bestSolutionSeen.getCost());}catch(Exception e){} + time++; + } + if(System.currentTimeMillis()>start+10000 && time == 1){ + try{System.out.println("10 Sekunde: " + bestSolutionSeen.getCost());}catch(Exception e){} + time++; } + if(System.currentTimeMillis()>start+60000 && time == 2){ + try{System.out.println("60 Sekunde: " + bestSolutionSeen.getCost());}catch(Exception e){} + time++; + } + try { + if(possibleBetterNeighbor.getCost() < currentBestNeighbor.getCost()){ + currentBestNeighbor = possibleBetterNeighbor; + currentBestNeighborNodeChanged = state[0]; + } + } catch (Exception e) { + + + } + //permutate state to get another neighbor which is not taboo state[0]++; while(taboos.contains(state[0])){ @@ -111,17 +165,22 @@ public class Algorithms { if(state[3] == 2){ currentSolution = currentBestNeighbor; //System.out.println("Made a step, taboos: "+taboos.size()); - if(currentSolution.getCost() < bestSolutionSeen.getCost()){ - bestSolutionSeen = currentSolution; - - System.out.println("Found new best solution "+(++newBestCount) + ": All "+taboos.size()+" taboos dropped"); - taboos.clear(); - } else { - taboos.add(currentBestNeighborNodeChanged); - if(taboos.size() > numberOfTaboos){ - taboos.remove(0); + try { + if(currentSolution.getCost() < bestSolutionSeen.getCost()){ + bestSolutionSeen = currentSolution; + + System.out.println("Found new best solution "+(++newBestCount) + ": All "+taboos.size()+" taboos dropped"); + taboos.clear(); + } else { + taboos.add(currentBestNeighborNodeChanged); + if(taboos.size() > numberOfTaboos){ + taboos.remove(0); + } } + } catch (Exception e) { + } + int[] help = {2,0,0,0}; state = help; currentBestNeighbor = getOtherNeighbor(state, currentSolution); @@ -136,8 +195,116 @@ public class Algorithms { } private Solution generateInitialSolutionAnt(Instance instance) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'generateInitialSolutionAnt'"); + Solution bestSeenSolution = null; + int time = 0; + int newBestSolutionCount = 0; + int[][] pheromonesOnEdge = new int[instance.getDimension()+1][instance.getDimension()+1]; + //initialize all edges with phermone score 1 + for (int i = 0; i < pheromonesOnEdge.length; i++) { + for (int j = 0; j < pheromonesOnEdge[i].length; j++) { + pheromonesOnEdge[i][j] = 1; + } + } + + long start = System.currentTimeMillis(); + long end = start + this.maxRuntimeInSeconds * 1000; + + while(maxRuntimeInSeconds > 0 && System.currentTimeMillis()<end){ + //if optional parameter is set, reset pheromones inbetween major rounds + if(System.currentTimeMillis()>start+1000 && time == 0){ + try{System.out.println("1 Sekunde: " + bestSeenSolution.getCost());}catch(Exception e){} + time++; + } + if(System.currentTimeMillis()>start+10000 && time == 1){ + try{System.out.println("10 Sekunde: " + bestSeenSolution.getCost());}catch(Exception e){} + time++; + } + if(System.currentTimeMillis()>start+60000 && time == 2){ + try{System.out.println("60 Sekunde: " + bestSeenSolution.getCost());}catch(Exception e){} + time++; + } + if(resetPheromones) { + for (int i = 0; i < pheromonesOnEdge.length; i++) { + for (int j = 0; j < pheromonesOnEdge[i].length; j++) { + pheromonesOnEdge[i][j] = 1; + } + } + } + + ArrayList<Ant> ants = new ArrayList<Ant>(); + for (int i = 0; i < numberOfAnts; i++) { + switch (antStartStrategy) { + case "depot": + ants.add(new Ant(instance)); + break; + case "even": + default: + ants.add(new Ant(instance, i+1)); + break; + } + + } + while(!antsAreAllDone(ants)){ + ArrayList<int[]> walkedEdges = new ArrayList<int[]>(); + //let ants do one minor round + for (Ant ant : ants) { + int[] walkedEdge = ant.makeStepInMinorRound(pheromonesOnEdge); + walkedEdges.add(walkedEdge); + } + //update pheromones after minor round + for (int[] walkedEdge : walkedEdges) { + if(walkedEdge != null){ + if(walkedEdge[0] < walkedEdge[1]){ + pheromonesOnEdge[walkedEdge[1]][walkedEdge[0]] += pheromonesStrength; + } else { + pheromonesOnEdge[walkedEdge[0]][walkedEdge[1]] += pheromonesStrength; + } + } + } + //let pheromones decay (not under 1) + for (int i = 0; i < pheromonesOnEdge.length; i++) { + for (int j = 0; j < pheromonesOnEdge[i].length; j++) { + pheromonesOnEdge[i][j] -= pheromonesDecayStrength; + if(pheromonesOnEdge[i][j]<1){ + pheromonesOnEdge[i][j] = 1; + } + } + } + } + //check if ant has discovered new best solution + for (Ant ant : ants) { + Solution antsSolution = ant.toSolution(); + + if(bestSeenSolution == null){ + System.out.println("Found new best solution "+(++newBestSolutionCount)); + bestSeenSolution = antsSolution; + } else { + try { + if(bestSeenSolution.getCost() > antsSolution.getCost()){ + System.out.println("Found new best solution "+(++newBestSolutionCount)); + bestSeenSolution = antsSolution; + } + } catch (Exception e) { + + } + } + + + } + } + + return bestSeenSolution; + } + + private boolean antsAreAllDone(ArrayList<Ant> ants){ + boolean allDone = true; + for (Ant ant : ants) { + if(!ant.done){ + allDone = false; + break; + } + } + return allDone; } //primitive greedy Approach @@ -200,7 +367,6 @@ public class Algorithms { i++; } solution.tours = convertedTours; - solution.getCost(); return solution; } @@ -209,50 +375,55 @@ public class Algorithms { Solution currentBestSolution = solution; int[] state = {2,0,0,0}; Solution possibleBetterSolution = getOtherNeighbor(state, currentBestSolution); - int newBestCount = 0; + int newBestSolutionCount = 0; long start = System.currentTimeMillis(); long end = start + this.maxRuntimeInSeconds * 1000; //tries all neighbors as possibleBetterSolution, if better solution found, change currentBestSolution and search from there //terminates when it cannot find a better solution in its neighbarhood while (possibleBetterSolution != null) { - + //stop if max execution time has exceeded if(maxRuntimeInSeconds > 0 && System.currentTimeMillis()>end){ System.out.println("terminated by time limit"); break; } - if(possibleBetterSolution.getCost() < currentBestSolution.getCost()){ - currentBestSolution = possibleBetterSolution; - int[] help = {2,0,0,0}; - state = help; - possibleBetterSolution = getOtherNeighbor(state, currentBestSolution); - System.out.println("found new best solution "+(++newBestCount)); - }else{ - //permutate state to get another neighbor - state[0]++; - if(state[0] > currentBestSolution.instance.getDimension()){ - //System.out.println("reset extracted node"); - state[0] = 2; - state[2]++; - if(state[2] > currentBestSolution.tours[state[1]].length-1){ - //System.out.println("reset position"); - state[2] = 0; - state[1]++; - if(state[1] > currentBestSolution.tours.length-1){ - //System.out.println("reset tours"); - state[1] = 0; - state[3]++; - //stop if all neighbors are worse/local optimum is reached - if(state[3] == 2){ - System.out.println("terminated by local optimum"); - break; + try { + if(possibleBetterSolution.getCost() < currentBestSolution.getCost()){ + currentBestSolution = possibleBetterSolution; + int[] help = {2,0,0,0}; + state = help; + possibleBetterSolution = getOtherNeighbor(state, currentBestSolution); + System.out.println("Found new best solution "+(++newBestSolutionCount)); + }else{ + //permutate state to get another neighbor + state[0]++; + if(state[0] > currentBestSolution.instance.getDimension()){ + //System.out.println("reset extracted node"); + state[0] = 2; + state[2]++; + if(state[2] > currentBestSolution.tours[state[1]].length-1){ + //System.out.println("reset position"); + state[2] = 0; + state[1]++; + if(state[1] > currentBestSolution.tours.length-1){ + //System.out.println("reset tours"); + state[1] = 0; + state[3]++; + //stop if all neighbors are worse/local optimum is reached + if(state[3] == 2){ + System.out.println("terminated by local optimum"); + break; + } } } - } - } - possibleBetterSolution = getOtherNeighbor(state, currentBestSolution); + } + possibleBetterSolution = getOtherNeighbor(state, currentBestSolution); + } + } catch (Exception e) { + } + } diff --git a/src/Ant.class b/src/Ant.class new file mode 100644 index 0000000000000000000000000000000000000000..962616e4582d639a480fea1dd5e70ab48cfa4588 GIT binary patch literal 3271 zcmX^0Z`VEs1_nol30w?J49x5dEIbUX3~Y=H0$GV=iTXK-dFlH8Nm;4MC5#MgHko;u zC3cJq%o>_u><k=?48mYVr6rj;`i@0KiIqN?#U)$}><rAD4BQMn><qj-415gyj10_< zc_oYt+{vXyMX7luA^D|6j0~baSTtLMGz#)C2!V95mgJWf6@x@Xco;+(#26V^Qu6as z85tO(K!OrH43Z2|j0_x^dBr7(dC94a3|u~*P_{J}gA9W#JA)h#gFJ%*BLfFaf{}qE zJ+;IyKP9!8k%3b~Guj8lw&r3`Vo+vhP~l-vWl)3p9^tWKMh3RTVvzS38B{f*Ax=jM z9BWO85LgFDnKdXFG(cgg$;cq7fh6mkpOcfCT#}ieXRR3q@`pALgAT~M{CW8$VVT95 zC8;SOCl!NypvS|Y&tL#?vrB40ehDK3hlVE1$?Ob9JPgJRCX5VhMX9;@WvPq|qEM?) z+y)LVGad$W1`9+ifb3voU_+Q?1v1MTWP~TwH^_#7{A0_*V8>t&3h|QEqQsK?B1Q%= z4X9eM&pn~y*4zw^3{LC}&O8h*46cj}LWrn_DPd$_&qyrxORXpYr>7{84tE{~4+c+0 z29`Xqun5d-WOuMLcr!AvfE>@s;Kks}!{Eo@&&a@*SDKrYTExh}=m`q8Kpuu5hG0ep zp7hibm(1MMyyDFKJg_~UAb*7NFoc0ZjX5zT1!PJD4?`p<d9kK|f*52#G!H`zLo6c$ zUwUeZYf5@*cxq;PMoBRv1FME+bhIZ(Q#=nt0@&)5)ZE0p6fOpCh9n+_WQG(*2A<;5 zT>mr|uy`>eg9J2Az(EAhC)S!^r>5~Rq=TF)ke*r+QdF9p?VMPUn4DQs$;FV#kj2iB z&BKtxkju!x2M$7TNcbj}WPqYPF)t-Q7wjt+c7}XL2Bv5iknak47>Yn9vJ_`lrLr@C zl1y-ZPAMqGaWND#lz|duIU@tF1|qY7vU4RP13Nr3urpNiFw`*AGBU82<b$2e$e@8W z-DAlMoD9Vb^`Jc5z{tQ64K<UIfipNWJuk7Ov?!I4K^7@PfQ<*`85>Aiw6kVpFu^Vl z4g=I+glht6V{y(;No8c<_sPsl^#iAfki?{%R7M6qB+q(khA}em2A3ozXZt1=KoyAO zCT6Dwm!uYW=J{sk<rf9zm*%A~GO%kzM|)~UdonU8V2wn$?V6s93|uAouz+S{;L*_Z zf$^-_85$TFxPtRbi;`2_GC>aFaLg;w19^u*k%60miGhKEje!AFo-u%cIfDg=0u`PN zj0}wo3=B*RO$-d6ViC@7W?%r78*n~IUX($Mfq{XQfsuigp`3w{p@o5gVFCjS*!&Q! z?F@`syBXLcw=-~VW#B?E1+<vAG6-vFZ)Fe%3u<p;klw+dxSc_LD}$ES76vWtZ4A2G z7!1R~jI9i&ATj1`43^;=85kHC8Cn?_7_=C;7#J9M7+4tC8Tc7E7^E1u7~~mv8B`ef z7|a;>8Jrjd7`zw+8G;#vz^-e9xQ<bgfd%aIr373Da)KWoCvIb~v0{;A*~#F*$S{*Z z7sPU7WH`X!WyLDVdW=C*l64D%kBs&<hJXT=gar(olB|Bq8Q7NpKM(Q?$Z)X#wlHXc z{RI+)_*fU>T`t{i3?X3eGJ(D8#URAMz#xL=T`>j~25|;W1_=gh21$k}1}TPo25E*O z1{sD@204Zb26=`S1_g#*21SNx3`z{M8I&28FsL%LGcYhnF);sUaA9C&XW(XMkYQwJ z@M33hWMDA(#lXbC$k4&i2?;Lda|~<@{0t0CleD%l2+w3-W!%8%%jX4+R4Z1kEexhx z7{X^V2!bOL64A>UwnM~yw6-vaZ)4Ei!r-%r!3x5Of>0naBd999c1t#Gtil}28O$LP zAZ?~w7<@o_phn`+Ccz=WmT$?$wujw{N0NtGGf0w$MN@(+IY^QR<YcG;?Lm^Pl02Yr z2FZDW;s6w@Y?5rySUm({L1UF&l6?z994K{iZDUAGfVe7kF~e-ACqU9Zix><b5>a3- z$gv<t>$O{QXrqg8Eoab$Dux<i1XhAwu>_X{2Y+(DB@f6?e3E=1Kk>0>O7J8HN%FCR zHG;jv2k{P1ve)weRy!CnG_x()n9MjNSwTMIl;ni^Oc%rg`z+6jOM*?3i`j7cYz7e! zi^Xup90o2)E>^=nGmho|&x>+ETnUP?1q_;6TNnhiwlHvk?14)7LPD-!7DJ#G%T@;A z<qVz>5gRLnjb?Bgy{xz-xwbI)h;l4okOdhf2{ufU3v3REV;Bz3D#uv&a78jh1IIs- zMQ00xkG~bCmd;iNQ%TMZ44^^^R21A}FlS(3&}3j|&|=_Z&|%<a&|~0b&}R^1Fknz% zFl5kUFlBIJFk^^kFlVS_uw<CVV8yVO!G>WAgDt~O20Mm*4E7Ai7#tX`GB`5aWpHA6 z#Nfin$l%H-$>71L!Qjd0z~IFg%HYG8%izmc&*0D4!4SaM%Mi#oi6Mw_7DF)O5{3}Q zH4LGQ8yUhGw=hI7?q-N&+{X~bc$*=b@jXKf<2Qyl#-9ucOdJe}Od<?POfn3~Olk}% zOnMCIOuh^mOyLZfOo<FxOeqZ6OnD4BOoa@2OeG9OOkE7cO#KX{;QZ>wAjtWTL4}>c zi<zB){WpWxUj}1l=AR5Ee;7E}865vGWU_<AG?|%yFc|(~VEV@(z|6?b;0VglP&JmI zyv+n^FfcHI3+f~WCI(gp1_ljgTkUNOHh#L$#38A>lL4GIysTJcBw4mF#3k4+|Nlg0 z4Lrof!1^i~m>8-Uq#3Filo@Im)EH{PF6Cih`pdu$vilc<9JDIwVqj$GX6S*GDGWP7 z4Sog&hPd4f#gU*iw4I?8R8$CTV<_0mP~ppL2TEk11dAwO_2308yA`XBEGRt}>}Bu@ z1~GMHjkYmV9bl*kZeeCz{{Nh|&Q^vxZAAKjR27X3JPb_?;tb6Uk_;^j77VQn&J1k~ xfeh^oAq*W1;S8M&F$`T`A4oDV{bx{umW{>i480)FFfjaLFkxV1=mQ5rKLA(y+f4uf literal 0 HcmV?d00001 diff --git a/src/Ant.java b/src/Ant.java new file mode 100644 index 0000000..121e4ff --- /dev/null +++ b/src/Ant.java @@ -0,0 +1,140 @@ + import java.util.ArrayList; +import java.util.Arrays; + +public class Ant { + Instance instance; + Node currentNode; + ArrayList<Node> currentTour = new ArrayList<Node>(); + ArrayList<ArrayList<Node>> tours = new ArrayList<ArrayList<Node>>(); + ArrayList<Node> notVisitedNodes; + boolean done = false; + + public Ant(Instance instance){ + this.instance = instance; + notVisitedNodes = new ArrayList<Node>(Arrays.asList(instance.getNodes())); + notVisitedNodes.remove(instance.getDepot()); + currentNode = instance.getDepot(); + notVisitedNodes.remove(0); + } + + public Ant(Instance instance, int startNodeNumber){ + Node currentNode; + currentNode = instance.getDepot(); + this.instance = instance; + notVisitedNodes = new ArrayList<Node>(Arrays.asList(instance.getNodes())); + for (Node node : notVisitedNodes) { + if(node != null && node.number == (startNodeNumber%instance.getDimension())+1){ + currentNode = node; + break; + } + } + notVisitedNodes.remove(instance.getDepot()); + notVisitedNodes.remove(0); + notVisitedNodes.remove(currentNode); + this.currentNode = currentNode; + currentTour.add(currentNode); + + } + + public int[] makeStepInMinorRound(int[][] pheromonesOnEdge){ + //if ant is done with tour return null, else return edge, that she walked + if(this.done){ + return null; + } + Node nextNode = null; + + double currentProbability = 0; + ArrayList<double[]> probabilities = new ArrayList<double[]>(); + if(currentNode.depot){ + currentTour = new ArrayList<Node>(); + } else { + double distance; + double pheromones; + if(currentNode.number < instance.getDepot().number){ + distance = instance.getEdgeWeights()[instance.getDepot().number][currentNode.number]; + pheromones = pheromonesOnEdge[instance.getDepot().number][currentNode.number]; + } else { + distance = instance.getEdgeWeights()[currentNode.number][instance.getDepot().number]; + pheromones = pheromonesOnEdge[instance.getDepot().number][currentNode.number]; + } + double probability = pheromones / distance; + double[] probabilityInterval= new double[3]; + probabilityInterval[0] = currentProbability; + probabilityInterval[1] = currentProbability+probability; + probabilityInterval[2] = instance.getDepot().number; + probabilities.add(probabilityInterval); + currentProbability += probability; + } + for (Node node : notVisitedNodes) { + if(node.demand + sumOfDemands(currentTour) <= instance.getTruckCapacity()){ + double distance; + double pheromones; + if(currentNode.number < node.number){ + distance = instance.getEdgeWeights()[node.number][currentNode.number]; + pheromones = pheromonesOnEdge[node.number][currentNode.number]; + } else { + distance = instance.getEdgeWeights()[currentNode.number][node.number]; + pheromones = pheromonesOnEdge[node.number][currentNode.number]; + } + double probability = pheromones / (distance+1); + double[] probabilityInterval= new double[3]; + probabilityInterval[0] = currentProbability; + probabilityInterval[1] = currentProbability+probability; + probabilityInterval[2] = node.number; + probabilities.add(probabilityInterval); + currentProbability += probability; + } + } + double randomNumber = Math.random()*currentProbability; + int nextNodeNumber = -1; + for (double[] interval : probabilities) { + if(randomNumber >= interval[0] && randomNumber < interval[1]){ + nextNodeNumber = (int)interval[2]; + } + } + + if(nextNodeNumber == instance.getDepot().number){ + tours.add(currentTour); + nextNode = instance.getDepot(); + if(notVisitedNodes.size() == 0){ + this.done = true; + } + } else { + for (Node node : notVisitedNodes) { + if(node.number == nextNodeNumber){ + currentTour.add(node); + nextNode = node; + notVisitedNodes.remove(node); + break; + } + } + } + + + int[] walkedEdge = {currentNode.number,nextNode.number}; + currentNode = nextNode; + + return walkedEdge; + } + + private int sumOfDemands(ArrayList<Node> currentTour){ + int demand = 0; + for (Node node : currentTour) { + demand += node.demand; + } + return demand; + } + + public Solution toSolution(){ + Solution sol = new Solution(instance); + Node[][] tours = new Node[this.tours.size()][]; + int i = 0; + for (ArrayList<Node> tour : this.tours) { + tours[i] = new Node[tour.size()]; + tours[i] = tour.toArray(tours[i]); + i++; + } + sol.tours = tours; + return sol; + } +} diff --git a/src/Node.java b/src/Node.java index 1f7287b..371ea59 100644 --- a/src/Node.java +++ b/src/Node.java @@ -14,6 +14,6 @@ public class Node { public void setDepot(){this.depot = true;} public void setDemand(Integer demand){this.demand = demand;} public String toString(){ - return ""+this.number; + return ""+this.number+"("+this.demand+")"; } } diff --git a/src/Solution.class b/src/Solution.class index a6578c9dc8b3828d0f0cb5db7c7645647a5e0ffc..8c79f11ab933334fabab25d17b62d83051ee20b6 100644 GIT binary patch literal 3634 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 TDFXuo7Xu^1GKLils~98!lUy}N delta 1339 zcmdla^ICxG)W2Q(7#J8F88Rkvd4*)=6_+IDC8shnaQS#b+18v491MIs4EziNj0`Nv z`NbuS42+&2K_MOnVFnRK2G)}N(xPHU29D@xAHV#RRBJ8<F$QsV1_>SpNd~EjrxevW z8Dtn_*%{<`805jGfK)Luu;rEJCZ!gER4ei@C^0Bcwqul3W@k`kWDw3uEKAhSNz6;v zcdbZHEhx#%&jYDb=V8!b(44%GNtI2The3xyck&q~naKgnTHK5b`XB)VMh3OXfy}~_ zKd=a^2{AA+XbUkgGw5?Lm@qOh>BMp{m@zUi#&R)OFj%rPSn)7eGuTX?$(&(e$HTzN zV9&_FtAX&iW*9qzBO?Pl+*i&FF6<1hJPd9O?vo8!JZu;lSe)}yQW+WeeKPY>{lLBn zNleN~Wn^GaPc3l<hZVDirY9o<Z*WOsa<*?`0a%`$L1eNGtMcS@Rs*+CMh5Y`#N1RX z1x7AV=z{1FP=Hz~a4>{3GB7i8MRPDjf*6cC91PKn3`~r%{A>)dTnupx@$3u<Aa5s5 z)@8fQm@=7>U5hbovJSg(Ju?FX12+Q?0|*E+h%hiPFoB|wfq{XAff3|a21W)C1_lN# z1||k31_lN$t?dkqTH0F~*f%mTFfcNBGB7akF@Q|rWME<7V&G)pW?*FSV(^COV~k*6 zVc=$9VA!w4yp@4hYYT&*kM=%WW;<D#MGPyoWx0&3ShTh<uy11!oqUH=p<Y^&a|?s? z5(Xu$$Sq*y?AsU=Bw4pGNE?A=^b)o*@GfVNN0A0;F#;<BOG|QEu`Xv|wc={wU|jxx z9*R=1Nl**7Fi3;dw=gp<{~w{Xg@JcXJp&_y4MPV*H-icT6WDK7418c8vNG^9NHPd8 zC@}~!*f0n)cru7EWH5*^v@l38bTG&;bTddY^fCxCOlFX0*uuciu!}*F!H0o?!JdKR z9|J!-gD)fFe+D@QPId+kFo&JNft^8yoxy>Tk%8e4D3!@byRnBbsQhAJ{K3HbpFxd* zk)4499L9bOnvl?Bc+0@dz{SA8PzdpY8pzSR7_=A|d_W=VtFzCJ*^EV$MRpN`r;aF# zkrk`<E(X2H3EWEc(z_T885n%PLGoC87lRRq!@{`y|8{L5V<FRR4CWiaaSw`5H3m)w z1_l)dK?YR@4F)v^eFk*~PX-N!PzH5|Xa+5YBnDN63<e#r|Lho8{xirhu!8+%0rnaL z1Hz{e5q5@p2dGznFv$OB;9+2bs0Vw`pCJJ1y(tW=3@i)`4BopLI3ht_+|FR@qYd&T zH0|u$%i!S4Y$pry?Y>0}@;YFatPzMWYqW0%gVO;9hhT7o-qY6E${?r>^;IbY1A`Jc zI1L$i7>pQ17>pTY8B7>77)%-L7)%&k7|a<w87#nF;%8v`#~=@OpfBSu1{DTohCp!G q1Th3NFfd3lurS0hFfxRI$uKY(0Vbmul0Z3xfsrAZA(bJWK@tGwDC#}{ diff --git a/src/Solution.java b/src/Solution.java index 9d53c54..afde669 100644 --- a/src/Solution.java +++ b/src/Solution.java @@ -1,16 +1,57 @@ import java.util.Arrays; +import java.util.ArrayList; +import java.util.HashSet; //represents a feasible solution to a instance public class Solution { Instance instance; Node[][] tours; private int cost; + private boolean feasible = false; public Solution(Instance instance){ this.instance = instance; } - public int getCost(){ + public boolean isFeasible() throws Exception{ + ArrayList<Node> allVisitedNodes = new ArrayList<Node>(); + for (Node[] tour : this.tours) { + int tourCost = 0; + int tourDemand = 0; + Node lastNode = instance.getDepot(); + for (Node node : tour) { + if(node != null){ + tourDemand += node.demand; + allVisitedNodes.add(node); + if(lastNode.number > node.number){ + tourCost += instance.getEdgeWeights()[lastNode.number][node.number]; + } else { + tourCost += instance.getEdgeWeights()[node.number][lastNode.number]; + } + lastNode = node; + } + } + tourCost += instance.getEdgeWeights()[lastNode.number][instance.getDepot().number]; + //check if tour is in capacity limit + if(tourDemand > instance.getTruckCapacity()) { + throw new Exception("capacity problem ("+tourDemand + " greater " +instance.getTruckCapacity()+")"); + } + + } + //check if nodes are duplicates + if(allVisitedNodes.size() != new HashSet<Node>(allVisitedNodes).size()) { + throw new Exception("duplicate problem"); + } + //check if right number of nodes is in all tours + if(allVisitedNodes.size() != instance.getDimension()-1) { + throw new Exception("not all nodes problem"); + } + + return this.feasible = true; + } + + public int getCost() throws Exception{ + isFeasible(); this.cost = 0; for (Node[] tour : tours) { Node lastNode = instance.getDepot(); @@ -32,7 +73,7 @@ public class Solution { return this.cost; }; public String toString(){ - String s = "name: "+instance.getName()+ "\n" + "cost: " + cost + "\nTours: "; + String s = "name: "+instance.getName()+ "\n" + "cost: " + cost + "feasible: " + feasible + "\nTours: "; for (Node[] tour : tours) { s += "\n["; for (Node node : tour) { @@ -57,6 +98,7 @@ public class Solution { public String toSol(){ String rep = ""; + for (int i = 0; i < tours.length; i++) { rep += "Route #"+(i+1)+":"; for (Node node : tours[i]) { @@ -68,7 +110,12 @@ public class Solution { } rep += "\n"; } - rep += "Cost " + this.getCost(); + try { + rep += "Cost " + this.getCost(); + } catch (Exception e) { + rep = "not feasible: " + e.getMessage() + "\n" + rep; + } + return rep; } } \ No newline at end of file diff --git a/src/cvrp_ls.class b/src/cvrp_ls.class index 98308e98a6a7e534721ee16364b6e19e9714c6e5..5a06464d68874cdd6103905a145b635ac59db0a5 100644 GIT binary patch literal 3850 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 X$*l}~85kJ27#JD$F&tnx#2^U(@FVyY delta 1430 zcmeB@TPVVH>ff$?3=9m84BZpC>@&C+co=xu8Tfb@_!$Hk83eKt%M$f-67$magDZ<m zQgay@1d~gPic<4RLNaqxeKT`%GK(1*m^C!LxEO>OgxMKHco;+(#26U_5js8dN>bBP zix?T$%Mx=+Q~lEz8Pq3VWEGxl$I9adm9z$Fm*8QLWRPNH;K<A?2?Hqwo9xNXAj8NY zj4;o&B0067Br`vclYxgpj)y^>L1E%;1xBTbf2_Dw7*yFA)OZ-w88jw4GFs_rF*0y? z<`tJD<|U_cF=#R{g9u$7237_QkZye*1_K5KMh528q9P6kqsc27HKU~&On4Yf8Q2&Z z_zQ|M^GbqC5|gt-iV{Hv@GzM3Fjz2HGBU8FR%DhiGO%cPYKE~hSTizkIp(D27iE@Y z<Q8)<*fKJ(r5B~9rc`n<STWdx>~mmb5Sx6FRfI<~3?$~n!{E%|GC7_}&&G|Bf!iId zSRo}pFBK%~0h0A(WDwKv3C_<c1$ow56T#$UuwwA$Venz_oy^6o$|c0Wz~Ilr5Wo;P zc?Po!uMh(xLokRN!pNWo4QNqiO@=TYhHy~u@};Mi_!pF9<|gJi=NFfNLL`!hA&Mb- zat*68cPv93J3~AVLjr@;<W;OP+)NC~AhS{!8MG%~WEGoS%qGsw%#a2WOJ`)z0C{P$ zG@A%BJ45E=scfOT1&j>B(LRXS3N9(i%uBasXDC8VPGI55jO=zS6^sl?lRG(7n5r@- zujjC1teX6eBZskOax|x+S{);UAftks0t_oCD8$6@voSPqF*GtXu`@J-+|e@mFz02K zc18x($?rK;+1MF685!gzzvq;zXJlaW$<NO&EnrY&$Y5Y%00AZjMg~>}HU>t9ECvP! zSq4T1Mg|53R;}#}j2jsk7#JC{85qFQ3=GT+oD4Y(xeQDorA)F6><qjN42;S`>^?%A zzD#yI7`V+@#8_knnO|hICYrPDVBi*Gn=*%iZTbK2TFgd1TJ<bOzFMqCI~WAFF^JnO zXW+Hs*u)?!q_~Yic{hV*<aP#aD-IAtdpm=U6~}T0F)PkZ40=L_+ZdE3Ikzzwv+Q6n z+s$AVDP+U6ox#qEQ<77XV;h5`6&J`9SFkBokvg&<Ic`aANv>@S?p8dT7-S{6w=j6g z?qaC-V_?|EpbQh)#SjGMgA56s$KVPQ=h(&&0n!))CfdMKZFxe8S&}^47-GN#vLMGc zhR|IMNnm4^GsvQv0MfCGAr&mSk%5UprJliz!ID9m!G|G?A(BCwfe9S8RSa^V0B2xk zU}IooU}xZ9;AG%s;9`(q;AT)^5Ma<?5M<C{5MnT65M!`p5N5Du5Mgj;kYVs)kYfmA zP-ci^kY|WyP+&*~N2(G-4ucv)1%o<6BZCG*CxbS_6b2oJxeWRY>lo?{81^w3G8|(t zV&q^jVN_x;WyoV-V2EJg_|G80z{bvy&(2WD&QQq6!otA79m38a&H0}}lz|;tf}KH= zfsvg-TIfH+YzA&L8FmIMc7|98$-p4VP|U!<z{0@DAkDzcP{P1q!ob8(%239@z#zrI j!cfn^$WRU@E5T$nn5<=JWnf_7Vqj!wW9VS$Vvqy?&A=MK diff --git a/src/cvrp_ls.java b/src/cvrp_ls.java index 481c199..df0ca02 100644 --- a/src/cvrp_ls.java +++ b/src/cvrp_ls.java @@ -42,15 +42,29 @@ public class cvrp_ls { } Solution optimizedSolution = chosen.generateSolution(greedySolution); - + //print results - System.out.println(("\nAfter initial greedy Approach, optimized with "+chosen.algorithmType+" with a maximum runtime of approximately "+chosen.maxRuntimeInSeconds+" seconds!").replace("-1", "unlimited")); - System.out.println("Instance name"+" & "+"Cost initial Solution"+" & "+"Cost optimized solution ("+chosen.algorithmType+")"+" & " + "Cost optimal solution (100%)"+ " \\\\"); - if(instance.getOptimalCost() > 0) - System.out.println(instance.getName()+" & "+greedySolution.getCost()+" ("+(float)greedySolution.getCost()/(float)instance.getOptimalCost()*100+"%) & "+optimizedSolution.getCost()+" ("+(float)optimizedSolution.getCost()/(float)instance.getOptimalCost()*100+"%) & "+instance.getOptimalCost() + " \\\\"); - else - System.out.println(instance.getName()+" & "+greedySolution.getCost()+" & "+optimizedSolution.getCost()+" & "+ " \\\\"); - System.out.println("\n Initial solution:\n"+greedySolution.toSol()); - System.out.println("\n Optimized solution:\n"+optimizedSolution.toSol()); + if(chosen.algorithmType.equals( "ant_colony") || chosen.algorithmType.equals("greedy")){ + System.out.println(("\nSolved with "+chosen.algorithmType+" with a maximum runtime of approximately "+chosen.maxRuntimeInSeconds+" seconds!").replace("-1", "unlimited")); + + if(chosen.algorithmType.equals("ant_colony")) + System.out.println("Ants: "+chosen.numberOfAnts+", Phermones Added: "+chosen.pheromonesStrength+", Pheromones Decayed: "+ chosen.pheromonesDecayStrength + ", Deploy Strategy: "+chosen.antStartStrategy+", Reset after Major round: "+chosen.resetPheromones); + System.out.println("Instance name"+" & "+" "+" & "+"Cost solution ("+chosen.algorithmType+")"+" & " + "Cost upper bound (100%)"+ " \\\\"); + if(instance.getOptimalCost() > 0) + System.out.println(instance.getName()+" & " + " & "+optimizedSolution.getCost()+" ("+(float)optimizedSolution.getCost()/(float)instance.getOptimalCost()*100+"%) & "+instance.getOptimalCost() + " \\\\"); + else + System.out.println(instance.getName()+" & "+greedySolution.getCost()+" & "+optimizedSolution.getCost()+" & "+ " \\\\"); + System.out.println("\n Solution:\n"+optimizedSolution.toSol()); + } else { + System.out.println(("\nAfter initial greedy Approach, optimized with "+chosen.algorithmType+" with a maximum runtime of approximately "+chosen.maxRuntimeInSeconds+" seconds!").replace("-1", "unlimited")); + System.out.println("Instance name"+" & "+"Cost initial Solution"+" & "+"Cost optimized solution ("+chosen.algorithmType+")"+" & " + "Cost upper bound (100%)"+ " \\\\"); + if(instance.getOptimalCost() > 0) + System.out.println(instance.getName()+" & "+greedySolution.getCost()+" ("+(float)greedySolution.getCost()/(float)instance.getOptimalCost()*100+"%) & "+optimizedSolution.getCost()+" ("+(float)optimizedSolution.getCost()/(float)instance.getOptimalCost()*100+"%) & "+instance.getOptimalCost() + " \\\\"); + else + System.out.println(instance.getName()+" & "+greedySolution.getCost()+" & "+optimizedSolution.getCost()+" & "+ " \\\\"); + System.out.println("\n Initial solution:\n"+greedySolution.toSol()); + System.out.println("\n Optimized solution:\n"+optimizedSolution.toSol()); + } + } } -- GitLab