tsp/internal/solver/problem/problem.go
2024-04-10 01:07:37 -04:00

51 lines
2.2 KiB
Go

package problem
type Problem[State comparable] interface {
// Discards the given state, allowing any resources associated with it to be released.
Discard(state State)
// Returns true if the first state is more likely to be a better solution than the second state,
// assuming the best case scenario. This is used to determine the best state to expand next.
//
// If this were to compare the distance traveled so far, this would be equivalent to Dijkstra's algorithm.
//
// If you added a heuristic to estimate the remaining distance, this would be equivalent to A*.
//
// For the traveling salesman problem, you might use traveled distance plus half of the remaining greedy tour length as a lower bound (optimistic) estimate.
OptimisticLess(a State, b State) bool
// Returns true if the first state is more likely to be a better solution than the second state,
// assuming the worst case scenario. This is used to determine if the worst state to discard when at capacity.
//
// This can be equivalent to OptimisticLess in many cases.
//
// For the traveling salesman problem, you might use traveled distance plus the remaining greedy tour length as an upper bound (pessimistic) estimate.
//
// You generally want to penalize states with a lot of uncertainty about their actual cost, especially
// for something like the traveling salesman problem where finding the optimal solution is impractical.
// We could maybe handle finding the optimal TSP solution for 100 points, but definitely not 1000.
// For that, you'd likely want to cluster your points (maybe using k-means) into a manageable number of groups,
// and recursively solve the problem on each group.
PessimisticLess(a State, b State) bool
}
type ProblemStateUpdates[State comparable] interface {
Problem[State]
// If this function returns true, then the solver needs to keep track of
// known states so that it can update their relative order when they're resubmitted.
//
// If a problem doesn't implement this method, then true is assumed by default.
StateUpdates() bool
}
func RequiresStateUpdates[P Problem[State], State comparable](p Problem[State]) bool {
if p, ok := p.(ProblemStateUpdates[State]); ok {
return p.StateUpdates()
}
// return true as a safe default.
return true
}