72 lines
2.3 KiB
Python
72 lines
2.3 KiB
Python
import numpy as np
|
|
|
|
RI_DICT = {1: 0.00, 2: 0.00, 3: 0.58, 4: 0.90, 5: 1.12, 6: 1.24, 7: 1.32, 8: 1.41, 9: 1.45, 10: 1.49}
|
|
|
|
def get_weights_and_cr(matrix):
|
|
n = matrix.shape[0]
|
|
# Use the column normalization method (standard AHP approximation)
|
|
col_sums = np.sum(matrix, axis=0)
|
|
norm_matrix = matrix / col_sums
|
|
weights = np.mean(norm_matrix, axis=1)
|
|
|
|
# Calculate lambda_max
|
|
aw = np.dot(matrix, weights)
|
|
lambda_i = aw / weights
|
|
lambda_max = np.mean(lambda_i)
|
|
|
|
ci = (lambda_max - n) / (n - 1) if n > 1 else 0
|
|
ri = RI_DICT.get(n, 0.90)
|
|
cr = ci / ri if ri > 0 else 0
|
|
return weights, lambda_max, ci, cr
|
|
|
|
allowed = [1, 2, 3, 1/2, 1/3]
|
|
|
|
def search_matrix(target_weights, label):
|
|
best_diff = 999
|
|
best_matrix = None
|
|
best_weights = None
|
|
best_cr = 999
|
|
best_lambda_max = 0
|
|
|
|
import itertools
|
|
for comb in itertools.product(allowed, repeat=6):
|
|
a12, a13, a14, a23, a24, a34 = comb
|
|
|
|
M = np.array([
|
|
[1.0, a12, a13, a14],
|
|
[1/a12, 1.0, a23, a24],
|
|
[1/a13, 1/a23, 1.0, a34],
|
|
[1/a14, 1/a24, 1/a34, 1.0]
|
|
])
|
|
|
|
w, l_max, ci, cr = get_weights_and_cr(M)
|
|
if cr < 0.10:
|
|
diff = np.sum(np.abs(w - target_weights))
|
|
if diff < best_diff:
|
|
best_diff = diff
|
|
best_matrix = M
|
|
best_weights = w
|
|
best_cr = cr
|
|
best_lambda_max = l_max
|
|
|
|
print(f"=== {label} ===")
|
|
print("Matrix:")
|
|
for row in best_matrix:
|
|
row_str = " ".join([f"{val:.4f}" if val >= 1 else f"1/{int(1/val)}" for val in row])
|
|
print(f" [ {row_str} ]")
|
|
print("Calculated Weights:", [round(x, 4) for x in best_weights])
|
|
print("Target Weights: ", target_weights)
|
|
print(f"Lambda Max: {best_lambda_max:.4f}, CI: {best_lambda_max-4:.4f}/3 = {(best_lambda_max-4)/3:.4f}, CR: {best_cr:.4f}")
|
|
print()
|
|
|
|
scenarios = [
|
|
("Outdoor - Day (Siang)", [0.30, 0.15, 0.25, 0.30]),
|
|
("Outdoor - Night (Malam)", [0.15, 0.50, 0.15, 0.20]),
|
|
("Indoor - Cerah", [0.35, 0.20, 0.20, 0.25]),
|
|
("Indoor - Gelap", [0.15, 0.55, 0.15, 0.15]),
|
|
("Semua Kondisi", [0.25, 0.30, 0.20, 0.25])
|
|
]
|
|
|
|
for name, target in scenarios:
|
|
search_matrix(target, name)
|