lonline_nb.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import math
  2. def lonline_network_benchmarking(network, path_list, bounces, C_budget):
  3. candidate_set = list(path_list)
  4. s = 0
  5. C = 0.01
  6. delta = 0.1
  7. cost = 0
  8. estimated_fidelities = {}
  9. # 1経路を1サンプル測る想定コスト(list 前提)
  10. cost_per_sample_unit = sum(bounces) if sum(bounces) > 0 else 1
  11. while cost < C_budget and len(candidate_set) > 1:
  12. s += 1
  13. Ns = math.ceil(C * (2 ** (2 * s)) * math.log2(max((2 ** s) * len(candidate_set) / delta, 2)))
  14. if Ns < 4:
  15. Ns = 4
  16. # --- 事前コスト見積り(lonline準拠) ---
  17. cost_needed_for_one_path = Ns * cost_per_sample_unit
  18. # 2ラウンド目以降で1経路ぶんすら入らないなら終了
  19. if cost + cost_needed_for_one_path > C_budget and s > 1:
  20. break
  21. # 1ラウンド目だけは Ns を縮退してでも1回は回す(入らなければ中止)
  22. """
  23. if cost + cost_needed_for_one_path > C_budget and s == 1:
  24. Ns_fit = (C_budget - cost) // max(cost_per_sample_unit, 1)
  25. if Ns_fit <= 0:
  26. break
  27. Ns = int(Ns_fit)
  28. cost_needed_for_one_path = Ns * cost_per_sample_unit
  29. """
  30. # ---------------------------------------
  31. sample_times = {i: Ns for i in bounces}
  32. p_s = {}
  33. measured_paths = [] # このラウンドで実際に測れた経路だけを削除判定に使う
  34. for path in list(candidate_set):
  35. if cost + cost_needed_for_one_path > C_budget:
  36. continue # 予算に入らない経路はこのラウンドはスキップ
  37. p, bounces_num = network.benchmark_path(path, bounces, sample_times)
  38. cost += bounces_num
  39. estimated_fidelities[path] = p + (1 - p) / 2 # ★ 既存式&変数名を踏襲
  40. p_s[path] = p
  41. measured_paths.append(path)
  42. if not p_s:
  43. break # このラウンドで1つも測れなかった
  44. # online_nb.py と同じ 2^{-s} 幅の連続削除
  45. p_max = max(p_s.values())
  46. new_candidate_set = []
  47. for path in measured_paths: # 測れたものだけで判定(KeyError防止)
  48. if p_s[path] + 2**(-s) > p_max - 2**(-s):
  49. new_candidate_set.append(path)
  50. # もし全消しになったら、保険として現集合を維持
  51. candidate_set = new_candidate_set or candidate_set
  52. if not estimated_fidelities:
  53. return None, cost, None
  54. best_path = max(estimated_fidelities, key=estimated_fidelities.get)
  55. best_path_fidelity = estimated_fidelities[best_path]
  56. correctness = (best_path == getattr(network, "best_path", None))
  57. return correctness, cost, best_path_fidelity