static void PathOpsSimplifyFailTest(skiatest::Reporter* reporter) {
    for (int index = 0; index < (int) (13 * nonFinitePtsCount * finitePtsCount); ++index) {
        SkPath path;
        int i = (int) (index % nonFinitePtsCount);
        int f = (int) (index % finitePtsCount);
        int g = (int) ((f + 1) % finitePtsCount);
        switch (index % 13) {
            case 0: path.lineTo(nonFinitePts[i]); break;
            case 1: path.quadTo(nonFinitePts[i], nonFinitePts[i]); break;
            case 2: path.quadTo(nonFinitePts[i], finitePts[f]); break;
            case 3: path.quadTo(finitePts[f], nonFinitePts[i]); break;
            case 4: path.cubicTo(nonFinitePts[i], finitePts[f], finitePts[f]); break;
            case 5: path.cubicTo(finitePts[f], nonFinitePts[i], finitePts[f]); break;
            case 6: path.cubicTo(finitePts[f], finitePts[f], nonFinitePts[i]); break;
            case 7: path.cubicTo(nonFinitePts[i], nonFinitePts[i], finitePts[f]); break;
            case 8: path.cubicTo(nonFinitePts[i], finitePts[f], nonFinitePts[i]); break;
            case 9: path.cubicTo(finitePts[f], nonFinitePts[i], nonFinitePts[i]); break;
            case 10: path.cubicTo(nonFinitePts[i], nonFinitePts[i], nonFinitePts[i]); break;
            case 11: path.cubicTo(nonFinitePts[i], finitePts[f], finitePts[g]); break;
            case 12: path.moveTo(nonFinitePts[i]); break;
        }
        SkPath result;
        result.setFillType(SkPath::kWinding_FillType);
        bool success = Simplify(path, &result);
        REPORTER_ASSERT(reporter, !success);
        REPORTER_ASSERT(reporter, result.isEmpty());
        REPORTER_ASSERT(reporter, result.getFillType() == SkPath::kWinding_FillType);
        reporter->bumpTestCount();
    }
    if (sizeof(reporter) == 4) {
        return;
    }
    for (int index = 0; index < (int) (11 * finitePtsCount); ++index) {
        SkPath path;
        int f = (int) (index % finitePtsCount);
        int g = (int) ((f + 1) % finitePtsCount);
        switch (index % 11) {
            case 0: path.lineTo(finitePts[f]); break;
            case 1: path.quadTo(finitePts[f], finitePts[f]); break;
            case 2: path.quadTo(finitePts[f], finitePts[g]); break;
            case 3: path.quadTo(finitePts[g], finitePts[f]); break;
            case 4: path.cubicTo(finitePts[f], finitePts[f], finitePts[f]); break;
            case 5: path.cubicTo(finitePts[f], finitePts[f], finitePts[g]); break;
            case 6: path.cubicTo(finitePts[f], finitePts[g], finitePts[f]); break;
            case 7: path.cubicTo(finitePts[f], finitePts[g], finitePts[g]); break;
            case 8: path.cubicTo(finitePts[g], finitePts[f], finitePts[f]); break;
            case 9: path.cubicTo(finitePts[g], finitePts[f], finitePts[g]); break;
            case 10: path.moveTo(finitePts[f]); break;
        }
        SkPath result;
        result.setFillType(SkPath::kWinding_FillType);
        bool success = Simplify(path, &result);
        REPORTER_ASSERT(reporter, success);
        REPORTER_ASSERT(reporter, result.getFillType() != SkPath::kWinding_FillType);
        reporter->bumpTestCount();
    }
}
Exemple #2
0
ZCC_Expression *ZCCCompiler::SimplifyFunctionCall(ZCC_ExprFuncCall *callop)
{
	ZCC_FuncParm *parm;
	int parmcount = 0;

	callop->Function = Simplify(callop->Function);
	parm = callop->Parameters;
	if (parm != NULL)
	{
		do
		{
			parmcount++;
			assert(parm->NodeType == AST_FuncParm);
			parm->Value = Simplify(parm->Value);
			parm = static_cast<ZCC_FuncParm *>(parm->SiblingNext);
		}
		while (parm != callop->Parameters);
	}
	// If the left side is a type ref, then this is actually a cast
	// and not a function call.
	if (callop->Function->Operation == PEX_TypeRef)
	{
		if (parmcount != 1)
		{
			Message(callop, ERR_cast_needs_1_parm, "Type cast requires one parameter");
			callop->ToErrorNode();
		}
		else
		{
			PType *dest = static_cast<ZCC_ExprTypeRef *>(callop->Function)->RefType;
			const PType::Conversion *route[CONVERSION_ROUTE_SIZE];
			int routelen = parm->Value->Type->FindConversion(dest, route, countof(route));
			if (routelen < 0)
			{
				// FIXME: Need real type names
				Message(callop, ERR_cast_not_possible, "Cannot convert type 1 to type 2");
				callop->ToErrorNode();
			}
			else
			{
				ZCC_Expression *val = ApplyConversion(parm->Value, route, routelen);
				assert(val->Type == dest);
				return val;
			}
		}
	}
	return callop;
}
Exemple #3
0
ZCC_Expression *ZCCCompiler::SimplifyMemberAccess(ZCC_ExprMemberAccess *dotop)
{
	dotop->Left = Simplify(dotop->Left);

	if (dotop->Left->Operation == PEX_TypeRef)
	{ // Type refs can be evaluated now.
		PType *ref = static_cast<ZCC_ExprTypeRef *>(dotop->Left)->RefType;
		PSymbol *sym = ref->Symbols.FindSymbol(dotop->Right, true);
		if (sym == NULL)
		{
			Message(dotop, ERR_not_a_member, "'%s' is not a valid member", FName(dotop->Right).GetChars());
		}
		else
		{
			ZCC_Expression *expr = NodeFromSymbol(sym, dotop);
			if (expr == NULL)
			{
				Message(dotop, ERR_bad_symbol, "Unhandled symbol type encountered");
			}
			else
			{
				return expr;
			}
		}
	}
	return dotop;
}
Exemple #4
0
struct fraction DivF(struct fraction f1, struct fraction f2)
{
  struct fraction result;
  result.numerator = f1.numerator*f2.denominator;
  result.denominator = f1.denominator*f2.numerator;
  return Simplify(result);
}
		/**
				This constructor takes as argument a rational number and convert it into a fractional number. 
				*/
		inline Fraction::Fraction(double p_rational, bool p_simplify) : m_simplify(p_simplify)
		{
			if (p_rational < 10)
			{
				p_rational *= HIGHEST_MULTIPLE_OF_TEN;
			}
			else
			{
				int i = 10;

				while (i < HIGHEST_MULTIPLE_OF_TEN)
				{
					if (p_rational >= i && p_rational < i * 10)
					{
						p_rational *= HIGHEST_MULTIPLE_OF_TEN / i;
						break;
					}

					i *= 10;
				}
			}

			m_numerator = static_cast<int>(p_rational);
			m_denominator = HIGHEST_MULTIPLE_OF_TEN;

			Simplify();
		}
