IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> cutting stock 列生成 python实现 -> 正文阅读

[人工智能]cutting stock 列生成 python实现

import numpy as np
from docplex.mp.model import Model as CplexModel


class ExactSolution:
    def __init__(self, mode_name, mode_corporate="cplex"):
        if mode_corporate == "cplex":
            self.model = CplexModel(mode_name)
        # elif mode_corporate == "scip":
        #     pass
        # todo 待补充
        else:
            raise AttributeError("the mode_corporate is not correct!")

    def __call__(self):
        self.add_decision_var()
        self.add_constraint()
        self.set_obj()
        # start solve
        self.optimize()
        return None

    def add_decision_var(self):
        raise NotImplementedError

    def add_constraint(self):
        raise NotImplementedError

    def set_obj(self, *args):
        raise NotImplementedError

    def optimize(self):
        raise NotImplementedError


class MasterProblem(ExactSolution):
    def __init__(self, model_name, lengths, quantities, max_length, mode_corporate="cplex"):
        self.lengths = lengths
        self.quantities = quantities
        self.max_length = max_length
        self.constr_coeff = np.eye(len(self.lengths)).astype(int) * [
            self.max_length // len_ for len_ in self.lengths]
        super().__init__(model_name, mode_corporate)

    def add_decision_var(self):
        self.x_var = {}
        for ix in range(len(self.lengths)):
            self.x_var[ix] = self.model.continuous_var(lb=0, name="x_%s" % ix)
        self.cut_method_count = len(self.lengths)

    def add_constraint(self):
        self.model.add_constraints(self.model.sum(self.x_var[j] * self.constr_coeff[i, j]
                                                  for j in range(self.cut_method_count)) >= self.quantities[i]
                                   for i in range(len(self.lengths)))

    def set_obj(self):
        self.model.minimize(self.model.sum(self.x_var[i] for i in range(self.cut_method_count)))

    def optimize(self):
        self.model.solve(log_output=False)
        if not self.model.solution:
            raise RuntimeError("can't get solution!")

    def get_dual_vars(self):
        self.model.solution.ensure_dual_values(self.model, self.model.get_engine())
        return self.model.solution.get_dual_values(self.model.iter_constraints())

    def update_model_and_solve(self, new_add_y):
        self.update_model_add_var()
        self.update_model_mdf_constraint(new_add_y)
        # self.model.clean_before_solve = True
        self.set_obj()
        self.optimize()

    def update_model_add_var(self):
        self.x_var[self.cut_method_count] = self.model.continuous_var(lb=0, name="addx_%s" % self.cut_method_count)
        self.cut_method_count += 1

    def update_model_mdf_constraint(self, new_col):
        self.constr_coeff = np.hstack((self.constr_coeff, np.array([new_col]).astype(int).transpose()))
        self.model.clear_constraints()
        self.add_constraint()


class SubProblem(ExactSolution):
    def __init__(self, model_name, lengths, quantities, max_length, mode_corporate="cplex"):
        self.lengths = lengths
        self.quantities = quantities
        self.max_length = max_length
        super().__init__(model_name, mode_corporate)
        self.add_decision_var()
        self.add_constraint()

    def add_decision_var(self):
        self.x_var = {}
        for ix in range(len(self.lengths)):
            self.x_var[ix] = self.model.integer_var(lb=0, name="y_%s" % ix)

    def add_constraint(self):
        self.model.add_constraint(
            self.model.sum(self.lengths[i] * self.x_var[i] for i in range(len(self.lengths))) <= self.max_length)

    def set_obj(self, multiplies):
        # self.model.maximize(self.model.sum(multiplies[i] * self.x_var[i] for i in range(len(self.lengths))))
        self.model.minimize(1 - self.model.sum(multiplies[i] * self.x_var[i] for i in range(len(self.lengths))))

    def optimize(self):
        self.model.solve(log_output=False)
        if not self.model.solution:
            raise RuntimeError("can't get solution!")

    def __call__(self, *args, **kwargs):
        # cutting stock的subproblem有点特殊 需要单独设置obj后才能跑
        raise RuntimeError("please call by other method.")

    def get_solution(self):
        return [self.model.get_var_by_index(i).solution_value for i in range(len(self.lengths))]

    def get_reduced_cost(self):
        return self.model.objective_value


class CuttingStock:
    def __init__(self):
        pass

    def reset(self):
        self.reduced_cost = float('-inf')

    def run(self, lengths, quantities, max_length, master_model_name='master', sub_model_name='sub'):
        self.reset()
        self.get_linear_result(lengths, quantities, max_length, master_model_name, sub_model_name)
        self.get_round_result()

    def get_linear_result(self, lengths, quantities, max_length, master_model_name, sub_model_name):
        master_prob = MasterProblem(master_model_name, lengths, quantities, max_length)
        master_prob()
        sub_prob = SubProblem(sub_model_name, lengths, quantities, max_length)

        while self.reduced_cost < 0:
            pi = master_prob.get_dual_vars()
            sub_prob.set_obj(pi)
            sub_prob.optimize()
            y = sub_prob.get_solution()
            self.reduced_cost = sub_prob.get_reduced_cost()
            print("the reduce_cost is %s, the obj_value is %s "
                  % (self.reduced_cost, master_prob.model.solution.objective_value))
            master_prob.update_model_and_solve(y)
        # print("final result:   ", list(master_prob.model.iter_variables()))

    def get_round_result(self):
        # todo
        pass


if __name__ == "__main__":
    # max_length = 20  # width of large roll
    # lengths = [3, 7, 9, 16]
    # quantities = [25, 30, 14, 8]
    max_length = 16  # width of large roll
    lengths = [3, 6, 7]
    quantities = [25, 20, 18]
    CuttingStock().run(lengths, quantities, max_length)

这个结果还是线性的 还需要转成整数的处理

另外, 如果需求是3种长度,那结果一定是3种砍法方案的组合; 需求是4种,结果也是4种。好像觉得这个建模有点不准确?极端情况, 如果需要?3,6,7? 三种长度的各20根,总长为16,解出来总是不对的..

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2022-05-05 11:19:11  更:2022-05-05 11:20:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:52:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码