001 package aima.test.search.searches; 002 003 import junit.framework.TestCase; 004 import aima.basic.BasicEnvironmentView; 005 import aima.search.map.ExtendableMap; 006 import aima.search.map.MapAgent; 007 import aima.search.map.MapEnvironment; 008 import aima.search.uninformed.BidirectionalSearch; 009 010 /** 011 * @author Ciaran O'Reilly 012 * 013 */ 014 public class BidirectionalSearchTest extends TestCase { 015 016 StringBuffer envChanges; 017 018 BidirectionalSearch bidirectionalSearch; 019 020 @Override 021 public void setUp() { 022 023 envChanges = new StringBuffer(); 024 025 bidirectionalSearch = new BidirectionalSearch(); 026 } 027 028 // 029 // Test IG(A) 030 public void test_A_StartingAtGoal() { 031 ExtendableMap aMap = new ExtendableMap(); 032 033 MapEnvironment me = new MapEnvironment(aMap); 034 MapAgent ma = new MapAgent(me, bidirectionalSearch, 035 new String[] { "A" }); 036 me.addAgent(ma, "A"); 037 me.registerView(new BasicEnvironmentView() { 038 @Override 039 public void envChanged(String command) { 040 envChanges.append(command).append(":"); 041 } 042 }); 043 me.stepUntilDone(); 044 045 assertEquals( 046 "CurrentLocation=In(A), Goal=In(A):NoOP:METRIC[pathCost]=0.0:METRIC[maxQueueSize]=2:METRIC[queueSize]=0:METRIC[nodesExpanded]=2:NoOP:", 047 envChanges.toString()); 048 049 assertEquals( 050 BidirectionalSearch.SearchOutcome.PATH_FOUND_BETWEEN_PROBLEMS, 051 bidirectionalSearch.getSearchOutcome()); 052 } 053 054 // 055 // Test IG(A)<->(B)<->(C) 056 public void test_ABC_StartingAtGoal() { 057 ExtendableMap aMap = new ExtendableMap(); 058 aMap.addBidirectionalLink("A", "B", 5.0); 059 aMap.addBidirectionalLink("B", "C", 5.0); 060 061 MapEnvironment me = new MapEnvironment(aMap); 062 MapAgent ma = new MapAgent(me, bidirectionalSearch, 063 new String[] { "A" }); 064 me.addAgent(ma, "A"); 065 me.registerView(new BasicEnvironmentView() { 066 @Override 067 public void envChanged(String command) { 068 envChanges.append(command).append(":"); 069 } 070 }); 071 me.stepUntilDone(); 072 073 assertEquals( 074 "CurrentLocation=In(A), Goal=In(A):NoOP:METRIC[pathCost]=0.0:METRIC[maxQueueSize]=2:METRIC[queueSize]=2:METRIC[nodesExpanded]=2:NoOP:", 075 envChanges.toString()); 076 077 assertEquals( 078 BidirectionalSearch.SearchOutcome.PATH_FOUND_BETWEEN_PROBLEMS, 079 bidirectionalSearch.getSearchOutcome()); 080 } 081 082 // 083 // Test I(A)<->G(B) 084 public void test_AB_BothWaysPath() { 085 ExtendableMap aMap = new ExtendableMap(); 086 aMap.addBidirectionalLink("A", "B", 5.0); 087 088 MapEnvironment me = new MapEnvironment(aMap); 089 MapAgent ma = new MapAgent(me, bidirectionalSearch, 090 new String[] { "B" }); 091 me.addAgent(ma, "A"); 092 me.registerView(new BasicEnvironmentView() { 093 @Override 094 public void envChanged(String command) { 095 envChanges.append(command).append(":"); 096 } 097 }); 098 me.stepUntilDone(); 099 100 assertEquals( 101 "CurrentLocation=In(A), Goal=In(B):B:METRIC[pathCost]=5.0:METRIC[maxQueueSize]=2:METRIC[queueSize]=2:METRIC[nodesExpanded]=2:NoOP:", 102 envChanges.toString()); 103 104 assertEquals( 105 BidirectionalSearch.SearchOutcome.PATH_FOUND_BETWEEN_PROBLEMS, 106 bidirectionalSearch.getSearchOutcome()); 107 } 108 109 // 110 // Test I(A)<->(B)<->G(C) 111 public void test_ABC_BothWaysPath() { 112 ExtendableMap aMap = new ExtendableMap(); 113 aMap.addBidirectionalLink("A", "B", 5.0); 114 aMap.addBidirectionalLink("B", "C", 5.0); 115 116 MapEnvironment me = new MapEnvironment(aMap); 117 MapAgent ma = new MapAgent(me, bidirectionalSearch, 118 new String[] { "C" }); 119 me.addAgent(ma, "A"); 120 me.registerView(new BasicEnvironmentView() { 121 @Override 122 public void envChanged(String command) { 123 envChanges.append(command).append(":"); 124 } 125 }); 126 me.stepUntilDone(); 127 128 assertEquals( 129 "CurrentLocation=In(A), Goal=In(C):B:C:METRIC[pathCost]=10.0:METRIC[maxQueueSize]=4:METRIC[queueSize]=4:METRIC[nodesExpanded]=4:NoOP:", 130 envChanges.toString()); 131 132 assertEquals( 133 BidirectionalSearch.SearchOutcome.PATH_FOUND_BETWEEN_PROBLEMS, 134 bidirectionalSearch.getSearchOutcome()); 135 } 136 137 // 138 // Test I(A)<->(B)<->(C)<->(D) 139 public void test_ABCD_BothWaysPath() { 140 ExtendableMap aMap = new ExtendableMap(); 141 aMap.addBidirectionalLink("A", "B", 5.0); 142 aMap.addBidirectionalLink("B", "C", 5.0); 143 aMap.addBidirectionalLink("C", "D", 5.0); 144 145 MapEnvironment me = new MapEnvironment(aMap); 146 MapAgent ma = new MapAgent(me, bidirectionalSearch, 147 new String[] { "D" }); 148 me.addAgent(ma, "A"); 149 me.registerView(new BasicEnvironmentView() { 150 @Override 151 public void envChanged(String command) { 152 envChanges.append(command).append(":"); 153 } 154 }); 155 me.stepUntilDone(); 156 157 assertEquals( 158 "CurrentLocation=In(A), Goal=In(D):B:C:D:METRIC[pathCost]=15.0:METRIC[maxQueueSize]=4:METRIC[queueSize]=4:METRIC[nodesExpanded]=4:NoOP:", 159 envChanges.toString()); 160 161 assertEquals( 162 BidirectionalSearch.SearchOutcome.PATH_FOUND_BETWEEN_PROBLEMS, 163 bidirectionalSearch.getSearchOutcome()); 164 } 165 166 // 167 // Test I(A)->G(B) 168 public void test_AB_OriginalOnlyPath() { 169 ExtendableMap aMap = new ExtendableMap(); 170 aMap.addUnidirectionalLink("A", "B", 5.0); 171 172 MapEnvironment me = new MapEnvironment(aMap); 173 MapAgent ma = new MapAgent(me, bidirectionalSearch, 174 new String[] { "B" }); 175 me.addAgent(ma, "A"); 176 me.registerView(new BasicEnvironmentView() { 177 @Override 178 public void envChanged(String command) { 179 envChanges.append(command).append(":"); 180 } 181 }); 182 me.stepUntilDone(); 183 184 assertEquals( 185 "CurrentLocation=In(A), Goal=In(B):B:METRIC[pathCost]=5.0:METRIC[maxQueueSize]=2:METRIC[queueSize]=1:METRIC[nodesExpanded]=2:NoOP:", 186 envChanges.toString()); 187 188 assertEquals( 189 BidirectionalSearch.SearchOutcome.PATH_FOUND_FROM_ORIGINAL_PROBLEM, 190 bidirectionalSearch.getSearchOutcome()); 191 } 192 193 // 194 // Test I(A)->(B)->G(C) 195 public void test_ABC_OriginalOnlyPath() { 196 ExtendableMap aMap = new ExtendableMap(); 197 aMap.addUnidirectionalLink("A", "B", 5.0); 198 aMap.addUnidirectionalLink("B", "C", 5.0); 199 200 MapEnvironment me = new MapEnvironment(aMap); 201 MapAgent ma = new MapAgent(me, bidirectionalSearch, 202 new String[] { "C" }); 203 me.addAgent(ma, "A"); 204 me.registerView(new BasicEnvironmentView() { 205 @Override 206 public void envChanged(String command) { 207 envChanges.append(command).append(":"); 208 } 209 }); 210 me.stepUntilDone(); 211 212 assertEquals( 213 "CurrentLocation=In(A), Goal=In(C):B:C:METRIC[pathCost]=10.0:METRIC[maxQueueSize]=2:METRIC[queueSize]=0:METRIC[nodesExpanded]=4:NoOP:", 214 envChanges.toString()); 215 216 assertEquals( 217 BidirectionalSearch.SearchOutcome.PATH_FOUND_FROM_ORIGINAL_PROBLEM, 218 bidirectionalSearch.getSearchOutcome()); 219 } 220 221 // 222 // Test I(A)->(B)->(C)<->(D)<->G(E) 223 public void test_ABCDE_OriginalOnlyPath() { 224 ExtendableMap aMap = new ExtendableMap(); 225 aMap.addBidirectionalLink("A", "B", 5.0); 226 aMap.addUnidirectionalLink("B", "C", 5.0); 227 aMap.addBidirectionalLink("C", "D", 5.0); 228 aMap.addBidirectionalLink("D", "E", 5.0); 229 230 MapEnvironment me = new MapEnvironment(aMap); 231 MapAgent ma = new MapAgent(me, bidirectionalSearch, 232 new String[] { "E" }); 233 me.addAgent(ma, "A"); 234 me.registerView(new BasicEnvironmentView() { 235 @Override 236 public void envChanged(String command) { 237 envChanges.append(command).append(":"); 238 } 239 }); 240 me.stepUntilDone(); 241 242 assertEquals( 243 "CurrentLocation=In(A), Goal=In(E):B:C:D:E:METRIC[pathCost]=20.0:METRIC[maxQueueSize]=4:METRIC[queueSize]=3:METRIC[nodesExpanded]=5:NoOP:", 244 envChanges.toString()); 245 246 assertEquals( 247 BidirectionalSearch.SearchOutcome.PATH_FOUND_FROM_ORIGINAL_PROBLEM, 248 bidirectionalSearch.getSearchOutcome()); 249 } 250 251 // 252 // Test I(A)<-G(B) 253 public void test_AB_ReverseOnlyPath() { 254 ExtendableMap aMap = new ExtendableMap(); 255 aMap.addUnidirectionalLink("B", "A", 5.0); 256 257 MapEnvironment me = new MapEnvironment(aMap); 258 MapAgent ma = new MapAgent(me, bidirectionalSearch, 259 new String[] { "B" }); 260 me.addAgent(ma, "A"); 261 me.registerView(new BasicEnvironmentView() { 262 @Override 263 public void envChanged(String command) { 264 envChanges.append(command).append(":"); 265 } 266 }); 267 me.stepUntilDone(); 268 269 assertEquals( 270 "CurrentLocation=In(A), Goal=In(B):NoOP:METRIC[pathCost]=0.0:METRIC[maxQueueSize]=2:METRIC[queueSize]=0:METRIC[nodesExpanded]=3:NoOP:", 271 envChanges.toString()); 272 273 assertEquals(BidirectionalSearch.SearchOutcome.PATH_NOT_FOUND, 274 bidirectionalSearch.getSearchOutcome()); 275 } 276 277 // 278 // Test I(A)<-(B)<-G(C) 279 public void test_ABC_ReverseOnlyPath() { 280 ExtendableMap aMap = new ExtendableMap(); 281 aMap.addUnidirectionalLink("B", "A", 5.0); 282 aMap.addUnidirectionalLink("C", "B", 5.0); 283 284 MapEnvironment me = new MapEnvironment(aMap); 285 MapAgent ma = new MapAgent(me, bidirectionalSearch, 286 new String[] { "C" }); 287 me.addAgent(ma, "A"); 288 me.registerView(new BasicEnvironmentView() { 289 @Override 290 public void envChanged(String command) { 291 envChanges.append(command).append(":"); 292 } 293 }); 294 me.stepUntilDone(); 295 296 assertEquals( 297 "CurrentLocation=In(A), Goal=In(C):NoOP:METRIC[pathCost]=0.0:METRIC[maxQueueSize]=2:METRIC[queueSize]=0:METRIC[nodesExpanded]=4:NoOP:", 298 envChanges.toString()); 299 300 assertEquals(BidirectionalSearch.SearchOutcome.PATH_NOT_FOUND, 301 bidirectionalSearch.getSearchOutcome()); 302 } 303 304 // Test I(A)<->(B)<->(C)<-(D)<-G(E) 305 public void test_ABCDE_ReverseOnlyPath() { 306 ExtendableMap aMap = new ExtendableMap(); 307 aMap.addBidirectionalLink("A", "B", 5.0); 308 aMap.addBidirectionalLink("B", "C", 5.0); 309 aMap.addUnidirectionalLink("D", "C", 5.0); 310 aMap.addUnidirectionalLink("E", "D", 5.0); 311 312 MapEnvironment me = new MapEnvironment(aMap); 313 MapAgent ma = new MapAgent(me, bidirectionalSearch, 314 new String[] { "E" }); 315 me.addAgent(ma, "A"); 316 me.registerView(new BasicEnvironmentView() { 317 @Override 318 public void envChanged(String command) { 319 envChanges.append(command).append(":"); 320 } 321 }); 322 me.stepUntilDone(); 323 324 assertEquals( 325 "CurrentLocation=In(A), Goal=In(E):NoOP:METRIC[pathCost]=0.0:METRIC[maxQueueSize]=3:METRIC[queueSize]=0:METRIC[nodesExpanded]=8:NoOP:", 326 envChanges.toString()); 327 328 assertEquals(BidirectionalSearch.SearchOutcome.PATH_NOT_FOUND, 329 bidirectionalSearch.getSearchOutcome()); 330 } 331 332 // Test I(A)<->(B)<->(C)<->(D)<->(E)<->G(F) 333 // | + 334 // ------------------------- 335 public void test_ABCDEF_OriginalFirst() { 336 ExtendableMap aMap = new ExtendableMap(); 337 aMap.addBidirectionalLink("A", "B", 5.0); 338 aMap.addBidirectionalLink("B", "C", 5.0); 339 aMap.addBidirectionalLink("C", "D", 5.0); 340 aMap.addBidirectionalLink("D", "E", 5.0); 341 aMap.addBidirectionalLink("E", "F", 5.0); 342 aMap.addUnidirectionalLink("B", "F", 5.0); 343 344 MapEnvironment me = new MapEnvironment(aMap); 345 MapAgent ma = new MapAgent(me, bidirectionalSearch, 346 new String[] { "F" }); 347 me.addAgent(ma, "A"); 348 me.registerView(new BasicEnvironmentView() { 349 @Override 350 public void envChanged(String command) { 351 envChanges.append(command).append(":"); 352 } 353 }); 354 me.stepUntilDone(); 355 356 assertEquals( 357 "CurrentLocation=In(A), Goal=In(F):B:F:METRIC[pathCost]=10.0:METRIC[maxQueueSize]=5:METRIC[queueSize]=5:METRIC[nodesExpanded]=6:NoOP:", 358 envChanges.toString()); 359 360 assertEquals( 361 BidirectionalSearch.SearchOutcome.PATH_FOUND_FROM_ORIGINAL_PROBLEM, 362 bidirectionalSearch.getSearchOutcome()); 363 } 364 365 // Test I(A)<->(B)<->(C)<->(D)<->(E)<->G(F) 366 // + | 367 // ------------------------- 368 public void test_ABCDEF_ReverseFirstButNotFromOriginal() { 369 ExtendableMap aMap = new ExtendableMap(); 370 aMap.addBidirectionalLink("A", "B", 5.0); 371 aMap.addBidirectionalLink("B", "C", 5.0); 372 aMap.addBidirectionalLink("C", "D", 5.0); 373 aMap.addBidirectionalLink("D", "E", 5.0); 374 aMap.addBidirectionalLink("E", "F", 5.0); 375 aMap.addUnidirectionalLink("E", "A", 5.0); 376 377 MapEnvironment me = new MapEnvironment(aMap); 378 MapAgent ma = new MapAgent(me, bidirectionalSearch, 379 new String[] { "F" }); 380 me.addAgent(ma, "A"); 381 me.registerView(new BasicEnvironmentView() { 382 @Override 383 public void envChanged(String command) { 384 envChanges.append(command).append(":"); 385 } 386 }); 387 me.stepUntilDone(); 388 389 assertEquals( 390 "CurrentLocation=In(A), Goal=In(F):B:C:D:E:F:METRIC[pathCost]=25.0:METRIC[maxQueueSize]=6:METRIC[queueSize]=6:METRIC[nodesExpanded]=7:NoOP:", 391 envChanges.toString()); 392 393 assertEquals( 394 BidirectionalSearch.SearchOutcome.PATH_FOUND_BETWEEN_PROBLEMS, 395 bidirectionalSearch.getSearchOutcome()); 396 } 397 398 // ------------- 399 // + + 400 // Test I(A)<->(B)<->(C)<->(D)<->(E)<-G(F) 401 // + + 402 // ------------------------- 403 public void test_ABCDEF_MoreComplexReverseFirstButNotFromOriginal() { 404 ExtendableMap aMap = new ExtendableMap(); 405 aMap.addBidirectionalLink("A", "B", 5.0); 406 aMap.addBidirectionalLink("B", "C", 5.0); 407 aMap.addBidirectionalLink("C", "D", 5.0); 408 aMap.addBidirectionalLink("D", "E", 5.0); 409 aMap.addUnidirectionalLink("F", "E", 5.0); 410 aMap.addBidirectionalLink("E", "A", 5.0); 411 aMap.addBidirectionalLink("D", "F", 5.0); 412 413 MapEnvironment me = new MapEnvironment(aMap); 414 MapAgent ma = new MapAgent(me, bidirectionalSearch, 415 new String[] { "F" }); 416 me.addAgent(ma, "A"); 417 me.registerView(new BasicEnvironmentView() { 418 @Override 419 public void envChanged(String command) { 420 envChanges.append(command).append(":"); 421 } 422 }); 423 me.stepUntilDone(); 424 425 assertEquals( 426 "CurrentLocation=In(A), Goal=In(F):B:C:D:F:METRIC[pathCost]=20.0:METRIC[maxQueueSize]=9:METRIC[queueSize]=9:METRIC[nodesExpanded]=7:NoOP:", 427 envChanges.toString()); 428 429 assertEquals( 430 BidirectionalSearch.SearchOutcome.PATH_FOUND_BETWEEN_PROBLEMS, 431 bidirectionalSearch.getSearchOutcome()); 432 } 433 }