Romanchello-bit commited on
Commit
da91f13
·
1 Parent(s): 8aef1af
Files changed (2) hide show
  1. algorithms.py +6 -4
  2. app.py +68 -0
algorithms.py CHANGED
@@ -1,10 +1,11 @@
1
- def bellman_ford_list(graph, start_node, visited_nodes=None, client_type="B2B"):
2
  """
3
  Advanced Bellman-Ford Algorithm.
4
 
5
  Features:
6
  1. Dynamic Weights based on Client Type (B2B prefers logic, B2C prefers speed).
7
  2. Penalty for re-visiting nodes (avoid loops).
 
8
  """
9
 
10
  # Ініціалізація
@@ -19,6 +20,9 @@ def bellman_ford_list(graph, start_node, visited_nodes=None, client_type="B2B"):
19
  "B2C": {"logic": 1.5, "emotion": 0.7, "speed": 0.5}
20
  }
21
  modifiers = type_modifier.get(client_type, {"logic": 1.0, "emotion": 1.0, "speed": 1.0})
 
 
 
22
 
23
  # Основний цикл релаксації
24
  for _ in range(num_vertices - 1):
@@ -26,9 +30,7 @@ def bellman_ford_list(graph, start_node, visited_nodes=None, client_type="B2B"):
26
  for v, weight in graph.adj_list[u]:
27
 
28
  # --- ПОКРАЩЕННЯ 1: Динамічна вага ---
29
- # Тут можна було б перевіряти тип ребра, якби він був у графі.
30
- # Поки що просто емулюємо:
31
- current_weight = weight
32
 
33
  # --- ПОКРАЩЕННЯ 2: Штраф за повторення ---
34
  if visited_nodes and v in visited_nodes:
 
1
+ def bellman_ford_list(graph, start_node, visited_nodes=None, client_type="B2B", sentiment_score=0.0):
2
  """
3
  Advanced Bellman-Ford Algorithm.
4
 
5
  Features:
6
  1. Dynamic Weights based on Client Type (B2B prefers logic, B2C prefers speed).
7
  2. Penalty for re-visiting nodes (avoid loops).
8
+ 3. Sentiment adjustment (-1 angry to +1 happy affects aggressive paths).
9
  """
10
 
11
  # Ініціалізація
 
20
  "B2C": {"logic": 1.5, "emotion": 0.7, "speed": 0.5}
21
  }
22
  modifiers = type_modifier.get(client_type, {"logic": 1.0, "emotion": 1.0, "speed": 1.0})
23
+
24
+ # Sentiment modifier: negative sentiment increases costs, positive decreases
25
+ sentiment_factor = 1.0 - (sentiment_score * 0.3) # Range: 0.7 (happy) to 1.3 (angry)
26
 
27
  # Основний цикл релаксації
28
  for _ in range(num_vertices - 1):
 
30
  for v, weight in graph.adj_list[u]:
31
 
32
  # --- ПОКРАЩЕННЯ 1: Динамічна вага ---
33
+ current_weight = weight * sentiment_factor
 
 
34
 
35
  # --- ПОКРАЩЕННЯ 2: Штраф за повторення ---
36
  if visited_nodes and v in visited_nodes:
app.py CHANGED
@@ -21,6 +21,7 @@ if "lead_info" not in st.session_state: st.session_state.lead_info = {}
21
  if "visited_history" not in st.session_state: st.session_state.visited_history = [] # Track visited nodes
22
  if "current_archetype" not in st.session_state: st.session_state.current_archetype = "UNKNOWN"
23
  if "reasoning" not in st.session_state: st.session_state.reasoning = ""
 
24
  # Checklist status based on your screenshot
25
  if "checklist" not in st.session_state:
26
  st.session_state.checklist = {
@@ -361,6 +362,73 @@ elif st.session_state.page == "chat":
361
  draw_graph(graph_data, st.session_state.current_node, path),
362
  use_container_width=True # Розтягує граф на всю ширину колонки
363
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
364
 
365
  with col_chat:
366
  for msg in st.session_state.messages:
 
21
  if "visited_history" not in st.session_state: st.session_state.visited_history = [] # Track visited nodes
22
  if "current_archetype" not in st.session_state: st.session_state.current_archetype = "UNKNOWN"
23
  if "reasoning" not in st.session_state: st.session_state.reasoning = ""
24
+ if "current_sentiment" not in st.session_state: st.session_state.current_sentiment = 0.0
25
  # Checklist status based on your screenshot
26
  if "checklist" not in st.session_state:
27
  st.session_state.checklist = {
 
362
  draw_graph(graph_data, st.session_state.current_node, path),
363
  use_container_width=True # Розтягує граф на всю ширину колонки
364
  )
365
+
366
+ # --- BELLMAN-FORD ALGORITHM LOGS ---
367
+ st.markdown("---")
368
+ with st.expander("🧮 Алгоритм Беллмана-Форда (Live Logs)", expanded=False):
369
+ st.markdown("""
370
+ **Математика прийняття рішень:**
371
+ Алгоритм шукає шлях $P$, де сума ваг $W$ є мінімальною:
372
+ $$ D[v] = \\min(D[v], D[u] + W(u, v)) $$
373
+ """)
374
+
375
+ # 1. Calculate real data
376
+ visited_ids = [node_to_id[n] for n in st.session_state.get('visited_history', []) if n in node_to_id]
377
+ client_type = st.session_state.lead_info.get('type', 'B2B')
378
+ current_sentiment = st.session_state.get("current_sentiment", 0.0)
379
+
380
+ # Call algorithm to get distance array
381
+ raw_dist = bellman_ford_list(
382
+ graph,
383
+ curr_id,
384
+ visited_nodes=visited_ids,
385
+ client_type=client_type,
386
+ sentiment_score=current_sentiment
387
+ )
388
+
389
+ # 2. Build beautiful table for humans
390
+ debug_data = []
391
+ target_path_set = set(path) # Path we already found for graph
392
+
393
+ for i, d in enumerate(raw_dist):
394
+ node_name = id_to_node[i]
395
+
396
+ # Format infinity
397
+ cost_display = "∞" if d == float('inf') else round(d, 2)
398
+
399
+ # Node status
400
+ status = "⬜"
401
+ if node_name == st.session_state.current_node: status = "📍 Start"
402
+ elif node_name in target_path_set: status = "✨ Path"
403
+ elif d == float('inf'): status = "🚫 Unreachable"
404
+
405
+ debug_data.append({
406
+ "Node": node_name,
407
+ "Cost (Weight)": cost_display,
408
+ "Status": status
409
+ })
410
+
411
+ # Convert to DataFrame
412
+ df_log = pd.DataFrame(debug_data)
413
+
414
+ # Sort: path first, then cheap, then expensive
415
+ df_log["sort_key"] = df_log["Cost (Weight)"].apply(lambda x: 9999 if x == "∞" else float(x))
416
+ df_log = df_log.sort_values(by="sort_key").drop(columns=["sort_key"])
417
+
418
+ # Display
419
+ st.dataframe(
420
+ df_log,
421
+ use_container_width=True,
422
+ hide_index=True
423
+ )
424
+
425
+ # 3. Explanation "Why?"
426
+ st.info(f"""
427
+ **Фактори впливу:**
428
+ - 🎭 **Емоція:** {current_sentiment} (впливає на вартість агресивних кроків)
429
+ - 🏢 **Тип:** {client_type} (змінює пріоритет швидкості)
430
+ - 🔄 **Повтори:** Вузли, де ми вже були, мають штраф x50.
431
+ """)
432
 
433
  with col_chat:
434
  for msg in st.session_state.messages: