package com.northglass.GlassLayout.Algorithm;
|
|
|
import java.lang.reflect.Array;
|
import java.sql.*;
|
import java.util.*;
|
|
import org.json.JSONArray;
|
import org.json.JSONException;
|
import org.json.JSONObject;
|
|
import com.northglass.GlassLayout.Tempering.LayoutAlgorithm;
|
import com.northglass.GlassLayout.Tempering.LayoutAlgorithm.AlgorithmParams;
|
import com.northglass.GlassLayout.Tempering.Piece.LayoutMode;
|
import com.northglass.GlassLayout.Tempering.RackComboInfo.RackInfo;
|
|
|
import com.northglass.GlassLayout.Tempering.LayoutResult;
|
import com.northglass.GlassLayout.Tempering.Piece;
|
import com.northglass.GlassLayout.Tempering.RackComboInfo;
|
import com.northglass.GlassLayout.Tempering.Rect;
|
import com.northglass.service.device.DeviceService;
|
|
public class AlgorithmDBInterface {
|
|
private String connectionString;
|
private int workId;
|
public AlgorithmDBInterface(String connectionString,int WorkId){
|
this.connectionString=connectionString;
|
this.workId=WorkId;
|
param_sql=String.format("SELECT `width`,`length`,`xinterval`,`yinterval`,maxLoadingRate,maxTolerance from gmms_furnace where id=%d", WorkId);
|
this.peice_sql=String.format("select id,processcard,position,front,width,height,glass_idx,thickness,color,layout_mode,w,h from tempere_task_glass where work_id=%d", WorkId);
|
this.tuijianpeice_sql=String.format("select `gs`.`id` AS `id`,`gs`.`processcard_id` AS `processcard`,lk.position,100 AS `front`,`gs`.`width` AS `width`,`gs`.`height` AS `height`,"
|
+"`gs`.`stop_rank` AS `glass_idx`,`gs`.`thickness` AS `thickness`,`gs`.`color` AS `color`,100 AS `work_id`,0 AS `layout_mode`,(select w from gmms_galss_task_buffer where id=gs.id) as w,"
|
+"(select h from gmms_galss_task_buffer where id=gs.id) as h from (select @rows:=@rows+1 as position,liuchengka from gmms_liuchengka, (select @rows:=0) as b where Occupied=10) as lk "
|
+"left join gmms_galss_task_stock as gs on lk.liuchengka=gs.processcard_id");
|
}
|
|
private String param_sql;//炉子数据
|
private String peice_sql;//优化小片数据
|
private String tuijianpeice_sql;//可推荐优化小片数据
|
private double ratioLimit_;//最大装载率
|
private double mixedLimit_;//最大面积差
|
|
|
private RackComboInfo[] startcom(){
|
AlgorithmParams param = new AlgorithmParams(); //炉子数据
|
List<Piece>[] ret; //小片数据
|
List<RackInfo> rackinfolist=new ArrayList<RackInfo>(); //流程卡数据
|
boolean canRotate=false;
|
Connection con=null;
|
try {
|
con = java.sql.DriverManager.getConnection(this.connectionString);
|
param=getParam(con);
|
param.resultcount = 2;
|
param.combocount=3;
|
// param.ratioLimit=ratioLimit_;
|
// param.mixedLimit=mixedLimit_;
|
ret=getPiecey(con,canRotate);
|
|
Statement sm= con.createStatement();
|
ResultSet rs= sm.executeQuery(this.tuijianpeice_sql);
|
Info[] infos=toInfo(rs,canRotate);
|
|
//流程卡数据加载
|
RackComboInfo rackcomboinfo = new RackComboInfo();
|
List<String> RackInfo_ids=new ArrayList<String>();
|
for (Info info : infos) {
|
RackInfo ri = rackcomboinfo.new RackInfo();
|
ri.id =info.Processcard;
|
ri.level = 1;
|
ri.needed = false;
|
if(!RackInfo_ids.contains(info.Processcard)){
|
rackinfolist.add(ri);
|
RackInfo_ids.add(info.Processcard);
|
}
|
}
|
if(rackinfolist.size()<=3){
|
param.resultcount = 1;
|
param.combocount=rackinfolist.size();
|
}
|
//System.out.println(param.resultcount+" "+infos.length+" "+param.combocount);
|
if(rackinfolist.size()==0||infos.length==0){
|
return new RackComboInfo[0];
|
}
|
} catch (Exception e) {
|
// TODO: handle exception
|
return new RackComboInfo[0];
|
}
|
//参数 param:炉子信息 rackinfolist:流程卡信息 ret:小片信息
|
System.out.println("炉子信息:");
|
String pstr=" width:"+param.width+
|
" length:"+param.length+
|
" h_interval:"+param.h_interval+
|
" v_interval:"+param.v_interval+
|
" method:"+param.method+
|
" resultcount:"+param.resultcount;
|
System.out.println(pstr);
|
|
System.out.println("小片信息:");
|
int i=1;
|
for(List<Piece> ps:ret){
|
System.out.println("第"+i+"架玻璃 共:"+ps.size()+"片");
|
for(Piece p:ps){
|
String piecestr=" width:"+p.width+
|
" height:"+p.height+
|
" Mode:"+p.Mode+
|
" Source:"+p.Source+
|
" w:"+p.w+
|
" h:"+p.h;
|
System.out.println(piecestr);
|
}
|
i++;
|
}
|
System.out.println("流程卡信息:");
|
|
for(RackInfo rackInfo:rackinfolist){
|
System.out.println(" id:"+rackInfo.id+" level:"+rackInfo.level+" needed:"+rackInfo.needed);
|
}
|
|
System.out.println("结束");
|
RackComboInfo[] resultratio = LayoutAlgorithm.GetAvgRatio(param,rackinfolist.toArray(new RackInfo[rackinfolist.size()]), ret);
|
|
for (RackComboInfo RackComboInfo:resultratio) {
|
for (RackInfo d:RackComboInfo.rackinfos) {
|
System.out.println(" id:"+d.id+" needed:"+d.needed+" level:"+d.level);
|
}
|
for (double d:RackComboInfo.ratioResult) {
|
System.out.println(d);
|
}
|
}
|
return resultratio;
|
}
|
//优化推荐传参数
|
public static RackComboInfo[] f(int line,String sql,double ratioLimit,double mixedLimit){
|
if(line==1){
|
a1.tuijianpeice_sql=sql;
|
a1.ratioLimit_=ratioLimit;
|
a1.mixedLimit_=mixedLimit;
|
return a1.startcom();
|
}else if(line==2){
|
a2.tuijianpeice_sql=sql;
|
a2.ratioLimit_=ratioLimit;
|
a2.mixedLimit_=mixedLimit;
|
return a2.startcom();
|
}else{
|
return new RackComboInfo[0];
|
}
|
}
|
//优化推荐小片数据
|
private List<Piece>[] getPiecey(Connection con,boolean canRotate) throws SQLException{
|
Statement sm= con.createStatement();
|
ResultSet rs= sm.executeQuery(this.tuijianpeice_sql);
|
ArrayList<ArrayList<Piece>> pss=new ArrayList<ArrayList<Piece>>();
|
Info[] infos=toInfo(rs,canRotate);
|
if(infos==null)
|
return null;
|
if(infos.length==0)
|
return null;
|
rs.close();
|
sm.close();
|
for(int i=0;i<infos.length;i++){
|
Info cur=infos[i];
|
Piece p=new Piece();
|
p.width=cur.width;
|
p.height=cur.height;
|
p.Mode=cur.layout_mode;
|
p.Source=cur;
|
p.w=cur.w;
|
p.h=cur.h;
|
boolean ok=false;
|
for(int j=0;j<pss.size();j++){
|
Piece pp=pss.get(j).get(0);
|
Info info=(Info)pp.Source;
|
if(info.FrameNumber==cur.FrameNumber){
|
pss.get(j).add(p);
|
ok=true;
|
break;
|
}
|
}
|
if(ok==false){
|
ArrayList<Piece> pl=new ArrayList<Piece>();
|
pl.add(p);
|
pss.add(pl);
|
}
|
}
|
for(int i=0;i<pss.size();i++){
|
pss.get(i).sort(this.piececompare);
|
List<Piece> list=pss.get(i);
|
for(int j=0;j<list.size();j++){
|
Info info= (Info)list.get(j).Source;
|
info.GlassNumber=j+1;
|
}
|
}
|
List<Piece> p=new ArrayList<Piece>();
|
List<Piece>[] ret=(List<Piece>[])Array.newInstance(p.getClass(), pss.size());
|
for(int i=0;i<ret.length;i++){
|
ret[i]=pss.get(i);
|
}
|
return ret;
|
}
|
private AlgorithmParams getParam(Connection con) throws SQLException{
|
Statement sm= con.createStatement();
|
ResultSet rs= sm.executeQuery(param_sql);
|
rs.next();
|
AlgorithmParams p=new AlgorithmParams();
|
p.width=rs.getInt(1);
|
p.length=rs.getInt(2);
|
p.h_interval=rs.getInt(3);
|
p.v_interval=rs.getInt(4);
|
p.ratioLimit=rs.getInt(5);
|
p.mixedLimit=rs.getInt(6);
|
p.method="Heuristic";
|
rs.close();
|
sm.close();
|
return p;
|
}
|
|
class Info {
|
public long id;
|
public int thicknss;
|
public String color;
|
public int width;
|
public int height;
|
public Piece.LayoutMode layout_mode;
|
public int FrameNumber;
|
public boolean IsFront;
|
public int GlassIndex;
|
public String Processcard;
|
public int GlassNumber;
|
public double w,h;
|
@Override
|
public String toString(){
|
return String.format("%d.%d[%d]",FrameNumber,GlassNumber,id);
|
}
|
|
}
|
|
compare piececompare=new compare();
|
|
|
class compare implements java.util.Comparator<Piece>{
|
|
@Override
|
public int compare(Piece arg0, Piece arg1) {
|
// TODO Auto-generated method stub
|
Info info1=(Info)arg0.Source;
|
Info info2=(Info)arg1.Source;
|
int a1=info1.IsFront?0:1;
|
int a2=info2.IsFront?0:1;
|
if(a1>a2)
|
return -1;
|
if(a1<a2)
|
return 1;
|
if(info1.GlassIndex<info2.GlassIndex)
|
return 1;
|
if(info1.GlassIndex>info2.GlassIndex)
|
return -1;
|
return 0;
|
}
|
|
}
|
|
|
|
private Info[] toInfo(ResultSet set,boolean canRotate) throws SQLException{
|
List<Info> list=new ArrayList<Info>();
|
while(set.next()){
|
Info info=new Info();
|
info.id=set.getLong("id");
|
info.thicknss= (int)set.getDouble("thickness");
|
info.color=set.getString("color");
|
info.width=(int)set.getDouble("width");
|
info.height=(int)set.getDouble("height");
|
info.Processcard=set.getString("processcard");
|
double w=set.getDouble("w");
|
double h=set.getDouble("h");
|
info.w=w;
|
info.h=h;
|
if(canRotate==true){
|
info.layout_mode=Piece.LayoutMode.Both;
|
}
|
else{
|
info.layout_mode=w<h?Piece.LayoutMode.Zhong:Piece.LayoutMode.Heng;
|
}
|
|
/*
|
int mode=set.getInt("layout_mode");
|
switch(mode){
|
case 1:
|
info.layout_mode= Piece.LayoutMode.Zhong;
|
break;
|
case 2:
|
info.layout_mode=Piece.LayoutMode.Heng;
|
break;
|
default:
|
info.layout_mode=Piece.LayoutMode.Both;
|
break;
|
}
|
*/
|
info.FrameNumber=set.getInt("position");
|
info.IsFront=set.getInt("front")==1;
|
info.GlassIndex=set.getInt("glass_idx");
|
list.add(info);
|
; }
|
Info[] ret=new Info[list.size()];
|
return list.toArray(ret);
|
}
|
|
|
|
private List<Piece>[] getPiece(Connection con,boolean canRotate) throws SQLException{
|
Statement sm= con.createStatement();
|
ResultSet rs= sm.executeQuery(this.peice_sql);
|
ArrayList<ArrayList<Piece>> pss=new ArrayList<ArrayList<Piece>>();
|
Info[] infos=toInfo(rs,canRotate);
|
if(infos==null)
|
return null;
|
if(infos.length==0)
|
return null;
|
rs.close();
|
sm.close();
|
for(int i=0;i<infos.length;i++){
|
Info cur=infos[i];
|
Piece p=new Piece();
|
p.width=cur.width;
|
p.height=cur.height;
|
p.Mode=cur.layout_mode;
|
p.Source=cur;
|
p.w=cur.w;
|
p.h=cur.h;
|
boolean ok=false;
|
for(int j=0;j<pss.size();j++){
|
Piece pp=pss.get(j).get(0);
|
Info info=(Info)pp.Source;
|
if(info.FrameNumber==cur.FrameNumber){
|
pss.get(j).add(p);
|
ok=true;
|
break;
|
}
|
}
|
if(ok==false){
|
ArrayList<Piece> pl=new ArrayList<Piece>();
|
pl.add(p);
|
pss.add(pl);
|
}
|
}
|
for(int i=0;i<pss.size();i++){
|
pss.get(i).sort(this.piececompare);
|
List<Piece> list=pss.get(i);
|
for(int j=0;j<list.size();j++){
|
Info info= (Info)list.get(j).Source;
|
info.GlassNumber=j+1;
|
}
|
}
|
List<Piece> p=new ArrayList<Piece>();
|
List<Piece>[] ret=(List<Piece>[])Array.newInstance(p.getClass(), pss.size());
|
for(int i=0;i<ret.length;i++){
|
ret[i]=pss.get(i);
|
}
|
return ret;
|
}
|
|
|
|
|
|
|
private void saveLayout(Connection con,LayoutResult result,AlgorithmParams param) throws SQLException {
|
int step=0;
|
try {
|
con.setAutoCommit(false);
|
int number=result.Number;
|
step=1;
|
CallableStatement call= con.prepareCall("{call insert_tempere_layout(?,?,?,?,?,?,?,?,?,?,?,?,?,?)}");
|
boolean ok=true;
|
for(int i=0;i<result.layout.length;i++){
|
Rect r=result.layout[i];
|
Info info=(Info)r.getSource().Source;
|
int move=0;
|
int pendulum=1;
|
if(i==result.layout.length-1){
|
pendulum=3;
|
}
|
else{
|
if(result.layout[i].Row!=result.layout[i+1].Row)
|
pendulum=2;
|
}
|
|
|
if(pendulum!=1){
|
move=param.width-result.layout[i].x;
|
}
|
else{
|
move=result.layout[i+1].x-result.layout[i].x;
|
}
|
|
call.setInt(1,this.workId);
|
call.setInt(2,number);
|
call.setDouble(3,result.rate);
|
call.setInt(4,i+1);
|
call.setInt(5,r.x);
|
call.setInt(6,r.y);
|
if(r.getLength()==r.getWidth()){
|
call.setInt(7,0);
|
}else{
|
call.setInt(7,r.isHeng?0:1);
|
}
|
|
call.setInt(8, pendulum);
|
call.setInt(9,move);
|
call.setInt(10, r.Row);
|
call.setInt(11,r.Col);
|
call.setLong(12,info.id);
|
call.setString(13, null);
|
call.registerOutParameter(14,java.sql.Types.INTEGER);
|
call.execute();
|
if(call.getInt(14)!=1){
|
ok=false;
|
break;
|
}
|
|
}
|
if(ok){
|
con.commit();
|
}
|
else{
|
con.rollback();
|
}
|
con.close();
|
|
} catch (SQLException e) {
|
if(step>=1)
|
con.rollback();
|
con.close();
|
|
// TODO Auto-generated catch block
|
e.printStackTrace();
|
}
|
|
}
|
|
public LayoutResult lastResult;
|
|
|
public class ComputeResult{
|
public Exception Error;
|
public boolean Success;
|
public int Number;
|
public boolean isNothing;
|
public LayoutResult Result;
|
public String toJson(){
|
|
try{
|
JSONArray arr=new JSONArray();
|
for(int i=0;i<Result.layout.length;i++){
|
Rect r=Result.layout[i];
|
JSONObject obj=new JSONObject();
|
obj.put("x",r.x);
|
obj.put("y",r.y);
|
obj.put("w",r.getXSize());
|
obj.put("h",r.getYSize());
|
obj.put("size",""+r.getSource().w+"*"+r.getSource().h);
|
int k=0;
|
if(r.canHeng()){
|
k=2;
|
}
|
if(r.canZhong()){
|
k+=1;
|
}
|
obj.put("mode",k);
|
arr.put(obj);
|
}
|
return arr.toString();
|
}
|
catch(Exception e){
|
return "{}";
|
}
|
}
|
}
|
|
|
|
int getNextLayoutNumber(Connection con) throws SQLException{
|
CallableStatement sm= con.prepareCall("{call get_next_tempere_number(?,?)}");
|
sm.setInt(1,this.workId);
|
sm.registerOutParameter(2,java.sql.Types.INTEGER);
|
|
int ret=0;
|
sm.execute();
|
ret=sm.getInt(2);
|
sm.close();
|
return ret;
|
}
|
|
//计算优化
|
public ComputeResult ComputeOnce(boolean canRotate){
|
Connection con=null;
|
lastResult=null;
|
try {
|
con = java.sql.DriverManager.getConnection(this.connectionString);
|
AlgorithmParams param=getParam(con);
|
List<Piece>[] ps=getPiece(con,canRotate);//获取小片
|
if(ps==null){
|
ComputeResult ret= new ComputeResult();
|
ret.Success=false;
|
ret.Number=0;
|
ret.Error=null;
|
ret.isNothing=true;
|
con.close();
|
return ret;
|
}
|
LayoutResult result= LayoutAlgorithm.Compute(param,ps);
|
int number= getNextLayoutNumber(con);
|
result.WorkId=this.workId;
|
result.Number=number;
|
if(result!=null){
|
this.saveLayout(con, result,param);
|
this.lastResult=result;
|
ComputeResult ret= new ComputeResult();
|
ret.Success=true;
|
ret.Number=number;
|
ret.Error=null;
|
ret.isNothing=false;
|
ret.Result=result;
|
con.close();
|
return ret;
|
}
|
ComputeResult ret1= new ComputeResult();
|
ret1.Success=false;
|
ret1.Number=0;
|
ret1.Error=null;
|
ret1.isNothing=true;
|
con.close();
|
return ret1;
|
|
} catch (SQLException e) {
|
// TODO Auto-generated catch block
|
e.printStackTrace();
|
ComputeResult ret= new ComputeResult();
|
ret.Success=false;
|
ret.Number=0;
|
ret.Error=e;
|
ret.isNothing=false;
|
try {
|
con.close();
|
} catch (SQLException e1) {
|
// TODO Auto-generated catch block
|
e1.printStackTrace();
|
}
|
return ret;
|
}
|
|
|
}
|
private static AlgorithmDBInterface a1,a2;
|
public static void initAlgorithm(String connectionString){
|
a1=new AlgorithmDBInterface(connectionString,1);
|
a2=new AlgorithmDBInterface(connectionString,2);
|
}
|
|
public static boolean canRotate1=true;
|
public static boolean canRotate2=true;
|
|
public static ComputeResult ComputeOnce(int line){
|
if(line==1){
|
return a1.ComputeOnce(canRotate1);
|
}
|
if(line==2){
|
return a2.ComputeOnce(canRotate2);
|
}
|
return null;
|
}
|
}
|