Exemple #6
0
static bool inner_simplify(skiatest::Reporter* reporter, const SkPath& path, const char* filename,
        bool checkFail) {
#if 0 && DEBUG_SHOW_TEST_NAME
    showPathData(path);
#endif
    SkPath out;
    if (!Simplify(path, &out)) {
        SkDebugf("%s did not expect %s failure\n", __FUNCTION__, filename);
        REPORTER_ASSERT(reporter, 0);
        return false;
    }
    SkBitmap bitmap;
    int errors = comparePaths(reporter, filename, path, out, bitmap);
    if (!checkFail) {
        if (!errors) {
            SkDebugf("%s failing test %s now succeeds\n", __FUNCTION__, filename);
            REPORTER_ASSERT(reporter, 0);
            return false;
        }
    } else if (errors) {
        REPORTER_ASSERT(reporter, 0);
    }
    reporter->bumpTestCount();
    return errors == 0;
}
Rational Rational::operator+(string W)
{
	int num, denom, rnum, rdenom, newNum, newDenom;
	
	//Parse string W
	stringstream ss(W);
	ss>>num;
	ss.ignore();
	ss>>denom;

	//Parse string inWords
	stringstream sr(inWords);
	sr>>rnum;
	sr.ignore();
	sr>>rdenom;

	//Add nums and denoms
	newNum = rnum+num;
	newDenom = rdenom+denom;

	//Create temps and simplify
	int& tempNum=newNum;
	int& tempDenom=newDenom;
	Simplify(tempNum, tempDenom);

	
	//Put it back into a string
	stringstream s2;
	s2<<newNum<<"/"<<newDenom;
	inWords=s2.str();

	return *this;
}
Exemple #8
0
bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& state,
                  const char* pathStr) {
    SkPath::FillType fillType = useXor ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType;
    path.setFillType(fillType);
    state.fReporter->bumpTestCount();
    if (!Simplify(path, &out)) {
        SkDebugf("%s did not expect failure\n", __FUNCTION__);
        REPORTER_ASSERT(state.fReporter, 0);
        return false;
    }
    if (!state.fReporter->verbose()) {
        return true;
    }
    int result = comparePaths(state.fReporter, nullptr, path, out, *state.fBitmap);
    if (result) {
        SkAutoMutexAcquire autoM(simplifyDebugOut);
        char temp[8192];
        sk_bzero(temp, sizeof(temp));
        SkMemoryWStream stream(temp, sizeof(temp));
        const char* pathPrefix = nullptr;
        const char* nameSuffix = nullptr;
        if (fillType == SkPath::kEvenOdd_FillType) {
            pathPrefix = "    path.setFillType(SkPath::kEvenOdd_FillType);\n";
            nameSuffix = "x";
        }
        const char testFunction[] = "testSimplify(reporter, path);";
        outputToStream(pathStr, pathPrefix, nameSuffix, testFunction, false, stream);
        SkDebugf("%s", temp);
        REPORTER_ASSERT(state.fReporter, 0);
    }
    state.fReporter->bumpTestCount();
    return result == 0;
}
Exemple #9
0
bool complex::InsertCube(block* b)
{
   bitcode* bc=new bitcode(BC(b).Bits());
   bc->SetAs(BC(b));
   
   cubes.Insert(*bc,b);
   if (previous_cube==NULL)
     {
	previous_cube=new bitcode(cube_bits);
	previous_cube->SetAs(bc);
	delete bc;
        return true;	
     }

//   assert(previous_cube->Bits()==cube_bits);
   
   node* simplifiable_node;
   block* simplifiable_block;
   int levels=Ancestor(bc,previous_cube);  
   while (levels>=DIM)
     {
	for (int j=0; j<DIM; ++j)
	   (*previous_cube)++;
	levels-=DIM;
        simplifiable_node=cubes.Find(*previous_cube);
	simplifiable_block=Merge(simplifiable_node);
	Simplify(simplifiable_block);
      }
   
   delete previous_cube;
   previous_cube=new bitcode(cube_bits);
   previous_cube->SetAs(*bc);
   delete bc;
   return true;
}
Exemple #10
0
static void failOne(skiatest::Reporter* reporter, int index) {
    SkPath path;
    int i = (int) (index % nonFinitePtsCount);
    int f = (int) (index % finitePtsCount);
    int g = (int) ((f + 1) % finitePtsCount);
    switch (index % 13) {
        case 0: path.lineTo(nonFinitePts[i]); break;
        case 1: path.quadTo(nonFinitePts[i], nonFinitePts[i]); break;
        case 2: path.quadTo(nonFinitePts[i], finitePts[f]); break;
        case 3: path.quadTo(finitePts[f], nonFinitePts[i]); break;
        case 4: path.cubicTo(nonFinitePts[i], finitePts[f], finitePts[f]); break;
        case 5: path.cubicTo(finitePts[f], nonFinitePts[i], finitePts[f]); break;
        case 6: path.cubicTo(finitePts[f], finitePts[f], nonFinitePts[i]); break;
        case 7: path.cubicTo(nonFinitePts[i], nonFinitePts[i], finitePts[f]); break;
        case 8: path.cubicTo(nonFinitePts[i], finitePts[f], nonFinitePts[i]); break;
        case 9: path.cubicTo(finitePts[f], nonFinitePts[i], nonFinitePts[i]); break;
        case 10: path.cubicTo(nonFinitePts[i], nonFinitePts[i], nonFinitePts[i]); break;
        case 11: path.cubicTo(nonFinitePts[i], finitePts[f], finitePts[g]); break;
        case 12: path.moveTo(nonFinitePts[i]); break;
    }
    SkPath result;
    result.setFillType(SkPath::kWinding_FillType);
    bool success = Simplify(path, &result);
    REPORTER_ASSERT(reporter, !success);
    REPORTER_ASSERT(reporter, result.isEmpty());
    REPORTER_ASSERT(reporter, result.getFillType() == SkPath::kWinding_FillType);
    reporter->bumpTestCount();
}
Exemple #11
0
struct fraction CreateFraction(short n,short d)
/*     short n,d;*/
{
  struct fraction result;
  result.numerator = n;
  result.denominator = d;
  return Simplify(result);
}
Exemple #12
0
ZCC_Expression *ZCCCompiler::SimplifyBinary(ZCC_ExprBinary *binary)
{
	binary->Left = Simplify(binary->Left);
	binary->Right = Simplify(binary->Right);
	ZCC_OpProto *op = PromoteBinary(binary->Operation, binary->Left, binary->Right);
	if (op == NULL)
	{
		binary->Type = TypeError;
	}
	else if (binary->Left->Operation == PEX_ConstValue &&
		binary->Right->Operation == PEX_ConstValue)
	{
		return op->EvalConst2(static_cast<ZCC_ExprConstant *>(binary->Left),
							  static_cast<ZCC_ExprConstant *>(binary->Right), AST.Strings);
	}
	return binary;
}
Exemple #13
0
void CParser::ParseExpression() 
{
    Clear();
    SkipSpaces();
    ProceedUnary();

    while (pos < sz) {
        SkipSpaces();
        char curChar = src[pos];

        if (IsControl(curChar)) {
            break;
        } else if (IsDigit(curChar)) {
            ParseNumber();
        } else if (curChar == '(') {
            ops.push_front(0); // 0 instead '('
            ++pos;
            ProceedUnary();
        } else if (curChar == ')') {
            while (!ops.empty() && ops.front()!=0) {
                Simplify();
            }
            ops.pop_front();
            ++pos;
        } else if (OpPriority(curChar) >= 0) {
            ProceedOperator();
        } else { 
            ParseName();
        }
    } // !while (pos < lim) 

    while(st.size() > 1 || !ops.empty()) {
        Simplify();
    } // 
    if (st.size() != 1 || !ops.empty()) {
        Clear();
        throw AST::ASTException("Miss parameters");
    }

    _pProgram->AddExpression(st.front());
    st.pop_front();
} 
//Postfix operator
Rational Rational::operator++(int)
{
	//Create temps
	int& tempNum=numerator;
	int& tempDenom=denominator;
	
	//Increment
	numerator++;
	//Simplify
	Simplify(tempNum, tempDenom);
	
	return *this;	
}
		inline Fraction::Fraction(int p_numerator, int p_denominator, bool p_simplify)
			: m_numerator(p_numerator),
			  m_denominator(p_denominator),
			  m_simplify(p_simplify)
		{
			if (m_denominator < 0)
			{
				m_numerator *= -1;
				m_denominator *= -1;
			}

			Simplify();
		}
Rational Rational::operator+(int N)
{
	//Convert int to a fraction over denom
	N*=denominator;
	numerator+=N;

	//Create temps and simplify
	int& tempNum=numerator;
	int& tempDenom=denominator;

	Simplify(tempNum, tempDenom);
	
	return *this;
}
Exemple #17
0
ZCC_Expression *ZCCCompiler::SimplifyUnary(ZCC_ExprUnary *unary)
{
	unary->Operand = Simplify(unary->Operand);
	ZCC_OpProto *op = PromoteUnary(unary->Operation, unary->Operand);
	if (op == NULL)
	{ // Oh, poo!
		unary->Type = TypeError;
	}
	else if (unary->Operand->Operation == PEX_ConstValue)
	{
		return op->EvalConst1(static_cast<ZCC_ExprConstant *>(unary->Operand));
	}
	return unary;
}
Exemple #18
0
/*-------------------------------------------------------------------------*
 * PL_FD_BOOL_META_3                                                       *
 *                                                                         *
 *-------------------------------------------------------------------------*/
Bool
Pl_Fd_Bool_Meta_3(WamWord le_word, WamWord re_word, WamWord op_word)
{
  WamWord word, tag_mask;
  WamWord *adr, *fdv_adr;
  WamWord *exp;
  int op;
  static WamWord h[3];		/* static to avoid high address */


  DEREF(op_word, word, tag_mask);
  op = UnTag_INT(op_word);

  h[0] = bool_tbl[op];		/* also works for NOT/1 */
  h[1] = le_word;
  h[2] = re_word;

  sp = stack;
  vars_sp = vars_tbl;

  exp = Simplify(1, Tag_STC(h));

#ifdef DEBUG
  Display_Stack(exp);
  DBGPRINTF("\n");
#endif

  if (!Load_Bool_Into_Word(exp, 1, NULL))
    return FALSE;

  while (--vars_sp >= vars_tbl)
    if (*vars_sp-- == 0)	/* bool var */
      {
	if (!Pl_Fd_Check_For_Bool_Var(*vars_sp))
	  return FALSE;
      }
    else			/* FD var */
      {
	DEREF(*vars_sp, word, tag_mask);
	if (tag_mask == TAG_REF_MASK)
	  {
	    adr = UnTag_REF(word);
	    fdv_adr = Pl_Fd_New_Variable();
	    Bind_UV(adr, Tag_REF(fdv_adr));
	  }
      }


  return TRUE;
}
Exemple #19
0
struct fraction SubF(struct fraction f1, struct fraction f2)
{
  struct fraction result;
  if (f1.denominator==f2.denominator) {
    result.denominator = f1.denominator;
    result.numerator = f1.numerator-f2.numerator;
    return result;
  }
  else {
    result.denominator = f1.denominator*f2.denominator;
    result.numerator = f1.numerator*f2.denominator-f2.numerator*f1.denominator;
    return Simplify(result);
  }
}
//Overloaded Arithmetic Binary Operators
Rational Rational::operator+(const Rational &obj)
{
	//Add num and denom
	numerator+=obj.numerator;
	denominator+=obj.denominator;

	//Create temps and simplify
	int& tempNum=numerator;
	int& tempDenom=denominator;

	Simplify(tempNum, tempDenom);
	
	return *this;			
}
Exemple #21
0
void complex::FinalCube()
{
   int levels=previous_cube->Bits();
   node*  simplifiable_node;
   block* simplifiable_block;
   while (levels>=DIM)
     {
	for (int j=0; j<DIM; ++j)
	  (*previous_cube)++;
	levels-=DIM;
        simplifiable_node=cubes.Find(*previous_cube);
	simplifiable_block=Merge(simplifiable_node);
	Simplify(simplifiable_block);
      }
   delete previous_cube;
}
Exemple #22
0
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Peephole::DoOneIteration(Function* function) {
    bool changed = false;
    int position = 0;
    
    while(position < worklist_.Count()) {
        // Get the instruction at the current position and try to simplify it.
        Instruction* instr = worklist_[position++];

        // Branching instructions don't have any resulting operand,
        // and report a simplification by returning 'true'.
        if(instr->IsBranching()) {
            changed |= ProcessBranching(instr);
            continue;
        }

        // For all other kinds of instructions.
        // If the result is 'nullptr' nothing could be simplified.
        auto result = Simplify(instr);
        if(result == nullptr) continue;

        if(result->IsUndefinedConstant()) {
            if(HandleUndefinedResult(instr)) {
                // The instruction should not be considered below.
                continue;
            }
        }

        // Replace the previous result operand with the new one
        // in all instructions that use it as a source operand.
        instr->GetDestinationOp()->ReplaceWith(result);
        InstructionSimplified(instr, result);
        
        HandleSpecialCases(instr, result);
        changed = true;
#if 1
		IRPrinter(function).Dump();
#endif
    }
	
	// Some instructions may be dead now; delete them here, so that
	// the next iteration doesn't consider them anymore. Note that 
    // this is necessary, else we would enter an infinite loop simplifying
    // the same instructions again and again...
	if(changed) DeleteDeadInstructions(function);
    return changed;
}
bool testSimplify(skiatest::Reporter* reporter, const SkPath& path, const char* filename) {
#if DEBUG_SHOW_TEST_NAME
    showPathData(path);
#endif
    SkPath out;
    if (!Simplify(path, &out)) {
        SkDebugf("%s did not expect failure\n", __FUNCTION__);
        REPORTER_ASSERT(reporter, 0);
        return false;
    }
    SkBitmap bitmap;
    int result = comparePaths(reporter, filename, path, out, bitmap);
    if (result && gPathStrAssert) {
        REPORTER_ASSERT(reporter, 0);
    }
    reporter->bumpTestCount();
    return result == 0;
}
Exemple #24
0
PSymbolConst *ZCCCompiler::CompileConstant(ZCC_ConstantDef *def)
{
	assert(def->Symbol == NULL);

	def->Symbol = DEFINING_CONST;	// avoid recursion
	ZCC_Expression *val = Simplify(def->Value);
	def->Value = val;
	PSymbolConst *sym = NULL;
	if (val->NodeType == AST_ExprConstant)
	{
		ZCC_ExprConstant *cval = static_cast<ZCC_ExprConstant *>(val);
		if (cval->Type == TypeString)
		{
			sym = new PSymbolConstString(def->Name, *(cval->StringVal));
		}
		else if (cval->Type->IsA(RUNTIME_CLASS(PInt)))
		{
			sym = new PSymbolConstNumeric(def->Name, cval->Type, cval->IntVal);
		}
		else if (cval->Type->IsA(RUNTIME_CLASS(PFloat)))
		{
			sym = new PSymbolConstNumeric(def->Name, cval->Type, cval->DoubleVal);
		}
		else
		{
			Message(def->Value, ERR_bad_const_def_type, "Bad type for constant definiton");
		}
	}
	else
	{
		Message(def->Value, ERR_const_def_not_constant, "Constant definition requires a constant value");
	}
	if (sym == NULL)
	{
		// Create a dummy constant so we don't make any undefined value warnings.
		sym = new PSymbolConstNumeric(def->Name, TypeError, 0);
	}
	def->Symbol = sym;
	PSymbol *addsym = Symbols.AddSymbol(sym);
	assert(NULL != addsym && "Symbol was redefined (but we shouldn't have even had the chance to do so)");
	return sym;
}
Exemple #25
0
  // This function will take an SExpression that is wrapped in as many nulls as possible, and return the minimum s expression.
  // If it's not an s expression, it will return the original value.
  // For example: ((5 null) null) will return 5, but (5 3) will return (5 3)
  ValuePtr Value::Simplify(BindingPtr binding, ValuePtr value)
  {
    auto sexp = dynamic_pointer_cast<SExp>(value);
    if (sexp) {
      if (sexp->Left() && !sexp->Right()) {
        value = Simplify(binding, sexp->Left());
      }
    }

    while (true) {
      auto result = binding->Interpret(value);
      if (result.Error()) return value;

      // Check to see if we got the same result back
      // If so, 
      if (value == result.Value()) return value;

      value = result.Value();
    }
  }
