2012-03-14 59 views
2

說我有一個對象類,稱爲Computer。然後說我有另一個類叫Wire。 (這些名字被用來簡單地解釋什麼,我試圖做的,真正的有一個比較複雜一點)網絡多個對象的問題

struct Computer { 
std::vector<Wire *> wires; 
}; 

struct Wire { 
Computer * computers[2]; 
}; 

現在讓我們說我有電腦課,並希望做一些事情來的所有計算機它通過導線連接。我可以遍歷所有的電線,並有電線的方法讓計算機做:

wire->doSomething(this,blahblah) 

所以線材找到另一臺計算機,通過它的導線不勝枚舉,並做同樣的事情:

otherWire->doSomething(&otherComputer,blahblah) 

(當然,它會在列表中找到它時跳過)。

這是有效的,但是當存在圓形連接時,它會連續地向所有球創建一個無限循環,調用doSomething。防止這種情況的最好方法是什麼?或者有更好的整體解決方案來解決這個問題?

+2

*除了*:真實世界的網絡具有[同樣的問題(http://en.wikipedia.org/wiki/Bridge_loop)儘管他們[解決方法不同](http://en.wikipedia.org/wiki/Spanning_tree_protocol)。 – 2012-03-14 17:58:01

回答

2

你得到的是一個指示,循環圖。

通常情況下,您想爲每個節點使用「visited」屬性,然後在訪問每個節點前檢查它是否已經訪問過。

在半僞代碼,你會怎麼做:

std::map<Wire*,bool> visited; // Outside the search, so that it's not local 

if (!visited[otherWire]) { 
    visited[otherWire] = true; 
    otherWire->doSomething(&otherComputer,blahblah) 
} 
+0

我明白了。但是,每次接線操作後,我是否必須清除訪問變量? – slartibartfast 2012-03-14 17:11:11

+0

@myrkos您希望每個搜索都有一個訪問節點的列表。 (如果它是全球性的,你重置它,那麼你不可重入這可能/可能不成問題)。雖然重置並且只允許同時搜索一個可能的解決方案。另一種是在整個搜索過程中傳遞對「visited」地圖的引用。 – Flexo 2012-03-14 17:12:25

+0

@myrkos - 對於一般情況不起作用,想象一下圖中的一個循環不會從您開始的節點開始。如果你知道唯一的方法循環可以從你的具體問題開始就是這樣,那麼它會好的,但它不能一概而論。 – Flexo 2012-03-14 17:16:19