lOMoARcPSD|45315597
Ni dung
main.py............................................................................................................................................
1
config.py...........................................................................................................................................
2
connect.py.......................................................................................................................................
3
filter.py.............................................................................................................................................
4
nx_solution.py.................................................................................................................................
6
raw_shortest_path.py......................................................................................................................
8
uniTestGraphProcessor.py...............................................................................................................
9
main.py
1. Làm v cái gì?
Entry point cho toàn b h thng mô phng lp kế hoạch đường đi (path planning
simulation).
Chy lp nhiu ln vi các cu hình khác nhau (solver, test automation, time
measurement), schedule và chy event-driven simulation, ri log kết qu vào CSV.
2. Có cái nào hay?
Luân phiên giữa ba phương pháp giải:
1. LINK II solver (t viết)
2. Parallel network-simplex
3. NetworkX
Dùng discrevpy.simulator để schedule và chy các Event mt cách event-driven.
lOMoARcPSD|45315597
Quản lý cleanup thư mục output t đng qua DirectoryManager trước mi ln chy,
giúp tách bit d liu gia các th nghim.
3. Làm như thế nào?
1. Khi to o Import các module: Graph, AGV, Event,
Logger, GraphProcessor, v.v. o Dn sạch thư mục output
vi dm.full_cleanup().
2. Định nghĩa các hàm helper o get_os(): phát hin h điu
hành.
o choose_solver(), choose_time_measurement(), choose_test_automation():
tương tác CLI để thiết lp config.
3. Vòng lp th nghim (while config.count < 6) o
Tăng config.count, nếu cn thì dm.half_cleanup(). o
Chn solver, chế đ test, mức đ đo thời gian.
o To GraphProcessor, gi use_in_main(), khi to Graph và Event (qua
init_agvs_n_events, init_tasks, init_nodes_n_edges). o Sp xếp và schedule s
kin, chy simulator.run(). o Tính và in thi gian thc thi, ghi log vào file CSV.
o Gọi reset() để đưa simulator và AGV về trạng thái ban đầu.
4. Gm có hàm gì?
get_os()
choose_solver()
choose_time_measurement()
choose_test_automation()
schedule_events(events)
reset(simulator)
Block if __name__ == "__main__": để thc thi cui cùng.
5. Th loi?
lOMoARcPSD|45315597
Script orchestration: CLI-driven, event-driven simulation driver.
Kết hp procedural (vòng lp, gi hàm) và interactive (nhp la chn qua input()).
config.py
1. Làm v cái gì?
config.py định nghĩa toàn b biến toàn cc dùng xuyên sut h thng mô phng:
La chn solver (solver_choice)
Danh sách node bắt đầu (started_nodes) và các ID liên quan (ID)
Tham s đồ th (H, d)
S ng AGV (num_max_agvs, numOfAGVs) và counters cho quá trình chy (count,
reachingTargetAGVs, haltingAGVs)
Theo dõi chi phí (totalCost) và thi gian gii (timeSolving)
Chế độ mô phng (level_of_simulation 0/1/2)
C test t động (test_automation) và hin th đồ ha (draw)
File cha các hàm ph tr (functions_file)
2. Có cái nào hay?
Tp trung cu hình: gom mi tham s mt nơi, giúp dễ điu chnh mà không phi mò
tng module.
level_of_simulation đưc comment rõ 3 chế đ: “Fully Random”, “Random in the list”,
“SFM” – linh hot cho nhiu kiu chy th.
solver_choice mặc định là 'network-simplex', d chuyển đổi giữa các phương pháp giải
bng cách sửa đúng biến này.
3. Làm như thế nào?
Các module khác import config và truy cp trc tiếp các biến:
lOMoARcPSD|45315597
Không có logic x lý trong file, ch khai báo và gán giá tr ban đầu cho biến.
4. Gm có hàm gì?
Không có hàm nào: toàn bbiến toàn cc và mt dòng comment cho
level_of_simulation.
5. Th loi?
Đây là configuration module (script cu hình) dùng để qun lý tham s cho toàn b
ng dng, tách bit khi phn logic x lý.
connect.py
1. Làm v cái gì?
Module này cung cp hàm tin ích để:
Thc thi các lnh shell t Python và ly v kết qu đầu ra (stdout) Trích xut các
giá tr thi gian (s nguyên) t chuỗi đầu ra ca lệnh đó
2. Có cái nào hay?
subprocess.run vi check=True: nếu lnh tr v mã li khác 0 s t đng ném
CalledProcessError, giúp bt li rõ ràng.
Tùy chn capture_output linh hot: bt/tt vic thu thp stdout theo nhu cu.
Dùng re.finditer vi pattern r's (\d+)' để quét và chuyn tng nhóm s thành int, thu
đưc danh sách thi gian
3. Làm như thế nào?
run_command(command, shell=False, capture_output=True)
1. Gi subprocess.run(...) với text=True để tr v chui.
2. Nếu capture_output=True, tr v result.stdout.strip(), ngược li tr v None.
3. Bt CalledProcessError và in li ri tr v None.
extract_time_values(output)
1. Khi to danh sách rng s_values.
2. Duyt matches = re.finditer(r's (\d+)', output) để tìm tt c các nhóm s sau ký
t "s ".
lOMoARcPSD|45315597
3. Vi mi match, chuyn match.group(1) thành int và thêm vào s_values.
4. Tr v s_values
4. Gm có hàm gì?
run_command(command, shell=False, capture_output=True)
extract_time_values(output)
5. Th loi?
Đây là utility module (h tr h thng) dành cho tương tác với shellx lý chui đu
ra, không cha logic nghip v chính. filter.py
1. Làm v cái gì?
File này x lý và lc d liu t các file text để chun b input cho mô phng:
remove_zero_lines loi b các dòng không cn thiết (ch gi dòng bắt đầu bng 'c'/'s'
hoc kết thúc bng s > 0).
filter_lines đọc điều kin t file sequence (seq-f.txt), quét file input, cng dn giá tr cui
dòng và in log chi tiết quá trình lc.
2. Có cái nào hay?
Kết hp lọc sơ bộtng hợp có điều kin, giúp chun hóa d liệu trước khi chy mô
phng.
In ra từng bước cp nht biến count vi cú pháp rõ ràng: old + inc = new, rt hu ích
cho vic debug.
3. Làm như thế nào?
remove_zero_lines(file_path)
1. Đọc toàn b dòng t file_path.
2. Gi li dòng nếu nó bắt đầu bng 'c' hoc 's', hoc dòng có ký t cui cùng là s
và giá tr > 0.
3. Ghi các dòng được gi vào file filtered.txt.
filter_lines(seq_file_path, input_file_path, H)
1. Đọc file sequence, vi mi dòng bắt đầu 'f' trích ra hai s tiếp theo thành phn
t ca mng X.
lOMoARcPSD|45315597
2. Đọc toàn b file input, và vi mi element trong X, tìm pattern "a " + element
trong tng dòng.
3. Khi tìm thy, ly s cui dòng (inc), tăng count += inc, in log chi tiết.
4. Cui cùng in tng count và gi remove_zero_lines('seq-f.txt') để cp nhật file đã
lc.
4. Gm có hàm gì?
remove_zero_lines(file_path)
filter_lines(seq_file_path, input_file_path, H)
5. Th loi?
Đây là data preprocessing script: chuyên v lctng hp d liu trên các file text,
chun b input cho các bước mô phỏng đường đi.
nx_solution.py
1. Làm v cái gì?
File này là mt script CLI đơn giản để đọc d liệu đồ th định dng DIMACS, xây dng đồ th
ng vi thuc tính demand trên các node và capacity/weight trên các cnh, ri gii bài toán
Minimum Cost Flow bng hàm network_simplex() ca NetworkX và in kết qu ra console.
2. Có cái nào hay?
Tn dng network_simplex(): không phi t trin khai thut toán lung chi phí thp
nht mà dùng gii thuật đã được tối ưu sẵn trong NetworkX.
X lý DIMACS: parse dòng bắt đầu bằng 'n' để lấy demand, dòng 'a' để ly capacity và
cost (lưu vào weight), phù hợp chun DIMACS.
Chế độ debug: có ch #pdb.set_trace() để d bt g li từng bước khi cn.
3. Làm như thế nào?
1. Nhập thư viện: import networkx as nx import pdb
2. Định nghĩa read_dimac_file(file_path):
lOMoARcPSD|45315597
o Khi to G = nx.DiGraph().
o M file, đọc từng dòng, split() để ly parts.
o Nếu parts[0] == 'n':
ID = parts[1]
demand = -int(parts[2])
G.add_node(ID, demand=demand) o Nếu parts[0] == 'a':
ID1, ID2 = parts[1], parts[2]
U = int(parts[4]) (capacity)
C = int(parts[5]) (cost)
G.add_edge(ID1, ID2, weight=C, capacity=U)
3. Gii lung:
flowCost, flowDict = nx.network_simplex(G)
4. In kết qu:
print("flowCost:", flowCost)
print("flowDict:", flowDict)
5. Phn chy chính: file_path = input("Path to DIMAC file:")
read_dimac_file(file_path)
``` :contentReference[oaicite:2]{index=2}
4. Gm có hàm gì?
read_dimac_file(file_path): duy nhất, đảm nhim t việc parse file DIMACS đến gi
solver và in kết qu.
Các hàm ca NetworkX (nx.DiGraph(), nx.network_simplex()) được gọi bên trong nhưng
không được đóng gói thêm.
5. Th loi?
lOMoARcPSD|45315597
Utility script / CLI demo:
o Không phi module importable, mà chy trc tiếp qua python nx_solution.py.
o Phc v minh ha hoc kim th nhanh thut toán Minimum Cost Flow vi d
liu DIMACS
raw_shortest_path.py
1. Làm v cái gì?
File này tính đường đi ngắn nht gia các đim bắt đầuđim kết thúc trên mt đồ th
ớng, được mô t trong file đầu vào (định dạng tương tự DIMACS). Kết qu là đ dài ngn
nht t mỗi start đến mi end, hoc inf nếu không kết nối được.
2. cái nào hay?
T trin khai Dijkstra vi heapq mà không cần thư viện ngoài, giúp hiu sâu cách hot
đng ca priority queue.
Cơ chế đánh dấu start/end linh hoạt: đọc dòng n … 1 thành start, n … -1 thành end.
Tr v float('inf') cho các cp không kết ni, thun tin khi x lý kết qu.
3. Làm như thế nào?
1. Đọc input (read_input(file_path)):
o M file, tách tng dòng theo du cách.
o Vi dòng bắt đầu 'n' và s cuối là 1 → thêm vào start_points; nếu là -1 → thêm
vào end_points.
o Với dòng 'a' → trích (source, destination, weight) vào edges.
2. Xây adjacency list trong find_shortest_paths:
o Duyt edges, nhóm theo source thành dict graph[source] = [(dest, weight), …].
3. Dijkstra (dijkstra(graph, start)):
o Khi distances[start]=0, push (0, start) vào min-heap.
lOMoARcPSD|45315597
o Lp: pop node có current_distance nh nht, cp nht neighbor nếu tìm được
đưng ngắn hơn, push vào heap.
4. Tính kết qu (find_shortest_paths):
o Vi mi start gọi dijkstra, sau đó xây dict {end: distances.get(end, inf)}.
5. In ra console (main):
o Hin th tng cặp Start point, End point và đ dài ngn nht.
4. Gm có hàm gì?
Hàm Mô t
read_input(file_path) Đc file, phân loi start_points, end_points, và edges. dijkstra(graph,
start) Tính khong cách ngn nht t start đến mi node vi min-heap.
find_shortest_paths(...) Xây graph, gi dijkstra cho mi start, tr kết qu dng dict.
main(file_path) Điu phi: gọi read_input → find_shortest_paths → in kết qu.
5. Th loi?
Script CLI thut toán: chy trc tiếp qua python raw_shortest_path.py, dùng để
benchmark hoc debug tính đúng đắn ca Dijkstra trên input file.
Phù hp làm baseline so sánh vi các gii thut phc tạp hơn (như NetworkX hay
network simplex).
uniTestGraphProcessor.py
1. Làm v cái gì?
Đây là b kim th (unit tests) dành cho lớp GraphProcessor, đảm bảo các bước x
đồ th (như nạp file, to ma trn, thêm constraints, khi to node/edge, cp nht graph)
hoạt đng đúng theo yêu cầu
lOMoARcPSD|45315597
2. cái nào hay?
S dng nhiều hàm assert_… để kim tra tính toàn vn ca graph các giai đoạn khác
nhau:
o S lượng node/edge phải đúng sau mỗi bước
o Node và edge tha mãn ràng buc thi gian (TimeWindowNode,
RestrictionNode, TimeWindowEdge, RestrictionEdge)
Kết hợp in thông báo rõ ràng (“Test cho file 2ndSimple.txt”) và t động lp qua hai tình
huống earliness/tardiness để kim th c hai kch bn.
3. Làm như thế nào?
1. Import và khi to
o Nhp các lp t model và controller (ví d Graph, Event, TimeWindowNode,
RestrictionEdge, v.v.)
o To instance processor = GraphProcessor() và tt in debug (processor.print_out
= False).
2. Np d liu & cu hình
o Dùng file "2ndSimple.txt", set started_nodes, H, d, alpha, beta, gamma,
restrictions, v.v.
3. Chy pipeline x
o processor.process_input_file() → generate_hm_matrix() →
generate_adj_matrix() → create_tsg_file() o Lp hai lần để test c earliness và
tardiness, gi add_time_windows_constraints()
o Thiết lp restriction_count, start_ban, end_ban, restrictions, ri
process_restrictions()
4. Khi to Graph & update o To graph = Graph(processor) o Gi
processor.init_nodes_n_edges(graph) để thêm node/edge vào graph o Kim tra tng s
edge/node khp vi processor.tsedges/processor.ts_nodes
o Gọi processor.update_graph(id1, id2, c12) để mô phng cp nht graph sau s
kin
lOMoARcPSD|45315597
5. Kim th các ràng buc o Gi tun t 8 hàm assert_… để c minh:
1. assert_Nodes(graph, current_time)
2. assert_Edges(graph, current_time)
3. assert_connection_TimeWindowNodes(graph)
4. assert_RestrictionNodes(graph)
5. So sánh s TimeWindowNode đúng = 2
6. assert_number_TimeWindowEdges(graph, current_time)
7. assert_new_RestrictionNodes(graph) 8.
assert_numberOf_RestrictionNodes(graph)
4. Gm có hàm gì?
assert_Nodes(graph, current_time): Đếm node thỏa mãn time ≥ current_time (loại tr
TimeWindow/RestrictionNode).
assert_Edges(graph, current_time): Kim tra các edge (ngoi tr
TimeWindow/RestrictionEdge) có ngun tha time ≥ current_time.
assert_connection_TimeWindowNodes(graph): Đảm bo mi TimeWindowNode có ít
nht mt edge ni vào.
assert_number_TimeWindowEdges(graph, current_time): So sánh s
TimeWindowEdge mới đúng bằng cũ trừ các edge không tha ràng buc thi gian.
assert_RestrictionNodes(graph): Mi RestrictionNode phi có ít nht mt edge ni vào.
assert_new_RestrictionNodes(graph): Tương tự vi RestrictionEdge có ngun không
phi RestrictionNode.
assert_numberOf_RestrictionNodes(graph): Kim tra s RestrictionEdge với đích không
phi RestrictionNode sau lc theo thi gian.
Block kim th cui file: To processor, thiết lp tham s, chy pipeline và gi các hàm
assert.
5. Th loi?
lOMoARcPSD|45315597
Unit Test Module: Dùng để xác minh tính đúng đắn ca lp GraphProcessor sau mi
c x lý, đảm bo các ràng buc v thi gian và cấu trúc graph luôn được duy trì.
Phù hợp để tích hp CI/CD, phát hin lỗi ngay khi có thay đổi code.

Preview text:

lOMoARcPSD| 45315597 Nội dung
main.py............................................................................................................................................ 1
config.py........................................................................................................................................... 2
connect.py....................................................................................................................................... 3
filter.py............................................................................................................................................. 4
nx_solution.py................................................................................................................................. 6
raw_shortest_path.py...................................................................................................................... 8
uniTestGraphProcessor.py............................................................................................................... 9 main.py 1. Làm về cái gì?
Entry point cho toàn bộ hệ thống mô phỏng lập kế hoạch đường đi (path planning simulation). •
Chạy lặp nhiều lần với các cấu hình khác nhau (solver, test automation, time
measurement), schedule và chạy event-driven simulation, rồi log kết quả vào CSV. 2. Có cái nào hay?
Luân phiên giữa ba phương pháp giải:
1. LINK II solver (tự viết) 2. Parallel network-simplex 3. NetworkX •
Dùng discrevpy.simulator để schedule và chạy các Event một cách event-driven. lOMoARcPSD| 45315597 •
Quản lý cleanup thư mục output tự động qua DirectoryManager trước mỗi lần chạy,
giúp tách biệt dữ liệu giữa các thử nghiệm.
3. Làm như thế nào?
1. Khởi tạo o Import các module: Graph, AGV, Event,
Logger, GraphProcessor, v.v. o Dọn sạch thư mục output với dm.full_cleanup().
2. Định nghĩa các hàm helper o get_os(): phát hiện hệ điều hành.
o choose_solver(), choose_time_measurement(), choose_test_automation():
tương tác CLI để thiết lập config. 3.
Vòng lặp thử nghiệm (while config.count < 6) o
Tăng config.count, nếu cần thì dm.half_cleanup(). o
Chọn solver, chế độ test, mức độ đo thời gian.
o Tạo GraphProcessor, gọi use_in_main(), khởi tạo Graph và Event (qua
init_agvs_n_events, init_tasks, init_nodes_n_edges). o Sắp xếp và schedule sự
kiện, chạy simulator.run(). o Tính và in thời gian thực thi, ghi log vào file CSV.
o Gọi reset() để đưa simulator và AGV về trạng thái ban đầu. 4. Gồm có hàm gì?get_os()choose_solver()
choose_time_measurement()
choose_test_automation()
schedule_events(events)reset(simulator)
Block if __name__ == "__main__": để thực thi cuối cùng. 5. Thể loại? lOMoARcPSD| 45315597 •
Script orchestration: CLI-driven, event-driven simulation driver. •
Kết hợp procedural (vòng lặp, gọi hàm) và interactive (nhập lựa chọn qua input()). config.py 1. Làm về cái gì?
config.py định nghĩa toàn bộ biến toàn cục dùng xuyên suốt hệ thống mô phỏng: •
Lựa chọn solver (solver_choice) •
Danh sách node bắt đầu (started_nodes) và các ID liên quan (ID) •
Tham số đồ thị (H, d) •
Số lượng AGV (num_max_agvs, numOfAGVs) và counters cho quá trình chạy (count,
reachingTargetAGVs, haltingAGVs) •
Theo dõi chi phí (totalCost) và thời gian giải (timeSolving) •
Chế độ mô phỏng (level_of_simulation – 0/1/2) •
Cờ test tự động (test_automation) và hiển thị đồ họa (draw) •
File chứa các hàm phụ trợ (functions_file) • … 2. Có cái nào hay?
Tập trung cấu hình: gom mọi tham số ở một nơi, giúp dễ điều chỉnh mà không phải mò từng module. •
level_of_simulation được comment rõ 3 chế độ: “Fully Random”, “Random in the list”,
“SFM” – linh hoạt cho nhiều kiểu chạy thử. •
solver_choice mặc định là 'network-simplex', dễ chuyển đổi giữa các phương pháp giải
bằng cách sửa đúng biến này.
3. Làm như thế nào?
Các module khác import config và truy cập trực tiếp các biến: lOMoARcPSD| 45315597 •
Không có logic xử lý trong file, chỉ khai báo và gán giá trị ban đầu cho biến. 4. Gồm có hàm gì?
Không có hàm nào: toàn bộ là biến toàn cục và một dòng comment cho level_of_simulation. 5. Thể loại?
Đây là configuration module (script cấu hình) – dùng để quản lý tham số cho toàn bộ
ứng dụng, tách biệt khỏi phần logic xử lý. connect.py 1. Làm về cái gì?
Module này cung cấp hàm tiện ích để: •
Thực thi các lệnh shell từ Python và lấy về kết quả đầu ra (stdout) Trích xuất các
giá trị thời gian (số nguyên) từ chuỗi đầu ra của lệnh đó 2. Có cái nào hay?
subprocess.run với check=True: nếu lệnh trả về mã lỗi khác 0 sẽ tự động ném
CalledProcessError, giúp bắt lỗi rõ ràng. •
Tùy chọn capture_output linh hoạt: bật/tắt việc thu thập stdout theo nhu cầu. •
Dùng re.finditer với pattern r's (\d+)' để quét và chuyển từng nhóm số thành int, thu
được danh sách thời gian
3. Làm như thế nào?
run_command(command, shell=False, capture_output=True)
1. Gọi subprocess.run(...) với text=True để trả về chuỗi.
2. Nếu capture_output=True, trả về result.stdout.strip(), ngược lại trả về None.
3. Bắt CalledProcessError và in lỗi rồi trả về None. •
extract_time_values(output)
1. Khởi tạo danh sách rỗng s_values.
2. Duyệt matches = re.finditer(r's (\d+)', output) để tìm tất cả các nhóm số sau ký tự "s ". lOMoARcPSD| 45315597
3. Với mỗi match, chuyển match.group(1) thành int và thêm vào s_values. 4. Trả về s_values 4. Gồm có hàm gì?
run_command(command, shell=False, capture_output=True)
extract_time_values(output) 5. Thể loại?
Đây là utility module (hỗ trợ hệ thống) dành cho tương tác với shellxử lý chuỗi đầu
ra, không chứa logic nghiệp vụ chính. filter.py 1. Làm về cái gì?
File này xử lý và lọc dữ liệu từ các file text để chuẩn bị input cho mô phỏng: •
remove_zero_lines loại bỏ các dòng không cần thiết (chỉ giữ dòng bắt đầu bằng 'c'/'s'
hoặc kết thúc bằng số > 0). •
filter_lines đọc điều kiện từ file sequence (seq-f.txt), quét file input, cộng dồn giá trị cuối
dòng và in log chi tiết quá trình lọc. 2. Có cái nào hay?
Kết hợp lọc sơ bộtổng hợp có điều kiện, giúp chuẩn hóa dữ liệu trước khi chạy mô phỏng. •
In ra từng bước cập nhật biến count với cú pháp rõ ràng: old + inc = new, rất hữu ích cho việc debug.
3. Làm như thế nào?
remove_zero_lines(file_path)
1. Đọc toàn bộ dòng từ file_path.
2. Giữ lại dòng nếu nó bắt đầu bằng 'c' hoặc 's', hoặc dòng có ký tự cuối cùng là số và giá trị > 0.
3. Ghi các dòng được giữ vào file filtered.txt. •
filter_lines(seq_file_path, input_file_path, H)
1. Đọc file sequence, với mỗi dòng bắt đầu 'f' trích ra hai số tiếp theo thành phần tử của mảng X. lOMoARcPSD| 45315597
2. Đọc toàn bộ file input, và với mỗi element trong X, tìm pattern "a " + element trong từng dòng.
3. Khi tìm thấy, lấy số cuối dòng (inc), tăng count += inc, in log chi tiết.
4. Cuối cùng in tổng count và gọi remove_zero_lines('seq-f.txt') để cập nhật file đã lọc. 4. Gồm có hàm gì? • remove_zero_lines(file_path) •
filter_lines(seq_file_path, input_file_path, H) 5. Thể loại?
Đây là data preprocessing script: chuyên về lọctổng hợp dữ liệu trên các file text,
chuẩn bị input cho các bước mô phỏng đường đi. nx_solution.py 1. Làm về cái gì?
File này là một script CLI đơn giản để đọc dữ liệu đồ thị định dạng DIMACS, xây dựng đồ thị có
hướng với thuộc tính demand trên các node và capacity/weight trên các cạnh, rồi giải bài toán
Minimum Cost Flow
bằng hàm network_simplex() của NetworkX và in kết quả ra console. 2. Có cái nào hay?
Tận dụng network_simplex(): không phải tự triển khai thuật toán luồng chi phí thấp
nhất mà dùng giải thuật đã được tối ưu sẵn trong NetworkX. •
Xử lý DIMACS: parse dòng bắt đầu bằng 'n' để lấy demand, dòng 'a' để lấy capacity và
cost (lưu vào weight), phù hợp chuẩn DIMACS. •
Chế độ debug: có chỗ #pdb.set_trace() để dễ bật gỡ lỗi từng bước khi cần.
3. Làm như thế nào?
1. Nhập thư viện: import networkx as nx import pdb
2. Định nghĩa read_dimac_file(file_path): lOMoARcPSD| 45315597
o Khởi tạo G = nx.DiGraph().
o Mở file, đọc từng dòng, split() để lấy parts. o Nếu parts[0] == 'n': ID = parts[1] demand = -int(parts[2])
G.add_node(ID, demand=demand) o Nếu parts[0] == 'a': ID1, ID2 = parts[1], parts[2] U = int(parts[4]) (capacity) C = int(parts[5]) (cost)
G.add_edge(ID1, ID2, weight=C, capacity=U) 3. Giải luồng:
flowCost, flowDict = nx.network_simplex(G) 4. In kết quả: print("flowCost:", flowCost) print("flowDict:", flowDict) 5.
Phần chạy chính: file_path = input("Path to DIMAC file:") read_dimac_file(file_path)
``` :contentReference[oaicite:2]{index=2} 4. Gồm có hàm gì?
read_dimac_file(file_path): duy nhất, đảm nhiệm từ việc parse file DIMACS đến gọi solver và in kết quả. •
Các hàm của NetworkX (nx.DiGraph(), nx.network_simplex()) được gọi bên trong nhưng
không được đóng gói thêm. 5. Thể loại? lOMoARcPSD| 45315597 •
Utility script / CLI demo:
o Không phải module importable, mà chạy trực tiếp qua python nx_solution.py.
o Phục vụ minh họa hoặc kiểm thử nhanh thuật toán Minimum Cost Flow với dữ liệu DIMACS raw_shortest_path.py 1. Làm về cái gì?
File này tính đường đi ngắn nhất giữa các điểm bắt đầuđiểm kết thúc trên một đồ thị có
hướng, được mô tả trong file đầu vào (định dạng tương tự DIMACS). Kết quả là độ dài ngắn
nhất từ mỗi start đến mỗi end, hoặc inf nếu không kết nối được. 2. Có cái nào hay?
Tự triển khai Dijkstra với heapq mà không cần thư viện ngoài, giúp hiểu sâu cách hoạt
động của priority queue. •
Cơ chế đánh dấu start/end linh hoạt: đọc dòng n … 1 thành start, n … -1 thành end. •
Trả về float('inf') cho các cặp không kết nối, thuận tiện khi xử lý kết quả.
3. Làm như thế nào?
1. Đọc input (read_input(file_path)):
o Mở file, tách từng dòng theo dấu cách.
o Với dòng bắt đầu 'n' và số cuối là 1 → thêm vào start_points; nếu là -1 → thêm vào end_points.
o Với dòng 'a' → trích (source, destination, weight) vào edges.
2. Xây adjacency list trong find_shortest_paths:
o Duyệt edges, nhóm theo source thành dict graph[source] = [(dest, weight), …].
3. Dijkstra (dijkstra(graph, start)):
o Khởi distances[start]=0, push (0, start) vào min-heap. lOMoARcPSD| 45315597
o Lặp: pop node có current_distance nhỏ nhất, cập nhật neighbor nếu tìm được
đường ngắn hơn, push vào heap.
4. Tính kết quả (find_shortest_paths):
o Với mỗi start gọi dijkstra, sau đó xây dict {end: distances.get(end, inf)}.
5. In ra console (main):
o Hiển thị từng cặp Start point, End point và độ dài ngắn nhất. 4. Gồm có hàm gì? Hàm Mô tả
read_input(file_path) Đọc file, phân loại start_points, end_points, và edges. dijkstra(graph,
start) Tính khoảng cách ngắn nhất từ start đến mọi node với min-heap.
find_shortest_paths(...) Xây graph, gọi dijkstra cho mỗi start, trả kết quả dạng dict. main(file_path)
Điều phối: gọi read_input → find_shortest_paths → in kết quả. 5. Thể loại?
Script CLI thuật toán: chạy trực tiếp qua python raw_shortest_path.py, dùng để
benchmark hoặc debug tính đúng đắn của Dijkstra trên input file. •
Phù hợp làm baseline so sánh với các giải thuật phức tạp hơn (như NetworkX hay network simplex). uniTestGraphProcessor.py 1. Làm về cái gì?
Đây là bộ kiểm thử (unit tests) dành cho lớp GraphProcessor, đảm bảo các bước xử lý
đồ thị (như nạp file, tạo ma trận, thêm constraints, khởi tạo node/edge, cập nhật graph)
hoạt động đúng theo yêu cầu lOMoARcPSD| 45315597 2. Có cái nào hay?
Sử dụng nhiều hàm assert_… để kiểm tra tính toàn vẹn của graph ở các giai đoạn khác nhau:
o Số lượng node/edge phải đúng sau mỗi bước
o Node và edge thỏa mãn ràng buộc thời gian (TimeWindowNode,
RestrictionNode, TimeWindowEdge, RestrictionEdge) •
Kết hợp in thông báo rõ ràng (“Test cho file 2ndSimple.txt”) và tự động lặp qua hai tình
huống earliness/tardiness để kiểm thử cả hai kịch bản.
3. Làm như thế nào?
1. Import và khởi tạo
o Nhập các lớp từ model và controller (ví dụ Graph, Event, TimeWindowNode, RestrictionEdge, v.v.)
o Tạo instance processor = GraphProcessor() và tắt in debug (processor.print_out = False).
2. Nạp dữ liệu & cấu hình
o Dùng file "2ndSimple.txt", set started_nodes, H, d, alpha, beta, gamma, restrictions, v.v.
3. Chạy pipeline xử lý
o processor.process_input_file() → generate_hm_matrix() →
generate_adj_matrix() → create_tsg_file() o Lặp hai lần để test cả earliness và
tardiness, gọi add_time_windows_constraints()
o Thiết lập restriction_count, start_ban, end_ban, restrictions, rồi process_restrictions()
4. Khởi tạo Graph & update o Tạo graph = Graph(processor) o Gọi
processor.init_nodes_n_edges(graph) để thêm node/edge vào graph o Kiểm tra tổng số
edge/node khớp với processor.tsedges/processor.ts_nodes
o Gọi processor.update_graph(id1, id2, c12) để mô phỏng cập nhật graph sau sự kiện lOMoARcPSD| 45315597
5. Kiểm thử các ràng buộc o Gọi tuần tự 8 hàm assert_… để xác minh:
1. assert_Nodes(graph, current_time)
2. assert_Edges(graph, current_time)
3. assert_connection_TimeWindowNodes(graph)
4. assert_RestrictionNodes(graph)
5. So sánh số TimeWindowNode đúng = 2
6. assert_number_TimeWindowEdges(graph, current_time)
7. assert_new_RestrictionNodes(graph) 8.
assert_numberOf_RestrictionNodes(graph) 4. Gồm có hàm gì?
assert_Nodes(graph, current_time): Đếm node thỏa mãn time ≥ current_time (loại trừ TimeWindow/RestrictionNode). •
assert_Edges(graph, current_time): Kiểm tra các edge (ngoại trừ
TimeWindow/RestrictionEdge) có nguồn thỏa time ≥ current_time. •
assert_connection_TimeWindowNodes(graph): Đảm bảo mỗi TimeWindowNode có ít
nhất một edge nối vào. •
assert_number_TimeWindowEdges(graph, current_time): So sánh số
TimeWindowEdge mới đúng bằng cũ trừ các edge không thỏa ràng buộc thời gian. •
assert_RestrictionNodes(graph): Mỗi RestrictionNode phải có ít nhất một edge nối vào. •
assert_new_RestrictionNodes(graph): Tương tự với RestrictionEdge có nguồn không phải RestrictionNode. •
assert_numberOf_RestrictionNodes(graph): Kiểm tra số RestrictionEdge với đích không
phải RestrictionNode sau lọc theo thời gian. •
Block kiểm thử cuối file: Tạo processor, thiết lập tham số, chạy pipeline và gọi các hàm assert. 5. Thể loại? lOMoARcPSD| 45315597 •
Unit Test Module: Dùng để xác minh tính đúng đắn của lớp GraphProcessor sau mỗi
bước xử lý, đảm bảo các ràng buộc về thời gian và cấu trúc graph luôn được duy trì. •
Phù hợp để tích hợp CI/CD, phát hiện lỗi ngay khi có thay đổi code.