数理システム 最適化メールマガジン

バックナンバー ( 2024 Vol.5 ) 2024 年 9 月 27 日 発行

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  数理システム 最適化メールマガジン
                     https://www.msi.co.jp/solution/nuopt/top.html
                           2024 Vol.5 ( 2024 年  9 月 27 日 発行 )
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

数理システム 最適化メールマガジンでは,数理最適化パッケージ
Nuorium Optimizer をはじめとして,最適化に関する様々な情報や
ご案内を提供していきます.

++++ [目次] ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ■ <イベント> MSIISM Conference 開催のお知らせ
 ■ <トピック> 展示会出展のご案内
 ■ <セミナー> 無料オンラインセミナーのご案内
 ■ <  tips  > 使ってみよう PySIMPLE(第 32 回)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

******************************************************************
■ <イベント> MSIISM Conference 開催のお知らせ
******************************************************************

今年も当社主催のイベントを 10 月 11 日(金)に開催いたします.
今回は「数理科学と生成AIで革新を」というテーマで,昨今のトレンドを
踏まえたAI・数理科学を活用したビジネスの展望を,講演を通じてお伝え
します.

参加費は無料ですので,是非参加ご検討いただければと思います.
また,本メルマガでは数理最適化に関する内容を簡単に紹介いたします.

- 講演者 : ライオン株式会社
- 講演タイトル : 数理最適化を用いたスケジューラによる生産計画の
  自動作成
- 概要 : 
  需要変動や在庫最適化への対応が重要となっており,生産計画策定の
  質・スピードの向上が求められています.
  週次サイクルでの計画策定を実現するために,工場・生産ライン・
  製品ごとの制約を加味した生産スケジューラを,数理最適化を活用して
  開発しました.その導入における課題や障壁をご紹介します.

また,当日は個別商談スペースもございますので,何か相談事項
ございましたら,お申込みの際にご記入お願いいたします.

数理最適化以外の技術の活用に関しても講演がございますので,
是非一度本イベントの Web ページをご確認ください.

https://www.msi.co.jp/event/conference/mc2024/lp/index.html

当日お会いできることを楽しみにしております.

                                                (保科 拓紀)

******************************************************************
■ <トピック> 展示会出展のご案内
******************************************************************

10 月に幕張メッセで開催される脱炭素経営 EXPO に弊社も出展します.
共同出展という形で NTT データのブースを間借りして出展いたしますので,
ご来場の際には弊社ブースにもお越しいただけますと幸いです.

当日は脱炭素に貢献する数理最適化というテーマで,特に SCM に関して
どう貢献するかといった展示をしております.
当日は技術の人間もいますので,簡単な個別相談も可能でございます.

当日お会いできることを楽しみにしております.

■ 脱炭素経営EXPO 概要
場所 : 幕張メッセ
日時 : 2024 年 10 月 2 日(水)~ 4 日(金)10:00 - 17:00
NTT データブース : 5 ホール ブース番号 : E1-2
展示会 URL : https://www.decarbonization-expo.jp/autumn/ja-jp.html

                                                (保科 拓紀)

******************************************************************
■ <セミナー> 無料オンラインセミナーのご案内
******************************************************************

11 月までに開催する数理最適化に関する無料のオンラインセミナーを
ご紹介します.

物流やエネルギー,シフト,生産計画の最適化に関して課題に特化した
セミナーを実施いたします.ご興味のあるセミナーございましたら詳細を
ご確認いただき,ご検討お願いいたします.今回紹介しているセミナーは
次回開催が未定ですので,是非この機会にご参加いただけますと幸いです.


[ 勤務シフト作成最適化セミナー ]
  2024 年 11 月 21 日(木)13:30~15:30
  詳細とお申込み : 
    https://www.msiism.jp/event/nuopt-schedule.html

[ エネルギーマネジメント最適化セミナー ]
  2024 年 10 月 18 日(金)13:30~15:30
  詳細とお申込み
    https://www.msiism.jp/event/nuopt-energy-management.html

[ 物流クライシスを解決 輸送業務の最適化セミナー ]
  2024 年 10 月 23 日(水)13:30~15:30
  詳細とお申込み : 
    https://www.msiism.jp/event/nuopt-logistics.html

[ 製造現場の業務改善に向けた数理最適化ソリューション紹介セミナー ]
  2024 年 11 月 12 日(火)13:30~15:30
  詳細とお申込み : 
    https://www.msiism.jp/event/nuopt-manufacturing-scheduling.html

                                                (保科 拓紀)

******************************************************************
■ <  tips  > 使ってみよう PySIMPLE(第 32 回)
******************************************************************

このコーナーでは,Nuorium Optimizer の Python インターフェース
PySIMPLE のエッセンスを紹介していきます.

3 月にリリースされた Nuorium Optimizer V26 に同梱される PySIMPLE
1.5.0 ではでは幾つもの機能拡張や機能追加がされました.
今回はこのうち,変数の値を固定する fix メソッドの使いどころについて
紹介します.まずは以下の関数 problem を見てみましょう.

