🖥️ IT, 컴퓨터/🚀 최적화

[최적화] Docplex로 p-median 문제 풀기

김 홍시 2023. 10. 13.
반응형

아직 CPLEX를 설치하지 않은 분은 아래 글 참고! 

 

https://kimhongsi.tistory.com/entry/Python-Docplex-%ED%8C%A8%ED%82%A4%EC%A7%80-%EC%84%A4%EC%B9%98

 

[Cplex] IBM Cplex, 파이썬 DoCplex 패키지 설치

Install the IBM Cplex, Python DoCplex package 1. Cplex 설치 https://www.ibm.com/academic/topic/data-science 혹은 https://academic.ibm.com/a2mt/email-auth 에서 학교 메일로 가입 후 로그인, 평가판 설치 풀버전은 매우 비싸고 commu

kimhongsi.tistory.com

pip install docplex

 

 

from docplex.mp.model import Model

# 모델 정의
mdl = Model("P-Median Problem")


# 데이터
Warehouses = ["w" + str(i) for i in range(1, 103)]
Customers = ["c" + str(i) for i in range(1, 363)]
MaxWarehousesP = 3

Demand = [~~, ~~, ~~, ..., ~~]
Distance = [
[~~, ~~, ...,~~],
[~~, ~~, ...,~~],
[~~, ~~, ...,~~]
]


# Decision Variables
Open = mdl.binary_var_dict(Warehouses, name="Open")
Assign = mdl.binary_var_matrix(Warehouses, Customers, name="Assign")


# Objective Function
mdl.minimize(mdl.sum(Demand[c_idx] * Distance[w_idx][c_idx] * Assign[w, c]
                     for w_idx, w in enumerate(Warehouses)
                     for c_idx, c in enumerate(Customers)))


# Constraints
for c in Customers:
    mdl.add_constraint(mdl.sum(Assign[w, c] for w in Warehouses) == 1, ctname="Demand_{}".format(c))

# Use Maximum_P_Warehouses constraint
mdl.add_constraint(mdl.sum(Open[w] for w in Warehouses) == MaxWarehousesP, ctname="MaxWarehouses")
# Cannot Assign Customer to WH Unless It Is Open constraint
for w in Warehouses:
    for c in Customers:
        mdl.add_constraint(Assign[w, c] <= Open[w], ctname="Assign_{}_{}".format(w, c))

# Solve
solution = mdl.solve()

# Print the result 
    
if solution:
    print("Objective value:", mdl.objective_value)
    # If you want to print the selected Warehouses and Customer assignments
    for w in Warehouses:
        if Open[w].solution_value:
            print("Warehouse {} is open".format(w))
else:
    print("No Solution")

 

기존에 cplex OPL 코드를 짜놨는데,

GPT 4.0으로 python 코드로 바꾸었다.

 

 

위의 코드를 실행하면

이렇게 결과가 나온다.

 

 

 

==============

 

 

 

pip install docplex

import xlrd
from docplex.mp.model import Model
import pandas as pd
import csv

# 모델 정의
mdl = Model("P-Median Problem")


# 데이터
Warehouses = ["w" + str(i) for i in range(1, 427)]
Customers = ["c" + str(i) for i in range(1, 200)]
MaxWarehousesP = 2

# 파일 불러오기
Distance = pd.read_csv("distance_whole_.csv")
input_path = "distance_whole_.csv"

# 파일을 UTF-8로 읽기
with open(input_path, 'r', encoding='utf-8') as f:
    content = f.read()

# 내용을 cp949로 다시 쓰기
with open(input_path, 'w', encoding='cp949') as f:
    f.write(content)


Distance = pd.read_csv("C:/Users/user/OneDrive - SNU/바탕 화면/1_노인복지관_학위논문_figure/5_네트워크거리/distance_whole_.csv")


Distance = []

with open("C:/Users/user/OneDrive - SNU/바탕 화면/1_노인복지관_학위논문_figure/5_네트워크거리/distance_whole_.csv", encoding = "utf-8") as csvfile:
    reader = csv.reader(csvfile)
    for row in reader:
        Distance.append(list(map(float, row)))  # float로 변환하는 것을 가정. 필요에 따라 int나 다른 형태로 변환 가능.

print(Distance)


def get_demand_data(file_path, sheet_index=0, column_index=0):
    # 파일 열기
    xls = xlrd.open_workbook(file_path)
    
    # 원하는 워크시트 선택
    sheet = xls.sheet_by_index(sheet_index)
    
    # 특정 열의 데이터를 리스트로 가져오기
    column_data = sheet.col_values(column_index)
    
    return column_data


file_path ="C:/Users/user/OneDrive - SNU/바탕 화면/1_노인복지관_학위논문_figure/5_네트워크거리/demand_whole.xls"
Demand = (get_demand_data(file_path))



# Decision Variables
Open = mdl.binary_var_dict(Warehouses, name="Open")
Assign = mdl.binary_var_matrix(Warehouses, Customers, name="Assign")


# Objective Function
mdl.minimize(mdl.sum(Demand[c_idx] * Distance[w_idx][c_idx] * Assign[w, c]
                     for w_idx, w in enumerate(Warehouses)
                     for c_idx, c in enumerate(Customers)))


# Constraints
for c in Customers:
    mdl.add_constraint(mdl.sum(Assign[w, c] for w in Warehouses) == 1, ctname="Demand_{}".format(c))

# Use Maximum_P_Warehouses constraint
mdl.add_constraint(mdl.sum(Open[w] for w in Warehouses) == MaxWarehousesP, ctname="MaxWarehouses")
# Cannot Assign Customer to WH Unless It Is Open constraint
for w in Warehouses:
    for c in Customers:
        mdl.add_constraint(Assign[w, c] <= Open[w], ctname="Assign_{}_{}".format(w, c))

# Solve
solution = mdl.solve()


if solution:
    print("Objective value:", mdl.objective_value)
    # If you want to print the selected Warehouses and Customer assignments
    for c in Customers:
        for w in Warehouses:
            if Assign[w, c].solution_value:
                print("Customer {} is assigned to Warehouse {}".format(c, w))
    else:
        print("No Solution")
반응형

댓글