[英]How to calculate the shortest path between two vertices in Graph with given parameters?
[英]How to calculate fast in a given graph the probability that one of n non overlapping pairs of vertices wont be on an edge
我有 45 個頂點的圖,我想計算如果我采用 n 個隨機非重疊對,其中一個不會在邊緣上的概率。 當我說非重疊對時,我的意思是它們不共享任何頂點。
例如,當 n == 2 時,還有這個圖:
左上角的頂點被選中的概率是4/5,那么如果他被選中了,它與右上角的頂點成對的概率是1/4。
所以結果應該是 (4/5)*(1-1/4)=0.6
我能想到的最快方法是檢測哪個頂點的鄰居最少,並對這個頂點進行遞歸。
這是我寫的代碼(在java中)
public class TwinNeighbor {
public static double get(byte[][] neighborsArr, int pairAmount) {
return getRec(neighborsArr, pairAmount, new boolean[neighborsArr.length]);
}
private static double getRec(byte[][] neighborsArr, int pairAmount, boolean[] deleted) {
int deleteAmount = total(deleted);
if (pairAmount == 0)
return 1;
if (pairAmount * 2 > neighborsArr.length - deleteAmount)
return 0;
int index = getIndexWithLeastNeighbors(neighborsArr, deleted);
double total = 0;
deleted[index] = true;
for (byte neighbor : neighborsArr[index]) {
if (deleted[neighbor])
continue;
deleted[neighbor] = true;
total += getRec(neighborsArr, pairAmount - 1, deleted);
deleted[neighbor] = false;
}
double probabilityIfSelected = total / (neighborsArr.length - deleteAmount - 1);
double probabilityIfNotSelected = getRec(neighborsArr, pairAmount, deleted);
deleted[index] = false;
double probabilitySelectCard = (double) pairAmount * 2 / (neighborsArr.length - deleteAmount);
return probabilitySelectCard * probabilityIfSelected + (1 - probabilitySelectCard) * probabilityIfNotSelected;
}
private static int total(boolean[] arr) {
int total = 0;
for (boolean b : arr)
if (b)
total++;
return total;
}
private static int getIndexWithLeastNeighbors(byte[][] neighborsArr, boolean[] deleted) {
int minNeighborsAmount = neighborsArr.length;
int minNeighborsIndex = -1;
for (int i = 0; i < neighborsArr.length; i++) {
if (deleted[i])
continue;
int neighborsAmount = 0;
for (byte neighbor : neighborsArr[i])
if (!deleted[neighbor])
neighborsAmount++;
if (neighborsAmount < minNeighborsAmount) {
minNeighborsAmount = neighborsAmount;
minNeighborsIndex = i;
}
}
return minNeighborsIndex;
}
}
public static void main(String[] args) {
System.out.println(1 - TwinNeighbor.get(new byte[][] {
{1},
{0,2,3,4},
{1,3,4},
{1,2,4},
{1,2,3}
}, 2));//prints 0.6000000000000001
}
有什么辦法可以讓我的代碼運行得更快?
編輯:
如果 n 很小,有沒有辦法讓它更快? (n <= 6, |V| = 45)
不幸的是,n = |V|/2 的特殊情況相當於計算完美匹配的數量,這是一個#P-hard 問題,所以除非出現奇跡,否則您將陷入指數時間算法的困境。
您可以通過記憶每個(誘導子圖,n')對的結果來獲得 O(n |V| 2 |V| ) 時間算法,其中 n' ≤ n。 這對|V| 來說很昂貴 = 45 但並非不可能,特別是如果 n 很小並且您只需要評估缺少 ≤ 2n 個頂點的子圖。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.