int pathcmp(const char *p1, const char *p2) { char *s1, *s2; int code; char tmp1[MAXPATHLEN], tmp2[MAXPATHLEN]; if (strlen(p1) < sizeof(tmp1) && strlen(p2) < sizeof(tmp2)) { /* put the names into canonical form if they are not */ p1 = strcpy(tmp1, p1); p2 = strcpy(tmp2, p2); TRACE(("\n\t(%s %s)", p1, p2)) while (*p1 == PATH_SLASH && *p2 == PATH_SLASH) p1++, p2++; /* faster than strcmp... */ while (*p1 && *p2) { CUT(p1, s1); CUT(p2, s2); TRACE((" [%s %s]", p1, p2)) if ((code = strcmp(p1, p2)) != 0) return (code); if ((s1 != 0) || (s2 != 0)) { if (s2 == 0) return (GT); if (s1 == 0) return (LT); p1 = s1 + 1; p2 = s2 + 1; } else { break; } } code = (*p1 - *p2); } else {
void IntervalVariable::propagateNC() { if (ToulBar2::verbose >= 3) cout << "propagateNC for " << getName() << endl; if (CUT(getInfCost() + wcsp->getLb(), wcsp->getUb())) increaseFast(getInf() + 1); if (CUT(getSupCost() + wcsp->getLb(), wcsp->getUb())) decreaseFast(getSup() - 1); if (getInfCost() > getSupCost()) { setMaxUnaryCost(getInf(), getInfCost()); } else { setMaxUnaryCost(getSup(), getSupCost()); } }
bool IntervalVariable::verifyNC() { if (CUT(getInfCost() + wcsp->getLb(),wcsp->getUb())) { cout << *this << " has inf cost not NC!" << endl; return false; } if (CUT(getSupCost() + wcsp->getLb(),wcsp->getUb())) { cout << *this << " has sup cost not NC!" << endl; return false; } return true; }
pair<pair<Cost, Cost>, pair<Cost, Cost> > BinaryConstraint::getMaxCost(int varIndex, Value a, Value b) { // cout << "getMaxCost(" << getVar(varIndex)->getName() << ") " << a << " <-> " << b << endl << *this << endl; Cost maxcosta = MIN_COST; Cost diffcosta = MIN_COST; Cost maxcostb = MIN_COST; Cost diffcostb = MIN_COST; if (varIndex == 0) { Cost ucosta = x->getCost(a); Cost ucostb = x->getCost(b); for (EnumeratedVariable::iterator iterY = y->begin(); iterY != y->end(); ++iterY) { Cost costa = getCost(a, *iterY); Cost costb = getCost(b, *iterY); if (costa > maxcosta) maxcosta = costa; if (costb > maxcostb) maxcostb = costb; Cost ucosty = y->getCost(*iterY); if (!CUT(ucostb + costb + ucosty + wcsp->getLb(), wcsp->getUb())) { if (costa - costb > diffcosta) diffcosta = costa - costb; } if (!CUT(ucosta + costa + ucosty + wcsp->getLb(), wcsp->getUb())) { if (costb - costa > diffcostb) diffcostb = costb - costa; } } } else { Cost ucosta = y->getCost(a); Cost ucostb = y->getCost(b); for (EnumeratedVariable::iterator iterX = x->begin(); iterX != x->end(); ++iterX) { Cost costa = getCost(*iterX, a); Cost costb = getCost(*iterX, b); if (costa > maxcosta) maxcosta = costa; if (costb > maxcostb) maxcostb = costb; Cost ucostx = x->getCost(*iterX); if (!CUT(ucostb + costb + ucostx + wcsp->getLb(), wcsp->getUb())) { if (costa - costb > diffcosta) diffcosta = costa - costb; } if (!CUT(ucosta + costa + ucostx + wcsp->getLb(), wcsp->getUb())) { if (costb - costa > diffcostb) diffcostb = costb - costa; } } } assert(maxcosta >= diffcosta); assert(maxcostb >= diffcostb); return make_pair(make_pair(maxcosta, diffcosta), make_pair(maxcostb, diffcostb)); }
bool BinaryConstraint::isFunctional(EnumeratedVariable* xin, EnumeratedVariable* yin, map<Value, Value>& functional) { assert(xin != yin); assert(getIndex(xin) >= 0); assert(getIndex(yin) >= 0); bool isfunctional = true; functional.clear(); for (EnumeratedVariable::iterator itx = xin->begin(); isfunctional && itx != xin->end(); ++itx) { bool first = true; for (EnumeratedVariable::iterator ity = yin->begin(); isfunctional && ity != yin->end(); ++ity) { if (!CUT(getCost(xin, yin, *itx, *ity) + wcsp->getLb(), wcsp->getUb())) { if (first) { functional[*itx] = *ity; first = false; } else { isfunctional = false; } } } assert(!first); // assumes it is SAC already } if (isfunctional) return true; functional.clear(); return false; }
void VACVariable::VACproject(Value v, const Cost c) { // Cost oldCost = getVACCost(v); costs[toIndex(v)] += c; // Cost newCost = getVACCost(v); // if ((v == maxCostValue) || (newCost > maxCost) || CUT(wcsp->getLb() + newCost,wcsp->getUb())) { if (CUT(wcsp->getLb() + getCost(v), wcsp->getUb())) { queueNC(); } // if (oldCost == MIN_COST) { // queueNC(); // queueDAC(); // queueEAC1(); // } // if ((isNull(oldCost)) && (!isNull(newCost))) { // queueVAC2(); // } // if(v == getSupport()) { // Value newSupport = getInf(); // Cost minCost = getCost(newSupport); // EnumeratedVariable::iterator iter = begin(); // for (++iter; minCost > MIN_COST && iter != end(); ++iter) { // Cost cost = getCost(*iter); // if (cost < minCost) { // minCost = cost; // newSupport = *iter; // } // } // assert(canbe(newSupport)); // // cout << "setsupport " << wcspIndex << " " << newSupport << endl; // setSupport(newSupport); // } }
int FIB_HEAP_DECREASE_KEY(node*H1,long x,long k) { node* y; if(H1==NULL) { printf("\nNO NODE IN THE HEAP!!! ABORTING!!!!"); return 0; } node* ptr=FIND_NODE(H1,x); if(ptr==NULL) { printf("\nTHE TARGET NODE NOT FOUND!!!!!"); return 1; } // cout<<"\nptr="<<ptr->n; if(ptr->n<k) { printf("\nTHE ENTERED KEY IS GREATER THAN THE CURRENT VALUE!!!"); return 0; } ptr->n=k; y=ptr->parent; if(y!=NULL&&ptr->n<y->n) { CUT(H1,ptr,y); CASCADE_CUT(H1,y); } if(ptr->n<H->n) H=ptr;//cout<<"\nH="<<ptr->n;} return 0; }
void IntervalVariable::projectInfCost(Cost cost) { infCost += cost; assert(infCost >= MIN_COST); if (getInf() == maxCostValue || infCost > maxCost) queueNC(); if (CUT(infCost + wcsp->getLb(),wcsp->getUb())) increaseFast(getInf() + 1); }
void IntervalVariable::projectSupCost(Cost cost) { supCost += cost; assert(supCost >= MIN_COST); if (getSup() == maxCostValue || supCost > maxCost) queueNC(); if (CUT(supCost + wcsp->getLb(), wcsp->getUb())) decreaseFast(getSup() - 1); }
void Unary::propagate() { if (ToulBar2::verbose >= 3) { print(cout); cout << " dxinf=" << deltaValueXinf << " dxsup=" << deltaValueXsup << endl; } wcsp->revise(this); set<Value>::iterator itinf = permitted.lower_bound(x->getInf()); set<Value>::iterator itsup = permitted.upper_bound(x->getSup()); --itsup; if (itinf == permitted.end() || itsup == permitted.end()) { // IC0 propagatation (increase global lower bound) deconnect(); projectLB(penalty); } else { // propagate hard constraint if (CUT(wcsp->getLb()+penalty, wcsp->getUb())) { if (x->getInf() < *itinf) x->increase(*itinf); if (x->getSup() > *itsup) x->decrease(*itsup); } // BAC* propagation (increase unary costs of domain bounds) Value xinf = x->getInf(); if (xinf != deltaValueXinf && xinf != deltaValueXsup && permitted.find(xinf) == permitted.end()) { deltaValueXinf = xinf; x->projectInfCost(penalty); } Value xsup = x->getSup(); if (xsup != deltaValueXinf && xsup != deltaValueXsup && permitted.find(xsup) == permitted.end()) { deltaValueXsup = xsup; x->projectSupCost(penalty); } } }
/// \warning always returns false for cost functions in intention bool Constraint::ishard() { if (!extension()) return false; String tuple; Cost cost; firstlex(); while (nextlex(tuple,cost)) { if (cost > MIN_COST && !CUT(cost,wcsp->getUb())) return false; } return true; }
int CASCADE_CUT(node* H1,node* y) { node* z=y->parent; if(z!=NULL) { if(y->mark=='F') { y->mark='T'; } else { CUT(H1,y,z); CASCADE_CUT(H1,z); } } }
/* * Propagation methods * */ bool BinaryConstraint::project(EnumeratedVariable* x, Value value, Cost cost, vector<StoreCost>& deltaCostsX) { assert(ToulBar2::verbose < 4 || ((cout << "project(C" << getVar(0)->getName() << "," << getVar(1)->getName() << ", (" << x->getName() << "," << value << "), " << cost << ")" << endl), true)); // hard binary constraint costs are not changed if (!CUT(cost + wcsp->getLb(), wcsp->getUb())) { TreeDecomposition* td = wcsp->getTreeDec(); if (td) td->addDelta(cluster, x, value, cost); deltaCostsX[x->toIndex(value)] += cost; // Warning! Possible overflow??? assert(getCost(x, (EnumeratedVariable*)getVarDiffFrom(x), value, getVarDiffFrom(x)->getInf()) >= MIN_COST); assert(getCost(x, (EnumeratedVariable*)getVarDiffFrom(x), value, getVarDiffFrom(x)->getSup()) >= MIN_COST); } Cost oldcost = x->getCost(value); x->project(value, cost); #ifdef DEECOMPLETE getVarDiffFrom(x)->queueDEE(); #endif return (x->getSupport() == value || SUPPORTTEST(oldcost, cost)); }
void Disjunction::propagate() { if (ToulBar2::verbose >= 3) { print(cout); cout << " dxinf=" << deltaValueXinf << " dxsup=" << deltaValueXsup << " dyinf=" << deltaValueYinf << " dysup=" << deltaValueYsup << endl; } wcsp->revise(this); // deconnect the constraint if always satisfied if (x->getInf() >= y->getSup() + csty || y->getInf() >= x->getSup() + cstx) { deconnect(); } else if (x->getSup() < y->getInf() + csty && y->getSup() < x->getInf() + cstx) { // IC0 propagatation (increase global lower bound if always unsatisfied) deconnect(); if (x->unassigned()) { if (x->getInf() == deltaValueXinf) x->projectInfCost(-penalty); if (x->getSup() == deltaValueXsup) x->projectSupCost(-penalty); } if (y->unassigned()) { if (y->getInf() == deltaValueYinf) y->projectInfCost(-penalty); if (y->getSup() == deltaValueYsup) y->projectSupCost(-penalty); } projectLB(penalty); } else { // propagate hard constraint if (CUT(wcsp->getLb()+penalty, wcsp->getUb())) { if (x->getSup() < y->getInf() + csty) { Value newInf = x->getInf() + cstx; if (y->getInf() < newInf) y->increase(newInf); Value newSup = y->getSup() - cstx; if (x->getSup() > newSup) x->decrease(newSup); } else if (y->getSup() < x->getInf() + cstx) { Value newInf = y->getInf() + csty; if (x->getInf() < newInf) x->increase(newInf); Value newSup = x->getSup() - csty; if (y->getSup() > newSup) y->decrease(newSup); } } // BAC* propagation (increase unary costs of domain bounds) if (x->unassigned()) { Value xinf = x->getInf(); if (xinf != deltaValueXinf && xinf != deltaValueXsup && xinf < y->getInf() + csty && xinf > y->getSup() - cstx) { deltaValueXinf = xinf; x->projectInfCost(penalty); } Value xsup = x->getSup(); if (xsup != deltaValueXsup && xsup != deltaValueXinf && xsup < y->getInf() + csty && xsup > y->getSup() - cstx) { deltaValueXsup = xsup; x->projectSupCost(penalty); } } if (y->unassigned()) { Value yinf = y->getInf(); if (yinf != deltaValueYinf && yinf != deltaValueYsup && yinf < x->getInf() + cstx && yinf > x->getSup() - csty) { deltaValueYinf = yinf; y->projectInfCost(penalty); } Value ysup = y->getSup(); if (ysup != deltaValueYsup && ysup != deltaValueYinf && ysup < x->getInf() + cstx && ysup > x->getSup() - csty) { deltaValueYsup = ysup; y->projectSupCost(penalty); } } } }
void SpecialDisjunction::propagate() { if (ToulBar2::verbose >= 3) { print(cout); cout << "deltaCost= " << deltaCost << " dxinf=" << deltaValueXinf << " dxsup=" << deltaValueXsup << " dyinf=" << deltaValueYinf << " dysup=" << deltaValueYsup << endl; } wcsp->revise(this); if (x->getSup()>xinfty) x->decrease(xinfty); if (y->getSup()>yinfty) y->decrease(yinfty); if ((x->getSup() < xinfty && y->getSup() < yinfty && (x->getInf() >= y->getSup() + csty || y->getInf() >= x->getSup() + cstx)) || (x->getInf() >= xinfty && y->getSup() < yinfty) || (y->getInf() >= yinfty && x->getSup() < xinfty)) { // deconnect the constraint if always satisfied assert(x->getInf() < xinfty || y->getSup() >= yinfty || deltaCost == costx); assert(y->getInf() < yinfty || x->getSup() >= xinfty || deltaCost == costy); deconnect(); } else if (x->getSup() < xinfty && y->getSup() < yinfty && x->getSup() < y->getInf() + csty && y->getSup() < x->getInf() + cstx) { // backtrack if the constraint if always unsatisfied THROWCONTRADICTION; } else { if (x->getInf() < xinfty && y->getInf() < yinfty) { // IC0 propagatation (increase global lower bound) if (min(x->getSup(),xinfty-1) < y->getInf() + csty && min(y->getSup(),yinfty-1) < x->getInf() + cstx) { Cost cost = min(costx,costy) - deltaCost; if (cost > MIN_COST) { deltaCost += cost; projectLB(cost); } } // propagate hard constraint if ((x->getSup() < xinfty || CUT(wcsp->getLb()+costx-deltaCost, wcsp->getUb())) && min(x->getSup(),xinfty-1) < y->getInf() + csty) { Value newInf = min(x->getInf() + cstx, yinfty); if (y->getInf() < newInf) y->increase(newInf); if (y->getSup() < yinfty) { Value newSup = y->getSup() - cstx; if (x->getSup() > newSup) x->decrease(newSup); } } if ((y->getSup() < yinfty || CUT(wcsp->getLb()+costy-deltaCost, wcsp->getUb())) && min(y->getSup(),yinfty-1) < x->getInf() + cstx) { Value newInf = min(y->getInf() + csty, xinfty); if (x->getInf() < newInf) x->increase(newInf); if (x->getSup() < xinfty) { Value newSup = x->getSup() - csty; if (y->getSup() > newSup) y->decrease(newSup); } } // BAC* propagation (increase unary costs of domain bounds) if (x->unassigned() && y->getInf() < yinfty) { Value xinf = x->getInf(); Cost cost = -((Cost) deltaCost); if (xinf < y->getInf() + csty && xinf > min(y->getSup(),yinfty-1) - cstx) cost += costy; if (xinf == deltaValueXinf) { Cost delta = cost - deltaCostXinf; if (delta != MIN_COST) { deltaCostXinf = cost; x->projectInfCost(delta); } } else { deltaValueXinf = xinf; deltaCostXinf = cost; x->projectInfCost(cost); } } if (x->unassigned() && y->getInf() < yinfty) { Value xsup = x->getSup(); Cost cost = -((Cost) deltaCost); if (xsup==xinfty) cost += costx; else if (xsup < y->getInf() + csty && xsup > min(y->getSup(),yinfty-1) - cstx) cost += costy; if (xsup == deltaValueXsup) { Cost delta = cost - deltaCostXsup; if (delta != MIN_COST) { deltaCostXsup = cost; x->projectSupCost(delta); } } else { deltaValueXsup = xsup; deltaCostXsup = cost; x->projectSupCost(cost); } } if (y->unassigned() && x->getInf() < xinfty) { Value yinf = y->getInf(); Cost cost = -((Cost) deltaCost); if (yinf < x->getInf() + cstx && yinf > min(x->getSup(),xinfty-1) - csty) cost += costx; if (yinf == deltaValueYinf) { Cost delta = cost - deltaCostYinf; if (delta != MIN_COST) { deltaCostYinf = cost; y->projectInfCost(delta); } } else { deltaValueYinf = yinf; deltaCostYinf = cost; y->projectInfCost(cost); } } if (y->unassigned() && x->getInf() < xinfty) { Value ysup = y->getSup(); Cost cost = -((Cost) deltaCost); if (ysup==yinfty) cost += costy; else if (ysup < x->getInf() + cstx && ysup > min(x->getSup(),xinfty-1) - csty) cost += costx; if (ysup == deltaValueYsup) { Cost delta = cost - deltaCostYsup; if (delta != MIN_COST) { deltaCostYsup = cost; y->projectSupCost(delta); } } else { deltaValueYsup = ysup; deltaCostYsup = cost; y->projectSupCost(cost); } } } } }
void VACExtension::enforcePass2() { int i0 = inconsistentVariable; int i, j; VACVariable *xi0, *xi, *xj; VACBinaryConstraint *cij; Cost tmplambda; Value v; //if (ToulBar2::verbose > 0) cout << "VAC Enforce Pass 2" << endl; assert(i0 >= 0); xi0 = (VACVariable *) wcsp->getVar(i0); for (EnumeratedVariable::iterator iti0 = xi0->begin(); iti0 != xi0->end(); ++iti0) { v = *iti0; xi0->addToK(v, 1, nbIterations); Cost cost = xi0->getVACCost(v); if (cost > MIN_COST) { if (cost < minlambda) { minlambda = cost; // NB: we don't need to check for bottleneck here as k=1 necessarily } } else xi0->setMark(v, nbIterations); } while (!queueP->empty()) { i = queueP->top().first; v = queueP->top().second; queueP->pop(); xi = (VACVariable *) wcsp->getVar(i); if (xi->isMarked(v, nbIterations)) { j = xi->getKiller(v); xj = (VACVariable *) wcsp->getVar(j); queueR->push(pair < int, int >(i, v)); cij = (VACBinaryConstraint *) xi->getConstr(xj); assert(cij); //if (ToulBar2::verbose > 6) cout << "x" << xi->wcspIndex << "," << v << " killer: " << xj->wcspIndex << endl; for (EnumeratedVariable::iterator itj = xj->begin(); itj != xj->end(); ++itj) { Value w = *itj; Cost costij = cij->getVACCost(xi, xj, v, w); if (costij > MIN_COST) { int tmpK = xi->getK(v, nbIterations); if (xj->getKiller(w) == i && xj->isMarked(w, nbIterations)) tmpK += xj->getK(w, nbIterations); if (!CUT (wcsp->getLb() + costij, wcsp->getUb())) { if ((costij / tmpK) < minlambda) { minlambda = costij / tmpK; if (minlambda < UNIT_COST) { //A cost function bottleneck here ! bneckCost = costij; bneckCF = cij; bneckVar = -1; } } } else { if ((costij / tmpK) < minlambda) { // costij should be made infinite to avoid to decrease minlambda Cost cost = tmpK * minlambda - costij; assert(cost > MIN_COST); assert(ToulBar2::verbose < 1 || ((cout << "inflate(C" << cij->getVar(0)->getName() << "," << cij->getVar(1)->getName() << ", (" << ((xi==cij->getVar(0))?v:w) << "," << ((xi==cij->getVar(0))?w:v) << "), " << cost << ")" << endl), true)); cij->addcost( xi, xj, v, w, cost ); } } } else { int tmpK = xi->getK(v, nbIterations) - cij->getK(xj, w, nbIterations); if (tmpK > 0) { xj->addToK(w, tmpK, nbIterations); cij->setK(xj, w, xi->getK(v, nbIterations), nbIterations); Cost cost = xj->getVACCost(w); if (cost == MIN_COST) xj->setMark(w, nbIterations); else if (!CUT (wcsp->getLb() + cost, wcsp->getUb())) { tmplambda = cost / xj->getK(w, nbIterations); if (tmplambda < minlambda) { minlambda = tmplambda; if (minlambda < UNIT_COST) { // A unary cost bottleneck here bneckVar = j; bneckCF = NULL; bneckCost = cost; } } } // else cost is infinite and it will not be decreased by VACextend } } } } } //if (maxK == 0) { // maxK = wcsp->getUb() - wcsp->getLb(); //} if (ToulBar2::verbose > 1) cout << "minLambda: " << minlambda << "\t\t (lb = " << wcsp-> getLb() << ", ub = " << wcsp->getUb() << ")" << endl; }
STATUS FtpData(FTP * con,char * command , char * file ,char * mode) { struct sockaddr_in data,from; register struct hostent *host; FtpString hostname; int NewSocket,Accepted_Socket,len=sizeof(data),one=1,fromlen=sizeof(from),i; char *a,*b; FREE(data); FREE(from); if ( gethostname( hostname , sizeof hostname ) == -1 ) return EXIT(con,QUIT); if ((host=(struct hostent *)gethostbyname(hostname))==0) return EXIT(con,QUIT); data.sin_family = host -> h_addrtype; bcopy(host-> h_addr_list[0],(char *)&data.sin_addr,host->h_length); if ((NewSocket = socket ( AF_INET , SOCK_STREAM , 0 ))<0) { fprintf( stderr, "socket() failed in FtpData: %s\n", strerror( errno ) ); return EXIT(con,QUIT); } if ( setsockopt ( NewSocket , SOL_SOCKET , SO_REUSEADDR , (char *)&one , sizeof(one) ) < 0 ) { fprintf( stderr, "setsockopt() failed in FtpData: %s\n", strerror( errno ) ); close(NewSocket); return EXIT ( con,QUIT ); } data.sin_port = 0 ; if ( bind ( NewSocket , (struct sockaddr*) &data , sizeof data ) < 0 ) { fprintf( stderr, "bind() failed in FtpData: %s\n", strerror( errno ) ); close(NewSocket); return EXIT(con,QUIT); } if ( getsockname ( NewSocket , (struct sockaddr*) &data , (socklen_t *) &len ) < 0 ) { fprintf( stderr, "bind() failed in FtpData: %s\n", strerror( errno ) ); close(NewSocket); return EXIT(con,QUIT); } if ( listen ( NewSocket , 1 ) < 0 ) { fprintf( stderr, "listen() failed in FtpData: %s\n", strerror( errno ) ); close(NewSocket); return EXIT(con,QUIT); } a = ( char * ) & data.sin_addr; b = ( char * ) & data.sin_port; FtpAssert(con,FtpPort(con,CUT(a[0]),CUT(a[1]),CUT(a[2]),CUT(a[3]),CUT(b[0]),CUT(b[1]))); if ( con -> seek != 0) { if ((i = FtpCommand ( con, "REST %d" , con -> seek , 0, EOF)) != 350 ) { close(NewSocket); return -i; } } FtpAssert(con, i=FtpCommand ( con , command , file , 200, 120 , 150 , 125 , 250 , EOF )); if (( Accepted_Socket = accept (NewSocket , (struct sockaddr *)&from , (socklen_t *) &fromlen )) < 0) { fprintf( stderr, "accept() failed in FtpData: %s\n", strerror( errno ) ); close(NewSocket); return EXIT(con,QUIT); } close(NewSocket); FTPDATA(con) = winsock_fdopen(Accepted_Socket, "r+"); return i; }
pair<Cost, Cost> Solver::recursiveSolve(Cluster* cluster, Cost lbgood, Cost cub) { if (ToulBar2::verbose >= 1) cout << "[" << Store::getDepth() << "] recursive solve cluster: " << cluster->getId() << " clb: " << lbgood << " cub: " << cub << " clb0: " << cluster->getLb() << " wcsp->lb: " << wcsp->getLb() << " wcsp->ub: " << wcsp->getUb() << endl; assert(lbgood <= cub); TreeDecomposition* td = wcsp->getTreeDec(); int varIndex = -1; if (ToulBar2::Static_variable_ordering) varIndex = getNextUnassignedVar(cluster); else if (ToulBar2::weightedDegree && ToulBar2::lastConflict) varIndex = ((ToulBar2::restart > 0) ? getVarMinDomainDivMaxWeightedDegreeLastConflictRandomized(cluster) : getVarMinDomainDivMaxWeightedDegreeLastConflict(cluster)); else if (ToulBar2::lastConflict) varIndex = ((ToulBar2::restart > 0) ? getVarMinDomainDivMaxDegreeLastConflictRandomized(cluster) : getVarMinDomainDivMaxDegreeLastConflict(cluster)); else if (ToulBar2::weightedDegree) varIndex = ((ToulBar2::restart > 0) ? getVarMinDomainDivMaxWeightedDegreeRandomized(cluster) : getVarMinDomainDivMaxWeightedDegree(cluster)); else varIndex = ((ToulBar2::restart > 0) ? getVarMinDomainDivMaxDegreeRandomized(cluster) : getVarMinDomainDivMaxDegree(cluster)); if (varIndex < 0) { // Current cluster is completely assigned Cost clb = wcsp->getLb(); assert(clb <= cub); Cost csol = clb; for (TClusters::iterator iter = cluster->beginSortedEdges(); clb < cub && iter != cluster->endSortedEdges();) { // Solves each cluster son with local lower and upper bounds Cluster* c = *iter; ++iter; Cost lbSon = MIN_COST; Cost ubSon = MAX_COST; bool good = false; if (!c->isActive()) { c->reactivate(); c->nogoodGet(lbSon, ubSon, &c->open); good = true; } else { lbSon = c->getLbRec(); ubSon = c->getUb(); #ifndef NDEBUG Cost dummylb = -MAX_COST; Cost tmpub = -MAX_COST; c->nogoodGet(dummylb, tmpub, &c->open); assert(tmpub == ubSon); #endif } if (ToulBar2::verbose >= 2) cout << "lbson: " << lbSon << " ubson: " << ubSon << " lbgood:" << lbgood << " clb: " << clb << " csol: " << csol << " cub: " << cub << " cluster->lb: " << c->getLbRec() << endl; if (lbSon < ubSon) { // we do not have an optimality proof if (clb <= lbgood || (csol < MAX_COST && ubSon >= cub - csol + lbSon)) { // we do not know a good enough son's solution or the currently reconstructed father's solution is not working or the currently reconstructed father's lower bound is not increasing bool csolution = (csol < MAX_COST && ubSon < cub - csol + lbSon); assert(!csolution || ubSon < cub - clb + lbSon); ubSon = MIN(ubSon, cub - clb + lbSon); td->setCurrentCluster(c); wcsp->setUb(ubSon); wcsp->setLb((good) ? c->getLbRec() : lbSon); try { Store::store(); wcsp->enforceUb(); wcsp->propagate(); Cost bestlb = MAX(wcsp->getLb(), lbSon); if (csol < MAX_COST && iter == cluster->endSortedEdges()) bestlb = MAX(bestlb, lbgood - csol + lbSon); // simple trick to provide a better initial lower bound for the last son if (ToulBar2::btdMode >= 2) { Cost rds = td->getLbRecRDS(); bestlb = MAX(bestlb, rds); if (CUT(bestlb, ubSon)) THROWCONTRADICTION; } pair<Cost, Cost> res = hybridSolve(c, bestlb, ubSon); assert(res.first >= bestlb && res.second <= ubSon); c->nogoodRec(res.first, ((res.second < ubSon) ? res.second : MAX_COST), &c->open); clb += res.first - lbSon; if (csol < MAX_COST) { if (res.second < ubSon || csolution) csol += res.second - lbSon; else csol = MAX_COST; } } catch (Contradiction) { wcsp->whenContradiction(); c->nogoodRec(ubSon, MAX_COST, &c->open); clb += ubSon - lbSon; if (csolution) csol += ubSon - lbSon; else csol = MAX_COST; } Store::restore(); } else { if (csol < MAX_COST) { assert(ubSon < MAX_COST); csol += ubSon - lbSon; } } } } assert(csol >= clb); if (csol < cub) { // A new solution has been found for the current cluster cub = csol; cluster->solutionRec(csol); if (cluster == td->getRoot() || cluster == td->getRootRDS()) { if (ToulBar2::verbose >= 0 || ToulBar2::showSolutions) { if (!ToulBar2::bayesian) cout << "New solution: " << std::setprecision(ToulBar2::decimalPoint) << wcsp->Cost2ADCost(csol) << std::setprecision(DECIMAL_POINT) << " (" << nbBacktracks << " backtracks, " << nbNodes << " nodes, depth " << Store::getDepth() << ")" << endl; else cout << "New solution: " << csol << " energy: " << -(wcsp->Cost2LogProb(csol) + ToulBar2::markov_log) << " prob: " << std::scientific << wcsp->Cost2Prob(csol) * Exp(ToulBar2::markov_log) << std::fixed << " (" << nbBacktracks << " backtracks, " << nbNodes << " nodes, depth " << Store::getDepth() << ")" << endl; } if (cluster == td->getRoot()) td->newSolution(csol); else { assert(cluster == td->getRootRDS()); // Remember current solution for value ordering heuristic wcsp->restoreSolution(cluster); TAssign a; cluster->getSolution(a); if (ToulBar2::showSolutions) { TAssign::iterator it = a.begin(); while (it != a.end()) { Value v = it->second; cout << it->first << ":" << v << " "; ++it; } cout << endl; } } } } Cost bestlb = MAX(lbgood, clb); if (ToulBar2::verbose >= 1) cout << "[" << Store::getDepth() << "] C" << cluster->getId() << " return " << bestlb << " " << cub << endl; assert(bestlb <= cub); if (ToulBar2::hbfs && bestlb < cub) { // keep current node in open list instead of closing it! if (cluster->getNbVars() > 0) { int varid = *cluster->getVars().begin(); assert(wcsp->assigned(varid)); cluster->cp->addChoicePoint(CP_ASSIGN, varid, wcsp->getValue(varid), true); // dummy additional choice point to avoid the reversal of the last effective choice point for this open node } #ifndef NDEBUG OpenList* prevopen = cluster->open; Cost tmplb = MIN_COST; Cost tmpub = MAX_COST; Cost tmpclusterub = cluster->getUb(); assert(cluster == wcsp->getTreeDec()->getRoot() || cluster->nogoodGet(tmplb, tmpub, &cluster->open)); // warning! it can destroy cluster->ub cluster->setUb(tmpclusterub); assert(prevopen == cluster->open); #endif addOpenNode(*(cluster->cp), *(cluster->open), bestlb, cluster->getCurrentDelta()); // reinsert as a new open node cluster->hbfsLimit = cluster->nbBacktracks; // and stop current visited node bestlb = cub; } return make_pair(bestlb, cub); } else { // Enumerates cluster proper variables *((StoreCost*)searchSize) += ((Cost)(10e6 * Log(wcsp->getDomainSize(varIndex)))); pair<Cost, Cost> res = make_pair(MIN_COST, MAX_COST); if (wcsp->enumerated(varIndex)) { assert(wcsp->canbe(varIndex, wcsp->getSupport(varIndex))); // Reuse last solution found if available Value bestval = ((ToulBar2::verifyOpt) ? (wcsp->getSup(varIndex) + 1) : wcsp->getBestValue(varIndex)); res = binaryChoicePoint(cluster, lbgood, cub, varIndex, (wcsp->canbe(varIndex, bestval)) ? bestval : wcsp->getSupport(varIndex)); } else { res = binaryChoicePoint(cluster, lbgood, cub, varIndex, wcsp->getInf(varIndex)); } if (ToulBar2::verbose >= 1) cout << "[" << Store::getDepth() << "] C" << cluster->getId() << " return " << res.first << " " << res.second << endl; assert(res.first >= lbgood); assert(res.second <= cub); assert(res.first <= res.second); return res; } }
BigInteger Solver::binaryChoicePointSBTD(Cluster* cluster, int varIndex, Value value) { if (ToulBar2::interrupted) throw TimeOut(); Cost cub = 1; Cost lbgood = 0; BigInteger nbSol = 0, nb = 0; assert(wcsp->unassigned(varIndex)); assert(wcsp->canbe(varIndex, value)); bool dichotomic = (ToulBar2::dichotomicBranching && ToulBar2::dichotomicBranchingSize < wcsp->getDomainSize(varIndex)); Value middle = value; bool increasing = true; if (dichotomic) { middle = (wcsp->getInf(varIndex) + wcsp->getSup(varIndex)) / 2; if (value <= middle) increasing = true; else increasing = false; } try { Store::store(); assert(wcsp->getTreeDec()->getCurrentCluster() == cluster); wcsp->setUb(cub); if (CUT(lbgood, cub)) THROWCONTRADICTION; lastConflictVar = varIndex; if (dichotomic) { if (increasing) decrease(varIndex, middle); else increase(varIndex, middle + 1); } else assign(varIndex, value); lastConflictVar = -1; nb = sharpBTD(cluster); nbSol += nb; } catch (Contradiction) { wcsp->whenContradiction(); } Store::restore(); nbBacktracks++; if (ToulBar2::restart > 0 && nbBacktracks > nbBacktracksLimit) throw NbBacktracksOut(); #ifdef OPENMPI if (ToulBar2::vnsParallel && ((nbBacktracks % 128) == 0) && MPI_interrupted()) throw TimeOut(); #endif try { Store::store(); assert(wcsp->getTreeDec()->getCurrentCluster() == cluster); // assert(wcsp->getLb() == cluster->getLbRec()); wcsp->setUb(cub); if (CUT(lbgood, cub)) THROWCONTRADICTION; if (dichotomic) { if (increasing) increase(varIndex, middle + 1); else decrease(varIndex, middle); } else remove(varIndex, value); nb = sharpBTD(cluster); nbSol += nb; } catch (Contradiction) { wcsp->whenContradiction(); } Store::restore(); return nbSol; }
pair<Cost, Cost> Solver::binaryChoicePoint(Cluster* cluster, Cost lbgood, Cost cub, int varIndex, Value value) { assert(lbgood < cub); if (ToulBar2::interrupted) throw TimeOut(); Cost clb = cub; TreeDecomposition* td = wcsp->getTreeDec(); assert(wcsp->unassigned(varIndex)); assert(wcsp->canbe(varIndex, value)); bool dichotomic = (ToulBar2::dichotomicBranching && ToulBar2::dichotomicBranchingSize < wcsp->getDomainSize(varIndex)); Value middle = value; bool increasing = true; if (dichotomic) { middle = (wcsp->getInf(varIndex) + wcsp->getSup(varIndex)) / 2; if (value <= middle) increasing = true; else increasing = false; } try { Store::store(); assert(td->getCurrentCluster() == cluster); assert(wcsp->getLb() == cluster->getLbRec()); wcsp->setUb(cub); Cost bestlb = lbgood; if (CUT(bestlb, cub)) THROWCONTRADICTION; if (ToulBar2::btdMode >= 2) { Cost rds = td->getLbRecRDS(); bestlb = MAX(bestlb, rds); if (CUT(bestlb, cub)) THROWCONTRADICTION; } lastConflictVar = varIndex; if (dichotomic) { if (increasing) decrease(varIndex, middle); else increase(varIndex, middle + 1); } else assign(varIndex, value); lastConflictVar = -1; bestlb = MAX(bestlb, wcsp->getLb()); pair<Cost, Cost> res = recursiveSolve(cluster, bestlb, cub); clb = MIN(res.first, clb); cub = MIN(res.second, cub); } catch (Contradiction) { wcsp->whenContradiction(); } Store::restore(); nbBacktracks++; if (ToulBar2::restart > 0 && nbBacktracks > nbBacktracksLimit) throw NbBacktracksOut(); #ifdef OPENMPI if (ToulBar2::vnsParallel && ((nbBacktracks % 128) == 0) && MPI_interrupted()) throw TimeOut(); #endif cluster->nbBacktracks++; try { Store::store(); assert(wcsp->getTreeDec()->getCurrentCluster() == cluster); assert(wcsp->getLb() == cluster->getLbRec()); wcsp->setUb(cub); Cost bestlb = lbgood; if (CUT(bestlb, cub)) THROWCONTRADICTION; if (ToulBar2::btdMode >= 2) { Cost rds = td->getLbRecRDS(); bestlb = MAX(bestlb, rds); if (CUT(bestlb, cub)) THROWCONTRADICTION; } if (dichotomic) { if (increasing) increase(varIndex, middle + 1, cluster->nbBacktracks >= cluster->hbfsLimit || nbBacktracks >= cluster->hbfsGlobalLimit); else decrease(varIndex, middle, cluster->nbBacktracks >= cluster->hbfsLimit || nbBacktracks >= cluster->hbfsGlobalLimit); } else remove(varIndex, value, cluster->nbBacktracks >= cluster->hbfsLimit || nbBacktracks >= cluster->hbfsGlobalLimit); bestlb = MAX(bestlb, wcsp->getLb()); if (!ToulBar2::hbfs && cluster == td->getRoot() && initialDepth + 1 == Store::getDepth()) { initialDepth++; showGap(bestlb, cub); }; if (cluster->nbBacktracks >= cluster->hbfsLimit || nbBacktracks >= cluster->hbfsGlobalLimit) { addOpenNode(*(cluster->cp), *(cluster->open), bestlb, cluster->getCurrentDelta()); } else { pair<Cost, Cost> res = recursiveSolve(cluster, bestlb, cub); clb = MIN(res.first, clb); cub = MIN(res.second, cub); } } catch (Contradiction) { wcsp->whenContradiction(); } Store::restore(); assert(lbgood <= clb); assert(clb <= cub); return make_pair(clb, cub); }
int main(int argc, char** argv) { /* FRONT & BACK v--- finger_size_x ### ### ### ### ### ### ### ### ### ######################################################### #######################frame_width########################### #### # # # # #### ## # # # # ^ ## ## # # # # |num_ ## #########front_mid_width############# . . . |front_ #### <-- finger_size_y #### # # # # . . . |holes_y #### ### # # # # v ## ## # # # hole at every cell (y[0]) ## #### # # ... <-----------> #### ############################################################# ######################################################### ### ### ### ### ### ### ### ### ### */ if(argc < 5) { printf("Usage: cnc_gen <outfile_prefix> <y1> <y2> <x> <y cellgap|offset> <x scaling factor> <gap1> <gap2> <gap3> <gap4>\n"); printf("Ex.: cnc_gen out 4 3 11\n"); printf(" ---- X ----> \n"); printf("__-_-_-_-_-_4_-_-_-_-_-__\n"); printf("| O O O O O O |\n"); printf("| O O O O O |\n"); printf("| O O O O O O |\n"); printf("1 O O O O O 3\n"); printf("| O O O O O O |\n"); printf("| O O O O O |\n"); printf("| O O O O O O |\n"); printf("------------2------------\n"); return 1; } fullcut_z = z_at_surface - thickness - cut_through_base; cellgap = cell_to_cell-cell; ys[0] = atoi(argv[2]); if(ys[0] < 1 || ys[0] > 100) { printf("Invalid y1\n"); return 1;} ys[1] = atoi(argv[3]); if(ys[1] < 1 || ys[1] > 100) { printf("Invalid y2\n"); return 1;} if(ys[1] < ys[0]-1 || ys[1] > ys[0]) { printf("y2 must be y1-1 or y1\n"); return 1;} x = atoi(argv[4]); if(x < 1 || x > 100) { printf("Invalid x\n"); return 1;} char mainfilename[1000]; char coverfilename[1000]; sprintf(mainfilename, "%s_main.ngc", argv[1]); sprintf(coverfilename, "%s_cover.ngc", argv[1]); FILE* gfile = fopen(mainfilename, "wb"); if(!gfile) { printf("Error opening file %s\n", mainfilename); return 1; } FILE* coverfile; if(do_covers) { coverfile = fopen(coverfilename, "wb"); if(!coverfile) { printf("Error opening file %s\n", coverfilename); return 1; } } float y_step = cell + cellgap; float x_step = sqrt( (3.0*(cell/2.0)*(cell/2.0)) + (2.0*(cell/2.0)*cellgap) ) * 1.05 * spacing_trim; // todo: fix math... printf("y_step = %f, x_step = %f\n", y_step, x_step); fprintf(gfile, "("); for(int i = 0; i < 4; i++) { fprintf(gfile, " %s ", argv[i]); } fprintf(gfile, ")\n"); fprintf(gfile, "G21\n"); fprintf(gfile, "G90\n"); // absolute coords. // fprintf(gfile, "G61\n"); // forces complete stop in corners, resulting in less rounding of corners. fprintf(gfile, "G00 Z%.2f\n", z_at_idle); if(do_covers) { fprintf(coverfile, "G21\n"); fprintf(coverfile, "G61\n"); COVER_UNCUT(); fprintf(coverfile, "G00 F%.2f\n", cover_feedrate); fprintf(coverfile, "M07 (air on)\n"); delay(coverfile, 5.0); } float front_origin_x = 10.0; float front_origin_y = 10.0; float side_origin_x = 10.0; float side_origin_y = 10.0; float cover_origin_x = 10.0; float cover_origin_y = 10.0; float origin_x = 10.0+thickness; float origin_y = 10.0+thickness; if(do_fronts) { origin_x += cell_length + part_separation; side_origin_x = origin_x; } if(do_sides == 1) { if(side_at_back) { side_origin_x = origin_x + wallgaps[0] + x_step*(x-1) + cell + wallgaps[2] + part_separation + thickness*2.0; } else { origin_y += cell_length + part_separation + (do_covers?(cover_thickness*2.0):0.0); front_origin_y = origin_y; } } for(int curx = 0; curx < x; curx++) { int y = ys[curx%2]; float y_offset = (curx%2)?(y_step/2.0):(0.0); for(int cury = 0; cury < y; cury++) { float mid_x = origin_x + wallgaps[0] + x_step*curx + cell/2.0; float mid_y = origin_y + wallgaps[1] + y_step*cury + cell/2.0 + y_offset; fprintf(gfile, "(WELDPOINT %u;%u;%.2f;%.2f)\n", curx, cury, mid_x-origin_x, mid_y-origin_y); do_cellhole(gfile, mid_x, mid_y); /* // Do end bms bonusholes: if(((curx == 0) || (curx == x-1)) && (cury == y-1) && end_bonusholes > 0.01) { float bonushole_midx = mid_x; if(curx == 0) bonushole_midx -= cell/2.0; else bonushole_midx += cell/2.0; float bonushole_midy = origin_y + wallgaps[1] + y_step*(ys[0]-1) + cell/2.0; float shift = cell/2.0 + end_bonusholes/2.0 + end_bonusholes_dist; bonushole_midy += shift; float bonushole_startx = bonushole_midx - end_bonusholes/2.0; float bonushole_startx_trimmed = bonushole_startx + toolsize; float bonushole_starty_trimmed = bonushole_midy; float bonushole_offset_i = end_bonusholes/2.0 - toolsize; float bonushole_offset_j = 0.0; fprintf(gfile, "G00 X%.2f Y%.2f\n", bonushole_startx_trimmed, bonushole_starty_trimmed); CUT(); fprintf(gfile, "G02 X%.2f Y%.2f I%.2f J%.2f\n", bonushole_startx_trimmed, bonushole_starty_trimmed, bonushole_offset_i, bonushole_offset_j); UNCUT(); delay(gfile, delay_per_cell*0.25); } // Do cell bms bonusholes: if((curx%2 == 0) && ((cury == y-1)) && bonushole > 0.01) { float bonushole_midx = mid_x; // ( // (2.0*(origin_x + wallgaps[0] + x_step*(curx-1) + cell/2.0))+ // (1.0*(origin_x + wallgaps[0] + x_step*curx + cell/2.0)) // )/3.0; float bonushole_midy = mid_y; float shift = cell/2.0 + bonushole/2.0 + bonushole_dist; if(cury == 0) bonushole_midy -= shift; else bonushole_midy += shift; float bonushole_startx = bonushole_midx - bonushole/2.0; float bonushole_startx_trimmed = bonushole_startx + toolsize; float bonushole_starty_trimmed = bonushole_midy; float bonushole_offset_i = bonushole/2.0 - toolsize; float bonushole_offset_j = 0.0; fprintf(gfile, "G00 X%.2f Y%.2f\n", bonushole_startx_trimmed, bonushole_starty_trimmed); CUT(); fprintf(gfile, "G02 X%.2f Y%.2f I%.2f J%.2f\n", bonushole_startx_trimmed, bonushole_starty_trimmed, bonushole_offset_i, bonushole_offset_j); UNCUT(); delay(gfile, delay_per_cell*0.25); } */ // delay(gfile, delay_per_cell); } } float outline[4][2]; float side_outline[2][2]; float cover_outline[4][2]; outline[0][X] = origin_x; outline[0][Y] = origin_y; outline[1][X] = origin_x + wallgaps[0] + x_step*(x-1) + cell + wallgaps[2]; outline[1][Y] = outline[0][Y]; outline[2][X] = outline[1][X]; outline[2][Y] = origin_y + wallgaps[1] + y_step*(ys[0]-1) + cell + wallgaps[3]; if(ys[1] == ys[0]) outline[2][Y] += y_step/2.0; outline[3][X] = origin_x; outline[3][Y] = outline[2][Y]; side_outline[0][X] = side_origin_x; side_outline[0][Y] = side_origin_y; side_outline[1][X] = side_origin_x + wallgaps[0] + x_step*(x-1) + cell + wallgaps[2]; side_outline[1][Y] = side_outline[0][Y]; cover_outline[0][X] = cover_origin_x; cover_outline[0][Y] = cover_origin_y; cover_outline[1][X] = cover_origin_x + wallgaps[0] + x_step*(x-1) + cell + wallgaps[2]; cover_outline[1][Y] = cover_outline[0][Y]; cover_outline[2][X] = cover_outline[1][X]; cover_outline[2][Y] = cover_origin_y + wallgaps[1] + y_step*(ys[0]-1) + cell + wallgaps[3]; if(ys[1] == ys[0]) cover_outline[2][Y] += y_step/2.0; cover_outline[3][X] = cover_outline[0][X]; cover_outline[3][Y] = cover_outline[2][Y]; fprintf(gfile, "G00 X%.2f Y%.2f (ALIGNPOINT 0;0;%.2f;%.2f)\n", outline[0][X]-toolsize, outline[0][Y]-toolsize, outline[0][X]-(do_fronts?thickness:0.0), outline[0][Y]-(do_sides?thickness:0.0)); if(do_covers) { fprintf(coverfile, "G00 X%.2f Y%.2f\n", cover_outline[0][X]-thickness-cover_toolsize, cover_outline[0][Y]-cover_toolsize); COVER_CUT(); } // horizontal bottom side if(do_sides) { // Finger cut for(int curx = 0; curx < x; curx++) { float finger_start_x = origin_x + wallgaps[0] + x_step*curx + cell/2.0 - finger_size_x/2.0; float finger_end_x = finger_start_x + finger_size_x; float cfinger_start_x = cover_origin_x + wallgaps[0] + x_step*curx + cell/2.0 - finger_size_x/2.0; float cfinger_end_x = cfinger_start_x + finger_size_x; fprintf(gfile, "G01 X%.2f Y%.2f Z%.2f F%.2f\n", finger_start_x-toolsize, outline[0][Y]-toolsize, fullcut_z, feedrate); fprintf(gfile, "G01 X%.2f Y%.2f\n", finger_start_x-toolsize, outline[0][Y] -thickness-toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", finger_end_x+toolsize, outline[0][Y] -thickness-toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", finger_end_x+toolsize, outline[0][Y]-toolsize); if(do_covers) { fprintf(coverfile, "G01 X%.2f Y%.2f F%.2f\n", cfinger_start_x-cover_toolsize, cover_outline[0][Y]-cover_toolsize, cover_feedrate); fprintf(coverfile, "G01 X%.2f Y%.2f\n", cfinger_start_x-cover_toolsize, cover_outline[0][Y] -thickness-cover_toolsize); fprintf(coverfile, "G01 X%.2f Y%.2f\n", cfinger_end_x+cover_toolsize, cover_outline[0][Y] -thickness-cover_toolsize); fprintf(coverfile, "G01 X%.2f Y%.2f\n", cfinger_end_x+cover_toolsize, cover_outline[0][Y]-cover_toolsize); } } } fprintf(gfile, "G01 X%.2f Y%.2f (ALIGNPOINT 1;0;%.2f;%.2f)\n", outline[1][X]+toolsize, outline[1][Y]-toolsize, outline[1][X]+(do_fronts?thickness:0.0), outline[1][Y]-(do_sides?thickness:0.0)); if(do_covers) { fprintf(coverfile, "G01 X%.2f Y%.2f F%.2f\n", cover_outline[1][X]+thickness+cover_toolsize, cover_outline[1][Y]-cover_toolsize, cover_feedrate); } if(do_covers) { COVER_UNCUT(); delay(coverfile, cover_delay_per_cell*x); COVER_CUT(); } // vertical right side if(do_fronts) { // Finger cut for(int cury = 0; cury < ys[0]; cury++) { float finger_start_y = origin_y + wallgaps[1] + y_step*cury + cell/2.0 - finger_size_y/2.0; float finger_end_y = finger_start_y + finger_size_y; float cfinger_start_y = cover_origin_y + wallgaps[1] + y_step*cury + cell/2.0 - finger_size_y/2.0; float cfinger_end_y = cfinger_start_y + finger_size_y; fprintf(gfile, "G01 X%.2f Y%.2f\n", outline[1][X]+toolsize, finger_start_y-toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", outline[1][X]+thickness+toolsize, finger_start_y-toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", outline[1][X]+thickness+toolsize, finger_end_y+toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", outline[1][X]+toolsize, finger_end_y+toolsize); /* if(do_covers) { fprintf(coverfile, "G01 X%.2f Y%.2f\n", cover_outline[1][X]+cover_toolsize, cfinger_start_y-cover_toolsize); fprintf(coverfile, "G01 X%.2f Y%.2f\n", cover_outline[1][X]+thickness+cover_toolsize, cfinger_start_y-cover_toolsize); fprintf(coverfile, "G01 X%.2f Y%.2f\n", cover_outline[1][X]+thickness+cover_toolsize, cfinger_end_y+cover_toolsize); fprintf(coverfile, "G01 X%.2f Y%.2f\n", cover_outline[1][X]+cover_toolsize, cfinger_end_y+cover_toolsize); } */ } } fprintf(gfile, "G01 X%.2f Y%.2f (ALIGNPOINT 1;1;%.2f;%.2f)\n", outline[2][X]+toolsize, outline[2][Y]+toolsize, outline[2][X]+(do_fronts?thickness:0.0), outline[2][Y]+(do_sides?thickness:0.0)); if(do_covers) { fprintf(coverfile, "G01 X%.2f Y%.2f\n", cover_outline[2][X]+thickness+cover_toolsize, cover_outline[2][Y]+cover_toolsize); } if(do_covers) { COVER_UNCUT(); delay(coverfile, 0.7*cover_delay_per_cell*ys[0]); COVER_CUT(); } // horizontal top side if(do_sides) { // Finger cut for(int curx = x-1; curx >= 0; curx--) { float finger_end_x = origin_x + wallgaps[0] + x_step*curx + cell/2.0 - finger_size_x/2.0; float finger_start_x = finger_end_x + finger_size_x; float cfinger_end_x = cover_origin_x + wallgaps[0] + x_step*curx + cell/2.0 - finger_size_x/2.0; float cfinger_start_x = cfinger_end_x + finger_size_x; fprintf(gfile, "G01 X%.2f Y%.2f\n", finger_start_x+toolsize, outline[2][Y]+toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", finger_start_x+toolsize, outline[2][Y]+thickness+toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", finger_end_x-toolsize, outline[2][Y]+thickness+toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", finger_end_x-toolsize, outline[2][Y]+toolsize); if(do_covers) { fprintf(coverfile, "G01 X%.2f Y%.2f\n", cfinger_start_x+cover_toolsize, cover_outline[2][Y]+cover_toolsize); fprintf(coverfile, "G01 X%.2f Y%.2f\n", cfinger_start_x+cover_toolsize, cover_outline[2][Y]+thickness+cover_toolsize); fprintf(coverfile, "G01 X%.2f Y%.2f\n", cfinger_end_x-cover_toolsize, cover_outline[2][Y]+thickness+cover_toolsize); fprintf(coverfile, "G01 X%.2f Y%.2f\n", cfinger_end_x-cover_toolsize, cover_outline[2][Y]+cover_toolsize); } } } fprintf(gfile, "G01 X%.2f Y%.2f (ALIGNPOINT 0;1;%.2f;%.2f)\n", outline[3][X]-toolsize, outline[3][Y]+toolsize, outline[3][X]-(do_fronts?thickness:0.0), outline[3][Y]+(do_sides?thickness:0.0)); if(do_covers) { fprintf(coverfile, "G01 X%.2f Y%.2f\n", cover_outline[3][X]-thickness-cover_toolsize, cover_outline[3][Y]+cover_toolsize); } if(do_covers) { COVER_UNCUT(); delay(coverfile, cover_delay_per_cell*x); COVER_CUT(); } // Vertical left side if(do_fronts) { // Finger cut for(int cury = ys[0]-1; cury >=0; cury--) { float finger_end_y = origin_y + wallgaps[1] + y_step*cury + cell/2.0 - finger_size_y/2.0; float finger_start_y = finger_end_y + finger_size_y; float cfinger_end_y = cover_origin_y + wallgaps[1] + y_step*cury + cell/2.0 - finger_size_y/2.0; float cfinger_start_y = cfinger_end_y + finger_size_y; fprintf(gfile, "G01 X%.2f Y%.2f\n", outline[3][X]-toolsize, finger_start_y+toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", outline[3][X]-thickness-toolsize, finger_start_y+toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", outline[3][X]-thickness-toolsize, finger_end_y-toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", outline[3][X]-toolsize, finger_end_y-toolsize); /* if(do_covers) { fprintf(coverfile, "G01 X%.2f Y%.2f\n", cover_outline[3][X]-cover_toolsize, cfinger_start_y+cover_toolsize); fprintf(coverfile, "G01 X%.2f Y%.2f\n", cover_outline[3][X]-thickness-cover_toolsize, cfinger_start_y+cover_toolsize); fprintf(coverfile, "G01 X%.2f Y%.2f\n", cover_outline[3][X]-thickness-cover_toolsize, cfinger_end_y-cover_toolsize); fprintf(coverfile, "G01 X%.2f Y%.2f\n", cover_outline[3][X]-cover_toolsize, cfinger_end_y-cover_toolsize); } */ } } fprintf(gfile, "G01 X%.2f Y%.2f\n", outline[0][X]-toolsize, outline[0][Y]-toolsize); fprintf(gfile, "G01 Z%.2f\n", z_at_idle); if(do_covers) { fprintf(coverfile, "G01 X%.2f Y%.2f\n", cover_outline[0][X]-thickness-cover_toolsize, cover_outline[0][Y]-cover_toolsize); } if(do_covers) { COVER_UNCUT(); // delay(coverfile, 0.7*cover_delay_per_cell*ys[0]); } printf("Main panel size without fingers: %.2f x %.2f\n", outline[1][X]-outline[0][X], outline[2][Y]-outline[1][Y]); printf("Total box size: %.2f x %.2f x %.2f\n", outline[1][X]-outline[0][X]+2.0*thickness, outline[2][Y]-outline[1][Y]+2.0*thickness, cell_length+2.0*cover_thickness); printf("Sheet needed: %.2f x %.2f\n", outline[1][X]-outline[0][X]+2.0*thickness+cell_length+part_separation, outline[2][Y]-outline[1][Y]+2.0*thickness+cell_length+2.0*cover_thickness+part_separation); if(do_covers) printf("Cover size with fingers (sheet needed): %.2f x %.2f\n", cover_outline[1][X]-cover_outline[0][X]+2.0*thickness, cover_outline[2][Y]-cover_outline[1][Y]+2.0*thickness); /* |||| thickness c |||| < 0.5 steps e || ^ 1 l |||| v step l || ^ 1 l |||| v step e || ^ 1 n |||| v step |||| thickness */ float side_front_finger_step = (cell_length - 2.0*thickness) / ((float)num_side_front_fingers-0.5); // Do side panel if(do_sides) { fprintf(gfile, "G00 X%.2f Y%.2f\n", side_outline[0][X]-toolsize, side_origin_y-(do_covers?cover_thickness:0.0)-toolsize); CUT(); // Bottom horizontal for(int curx = 0; curx < x; curx++) { float finger_start_x = side_origin_x + wallgaps[0] + x_step*curx + cell/2.0 - finger_size_x/2.0; float finger_end_x = finger_start_x + finger_size_x; fprintf(gfile, "G01 X%.2f Y%.2f\n", finger_start_x+toolsize, side_origin_y-(do_covers?cover_thickness:0.0)-toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", finger_start_x+toolsize, side_origin_y+thickness-toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", finger_end_x-toolsize, side_origin_y+thickness-toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", finger_end_x-toolsize, side_origin_y-(do_covers?cover_thickness:0.0)-toolsize); } fprintf(gfile, "G01 X%.2f Y%.2f\n", side_outline[1][X]+toolsize, side_origin_y-(do_covers?cover_thickness:0.0)-toolsize); UNCUT(); delay(gfile, delay_per_cell*x); CUT_PWR(vertical_power_mult); // Right vertical for(int cury = 0; cury < num_side_front_fingers; cury++) { float finger_start_y = side_origin_y + thickness + side_front_finger_step*cury; float finger_end_y = finger_start_y + side_front_finger_step/2.0; fprintf(gfile, "G01 X%.2f Y%.2f\n", side_outline[1][X]+toolsize, finger_start_y-toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", side_outline[1][X]+thickness+toolsize, finger_start_y-toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", side_outline[1][X]+thickness+toolsize, finger_end_y+toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", side_outline[1][X]+toolsize, finger_end_y+toolsize); } fprintf(gfile, "G01 X%.2f Y%.2f\n", side_outline[1][X]+toolsize, side_origin_y+cell_length+(do_covers?cover_thickness:0.0)+toolsize); UNCUT(); delay(gfile, delay_per_cell*3); CUT(); // Top horizontal for(int curx = x-1; curx >= 0; curx--) { float finger_end_x = side_origin_x + wallgaps[0] + x_step*curx + cell/2.0 - finger_size_x/2.0; float finger_start_x = finger_end_x + finger_size_x; fprintf(gfile, "G01 X%.2f Y%.2f\n", finger_start_x-toolsize, side_origin_y+cell_length+(do_covers?cover_thickness:0.0)+toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", finger_start_x-toolsize, side_origin_y+cell_length-thickness+toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", finger_end_x+toolsize, side_origin_y+cell_length-thickness+toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", finger_end_x+toolsize, side_origin_y+cell_length+(do_covers?cover_thickness:0.0)+toolsize); } fprintf(gfile, "G01 X%.2f Y%.2f\n", side_outline[0][X]-toolsize, side_origin_y+cell_length+(do_covers?cover_thickness:0.0)+toolsize); UNCUT(); delay(gfile, delay_per_cell*x); CUT_PWR(vertical_power_mult); // Left vertical for(int cury = num_side_front_fingers-1; cury >= 0; cury--) { float finger_end_y = side_origin_y + thickness + side_front_finger_step*cury; float finger_start_y = finger_end_y + side_front_finger_step/2.0; fprintf(gfile, "G01 X%.2f Y%.2f\n", side_outline[0][X]-toolsize, finger_start_y+toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", side_outline[0][X]-thickness-toolsize, finger_start_y+toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", side_outline[0][X]-thickness-toolsize, finger_end_y-toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", side_outline[0][X]-toolsize, finger_end_y-toolsize); } fprintf(gfile, "G01 X%.2f Y%.2f\n", side_outline[0][X]-toolsize, side_origin_y-(do_covers?cover_thickness:0.0)-toolsize); UNCUT(); delay(gfile, delay_per_cell*3); if(do_side_bonusholes) { for(int curx = 0; curx < x; curx++) { int y = ys[curx%2]; float y_offset = (curx%2)?(y_step/2.0):(0.0); for(int cury = 0; cury < 2; cury++) { if(curx%2) { float bonushole_midx = side_origin_x + wallgaps[0] + x_step*curx + cell/2.0; float bonushole_midy = cury? (side_origin_y+cell_length-thickness-side_bonushole_dist): (side_origin_y+thickness+side_bonushole_dist); float bonushole_startx = bonushole_midx - side_bonushole_size/2.0; float bonushole_startx_trimmed = bonushole_startx + toolsize; float bonushole_starty_trimmed = bonushole_midy; float bonushole_offset_i = side_bonushole_size/2.0 - toolsize; float bonushole_offset_j = 0.0; fprintf(gfile, "G00 X%.2f Y%.2f\n", bonushole_startx_trimmed, bonushole_starty_trimmed); if(do_side_bonusholes == 2) { CUT_MARK(); } else { CUT(); } fprintf(gfile, "G02 X%.2f Y%.2f I%.2f J%.2f\n", bonushole_startx_trimmed, bonushole_starty_trimmed, bonushole_offset_i, bonushole_offset_j); UNCUT(); if(do_side_bonusholes != 2) { delay(gfile, delay_per_cell*0.25); } } } } } // end do_side_bonusholes } // end do side panel // Do front panel if(do_fronts) { // Cut ventilation holes float fhole_width = (cell+cellgap) - front_mid_width; float fhole_hstep = (cell_length - 2.0*thickness - 2.0*front_y_frame_width)/((float)num_front_holes_y); float fhole_height = fhole_hstep-front_mid_width; for(int cury = 0; cury < ys[0]; cury++) { float fhole_start_y = origin_y + wallgaps[1] + y_step*cury + cell/2.0 - fhole_width/2.0; if(ys[0] == ys[1]) fhole_start_y += (cell+cellgap)/4.0; float fhole_end_y = fhole_start_y + fhole_width; for(int curx = 0; curx < num_front_holes_y; curx++) { float fhole_start_x = front_origin_x + thickness + front_y_frame_width + fhole_hstep*curx + front_mid_width/2.0; float fhole_end_x = fhole_start_x + fhole_height; fprintf(gfile, "G00 X%.2f Y%.2f\n", fhole_start_x+toolsize, fhole_start_y+toolsize); CUT(); fprintf(gfile, "G01 X%.2f Y%.2f\n", fhole_end_x-toolsize, fhole_start_y+toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", fhole_end_x-toolsize, fhole_end_y-toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", fhole_start_x+toolsize, fhole_end_y-toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", fhole_start_x+toolsize, fhole_start_y+toolsize); UNCUT(); delay(gfile, delay_per_cell); } } // Left vertical (joins bottom main cell board) fprintf(gfile, "G00 X%.2f Y%.2f\n", front_origin_x-toolsize, outline[3][Y]+thickness+toolsize); CUT_PWR(vertical_power_mult); for(int cury = ys[0]-1; cury >=0; cury--) { float finger_end_y = origin_y + wallgaps[1] + y_step*cury + cell/2.0 - finger_size_y/2.0; float finger_start_y = finger_end_y + finger_size_y; fprintf(gfile, "G01 X%.2f Y%.2f\n", front_origin_x-toolsize, finger_start_y-toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", front_origin_x+thickness-toolsize, finger_start_y-toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", front_origin_x+thickness-toolsize, finger_end_y+toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", front_origin_x-toolsize, finger_end_y+toolsize); } fprintf(gfile, "G01 X%.2f Y%.2f\n", front_origin_x-toolsize, outline[0][Y]-thickness-toolsize); UNCUT(); delay(gfile, delay_per_cell*ys[0]); CUT(); // Bottom horizontal (joins to a side board) for(int curx = 0; curx < num_side_front_fingers; curx++) { float finger_start_x = front_origin_x + thickness + side_front_finger_step*curx; float finger_end_x = finger_start_x + side_front_finger_step/2.0; fprintf(gfile, "G01 X%.2f Y%.2f\n", finger_start_x+toolsize, outline[0][Y]-thickness-toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", finger_start_x+toolsize, outline[0][Y]-toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", finger_end_x-toolsize, outline[0][Y]-toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", finger_end_x-toolsize, outline[0][Y]-thickness-toolsize); } fprintf(gfile, "G01 X%.2f Y%.2f\n", front_origin_x+cell_length+toolsize, outline[0][Y]-thickness-toolsize); UNCUT(); delay(gfile, delay_per_cell*3); CUT_PWR(vertical_power_mult); // Right vertical (joins to top main cell board) for(int cury = 0; cury < ys[0]; cury++) { float finger_start_y = origin_y + wallgaps[1] + y_step*cury + cell/2.0 - finger_size_y/2.0; float finger_end_y = finger_start_y + finger_size_y; fprintf(gfile, "G01 X%.2f Y%.2f\n", front_origin_x+cell_length+toolsize, finger_start_y+toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", front_origin_x+cell_length-thickness+toolsize, finger_start_y+toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", front_origin_x+cell_length-thickness+toolsize, finger_end_y-toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", front_origin_x+cell_length+toolsize, finger_end_y-toolsize); } fprintf(gfile, "G01 X%.2f Y%.2f\n", front_origin_x+cell_length+toolsize, outline[2][Y]+thickness+toolsize); UNCUT(); delay(gfile, delay_per_cell*ys[0]); CUT(); // Top horizontal (joins to another side board) for(int curx = num_side_front_fingers-1; curx >= 0; curx--) { float finger_end_x = front_origin_x + thickness + side_front_finger_step*curx; float finger_start_x = finger_end_x + side_front_finger_step/2.0; fprintf(gfile, "G01 X%.2f Y%.2f\n", finger_start_x-toolsize, outline[2][Y]+thickness+toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", finger_start_x-toolsize, outline[2][Y]+toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", finger_end_x+toolsize, outline[2][Y]+toolsize); fprintf(gfile, "G01 X%.2f Y%.2f\n", finger_end_x+toolsize, outline[2][Y]+thickness+toolsize); } fprintf(gfile, "G01 X%.2f Y%.2f\n", front_origin_x-toolsize, outline[3][Y]+thickness+toolsize); UNCUT(); // delay(gfile, delay_per_cell*3); } fprintf(gfile, "G00 X%.2f Y%.2f\n", origin_x, origin_y); delay(gfile, 15.0); fprintf(gfile, "M2\n%%\n"); fclose(gfile); if(do_covers) { fprintf(coverfile, "G00 X%.2f Y%.2f\n", cover_origin_x, cover_origin_y); delay(coverfile, 15.0); fprintf(coverfile, "M2\n%%\n"); fclose(coverfile); } return 0; }