Example #1
0
func TestFWOneEdge(t *testing.T) {
	dg := concrete.NewDenseGraph(2, true)
	aPaths, sPath := search.FloydWarshall(dg, nil)

	path, cost, err := sPath(concrete.Node(0), concrete.Node(1))
	if err != nil {
		t.Fatal(err)
	}

	if math.Abs(cost-1) > 1e-6 {
		t.Errorf("FW got wrong cost %f", cost)
	}

	if len(path) != 2 || path[0].ID() != 0 && path[1].ID() != 1 {
		t.Errorf("Wrong path in FW %v", path)
	}

	paths, cost, err := aPaths(concrete.Node(0), concrete.Node(1))
	if err != nil {
		t.Fatal(err)
	}

	if math.Abs(cost-1) > 1e-6 {
		t.Errorf("FW got wrong cost %f", cost)
	}

	if len(paths) != 1 {
		t.Errorf("Didn't get right paths in FW %v", paths)
	}

	path = paths[0]
	if len(path) != 2 || path[0].ID() != 0 && path[1].ID() != 1 {
		t.Errorf("Wrong path in FW allpaths %v", path)
	}
}
Example #2
0
func TestFWTwoPaths(t *testing.T) {
	dg := concrete.NewDenseGraph(5, false)
	// Adds two paths from 0->2 of equal length
	dg.SetEdgeCost(concrete.Edge{concrete.Node(0), concrete.Node(2)}, 2, true)
	dg.SetEdgeCost(concrete.Edge{concrete.Node(0), concrete.Node(1)}, 1, true)
	dg.SetEdgeCost(concrete.Edge{concrete.Node(1), concrete.Node(2)}, 1, true)

	aPaths, sPath := search.FloydWarshall(dg, nil)
	path, cost, err := sPath(concrete.Node(0), concrete.Node(2))
	if err != nil {
		t.Fatal(err)
	}

	if math.Abs(cost-2) > .00001 {
		t.Errorf("Path has incorrect cost, %f", cost)
	}

	if len(path) == 2 && path[0].ID() == 0 && path[1].ID() == 2 {
		t.Logf("Got correct path: %v", path)
	} else if len(path) == 3 && path[0].ID() == 0 && path[1].ID() == 1 && path[2].ID() == 2 {
		t.Logf("Got correct path %v", path)
	} else {
		t.Errorf("Got wrong path %v", path)
	}

	paths, cost, err := aPaths(concrete.Node(0), concrete.Node(2))

	if err != nil {
		t.Fatal(err)
	}

	if math.Abs(cost-2) > .00001 {
		t.Errorf("All paths function gets incorrect cost, %f", cost)
	}

	if len(paths) != 2 {
		t.Fatalf("Didn't get all shortest paths %v", paths)
	}

	for _, path := range paths {
		if len(path) == 2 && path[0].ID() == 0 && path[1].ID() == 2 {
			t.Logf("Got correct path for all paths: %v", path)
		} else if len(path) == 3 && path[0].ID() == 0 && path[1].ID() == 1 && path[2].ID() == 2 {
			t.Logf("Got correct path for all paths %v", path)
		} else {
			t.Errorf("Got wrong path for all paths %v", path)
		}
	}
}
Example #3
0
// Tests with multiple right paths, but also one dead-end path
// and one path that reaches the goal, but not optimally
func TestFWConfoundingPath(t *testing.T) {
	dg := concrete.NewDenseGraph(6, false)

	// Add a path from 0->5 of cost 4
	dg.SetEdgeCost(concrete.Edge{concrete.Node(0), concrete.Node(1)}, 1, true)
	dg.SetEdgeCost(concrete.Edge{concrete.Node(1), concrete.Node(2)}, 1, true)
	dg.SetEdgeCost(concrete.Edge{concrete.Node(2), concrete.Node(3)}, 1, true)
	dg.SetEdgeCost(concrete.Edge{concrete.Node(3), concrete.Node(5)}, 1, true)

	// Add direct edge to goal of cost 4
	dg.SetEdgeCost(concrete.Edge{concrete.Node(0), concrete.Node(5)}, 4, true)

	// Add edge to a node that's still optimal
	dg.SetEdgeCost(concrete.Edge{concrete.Node(0), concrete.Node(2)}, 2, true)

	// Add edge to 3 that's overpriced
	dg.SetEdgeCost(concrete.Edge{concrete.Node(0), concrete.Node(3)}, 4, true)

	// Add very cheap edge to 4 which is a dead end
	dg.SetEdgeCost(concrete.Edge{concrete.Node(0), concrete.Node(4)}, 0.25, true)

	aPaths, sPath := search.FloydWarshall(dg, nil)

	path, cost, err := sPath(concrete.Node(0), concrete.Node(5))
	if err != nil {
		t.Fatal(err)
	}

	if math.Abs(cost-4) > 1e-6 {
		t.Errorf("Incorrect cost %f", cost)
	}

	if len(path) == 5 && path[0].ID() == 0 && path[1].ID() == 1 && path[2].ID() == 2 && path[3].ID() == 3 && path[4].ID() == 5 {
		t.Logf("Correct path found for single path %v", path)
	} else if len(path) == 2 && path[0].ID() == 0 && path[1].ID() == 5 {
		t.Logf("Correct path found for single path %v", path)
	} else if len(path) == 4 && path[0].ID() == 0 && path[1].ID() == 2 && path[2].ID() == 3 && path[3].ID() == 5 {
		t.Logf("Correct path found for single path %v", path)
	} else {
		t.Errorf("Wrong path found for single path %v", path)
	}

	paths, cost, err := aPaths(concrete.Node(0), concrete.Node(5))
	if err != nil {
		t.Fatal(err)
	}

	if math.Abs(cost-4) > 1e-6 {
		t.Errorf("Incorrect cost %f", cost)
	}

	if len(paths) != 3 {
		t.Errorf("Wrong paths gotten for all paths %v", paths)
	}

	for _, path := range paths {
		if len(path) == 5 && path[0].ID() == 0 && path[1].ID() == 1 && path[2].ID() == 2 && path[3].ID() == 3 && path[4].ID() == 5 {
			t.Logf("Correct path found for multi path %v", path)
		} else if len(path) == 2 && path[0].ID() == 0 && path[1].ID() == 5 {
			t.Logf("Correct path found for multi path %v", path)
		} else if len(path) == 4 && path[0].ID() == 0 && path[1].ID() == 2 && path[2].ID() == 3 && path[3].ID() == 5 {
			t.Logf("Correct path found for multi path %v", path)
		} else {
			t.Errorf("Wrong path found for multi path %v", path)
		}
	}

	path, _, err = sPath(concrete.Node(4), concrete.Node(5))
	if err != nil {
		t.Log("Success!", err)
	} else {
		t.Errorf("Path was found by FW single path where one shouldn't be %v", path)
	}

	paths, _, err = aPaths(concrete.Node(4), concrete.Node(5))
	if err != nil {
		t.Log("Success!", err)
	} else {
		t.Errorf("Path was found by FW multi-path where one shouldn't be %v", paths)
	}
}