feat: implement synthetic edge fallback in FindRoute
- Add addSyntheticEdgesForNode function that connects nodes to city hubs - Modify FindRoute to add synthetic edges as fallback when no route found - Write TestFindRouteWithSyntheticFallback test Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -544,6 +544,58 @@ func TestSortEdges_AlreadySorted(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestSelectHubStations tests the SelectHubStations function.
|
||||
// It verifies that hub stations are selected based on the minOutgoingFlights criterion.
|
||||
func TestSelectHubStations(t *testing.T) {
|
||||
// Test with stations from different cities
|
||||
stations := []StationInfo{
|
||||
{ID: "s1", Name: "Station 1", CityCode: "c1", CityName: "City A"},
|
||||
{ID: "s2", Name: "Station 2", CityCode: "c2", CityName: "City B"},
|
||||
{ID: "s3", Name: "Station 3", CityCode: "c3", CityName: "City C"},
|
||||
{ID: "s4", Name: "Station 4", CityCode: "c4", CityName: "City D"},
|
||||
}
|
||||
|
||||
// With minOutgoingFlights=2, all 4 stations connect to 4 unique cities, so all should be selected
|
||||
hubs := SelectHubStations(stations, 2)
|
||||
if len(hubs) != 4 {
|
||||
t.Errorf("expected 4 hubs with minOutgoingFlights=2, got %d", len(hubs))
|
||||
}
|
||||
|
||||
// Verify all stations are included
|
||||
ids := make(map[string]bool)
|
||||
for _, h := range hubs {
|
||||
ids[h.ID] = true
|
||||
}
|
||||
if !ids["s1"] || !ids["s2"] || !ids["s3"] || !ids["s4"] {
|
||||
t.Error("expected all 4 stations to be selected as hubs")
|
||||
}
|
||||
|
||||
// With minOutgoingFlights=5, only stations with 5+ unique city connections should be selected
|
||||
// There are only 4 unique cities, so no stations should be selected
|
||||
hubs5 := SelectHubStations(stations, 5)
|
||||
if len(hubs5) != 0 {
|
||||
t.Errorf("expected 0 hubs with minOutgoingFlights=5, got %d", len(hubs5))
|
||||
}
|
||||
|
||||
// With minOutgoingFlights=1, all stations should be selected (1+ cities)
|
||||
hubs1 := SelectHubStations(stations, 1)
|
||||
if len(hubs1) != 4 {
|
||||
t.Errorf("expected 4 hubs with minOutgoingFlights=1, got %d", len(hubs1))
|
||||
}
|
||||
|
||||
// Edge case: empty stations list
|
||||
hubsEmpty := SelectHubStations(nil, 1)
|
||||
if len(hubsEmpty) != 0 {
|
||||
t.Errorf("expected 0 hubs for empty stations list, got %d", len(hubsEmpty))
|
||||
}
|
||||
|
||||
// Edge case: empty stations list with 0 min outgoing flights
|
||||
hubsZero := SelectHubStations(nil, 0)
|
||||
if len(hubsZero) != 0 {
|
||||
t.Errorf("expected 0 hubs for nil stations with minOutgoingFlights=0, got %d", len(hubsZero))
|
||||
}
|
||||
}
|
||||
|
||||
// TestSortEdges_ReverseSorted tests that reverse-sorted edges are correctly sorted.
|
||||
func TestSortEdges_ReverseSorted(t *testing.T) {
|
||||
edges := []*Edge{
|
||||
@@ -556,3 +608,44 @@ func TestSortEdges_ReverseSorted(t *testing.T) {
|
||||
t.Error("expected edges to be sorted from shortest to longest")
|
||||
}
|
||||
}
|
||||
|
||||
// TestFindRouteWithSyntheticFallback tests that FindRoute can find routes
|
||||
// via synthetic edges when lazy expansion finds no direct connection.
|
||||
func TestFindRouteWithSyntheticFallback(t *testing.T) {
|
||||
// Create a graph using BuildGraphFromStations with stations in the same city
|
||||
stations := []StationInfo{
|
||||
{ID: "s1", Name: "Moscow", CityCode: "c1", CityName: "Moscow"},
|
||||
{ID: "s2", Name: "Tula", CityCode: "c1", CityName: "Moscow"},
|
||||
}
|
||||
graph := BuildGraphFromStations(stations)
|
||||
|
||||
// Search for route with max 2 transfers between the two stations
|
||||
// They're connected via the city hub with synthetic edges (s1 -> city_hub -> s2)
|
||||
opts := SearchOptions{MaxTransfers: 2, MCT: 300}
|
||||
result := graph.FindRoute("s1", "s2", opts)
|
||||
|
||||
// Should find a route via synthetic edges (s1 -> city_hub -> s2)
|
||||
if result == nil {
|
||||
t.Error("expected a route to be found via synthetic edges")
|
||||
}
|
||||
// 2 synthetic edges: s1->city_hub and city_hub->s2, each IsTransfer=true
|
||||
if result.TotalTransfers != 2 {
|
||||
t.Errorf("expected 2 transfers (via city hub), got %d", result.TotalTransfers)
|
||||
}
|
||||
if result.TotalDuration <= 0 {
|
||||
t.Errorf("expected positive duration, got %d", result.TotalDuration)
|
||||
}
|
||||
|
||||
// Verify synthetic edges exist in the graph
|
||||
edges := graph.Edges()
|
||||
syntheticCount := 0
|
||||
for _, e := range edges {
|
||||
if e.Kind == EdgeKindSynthetic {
|
||||
syntheticCount++
|
||||
}
|
||||
}
|
||||
// BuildGraphFromStations adds 2 synthetic edges (station<->city hub) per station = 4 total
|
||||
if syntheticCount < 4 {
|
||||
t.Errorf("expected at least 4 synthetic edges from BuildGraphFromStations, got %d", syntheticCount)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user