问题描述
大家好,
我正在尝试从文件(主要是 .csv)导入列表“jobs_data”的数据。我尝试过常见的导入方法,如 open.csv
pandas
等,但到目前为止没有任何效果。我大部分时间收到的错误是“类型错误:+ 不支持的操作数类型:‘int’和‘str’”。我也尝试将数据转换为列表,但它失去了预期的格式:
jobs_data = [ # task = (machine_id,processing_time).
[(0,3),(1,2),(2,2)],# Job0
[(0,1),4)],# Job1
[(1,4),3)] # Job2
]
我不习惯Python编程。所以我希望有人能帮忙。 谢谢。
在@Ashok Arora 给出答案之后,代码的作用就像魅力一样:
import tkinter as tk
import csv
from ortools.sat.python import cp_model
with open("schedule.csv") as csv_file:
global jd
csv_reader = csv.reader(csv_file,delimiter=",")
jd = [[tuple(row[i : i + 2]) for i in range(0,len(row),2)] for row in csv_reader]
def MinimalJobshopSat():
model = cp_model.CpModel()
jobs_data = jd
machines_count = 1 + max(task[0] for job in jobs_data for task in job)
all_machines = range(machines_count)
horizon = sum(task[1] for job in jobs_data for task in job)
task_type = collections.namedtuple('task_type','start end interval')
assigned_task_type = collections.namedtuple('assigned_task_type','start job index duration')
all_tasks = {}
machine_to_intervals = collections.defaultdict(list)
for job_id,job in enumerate(jobs_data):
for task_id,task in enumerate(job):
machine = task[0]
duration = task[1]
suffix = '_%i_%i' % (job_id,task_id)
start_var = model.NewIntvar(0,horizon,'start' + suffix)
end_var = model.NewIntvar(0,'end' + suffix)
interval_var = model.NewIntervalVar(start_var,duration,end_var,'interval' + suffix)
all_tasks[job_id,task_id] = task_type(start=start_var,end=end_var,interval=interval_var)
machine_to_intervals[machine].append(interval_var)
for machine in all_machines:
model.AddNoOverlap(machine_to_intervals[machine])
for job_id,job in enumerate(jobs_data):
for task_id in range(len(job) - 1):
model.Add(all_tasks[job_id,task_id +
1].start >= all_tasks[job_id,task_id].end)
obj_var = model.NewIntvar(0,'makespan')
model.AddMaxEquality(obj_var,[
all_tasks[job_id,len(job) - 1].end
for job_id,job in enumerate(jobs_data)])
model.Minimize(obj_var)
solver = cp_model.cpsolver()
status = solver.solve(model)
if status == cp_model.OPTIMAL:
assigned_jobs = collections.defaultdict(list)
for job_id,job in enumerate(jobs_data):
for task_id,task in enumerate(job):
machine = task[0]
assigned_jobs[machine].append(
assigned_task_type(start=solver.Value(
all_tasks[job_id,task_id].start),job=job_id,index=task_id,duration=task[1]))
output = ''
for machine in all_machines:
assigned_jobs[machine].sort()
sol_line_tasks = 'Machine ' + str(machine) + ': '
sol_line = ' '
for assigned_task in assigned_jobs[machine]:
name = 'job_%i_%i' % (assigned_task.job,assigned_task.index)
sol_line_tasks += '%-10s' % name
start = assigned_task.start
duration = assigned_task.duration
sol_tmp = '[%i,%i]' % (start,start + duration)
sol_line += '%-10s' % sol_tmp
sol_line += '\n
sol_line_tasks += '\n'
output += sol_line_tasks
output += sol_line
print('Optimal Schedule Length: %i' % solver.ObjectiveValue())
print(output)
MinimalJobshopSat()
解决方法
假设 jobs.csv
如下:
0,3,1,2,2
0,4
1,4,3
其中每一行代表一个作业,每行都有 len(row)/2
形式的元组 (m,p)
其中 m = 机器 ID 和 p = 处理时间。这遵循 Google OR-Tools 使用的约定。
一种将 CSV 读入 a list of list of tuples of string
的方法:
import csv
with open("jobs.csv") as csv_file:
csv_reader = csv.reader(csv_file,delimiter=",")
jobs_data = [[tuple(row[i : i + 2]) for i in range(0,len(row),2)] for row in csv_reader]
print(jobs_data)
将打印:
[[('0','3'),('1','2'),('2','2')],[('0','1'),'4')],[('1','4'),'3')]]
编辑:要生成 int
的元组,请使用 map()
函数。
with open("jobs.csv") as csv_file:
csv_reader = csv.reader(csv_file,")
jobs_data = [[tuple(map(int,row[i : i + 2])) for i in range(0,2) ] for row in csv_reader ]
print(jobs_data)