📄 steelcutrun.cpp
字号:
// SteelCut1.cpp: implementation of the CSteelCut class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SteelCut.h"
#include "SteelCutRun.h"
#include <stdio.h>
#include <malloc.h>
#include <time.h>
#include "shlwapi.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
extern CString g_IDC_COMBO[5];
extern CString g_IDC_EDIT_MC[5];
extern CString g_IDC[4];
extern CString g_IDC_EDIT_PL[5];
extern CString g_IDC_EDIT_PC[5];
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSteelCut::CSteelCut()
{
cn = 1;
fp = NULL;
m_Flag = true;
m_Rawtotallen = 0;
m_Wastelen = 0;
}
CSteelCut::~CSteelCut()
{
}
ST *CSteelCut::AddProduct(int pLen, int pNum, bool pSortFlag)
{
ST * tmpST;
tmpST = (ST *)malloc(sizeof(ST));
tmpST->len = pLen;
tmpST->num = pNum;
if(pSortFlag)
{
while(1)
{
if( (tmpP->next != NULL) && (tmpST->len > tmpP->next->len))
{
tmpST->next = tmpP->next;
tmpP->next = tmpST;
break;
}
else if(tmpP->next == NULL)
{
tmpP->next = tmpST;
tmpST->next = NULL;
break;
}
else
{
tmpP = tmpP->next;
}
}
tmpP = headP;
return tmpP;
}
else
{
tmpR->next = tmpST;
tmpST->next = NULL;
tmpR = tmpST;
return tmpR;
}
}
/* Create product chain and sort by product length. */
ST *CSteelCut::InitProduct()
{
int p1_Len = atoi(g_IDC_EDIT_PL[0]);
int p2_Len = atoi(g_IDC_EDIT_PL[1]);
int p3_Len = atoi(g_IDC_EDIT_PL[2]);
int p4_Len = atoi(g_IDC_EDIT_PL[3]);
int p5_Len = atoi(g_IDC_EDIT_PL[4]);
int p1_Num = atoi(g_IDC_EDIT_PC[0]);
int p2_Num = atoi(g_IDC_EDIT_PC[1]);
int p3_Num = atoi(g_IDC_EDIT_PC[2]);
int p4_Num = atoi(g_IDC_EDIT_PC[3]);
int p5_Num = atoi(g_IDC_EDIT_PC[4]);
/* The headP is head node of chain,not store information. */
headP = (ST *)malloc(sizeof(ST));
headP->next = NULL;
tmpP = headP;
if(p1_Len && p1_Num)
{
tmpP = AddProduct(p1_Len, p1_Num, true);
}
if(p2_Len && p2_Num)
{
tmpP = AddProduct(p2_Len, p2_Num, true);
}
if(p3_Len && p3_Num)
{
tmpP = AddProduct(p3_Len, p3_Num, true);
}
if(p4_Len && p4_Num)
{
tmpP = AddProduct(p4_Len, p4_Num, true);
}
if(p5_Len && p5_Num)
{
tmpP = AddProduct(p5_Len, p5_Num, true);
}
return headP;
}
/* Create Raw chain . */
ST *CSteelCut::InitRaw()
{
int R1_Len = atoi(g_IDC_COMBO[0]);
int R2_Len = atoi(g_IDC_COMBO[1]);
int R3_Len = atoi(g_IDC_COMBO[2]);
int R4_Len = atoi(g_IDC_COMBO[3]);
int R5_Len = atoi(g_IDC_COMBO[4]);
int R1_Num = atoi(g_IDC_EDIT_MC[0]);
int R2_Num = atoi(g_IDC_EDIT_MC[1]);
int R3_Num = atoi(g_IDC_EDIT_MC[2]);
int R4_Num = atoi(g_IDC_EDIT_MC[3]);
int R5_Num = atoi(g_IDC_EDIT_MC[4]);
/* The headR is head node of chain, not store information. */
headR = (ST *)malloc(sizeof(ST));
headR->next = NULL;
tmpR = headR;
if(R1_Len && R1_Num)
{
tmpR = AddProduct(R1_Len, R1_Num, false);
}
if(R2_Len && R2_Num)
{
tmpR = AddProduct(R2_Len, R2_Num, false);
}
if(R3_Len && R3_Num)
{
tmpR = AddProduct(R3_Len, R3_Num, false);
}
if(R4_Len && R4_Num)
{
tmpR = AddProduct(R4_Len, R4_Num, false);
}
if(R5_Len && R5_Num)
{
tmpR = AddProduct(R5_Len, R5_Num, false);
}
return headR;
}
/* Search for suitable product ,pRawLen is remainder length . */
RST* CSteelCut::Rselect(ST *h, int pRawLen, int pMillLen)
{
/* Return the pointer to product information chain. */
RST *r = NULL;
RST *t;
ST *p,*k;
if(h == NULL)
{
/* If no suitable product was found then return null. */
return NULL;
}
for(k=p=h; p!=NULL && r==NULL; k=p,p=p->next)
{
/* If found then . */
if(p->len==pRawLen)
{
r = (RST *)malloc(sizeof(RST));
r->len = p->len;
r->num = p->num;
r->times = 1;
r->next = NULL;
return r; /*Return pointer. */
}
/* If raw is not enough then search for next. */
if(p->len > pRawLen)
{
//test code begin
WriteInfo("1--begin \n");
char dd[1024];
sprintf(dd, "%d%s%d%s", pRawLen + p->len + pMillLen, ",", p->len, ",\n");
WriteInfo(dd);
WriteInfo("1--end\n");
WriteInfo("\n");
//test code end
r = Rselect(p, pRawLen + p->len + pMillLen, pMillLen);
if(r == NULL)
{
r = Rselect(p->next, pRawLen + p->len + pMillLen, pMillLen);
}
if(r != NULL)
{
return r;
}
}
else if((cn+1) > p->num)
{
//test code begin
WriteInfo("2--begin \n");
char ddd[1024];
sprintf(ddd, "%d%s%d%s%d%s",pRawLen, ",", pRawLen - p->len - pMillLen, ",", p->len,",\n");
WriteInfo(ddd);
WriteInfo("2--end\n");
WriteInfo("\n");
//test code end
cn = 1;
r = Rselect(p->next, pRawLen - p->len - pMillLen, pMillLen);
}
else
{
cn++;
//test code begin
WriteInfo("3--begin \n");
char dddd[1024];
sprintf(dddd, "%d%s%d%s%d%s", pRawLen, "," ,pRawLen - p->len - pMillLen, ",", p->len,",\n");
WriteInfo(dddd);
WriteInfo("3--end\n");
WriteInfo("\n");
//test code end
/* judge the remainder raw material. */
r = Rselect(p, pRawLen - p->len- pMillLen, pMillLen);
/* If this product deal with more times. */
if( (r != NULL) && (r->len == p->len) )
{
/* If is more than product plan. */
if((r->times+1) > p->num)
{
if(r->len == h->len)
{
//test code begin
WriteInfo("4--begin \n");
char dd[1024];
sprintf(dd, "%d%s%d%s%d%s", pRawLen, ",", pRawLen - p->len - pMillLen, ",", r->len,",\n");
WriteInfo(dd);
WriteInfo("4--end\n");
WriteInfo("\n");
//test code end
/* Search for other suitable product. */
r = Rselect(p->next, pRawLen-r->len-pMillLen, pMillLen);
}
else
{
return NULL;
}
}
else
{
r->times += 1;
return r;
}
}
}
}
/* If found the product then store this product information. */
if(r !=NULL)
{
t = (RST *)malloc(sizeof(RST));
t->len = k->len;
t->num = k->num;
t->times = 1;
t->next = r;
r = t;
}
return r;
}
/* Print title. */
void CSteelCut::PrintProTitle()
{
WriteInfo("原材料长度, 原材料数量, 单根废料长度, 废料总长度, 废料率, ");
WriteInfo("产品长度,产品数量 ");
WriteInfo("\n");
}
/* Print a result. */
ST* CSteelCut::Hregulate(ST *h,RST *rstWay, ST *Raw)
{
RST *t = rstWay->next;
RST *cslRstWay = rstWay;
ST *p = h;
ST *k;
char info_1[20][1024] = {{0,0}} ;
char info_2[1024] ;
int i = 0;
/* waste raw length. */
int clsWaste;
/* Cut times. */
int clstimes = 0;
/* Store remainder raw material. */
int clsRemain = 0;
/* Store smallest product length. */
int clslen;
/* The clsCount store the count of raw. */
int clsCount = rstWay->num/rstWay->times;
/* Find the smallest is clsCount. */
while(t != NULL)
{
if(clsCount > (t->num / t->times) )
{
clsCount = t->num / t->times;
}
t = t->next;
}
/* Judge the raw count . */
if(clsCount > Raw->next->num)
{
clsCount = Raw->next->num;
}
/* Update the count of remainder raw. */
Raw->next->num = Raw->next->num - clsCount;
/* Print Raw length and total of Raw. */
sprintf(info_2, "%d%s%d%s", Raw->next->len, ",", clsCount, ",");
WriteInfo(info_2);
/* Raw material total length. */
m_Rawtotallen = m_Rawtotallen + (clsCount * Raw->next->len);
clsWaste = Raw->next->len;
/* Print each product count. */
while(rstWay != NULL)
{
if(i == 0 )
{
sprintf(info_1[i], "%d%s%d%s", rstWay->len, ",",clsCount * rstWay->times, ",");
}
else
{
sprintf(info_1[i], "%s%d%s%d%s", ",,,,,",rstWay->len, ",",clsCount * rstWay->times, ",");
}
clsWaste = clsWaste - rstWay->len * rstWay->times;
clstimes = clstimes + rstWay->times;
/* Update the remainder product . */
while(p->next != NULL)
{
if(rstWay->len == p->next->len)
{
if(p->next->num - clsCount*rstWay->times != 0)
{
p->next->num -= clsCount*rstWay->times;
p = p->next;
break;
}
else
{
k = p->next;
p->next = p->next->next;
free(k);
break;
}
}
p = p->next;
}
/* The last one length is the smallest . */
clslen = rstWay->len;
rstWay = rstWay->next;
i++;
}
/* Calculate remainder raw material length. */
clsRemain = clsWaste - (clstimes * m_MillLen);
if(clsRemain >= clslen)
{
clsWaste = clsWaste - clsRemain;
}
/* Waste material total length. */
m_Wastelen = m_Wastelen + (clsWaste*clsCount);
/* Print the rate of Waste. */
sprintf(info_2, "%d%s%d%s%0.5f%s",clsWaste, ",", clsWaste*clsCount, ",", (float)clsWaste / Raw->next->len, ",");
WriteInfo(info_2);
WriteInfo(info_1[0]);
while(i >= 1)
{
WriteInfo(info_1[i]);
WriteInfo("\n");
i--;
}
cn = 1;
return h;
}
/* Search for the best way of cutting and output. */
void CSteelCut::Product(ST *Prod, ST *pRaw, int pMillLen)
{
ST *p,*k;
ST *Raw = pRaw;
RST *r;
int i = 1;
int min;
int pRawLen;
while(Prod->next != NULL)
{
p = Prod;
/* Obtain length of raw materials. */
while(Raw->next != NULL)
{
if(Raw->next->num)
{
pRawLen = Raw->next->len;
break;
}
else
{
Raw = Raw->next;
}
}
if(Raw->next == NULL)
{
m_Flag = false;
return ;
}
START:
/* Find all the way of cutting steel and print. */
if((r = Rselect(p->next, pRawLen, pMillLen)) != NULL)
{
Prod = Hregulate(p, r, Raw);
WriteInfo("\n");
}
else
{
k = p;
while(k->next != NULL)
{
k = k->next;
}
/* The min store the smallest length of product. */
min = k->len;
k = p;
/* Print the product which length is smaller than length of subtracting smallest product length from Raw . */
while(pRawLen <= (k->next->len + min))
{
r = (RST *)malloc(sizeof(RST));
r->len = k->next->len;
r->num = k->next->num;
r->times = 1;
r->next = NULL;
Prod = k = Hregulate(k, r, Raw);
WriteInfo("\n");
/* If done then exit. */
if(k->next == NULL)
{
return ;
}
}
/* Set new length. */
pRawLen = pRawLen - 1;
goto START;
}
}
}
/* Get time for path. */
void CSteelCut::GetDate(char *pdate)
{
char dbuffer[9];
char tbuffer[9];
_strdate(dbuffer);
_strtime(tbuffer);
char * tmpD = (char *)malloc(20);
strcpy(tmpD, dbuffer);
strcat(tmpD, "_");
strcat(tmpD, tbuffer);
strcpy(pdate, tmpD);
free(tmpD);
}
/* Write into target file. */
void CSteelCut::WriteInfo(char *pData)
{
fwrite(pData, strlen(pData), 1, fp);
}
/* Set output file path. */
void CSteelCut::SetPath()
{
char chDate[20];
int i = 2;
GetDate(chDate);
strcpy(Path, "D:\\");
strcat(Path, chDate);
strcat(Path, ".txt");
while(Path[i])
{
if(Path[i] == '/')
{
Path[i] = '-';
}
if(Path[i] == ':')
{
Path[i] = '-';
}
i++;
}
}
/* Set name of output file. */
void CSteelCut::GetrenamePath(char *pFileNamebuf)
{
char tmp[255] = {0};
memcpy(tmp, Path, strlen(Path) - 4);
strcpy(pFileNamebuf, tmp);
strcat(pFileNamebuf, ".csv");
}
/* Print Raw information. */
void CSteelCut::PrintRowInfo(ST *pstRaw)
{
char tmpBuf[1024];
/* Print raw information title. */
WriteInfo("原材料直径,下料方式, 磨损长度,原材料长度,原材料数量\n");
sprintf(tmpBuf, "%s%s%s%s%s%s", g_IDC[0], ",", g_IDC[1], ",", g_IDC[2], ",");
WriteInfo(tmpBuf);
/* Print the first raw information. */
sprintf(tmpBuf, "%d%s%d", pstRaw->next->len, ",", pstRaw->next->num);
WriteInfo(tmpBuf);
WriteInfo("\n");
pstRaw = pstRaw->next;
while(pstRaw->next)
{
WriteInfo(",,,");
sprintf(tmpBuf, "%d%s%d", pstRaw->next->len, ",", pstRaw->next->num);
WriteInfo(tmpBuf);
WriteInfo("\n");
pstRaw = pstRaw->next;
}
WriteInfo("\n");
}
void CSteelCut::PrintTotalRate()
{
char tmpBuf[1024];
WriteInfo("\n");
WriteInfo("废料总长度,总废料率\n");
sprintf(tmpBuf, "%d%s%0.5f", m_Wastelen, ",", (float)m_Wastelen/m_Rawtotallen);
WriteInfo(tmpBuf);
}
/* Perform run to get result. */
void CSteelCut::Run()
{
m_MillLen = atoi(g_IDC[2]);
char RenamePath[255];
/* Pointer to Product chain. */
ST *ProdList;
/* Pointer to Raw chain. */
ST *RawList;
ST *RawList_2;
/* Create Product chain. */
ProdList = InitProduct();
if(ProdList->next == NULL)
{
AfxMessageBox("没有任何要生产的产品,请确认! ");
return;
}
/* Create Raw chain. */
RawList = InitRaw();
if(RawList->next == NULL)
{
AfxMessageBox("没有任何原材料,请确认! ");
return;
}
RawList_2 = RawList;
/* Create output file path. */
SetPath();
fp = fopen(Path, "w+");
/* Print Raw information. */
PrintRowInfo(RawList_2);
/* Print Data Title. */
PrintProTitle();
/* Search for cutting way and Print Data List . */
Product(ProdList, RawList, m_MillLen);
/* Print total waste rate. */
PrintTotalRate();
if(!m_Flag)
{
AfxMessageBox("原材料不足! ");
if(fp != NULL)
{
fclose(fp);
// DeleteFile(Path);
return;
}
}
/* Close result file. */
if(fp != NULL)
{
fclose(fp);
}
/* Release memory. */
if(ProdList)
{
free(ProdList);
ProdList = NULL;
}
/* Release memory. */
if(RawList)
{
free(RawList);
RawList = NULL;
}
GetrenamePath(RenamePath);
/* Change the extension of result file. */
// if(!rename(Path, RenamePath))
// {
// return;
// }
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -