文档中的代码有问题,怎么改才可以运行
时间: 2024-12-20 10:30:45 浏览: 3
DeepICL 完整测评文档+可运行代码
从你提供的错误信息来看,代码中的 `IndexError` 是因为 `positions` 数组在一维的情况下试图访问二维索引导致的。为了解决这个问题,需要检查并修正以下几个地方:
1. **初始化粒子位置**:确保 `initialize_population` 函数中生成的粒子位置是两维数组。
2. **粒子位置更新**:在 `update_particles` 和 `pso_main` 函数中,确保粒子的位置始终是两维数组。
3. **目标函数中的位置使用**:在 `objective_function` 函数中,确保正确地处理一维数组的情况。
下面是修改后的代码示例:
```python
import numpy as np
from scipy.spatial.distance import pdist, squareform
import matplotlib.pyplot as plt
from tqdm import tqdm
# 数据提取
waste_sources = [
('石桥镇', 107.118101, 31.298319, 2.86),
# ... 其他数据 ...
]
recycling_centers = [
('分类回收节点 1', 107.381715, 31.469126, 150000, 65, 7.4, 0.87),
# ... 其他数据 ...
]
remanufacturing_centers = [
('再制造中心 1', 107.095849, 30.759173, 300000, 200, 102, 0.87),
# ... 其他数据 ...
]
landfills = [
('填埋场 1', 107.063886246, 31.3623822568, 54, 6.23),
# ... 其他数据 ...
]
# 计算两个地点之间的欧氏距离(公里)
def haversine(lat1, lon1, lat2, lon2):
R = 6371 # 地球半径(公里)
phi1, phi2 = np.radians(lat1), np.radians(lat2)
delta_phi = np.radians(lat2 - lat1)
delta_lambda = np.radians(lon2 - lon1)
a = np.sin(delta_phi / 2)**2 + np.cos(phi1) * np.cos(phi2) * np.sin(delta_lambda / 2)**2
c = 2 * np.arctan2(np.sqrt(a), np.sqrt(1 - a))
return R * c
# 计算所有节点间的距离矩阵
def calculate_distances(sources, centers, landfills, manufacturing_centers):
points = []
for _, lat, lon, _ in sources:
points.append((lat, lon))
for _, lat, lon, _, _, _, _ in centers:
points.append((lat, lon))
for _, lat, lon, _, _, _, _ in manufacturing_centers:
points.append((lat, lon))
for _, lat, lon, _, _ in landfills:
points.append((lat, lon))
dist = pdist(points, metric=lambda u, v: haversine(u[0], u[1], v[0], v[1]))
return squareform(dist)
# 目标函数定义
def objective_function(positions, distances, waste_sources, recycling_centers, remanufacturing_centers, landfills):
n_sources = len(waste_sources)
n_recyc = len(recycling_centers)
n_manuf = len(remanufacturing_centers)
n_landfills = len(landfills)
total_cost = 0
total_emission = 0
alpha = 5.5 # 单位距离运输成本(元 / 吨 • 千米)
beta = 0.35 # 单位距离运输碳排放因子( kg/t•km )
recycling_indices = positions[:n_sources, 0].astype(int) % n_recyc
remanufacturing_indices = positions[:n_sources, 1].astype(int) % n_manuf
for i in range(n_sources):
source_id = recycling_indices[i]
source_waste = waste_sources[i][3]
for j in range(n_recyc):
if j == source_id:
rec_fixed_cost = recycling_centers[j][3]
rec_variable_cost = recycling_centers[j][4]
rec_emission = recycling_centers[j][5]
transport_distance = distances[i][j + n_sources]
transport_cost = alpha * source_waste * transport_distance
transport_emission = beta * source_waste * transport_distance
total_cost += rec_fixed_cost + rec_variable_cost * source_waste + transport_cost
total_emission += rec_emission * source_waste + transport_emission
rec_waste_to_manu = source_waste * 0.5
rec_waste_to_landfill = source_waste * 0.5
for k in range(n_manuf):
if k == remanufacturing_indices[i]:
manu_fixed_cost = remanufacturing_centers[k][3]
manu_variable_cost = remanufacturing_centers[k][4]
manu_emission = remanufacturing_centers[k][5]
transport_distance_to_manu = distances[j + n_sources][k + n_sources + n_recyc]
transport_cost_to_manu = alpha * rec_waste_to_manu * transport_distance_to_manu
transport_emission_to_manu = beta * rec_waste_to_manu * transport_distance_to_manu
total_cost += manu_fixed_cost + manu_variable_cost * rec_waste_to_manu + transport_cost_to_manu
total_emission += manu_emission * rec_waste_to_manu + transport_emission_to_manu
break
for l in range(n_landfills):
transport_distance_to_landfill = distances[j + n_sources][l + n_sources + n_recyc + n_manuf]
transport_cost_to_landfill = alpha * rec_waste_to_landfill * transport_distance_to_landfill
transport_emission_to_landfill = beta * rec_waste_to_landfill * transport_distance_to_landfill
total_cost += landfills[l][3] * rec_waste_to_landfill + transport_cost_to_landfill
total_emission += landfills[l][4] * rec_waste_to_landfill + transport_emission_to_landfill
break
return total_cost, total_emission
# PSO 初始化
def initialize_population(num_particles, num_dimensions, n_recyc, n_manuf):
positions = np.random.rand(num_particles, num_dimensions) * max(n_recyc, n_manuf)
velocities = np.zeros_like(positions)
personal_best_positions = positions.copy()
personal_best_values = np.full(num_particles, float('inf'))
global_best_position = None
global_best_value = float('inf')
return positions, velocities, personal_best_positions, personal_best_values, global_best_position, global_best_value
# 更新个人最佳和全局最佳
def update_best_positions(values, particles, personal_best_values, personal_best_positions, global_best_value, global_best_position):
for i, value in enumerate(values):
if value < personal_best_values[i]:
personal_best_positions[i] = particles[i]
personal_best_values[i] = value
global_best_value_new = np.min(personal_best_values)
if global_best_value_new < global_best_value:
global_best_index = np.argmin(personal_best_values)
global_best_value = global_best_value_new
global_best_position = personal_best_positions[global_best_index].copy()
return personal_best_positions, personal_best_values, global_best_value, global_best_position
# 更新速度和位置
def update_particles(particles, velocities, personal_best_positions, global_best_position, w=0.5, c1=2, c2=2):
r1 = np.random.rand(*particles.shape)
r2 = np.random.rand(*particles.shape)
velocities = w * velocities + c1 * r1 * (personal_best_positions - particles) + c2 * r2 * (global_best_position - particles)
particles += velocities
return particles, velocities
# 主程序
def pso_main(distances, waste_sources, recycling_centers, landfills, remanufacturing_centers, max_iterations=100, num_particles=30, verbose=True):
n_sources = len(waste_sources)
n_recyc = len(recycling_centers)
n_manuf = len(remanufacturing_centers)
n_landfills = len(landfills)
num_dimensions = 2 * n_sources # 每个源头有两个维度,一个表示回收节点,另一个表示再制造节点
particles, velocities, personal_best_positions, personal_best_values, global_best_position, global_best_value = initialize_population(num_particles, num_dimensions, n_recyc, n_manuf)
best_costs = []
best_emissions = []
for iteration in tqdm(range(max_iterations)):
costs, emissions = zip(*[objective_function(p.reshape(n_sources, 2), distances, waste_sources, recycling_centers, remanufacturing_centers, landfills) for p in particles])
personal_best_positions, personal_best_values, global_best_value, global_best_position = update_best_positions(costs, particles, personal_best_values, personal_best_positions, global_best_value, global_best_position)
best_costs.append(min(costs))
best_emissions.append(min(emissions))
particles, velocities = update_particles(particles, velocities, personal_best_positions, global_best_position)
if verbose:
print(f'Iteration {iteration}: Best Cost: {best_costs[-1]}, Best Emission: {best_emissions[-1]}')
return best_costs, best_emissions, global_best_position.reshape(n_sources, 2)
if __name__ == "__main__":
distances = calculate_distances(waste_sources, recycling_centers, landfills, remanufacturing_centers)
best_costs, best_emissions, global_best_position = pso_main(distances, waste_sources, recycling_centers, landfills, remanufacturing_centers)
# 输出总成本和总碳排放量
print(f"Final Total Cost: {best_costs[-1]}")
print(f"Final Total Emission: {best_emissions[-1]}")
# 提取并输出选中的节点
n_sources = len(waste_sources)
n_recyc = len(recycling_centers)
n_manuf = len(remanufacturing_centers)
n_selected_recyc = 8
n_selected_manuf = 5
# 确保每个回收中心和再制造中心的选择数符合要求
recycling_indices = global_best_position[:, 0].astype(int) % n_recyc
remanufacturing_indices = global_best_position[:, 1].astype(int) % n_manuf
selected_recycling_counts = np.bincount(recycling_indices, minlength=n_recyc)
selected_manufacturing_counts = np.bincount(remanufacturing_indices, minlength=n_manuf)
top_n_recycling = np.argsort(selected_recycling_counts)[-n_selected_recyc:]
top_n_remanufacturing = np.argsort(selected_manufacturing_counts)[-n_selected_manuf:]
print("Selected Recycling Nodes:")
for idx in top_n_recycling:
print(f"Recycling Center {idx}: Count {selected_recycling_counts[idx]}")
print("Selected Remanufacturing Nodes:")
for idx in top_n_remanufacturing:
print(f"Remanufacturing Center {idx}: Count {selected_manufacturing_counts[idx]}")
# 绘制收敛曲线
fig, ax1 = plt.subplots()
ax1.plot(best_costs, 'r-', label='Cost')
ax1.set_xlabel('Iterations')
ax1.set_ylabel('Total Cost')
ax2 = ax1.twinx()
ax2.plot(best_emissions, 'b-', label='Emission')
ax2.set_ylabel('Total Emission')
plt.title('Convergence of PSO Algorithm')
fig.tight_layout()
plt.show()
```
### 修改要点
1. **初始化粒子位置**:将 `positions` 数组的形状设为 `(num_particles, num_dimensions)`,其中 `num_dimensions` 是源数量乘以2。
2. **目标函数中的位置使用**:在调用 `objective_function` 时,确保将 `positions` reshape 为 `(n_sources, 2)` 形状。
3. **主程序中**:确保在每一代粒子迭代后,输出当前的最佳成本和排放量,并在最终输出时也将最佳位置重新 reshape 为 `(n_sources, 2)` 形状。
这样修改后,代码应该可以正常运行并且不会出现 `IndexError`。希望这些改动能帮助你解决问题!如果有其他问题,请随时告诉我。
阅读全文