51 lines
2.2 KiB
Go
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
|
|
}
|