private void __SetGLinkLstSet(UGLink_unit LKx, int SW, int rc, int no1, int no2) // in-cell link { UGLink_pair LK1 = new UGLink_pair(LKx, SW, rc, no2); if (GLK_connection[rc, no1] == null) { GLK_connection[rc, no1] = new List <UGLink_pair>(); } GLK_connection[rc, no1].Add(LK1); UGLink_pair LK2 = new UGLink_pair(LKx, SW, rc, no1); if (GLK_connection[rc, no2] == null) { GLK_connection[rc, no2] = new List <UGLink_pair>(); } GLK_connection[rc, no2].Add(LK2); }
private void __SetGLinkLstSet(UGLink_unit LKx, int SW, int tfx, int no, UCell UC1, UCell UC2) // cell-cell link { int rc1 = UC1.rc, rc2 = UC2.rc; UGLink_pair LK1 = new UGLink_pair(LKx, SW, rc2, no); if (GLK_connection[rc1, no] == null) { GLK_connection[rc1, no] = new List <UGLink_pair>(); } GLK_connection[rc1, no].Add(LK1); UGLink_pair LK2 = new UGLink_pair(LKx, SW, rc1, no); if (GLK_connection[rc2, no] == null) { GLK_connection[rc2, no] = new List <UGLink_pair>(); } GLK_connection[rc2, no].Add(LK2); }
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; }
private void _LinkSearch(bool printSW = false) { int IDx = -1; // *==* cell-cell link for (int no = 0; no < 9; no++) { for (int tfx = 0; tfx < 27; tfx++) { int noB = 1 << no; List <UCell> PLst = pBDL.IEGetCellInHouse(tfx, noB).ToList(); int szL = PLst.Count; if (szL <= 1) { continue; } int SW = (szL == 2)? 0: 1; IDx++; var LK1 = new UGLink_unit(IDx, SW, tfx, no, PLst); GLK_UList_All.Add(LK1); Combination cmb = new Combination(szL, 2); while (cmb.Successor()) { UCell UC1 = PLst[cmb.Index[0]], UC2 = PLst[cmb.Index[1]]; __SetGLinkLstSet(LK1, SW, tfx, no, UC1, UC2); } } } // *==* in-cell link foreach (var P in pBDL.Where(p => p.No == 0)) { int rc = P.rc; int[] noLst = P.FreeB.IEGet_BtoNo().ToArray(); int szL = noLst.Length; if (szL <= 1) { continue; } int SW = (szL == 2)? 0: 1; IDx++; var LK2 = new UGLink_unit(IDx, SW, rc, P.FreeB); GLK_UList_All.Add(LK2); Combination cmb = new Combination(szL, 2); while (cmb.Successor()) { int no1 = noLst[cmb.Index[0]], no2 = noLst[cmb.Index[1]]; __SetGLinkLstSet(LK2, SW, rc, no1, no2); } } if (printSW) { WriteLine($"============================ stage:{stageNo} GLK_UList_All"); foreach (var P in GLK_UList_All) { WriteLine(P); } WriteLine($"============================ stage:{stageNo} GLK_connection"); foreach (var rc in Enumerable.Range(0, 81)) { foreach (var no in Enumerable.Range(0, 9)) { if (GLK_connection[rc, no] != null) { GLK_connection[rc, no].ForEach(P => WriteLine(P.ToString_rcno(rc, no))); } } } } }