private string _generalLogicResult(UBasCov2 BasCov) { try{ var BaseSetLst = BasCov.BaseSetLst; //BaseSet list var CoverSetLst = BasCov.CoverSetLst; //CoverSet list Bit81 Q = new Bit81(); foreach (var P in CoverSetLst) { Q |= P.rcnBit.CompressToHitCells(); } foreach (var UC in Q.IEGetRC().Select(rc => pBDL[rc])) { UC.SetCellBgColor(SolBkCr2); } for (int rc = 0; rc < 81; rc++) { int noB = BasCov.HB981.IsHit(rc); if (noB > 0) { pBDL[rc].SetNoBBgColor(noB, AttCr, SolBkCr); } } string msg = "\r BaseSet: "; string msgB = BaseSetLst.Aggregate("", (Q, P) => Q + $" {P.ToAppearance()}"); msg += msgB.ToString_SameHouseComp1(); msg += "\r CoverSet: "; string msgC = CoverSetLst.Aggregate("", (Q, P) => Q + $" {P.ToAppearance()}"); msg += msgC.ToString_SameHouseComp1(); string st = $"GeneralLogic size:{BasCov.sz} rank:{BasCov.rnk}"; Result = st; msg += $"\rChkBas:{ChkBas4}/{ChkBas1} ChkCov:{ChkCov2}/{ChkCov1}"; ResultLong = st + "\r " + msg; return(st + "\r" + msg); } catch (Exception ex) { WriteLine(ex.Message + "\r" + ex.StackTrace); } return(""); }
public IEnumerable <UBasCov2> IEGet_BaseSet(int sz, int rnk) //### BaseSet generator { if (GLK_UList_All.Count < sz * 2 + rnk) { yield break; } BSstatus2 = new BaseSet_Status2(sz, rnk); //Marking method // #1:Focus on the link(LK0) and follow the connecting links. A link of size(sz) is a candidate for BaseSet/CoverSet. // (This alone won't make it faster.) // #2:Select BaseSet from the candidates and check suitability. // Excludes generation G1 links. // #3:Also select the CoverSet from the candidates. At least common elements with baseset are required. // Light selection and aptitude testing. // Efficient evaluation of aptitude of baseSet is important. // #4:If there is no solution for the candidate starting from LK0, record LK0 in the invalid list. // #2':Select BaseSet from the candidates, exclude links in the invalid list. Bit324 invalidLink = new Bit324(); foreach (var LK0 in GLK_UList_All) //#1 LK0:First link { _chkX1 = false; _chkX2 = false; // if( SDK_Ctrl.UGPMan.stageNo>=12 && sz>=3 ){//&& rnk==1){ // _chkX1=false; _chkX2=true; // if(LK0.ToAppearance()=="r4#2"){ // WriteLine($"--->{LK0.ToAppearance()}"); // _chkX1=false; _chkX2=true; // } // } if (_chkX1) { WriteLine($"\r-1- baseset sz:{sz} rnk:{rnk} first:{LK0} -"); } GLK_UList_Marked.Clear(); QueueGlk.Clear(); rcnGenNo = new int[9, 81]; //### gen ### BasCovCandidates = new Bit324(); #region ----- marking for LK0 ------------------------- BasCovCandidates.BPSet(LK0.IDsq); //1)BC_Set 候補のリスト ## 初のリンク(LK0)の登録 LK0._gen = 1; foreach (var NDx in LK0.ConnectLinks) //LK0の他端ノードNDx に着目 { var(rc, no) = (NDx >> 4, NDx & 0xF); // (rc,no) <-- NDx rcnGenNo[no, rc] = 1; //### gen ### //NDXの世代<-1 set rcnGenNo QueueGlk.Enqueue(NDx); //Enqueue(ND1) if (_chkX1) { WriteLine($"@{_jkc_++} -1.5- Enqueue {rc.ToRCString()}#{no+1}"); } } //==== sz>=2 ==== while (QueueGlk.Count > 0) { var ND2 = QueueGlk.Dequeue(); var(rc, no) = (ND2 >> 4, ND2 & 0xF); int gen = rcnGenNo[no, rc]; //### gen ### if (_chkX1) { WriteLine($"@{_jkc_++} -2- Dequeue {rc.ToRCString()}#{no+1}-G{gen}"); } if (gen > sz) { continue; } foreach (var LKpair in GLK_connection[rc, no]) { var(no2, rc2) = (LKpair.no2, LKpair.rc2); var gen2 = rcnGenNo[no2, rc2]; //### gen ### UGLink_unit LKx = LKpair.objUGL; LKx._gen = gen; bool hit = BasCovCandidates.IsHit(LKx.IDsq); BasCovCandidates.BPSet(LKx.IDsq); //1)BC_Set 候補のリスト ビット表現で重複を回避 if (_chkX1) { string st3 = $"@{_jkc_++} -2.5- Link set {LKx} {(hit? "---": "New")}"; WriteLine(st3); } if (gen2 == 0) { rcnGenNo[no2, rc2] = gen + 1; //### gen ### if (gen < sz) { QueueGlk.Enqueue(LKpair.rcno); if (_chkX1) { string st3 = $"@{_jkc_++} -3- Enqueue {rc2.ToRCString()}#{no2+1}-G{gen+1}"; st3 += " " + LKx.ToString(); WriteLine(st3); } } } } } GLK_UList_Marked.Add(LK0); //First is LK0. BasCovCandidates.BPReset(LK0.IDsq); //reset LK0. foreach (var LX in BasCovCandidates.IEGet_Index().Select(kx => GLK_UList_All[kx])) { GLK_UList_Marked.Add(LX); } if (_chkX2) { string stBC = $"\r@{_jkc_++} BasCovCandidates({GLK_UList_Marked.Count}) :"; GLK_UList_Marked.ForEach(LK => stBC += $" {LK.ToAppearance(Gen:true)}"); //#### debug print WriteLine(stBC); } if (GLK_UList_Marked.Count < sz) { continue; } #endregion ----- marking ------------------------- #region ----- selecte ------------------------- var GLK_UList_Sel = new List <UGLink_unit>(); Combination cmbBas = new Combination(GLK_UList_Marked.Count, sz); string st, stw = ""; int nxt = int.MaxValue; //(skip function) string stT = ""; while (cmbBas.Successor(nxt)) { nxt = int.MaxValue; if (cmbBas.Index[0] != 0) { continue; //"The first link is fixed at 0!" } GeneralLogicGen2.ChkBas0++; //***** var usedLKIDsq = new Bit324(); var BaseSetLst = new List <UGLink_unit>(); var HB981 = new Bit981(); //BaseSet bitPattern long RCBN_frameA = 0; int[] RCB_frameB9 = new int[9]; foreach (var(kx, elementX) in cmbBas.IEGetIndex2()) { nxt = kx; var UGL = GLK_UList_Marked[elementX]; if (kx >= 1 && UGL._gen == 1) { goto LnxtCombination; // (#2) excludes generation G1 links. } if (invalidLink.IsHit(UGL.IDsq)) { goto LnxtCombination; // (#2')exclude links in the invalid list. } usedLKIDsq.BPSet(UGL.IDsq); BaseSetLst.Add(UGL); foreach (var P in UGL.ConnectLinks) { int no2 = P & 0xF, rc2 = P >> 4; if (HB981.IsHit(no2, rc2)) { goto LnxtCombination; // BaseSet links do not overlap. } HB981.BPSet(no2, rc2); } long RCBN_frameB = UGL.RCBN_frameB; //bit expression of [ UC.FreeB<<27 | 1<<(UC.b+18)) | 1<<(UC.c+9) | (1<<UC.r) ] int freebX = (int)(RCBN_frameB >> 27); foreach (var no in freebX.IEGet_BtoNo()) { RCB_frameB9[no] |= (int)(RCBN_frameB & 0x7FFFFFF); } RCBN_frameA |= UGL.RCBN_frameB; //bit expression of rcb if (kx > 0) { if (!Check_rcbnCondition(sz, rnk, elementX, RCBN_frameA)) { goto LnxtCombination; //(### extremely efficient) ???? } } } if (!Check_rcbnCondition(sz, rnk, 0, RCBN_frameA)) { goto LnxtCombination; //Evaluate BaseSet pattern. Extremely efficient. } if (sz >= 2) { BSstatus2.Prepare(usedLKIDsq, BaseSetLst, HB981, RCB_frameB9); //check 421 52.1sec //check 124 53.6sec if (!BSstatus2.Check_4()) { goto LnxtCombination; //Each element of LK0 is associated with the rest of the links. } if (!BSstatus2.Check_2()) { goto LnxtCombination; //Each cell(A) is in a position to link with other cells. } if (!BSstatus2.Check_1()) { goto LnxtCombination; //A and B are not linked by other link(C). } // if( !BSstatus2.Check_3() ) goto LnxtCombination; //There is a limit to the number of cells that have no links other than BaseSet. // Check_1 and _3 are almost the same evaluation. Check_3 is a heavy process. // if( !BSstatus2.Check_5() ) goto LnxtCombination; //XXX Almost no effect. Check_1-4 has been determined. } var BasCov = new UBasCov2(usedLKIDsq, BaseSetLst, HB981, sz); if (_chkX2) { string st2 = $"\r{_jkc_++} BaseSet:"; BaseSetLst.ForEach(P => st2 += " " + P.ToAppearance()); // WriteLine(st2); WriteLine($"Check_5---->{st2}"); //################### } yield return(BasCov); LnxtCombination: continue; } //*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==* invalidLink.BPSet(LK0.IDsq); //#4:If there is no solution for the candidate starting from LK0, record LK0 in the invalid list. //*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==* #endregion ----- selecte ------------------------- } yield break; }
//1..4....8.9.1...5.....63.....13.5.79..3...8..76.2.94.....75.....1...6.4.8....4..2 public IEnumerable <UBasCov2> IEGet_CoverSet(UBasCov2 BasCov, int rnk) //### CoverSet generator { if (GLK_UList_All == null) { yield break; } int sz = BasCov.sz; if (GLK_UList_Marked.Count < sz) { yield break; } var BaseSetLst = BasCov.BaseSetLst; var usedLKIDsq = BasCov.usedLKIDsq; //used links var HB981 = BasCov.HB981; //BaseSet bit expression int noBit = HB981.noBit; //bit expression of digits containing cell elements var UGLCovCandidates = new List <UGLink_unit>(); // UGLCovCandidates:candidate link #region Preparation(Create UGLCovCandidates) //Preparation: select candidates for CoverSet.(this process is extremely effective!) // 1)First select BaseSet, then select CoverSet to cover. // 2)CoverSet requirements: // .Exclude links that do not contain BaseSet elements // .Rank=0 includes two or more elements of BaseSet // .Rank>0 contains one or more elements of BaseSet Bit81 Bcmp = HB981.CompressToHitCells(); //x long RCBN_frameBex = BaseSetLst.Aggregate((long)0,(p,q)=>p|q.RCBN_frameBex); foreach (var P in GLK_UList_Marked) //Exclude Baseset links //x if((RCBN_frameBex&P.RCBN_frameB) == 0) continue; { if (BaseSetLst.Contains(P)) { continue; } if (P.type == 0) // 0:link { if ((noBit & (1 << P.no)) == 0) { continue; //Exclude links with digits not included in BaseSet. } int Bcount = (HB981._BQ[P.no] & P.rcBit81).BitCount(); //Bcount : Number of cells in common with BaseSet. if (Bcount == 0) { continue; //Link without common parts is excluded from candidate links. } if (rnk == 0 && Bcount < 2) { continue; //if rank=0, the CoverSet has two or more common items } UGLCovCandidates.Add(P); } else // 1:cell { if (noBit.BitCount() <= 1) { continue; //For links within a cell, the Coverset digits must be 2 or more. } if ((noBit & P.FreeB) == 0) { continue; //Exclude links with digits not included in BaseSet. } int B = noBit & P.FreeB; //Common digits of BaseSet and link if (B == 0) { continue; //Link without common parts are excluded from candidate links. } int rc = P.rc; //focused cell int kcc = 0, kccLim = (rnk == 0)? 2:1; foreach (var no in B.IEGet_BtoNo()) //no:Candidate digit of forcused cell. { if (!HB981._BQ[no].IsHit(rc)) { continue; //do not check if BaseSet does not include no. } if (++kcc >= kccLim) { UGLCovCandidates.Add(P); break; } //number of digits contained in BaseSet satisfies the condition(kccLim). } } } if (_chkX2) { string st2 = $"{_jkc_++} UGLCovCandidates for CoverSet:"; st2 = UGLCovCandidates.Aggregate(st2, (p, q) => p + " " + q.ToAppearance());//#### debug print WriteLine(st2); } #endregion Preparation(Create UGLCovCandidates) #region CoverSet generator if (UGLCovCandidates.Count < sz + rnk) { yield break; } Bit981 HC981 = new Bit981(); //CoverSet Bit981 Can981 = new Bit981(); //Items that break "Locked"(excludable candidates) Combination cmbCvr = new Combination(UGLCovCandidates.Count, sz + rnk); int nxt = int.MaxValue; while (cmbCvr.Successor(nxt)) //Combination one-element generator { ++GeneralLogicGen2.ChkCov1; HC981.Clear(); Array.ForEach(cmbCvr.Index, m => HC981 |= UGLCovCandidates[m].rcnBit); //CoverSet bit expression if (!(HB981 - HC981).IsZero()) { goto LNextSet; //BaseSet is covered? } Bit981 CsubB = HC981 - HB981; //CsubB:excludable candidates if (CsubB.IsZero()) { goto LNextSet; // is exist? } var CoverSetLst = new List <UGLink_unit>(); Array.ForEach(cmbCvr.Index, m => CoverSetLst.Add(UGLCovCandidates[m])); //CoverSet List if (rnk == 0) { Can981 = CsubB; } //(excludable candidates) else //if(rnk>0){ // rank=k // Consider the case of covering n-BaseSet with (n+k)-CoverSet. // In order to be an analysis algorithm, the following conditions must be satisfied. // 1:(n+k)-CoverSet completely covers n-BaseSet. // 2:(k+1) of the (n+k) links of CoverSet have elements in common which are not included in the n-BaseSet. // When these conditions are satisfied, the elements of the intersection of condition 2 are not true. { bool SolFound = false; Can981.Clear(); foreach (int n in CsubB.noBit.IEGet_BtoNo()) { foreach (int rc in CsubB._BQ[n].IEGetRC()) { int kc = CoverSetLst.Count(Q => Q.rcnBit.IsHit(n, rc)); if (kc == rnk + 1) { Can981.BPSet(n, rc); SolFound = true; } } } if (!SolFound) { continue; } } ++GeneralLogicGen2.ChkCov2; //***** BasCov.addCoverSet(CoverSetLst, HC981, Can981, rnk); if (_chkX2) { string st = $"{_jkc_++} ◆CoverSet:"; foreach (var P in CoverSetLst) { st += $" {P.ToAppearance()}"; //#### debug print } WriteLine(st); } yield return(BasCov); LNextSet: continue; } yield break; #endregion CoverSet generator }