2022年8月15日月曜日

Post_main only プロジェクト

 本来の機能である、制約して充足解を出力する機能は全く使っていません。

Excel表シートの整形のみを目的としたプロジェクト例です。

作り方は、何も定義せずに下の青部をチェックして求解します。



今回のプロジェクト例は、列制約を予定制約基数制約に置き換える例です。工場現場において各プロセスに必要な人員は、生産予定数量・スキル・休日等で月々変動します。列制約とDay集合で各々定義してもよいのですが、各曜日で必要人員を予定基数制約で置き換えた方がすっきりする場合もあります。こうすると、月々予定基数制約をインポートすれば、列制約自体を書き換える必要がなくなります。

予定基数制約に書き換えるためのプロジェクト例を紹介します。(Pythonのソースのみに意味があります。)

下は、列制約の解を示しています。これを、Pythonで予定基数制約形式に書き換えてみます。


下が、Pythonで書き換え後のImport用ファイルです。


Exportした列制約の最大・最小部を書き換えます。

予定基数制約を参照するように書き換えました。

インポートします。
インポート後の予定基数制約です。



これをインポートして求解して次の解を得ました。




Pythonソース

def post_main():
    
    import pdb
    #pdb.set_trace()
    print('\n\n*********ポスト処理を実行中です。*************\n')
    import win32com.client#pywin32をインポート
    import os

#すでにExcelが起動されている場合はそのタスクが使われる
#エラー終了するとタスクは残ります
    try :
        xl = win32com.client.Dispatch("Excel.Application")
    except:
        print("can not invoke excel")
        exit()
    #動いている様子を見てみる
    xl.Visible = True
    os.chdir(project_file_path)
    file=os.path.join(project_file_path,"出力SC解.xlsx")

    wb = xl.Workbooks.Open(file)
    # Excelシートオブジェクト
    ws = wb.Worksheets("SC解")

    # 指定したシートを選択
    # Select()の使用前にシートのActivate()が必要
    ws.Activate()
    lastRow = ws.UsedRange.Rows.Count
    lastCol = ws.UsedRange.Columns.Count
    c=ws.Range("A1:A200").Find("列制約項目")
 
    nrows=lastRow-(c.Row+1)+1
    ncols=0
    for col in range(3,lastCol+1):#曜日がDrawされている範囲がActual範囲
        if ws.Cells(c.Row,col).Text=="":
            break
        ncols+=1

    nphases=0
    text=""
    for col in range(3,lastCol+1):#phase数取得 同じ曜日が続く数を数える囲
        if ws.Cells(c.Row,col).Text=="":
            break
        if col==3:
            text=ws.Cells(c.Row,col).Text
            nphases+=1
        elif text==ws.Cells(c.Row,col).Text:
            nphases+=1
        else:
            break
    days=ncols/nphases
    days_rem=ncols%nphases
    if days_rem !=0:
        print("days がnphasesで割り切れません",ncols,nphases)
        exit()
    print("rowmax=",lastRow,"列制約開始=",c.Row+1,"nrows=",nrows,"ncols=",ncols,"nphases=",nphases,"days=",days)
    list2 = [['' for i in range(ncols)] for j in range(nrows)]#Constructor
    list=['' for j in range(nrows)]
    Row=0
    for row in range(c.Row+1,lastRow):
        if ws.Cells(row,1)=="":
            continue
        for col in range(3,3+ncols):
            Col=col-3
            #print(Row,Col)
            list2[Row][Col]=ws.Cells(row,col).Text
            list[Row]=ws.Cells(row,1).Text
        Row+=1
    nRows=Row
    print("nRows=",nRows)
            #print(ws.Cells(row,col).Text,end=" ")
        #print("")
    wb.Close(False)# Trueで保存。False=Defaultでブックを保存せずにクローズ
    for row in range(nRows):
        for col in range(ncols):
            if col%nphases !=0:
                r=col%nphases
                if row>=r:
                    list2[row-r][col]=list2[row][col]
    for row in range(nRows):
        print(list[row],end=" ")
        for col in range(ncols):
            print(list2[row][col],end=" ")
        print("")

    #Open Target Excel
    file=os.path.join(project_file_path,"RevisedD.xlsx")
    wb = xl.Workbooks.Open(file)
    # Excelシートオブジェクト
    ws = wb.Worksheets("タスク 予定入力基数制約")
    ws.Activate()
    c=ws.Range("A1:A200").Find("タスク名")
    row_start=c.Row+1
    print("row_start=",row_start)
    Row=0
    for row in range(nRows):
        #print(list[row],end=" ")
        has_data=False
        for col in range(ncols):
            if list2[row][col] !="":
                has_data=True
                break
        if has_data:
            #print(list[row])
            ws.Cells(Row+row_start,1).Value=list[row]
            for col in range(ncols):
                ws.Cells(Row+row_start,col+3).Value=list2[row][col]
                ws.Cells(Row+row_start+1,col+3).Value=list2[row][col]
            Row+=2
    wb.Close(True)# Trueで保存。False=Defaultでブックを保存せずにクローズ
    # Excel終了
    xl.Quit()
    print('\n\n*********ポスト処理を実行終了しました。*************\n')


0 件のコメント:

コメントを投稿