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