這是一個「現實生活」的OO設計問題。我正在與Scala合作,並對特定的Scala解決方案感興趣,但我絕對樂於聽到類似的想法。如果方法沒有完全相同的簽名,如何設計抽象類?
我正在實施分支定界組合優化程序。算法本身很容易實現。對於每一個不同的問題,我們只需要實現一個類,其中包含有關搜索允許的鄰居狀態的信息,如何計算成本,然後可能是什麼下限等...
我也希望能夠嘗試不同的數據結構。例如,存儲邏輯公式的一種方法是使用一個簡單的整數列表列表。這表示一組子句,每個整數都是文字。我們可以有更好的表現,儘管如果我們做一些像「雙字面觀察名單」這樣的東西,並且通常會存儲關於公式的額外信息。
這一切都將意味着像這樣
object BnBSolver[S<:BnBState]{
def solve(states: Seq[S], best_state:Option[S]): Option[S] = if (states.isEmpty) best_state else
val next_state = states.head
/* compare to best state, etc... */
val new_states = new_branches ++ states.tail
solve(new_states, new_best_state)
}
class BnBState[F<:Formula](clauses:F, assigned_variables) {
def cost: Int
def branches: Seq[BnBState] = {
val ll = clauses.pick_variable
List(
BnBState(clauses.assign(ll), ll :: assigned_variables),
BnBState(clauses.assign(-ll), -ll :: assigned_variables)
)
}
}
case class Formula[F<:Formula[F]](clauses:List[List[Int]]) {
def assign(ll: Int) :F =
Formula(clauses.filterNot(_ contains ll)
.map(_.filterNot(_==-ll))))
}
但願這不是太瘋狂了,錯誤或混淆。這裏的整個問題是,這個公式的這個assign
方法通常只會使用將要分配的當前文字。然而,在兩個字面的觀察列表中,你正在做一些懶惰的事情,需要你稍後知道以前分配了哪些文字。
解決此問題的一種方法是,您只需將以前分配的文字列表保留在數據結構中,也許作爲私人事物。使其成爲獨立的懶惰數據結構。但是,以前任務的列表實際上是任何使用Formula類的人都可以使用的。因此,如果有必要,允許使用它的人每次只在assign
時提供列表。
這裏的問題是,我們現在不能有一個摘要Formula
類,只是聲明assign(ll:Int):Formula
。在正常情況下,這是好的,但如果這是一個雙字面觀察列表公式,它實際上是一個assign(literal: Int, previous_assignments: Seq[Int])
。
從使用它的類的角度來看,它是好的。但是,我們如何編寫通用代碼,可以使用所有這些不同版本的Formula
?由於簽名的劇烈變化,它不能簡單地成爲抽象方法。我們可以強迫用戶總是提供完整的分配變量,但這也是一種謊言。該怎麼辦?
這個想法是觀察列表類只是成爲一種常規assign(Int)
類,如果我寫下某種適配器方法,知道從哪裏採取以前的任務...我想也許用implicit
我們可以做點什麼向上。
我發現你的問題,因爲它有點混亂。我的感覺是,你正在混淆你的算法的許多擔憂(再次)對Scala的太多關注。 – pedrofurla
公式是否帶有類型參數? – pedrofurla
順便解決不會編譯。 – pedrofurla