public ChiPhi TimSoLuongThietBi(double chiPhiDauTu, double Pr, double Ps, double Pf) { // reset lai cay search this.resetTree(); List <SearchPosition> set = this.search; int soMC = 0; int soDTD = 0; int soDB = 0; double F_tong = Double.MaxValue; int MaxMC = (int)(chiPhiDauTu / Pr); double F_best = double.MaxValue; double F_underbound = 0.0; double F_last = 0.0; int best_pos = 0; // set F_best = tong chi phi hien tai. foreach (SearchPosition s in set) { F_best += s.sumF2(); } // Tieu hao luu tat cac cac F(N1, N2, N3) TieuHao F = new TieuHao(); // vtMC, vtDTD, vtDB luu vi tri tam thoi cua cac thiet bi List <int[]> vtMC = new List <int[]>(); List <int[]> vtDTD = new List <int[]>(); List <int[]> vtDB = new List <int[]>(); // Tim F(N1, 0, 0); 1 <= N1 <= N1_max for (int nMC = 1; nMC <= MaxMC; nMC++) { List <double> temp = new List <double>(); List <int> viTriDatTrongCay = new List <int>(); List <int> viTriCay = new List <int>(); for (int j = 0; j < set.Count; j++) { SearchPosition a = set[j]; double tong = 0; for (int k = 0; k < set.Count; k++) { if (k != j) { tong += set[k].sumF1(); } } for (int i = 0; i < a.numNode; i++) { if (!a.getMC(i)) { if (a.l[i] != 0 || a.d[i] != 0 || a.w[i] != 0) { a.setMC(i); temp.Add(a.sumF1() + tong); viTriCay.Add(j); viTriDatTrongCay.Add(i); a.refresh(); } } } } int vitri = findMinPos(temp); if (vitri == -1) { break; } if (temp[vitri] > F_tong) { break; } else { F_tong = temp[vitri]; } // set lai vi tri DTD trong cay set[viTriCay[vitri]].setLastMC(viTriDatTrongCay[vitri]); set[viTriCay[vitri]].refresh(); // Cap nhat F_best; if (F_tong < F_best) { F_best = F_tong; best_pos = F.currentLength(); } Console.WriteLine(F_best.ToString() + "," + F_tong.ToString() + "," + F_underbound.ToString() + "," + nMC.ToString() + ",0, 0"); // Them F(N1, 0, 0) vao N1 =1...N1_max; F.Add(nMC, 0, 0, F_tong, Clone(vtMC, new int[] { viTriCay[vitri], viTriDatTrongCay[vitri] }), vtDTD, vtDB); vtMC.Add(new int[] { viTriCay[vitri], viTriDatTrongCay[vitri] }); // Them vao vtMC } for (int nMC = 1; nMC <= MaxMC; nMC++) { // voi moi N1, N2 = 1...N2_max, N2_max = (chiPhiDauTu - so MC * Pr)/Ps; int MaxDTD = (int)((chiPhiDauTu - nMC * Pr) / Ps); vtMC = F.getMC_position(nMC, 0, 0); // Lay vi tri cac may cat cua truong hop F(nMC, 0, 0) // Neu khong tim duoc vtMC , ket thuc vong lap if (vtMC.Count == 0) { break; } F_tong = F.getF(nMC, 0, 0); for (int nDTD = 1; nDTD <= MaxDTD; nDTD++) { List <double> temp = new List <double>(); List <int> viTriDatTrongCay = new List <int>(); List <int> viTriCay = new List <int>(); for (int j = 0; j < set.Count; j++) { SearchPosition a = set[j]; double tong = 0; for (int k = 0; k < set.Count; k++) { if (k != j) { tong += set[k].sumF1(); } } for (int i = 0; i < a.numNode; i++) { if (!a.getMC(i) && !a.getDTD(i) && a.currentM(i) < 4) { if (a.l[i] != 0 || a.d[i] != 0 || a.w[i] != 0) { a.setDTD(i); temp.Add(a.sumF1() + tong); viTriCay.Add(j); viTriDatTrongCay.Add(i); a.refresh(); } } } } int vitri = findMinPos(temp); if (vitri == -1) { break; } if (temp[vitri] > F_tong) { break; } else { F_last = F_tong; // F(nMC, nDTD-1,0) F_tong = temp[vitri]; // F(nMC, nDTD, 0) } // set lai vi tri DTD trong cay set[viTriCay[vitri]].setLastDTD(viTriDatTrongCay[vitri]); set[viTriCay[vitri]].refresh(); // Neu F_underbound > F_best thi ket thuc // SUA F_underbound = F_tong - (F_last - F_tong) * (MaxDTD - nDTD); // F_underbound = F(N1, x, 0) - (F(N1, x-1, 0) - F(N1, x, 0)) *(N2 - x) if (F_underbound > F_best) { Console.WriteLine("Cut"); break; } Console.WriteLine(F_best.ToString() + "," + F_tong.ToString() + "," + F_underbound.ToString() + "," + nMC.ToString() + "," + nDTD.ToString() + ", 0"); if (F_tong < F_best) { F_best = F_tong; best_pos = F.currentLength(); } // Them F(N1, N2, 0) vao N2 =1...N2_max; F.Add(nMC, nDTD, 0, F_tong, vtMC, Clone(vtDTD, new int[] { viTriCay[vitri], viTriDatTrongCay[vitri] }), vtDB); vtDTD.Add(new int[] { viTriCay[vitri], viTriDatTrongCay[vitri] }); // them best hien tai vao vtDTD } } for (int nMC = 1; nMC <= MaxMC; nMC++) { // voi moi N1, N2 = 1...N2_max, N2_max = (chiPhiDauTu - so MC * Pr)/Ps; int MaxDTD = (int)((chiPhiDauTu - nMC * Pr) / Ps); vtMC = F.getMC_position(nMC, 0, 0); // Lay vi tri cac may cat cua truong hop F(nMC, 0, 0) // Neu khong tim duoc vtMC , ket thuc vong lap if (vtMC.Count == 0) { break; } for (int nDTD = 1; nDTD <= MaxDTD; nDTD++) { // so den bao toi da N3_max; int MaxDB = (int)((chiPhiDauTu - nMC * Pr - nDTD * Ps) / Pf); vtDTD = F.getDTD_position(nMC, nDTD, 0); if (vtDTD.Count == 0) { break; } F_tong = F.getF(nMC, nDTD, 0); for (int nDB = 1; nDB <= MaxDB; nDB++) { List <double> temp = new List <double>(); List <int> viTriDatTrongCay = new List <int>(); List <int> viTriCay = new List <int>(); for (int j = 0; j < set.Count; j++) { SearchPosition a = set[j]; double tong = 0; for (int k = 0; k < set.Count; k++) { if (k != j) { tong += set[k].sumF2(); } } for (int i = 0; i < a.numNode; i++) { if (a.l[i] != 0 || a.d[i] != 0 || a.w[i] != 0) { if (!a.getMC(i) && !a.getDTD(i) && !a.getDB(i)) { a.setDB(i); temp.Add(a.sumF2() + tong); viTriCay.Add(j); viTriDatTrongCay.Add(i); a.refresh(); } } } } int vitri = findMinPos(temp); if (vitri == -1) { break; } if (temp[vitri] > F_tong) { break; } else { F_last = F_tong; F_tong = temp[vitri]; } //cap nhat set[viTriCay[vitri]].setLastDB(viTriDatTrongCay[vitri]); set[viTriCay[vitri]].refresh(); // F_underbound F_underbound = F_tong - (F_last - F_tong) * (MaxDB - nDB); if (F_underbound > F_best) { Console.WriteLine("Cut"); break; } Console.WriteLine(F_best.ToString() + "," + F_tong.ToString() + "," + F_underbound.ToString() + "," + nMC.ToString() + "," + nDTD.ToString() + "," + nDB.ToString()); if (F_tong < F_best) { F_best = F_tong; best_pos = F.currentLength(); } // Them F(N1, N2, 0) vao N2 =1...N2_max; F.Add(nMC, nDTD, nDB, F_tong, vtMC, vtDTD, Clone(vtDB, new int[] { viTriCay[vitri], viTriDatTrongCay[vitri] })); vtDB.Add(new int[] { viTriCay[vitri], viTriDatTrongCay[vitri] }); // them best hien tai vao vDB } } } return(F.getAt(best_pos)); }
// Ham chinh public void TimViTriThietBi(int sMC, int sDTD, int sDB) { this.resetTree(); List <SearchPosition> set = this.search; int dem = sDB; int soMC = sMC; int soDTD = sDTD; int soDB = dem; double F_tong = Double.MaxValue; while (soMC > 0) { List <double> temp = new List <double>(); List <int> viTriDatTrongCay = new List <int>(); List <int> viTriCay = new List <int>(); for (int j = 0; j < set.Count; j++) { SearchPosition a = set[j]; double tong = 0; for (int k = 0; k < set.Count; k++) { if (k != j) { tong += set[k].sumF1(); } } for (int i = 0; i < a.numNode; i++) { if (!a.getMC(i)) { if (a.l[i] != 0 || a.d[i] != 0 || a.w[i] != 0) { a.setMC(i); temp.Add(a.sumF1() + tong); viTriCay.Add(j); viTriDatTrongCay.Add(i); a.refresh(); } } } } int vitri = findMinPos(temp); if (vitri == -1) { break; } if (temp[vitri] > F_tong) { break; } else { F_tong = temp[vitri]; } set[viTriCay[vitri]].setLastMC(viTriDatTrongCay[vitri]); set[viTriCay[vitri]].refresh(); soMC -= 1; } while (soDTD > 0) { List <double> temp = new List <double>(); List <int> viTriDatTrongCay = new List <int>(); List <int> viTriCay = new List <int>(); for (int j = 0; j < set.Count; j++) { SearchPosition a = set[j]; double tong = 0; for (int k = 0; k < set.Count; k++) { if (k != j) { tong += set[k].sumF1(); } } for (int i = 0; i < a.numNode; i++) { if (!a.getMC(i) && !a.getDTD(i) && a.currentM(i) < 4) { if (a.l[i] != 0 || a.d[i] != 0 || a.w[i] != 0) { a.setDTD(i); temp.Add(a.sumF1() + tong); viTriCay.Add(j); viTriDatTrongCay.Add(i); a.refresh(); } } } } int vitri = findMinPos(temp); if (vitri == -1) { break; } if (temp[vitri] > F_tong) { break; } else { F_tong = temp[vitri]; } set[viTriCay[vitri]].setLastDTD(viTriDatTrongCay[vitri]); set[viTriCay[vitri]].refresh(); soDTD -= 1; } while (soDB > 0) { List <double> temp = new List <double>(); List <int> viTriDatTrongCay = new List <int>(); List <int> viTriCay = new List <int>(); for (int j = 0; j < set.Count; j++) { SearchPosition a = set[j]; double tong = 0; for (int k = 0; k < set.Count; k++) { if (k != j) { tong += set[k].sumF2(); } } for (int i = 0; i < a.numNode; i++) { if (a.l[i] != 0 || a.d[i] != 0 || a.w[i] != 0) { if (!a.getMC(i) && !a.getDTD(i) && !a.getDB(i)) { a.setDB(i); temp.Add(a.sumF2() + tong); viTriCay.Add(j); viTriDatTrongCay.Add(i); a.refresh(); } } } } int vitri = findMinPos(temp); if (vitri == -1) { break; } if (temp[vitri] > F_tong) { break; } else { F_tong = temp[vitri]; } set[viTriCay[vitri]].setLastDB(viTriDatTrongCay[vitri]); set[viTriCay[vitri]].refresh(); soDB -= 1; } this.current_F = F_tong; tapMC.Clear(); tapMC_toaDo.Clear(); tapDTD.Clear(); tapDTD_toaDo.Clear(); tapDB.Clear(); tapDB_toaDo.Clear(); for (int i = 0; i < parent.Count; i++) { for (int j = 1; j < parent[i].Count; j++) { if (search[i].mc[j]) { tapMC.Add(c.cay_maCot[i][j][1]); tapMC_toaDo.Add(c.cay_toaDo[i][j][1]); } else if (search[i].dtd[j]) { tapDTD.Add(c.cay_maCot[i][j][1]); tapDTD_toaDo.Add(c.cay_toaDo[i][j][1]); } else if (search[i].db[j]) { tapDB.Add(c.cay_maCot[i][j][1]); tapDB_toaDo.Add(c.cay_toaDo[i][j][1]); } } } }