main()
{
PATH path;
NODE root = {
0, /* 花费下界 */
{{{I, 1, 2, 7, 5}, /* 花费矩阵 */
  {1, I, 4, 4, 3},
  {2, 4, I, 1, 2},
  {7, 4, 1, I, 3},
  {5, 3, 2, 3, I}}, 5}, /* 城市数目 */
{{0}, 0}, /* 经历过的路径 */
NULL, NULL /* 左枝与右枝 */
};

/* 归约,建立根结点 */
root.bound += Simplify(&root.matrix);
/* 进入搜索循环 */
path = BABA(root);
ShowPath(path, root.matrix);

}
Exemple #27
0
void CParser::ProceedOperator() 
{
    char curChar = src[pos];

    AST::BasicCallExpr* expr = new AST::CallOperatorExpr(AST::GetOperationType(curChar));
    ParserVisitor curWalk;
    expr->Accept(curWalk);

    while(!ops.empty() && ops.front() != 0) {
        ParserVisitor wl;
        ops.front()->Accept(wl);
        if (wl.priority < curWalk.priority + curWalk.assoc) {
            break;
        }
        Simplify();
    }
    ops.push_front(expr);
    ++pos;
    if (curChar == '=') {
        ProceedUnary();
    }
}
/*
* 算法主搜索函数,Branch-And-Bound Algorithm Search
*            root 是当前的根结点,已归约,数据完善
*/
PATH BABA(NODE root)
{
    int i;
    static int minDist = INFINITY;
    static PATH minPath;
    EDGE selectedEdge;
    NODE *left, *right;

    puts("Current Root:\n------------");
    ShowMatrix(root.matrix);
    printf("Root Bound:%d\n", root.bound);

    /* 如果当前矩阵大小为2,说明还有两条边没有选,而这两条边必定只能有一种组合,
    * 才能构成整体回路,所以事实上所有路线已经确定。
    */
    if (MatrixSize(root.matrix, root.path) == 2) {
        if (root.bound < minDist) {
            minDist = root.bound;
            minPath = MendPath(root.path, root.matrix);
            getch();
            return (minPath);
        }
    }
    /* 根据左下界尽量大的原则选分枝边 */
    selectedEdge = SelectBestEdge(root.matrix);
    printf("Selected Edge:(%d, %d)\n", selectedEdge.head + 1, selectedEdge.tail + 1);

    /* 建立左右分枝结点 */
    left = (NODE *)malloc(sizeof(NODE));
    right = (NODE *)malloc(sizeof(NODE));
    if (left == NULL || right == NULL) {
        fprintf(stderr,"Error malloc.\n");
        exit(-1);
    }
    /* 初始化左右分枝结点 */
    left->bound = root.bound; /* 继承父结点的下界 */
    left->matrix = LeftNode(root.matrix, selectedEdge); /* 删掉分枝边 */
    left->path = root.path; /* 继承父结点的路径,没有增加新边 */
    left->left = NULL;
    left->right = NULL;

    right->bound = root.bound;
    right->matrix = RightNode(root.matrix, selectedEdge, root.path);/* 删除行列和回路边 */
    right->path = AddEdge(selectedEdge, root.path); /* 加入所选边 */
    right->left = NULL;
    right->right = NULL;

    /* 归约左右分枝结点 */
    left->bound += Simplify(&left->matrix);
    right->bound += Simplify(&right->matrix);

    /* 链接到根 */
    root.left = left;
    root.right = right;

    /* 显示到监视器 */
    puts("Right Branch:\n------------");
    ShowMatrix(right->matrix);
    puts("Left Branch:\n-----------");
    ShowMatrix(left->matrix);

    /* 如果右结点下界小于当前最佳答案,继续分枝搜索 */
    if (right->bound < minDist) {
        BABA(*right);
    }
    /* 否则不搜索,因为这条枝已经不可能产生更佳路线 */
    else {
        printf("Current minDist is %d, ", minDist);
        printf("Right Branch's Bound(= %d).\n", right->bound);
        printf("This branch is dead.\n");
    }

    /* 如果右结点下界小于当前最佳答案,继续分枝搜索 */
    if (left->bound < minDist) {
        BABA(*left);
    }
    /* 否则不搜索,因为这条枝已经不可能产生更佳路线 */
    else {
        printf("Current minDist is %d, ", minDist);
        printf("Left Branch's Bound(= %d).\n", left->bound);
        printf("This branch is dead.\n");
    }

    printf("The best answer now is %d\n", minDist);
    return (minPath);
}
Exemple #29
0
void Tree::Eliminate(string species)	{

	Eliminate(mRoot, species);	
	Simplify();
}
Exemple #30
0
void Tree::Eliminate(int label)	{

	Eliminate(mRoot, label);
	Simplify();
}