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; }
public void Initialize() //Initialization for each trial { BSstatus2 = null; QueueGlk.Clear(); _jkc_ = 0; }