⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 steelcutrun.cpp

📁 线材切割
💻 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 + -