本来の機能である、制約して充足解を出力する機能は全く使っていません。
Excel表シートの整形のみを目的としたプロジェクト例です。
作り方は、何も定義せずに下の青部をチェックして求解します。
今回のプロジェクト例は、列制約を予定制約基数制約に置き換える例です。工場現場において各プロセスに必要な人員は、生産予定数量・スキル・休日等で月々変動します。列制約とDay集合で各々定義してもよいのですが、各曜日で必要人員を予定基数制約で置き換えた方がすっきりする場合もあります。こうすると、月々予定基数制約をインポートすれば、列制約自体を書き換える必要がなくなります。
予定基数制約に書き換えるためのプロジェクト例を紹介します。(Pythonのソースのみに意味があります。)
下は、列制約の解を示しています。これを、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 件のコメント:
コメントを投稿