------------------------------------------------------------------
def problem(type):
    x = Variable(type=type, lb=0, ub=5)
    y = Variable(lb=0, ub=5)
    p = Problem()
    p += 180*x + 160*y
    p += 6*x +   y >= 12
    p += 4*x + 6*y >= 24
    return p
------------------------------------------------------------------

problem は type=int とすれば元問題の MILP を,type=float とすれば
その連続緩和問題を返す関数です.
混合整数線形計画問題(MILP)は線形計画問題(LP)に比べ難しく,実行可能
解や最適解が求まらないこともあります.一方で MILP の整数変数を連続
変数に緩和した問題(連続緩和問題)は線形計画問題のため,ずっと簡単に
なります.
今回は fix メソッドを活用して,連続緩和問題の丸め値を元問題の近似値
として与えることで近似解を求める手法を紹介します.

------------------------------------------------------------------
rp = problem(type=float)  # 緩和問題(rp は relaxed problem の頭文字)
rp.solve()                # 緩和問題を解く(LP なので簡単)
rx = rp.variables['x']
rx[rx.index] = round(rx.val)  # 整数値に丸めた値を設定
rx.fix()                  # x の値を固定
rp.solve()
print(rx.val, rp.objective.val)
------------------------------------------------------------------

fix メソッドは変数の上下限を現在の値に固定します.すなわち今回の
場合は「rp += rx == rx.val」という制約と同じ意味ですが,fix は制約
ではなく上下限扱いとなります.また,後述の unfix で固定状態を細かく
制御できる点でも異なります.

連続緩和問題で得られた x の値(実数値)を整数に丸めて固定し,再求解
することで MILP を解くことなく整数性を満たした求解を行っています.
ただし,この解はあくまで近似解であり,実行可能解である保証もあり
ませんが,元問題が難しい場合は検討の余地があるでしょう.
また,丸め値を設定する箇所は「rx = ...」と記述できないことに注意
しましょう.このように記述してしまうと rx の参照先が上書きされて
しまいます.なお,「rx[rx.index] = ...」という記述は添字の有無に
拘わらず利用できます.

上記では元問題の整数変数が x ひとつでしたが,以下のように汎用的に
記述することで,モデルに含まれるすべての整数変数に丸め値を固定する
ことができます.

------------------------------------------------------------------
p = problem(type=int)     # 元問題(MILP)
rp = problem(type=float)  # 連続緩和問題(LP)
rp.solve()
for rvar, var in zip(rp.variables.values(), p.variables.values()):
    if var.type is not float:  # 元問題で整数変数の変数のみ
        rvar[rvar.index] = round(rvar[rvar.index].val)
        rvar.fix()
rp.solve()
print(rp.objective.val)
------------------------------------------------------------------

以下に今回用いた問題の最適解をまとめておきます.(IP は参考)

class | x.type | y.type | x.val | y.val | 目的関数値
----- | ------ | ------ | ----- | ----- | ---------
LP    |  float |  float |  1.5  |  3.0  |   750.0
MILP  |   int  |  float |  2.0  |  2.7  |   786.7
IP    |   int  |   int  |  2.0  |  3.0  |   840.0

連続緩和問題で得られた x の値 1.5 を整数に丸めた値 2.0 は元問題に
おける最適解と一致していますが,偶然であることに注意しましょう.
実際,x の値を 1.0 に丸めた場合は実行不可能となります.実行不可能な
場合に一部の整数変数の固定を解除するといった対応を考えてみましょう.

次の例は,一度 fix メソッドで固定した変数の値の一部を unfix メソッドを
用いて解除しています.このような部分的な解除は制約式では行うことが
できません.

------------------------------------------------------------------
i = Element(value=[1, 2, 3])
z = IntegerVariable(index=i, lb=10, init=20)
p = Problem()
p += Sum(z[i])
z.fix()       # p += z[i] == z[i].val, 'cons' と意味は同じ
p.solve()
print(z.val)  # {1: 20, 2: 20, 3: 20}
z[2].unfix()  # del p['cons'][2] はできない
p.solve()
print(z.val)  # {1: 20, 2: 10, 3: 20}
------------------------------------------------------------------

いかがでしたでしょうか.V26 では他にも新機能が加わったり,動作環境の
追加も行われていますので確認してみてください.

LP の値を丸めて MILP の近似解を得るテクニックはこちら:
    https://www.msi.co.jp/solution/nuopt/docs/pysimple/guide/fix.html
fix メソッドのマニュアルはこちら:
    https://www.msi.co.jp/solution/nuopt/docs/pysimple/api/class.html#pysimple.Variable.fix
PySIMPLE の更新履歴はこちら:
    https://www.msi.co.jp/solution/nuopt/docs/pysimple/changelog.html

                                                (池田 悠)
==================================================================