public void FillTable(DataGridView dataSolve) { DataGridViewRowCollection dataRowCollection = dataSolve.Rows; int iLastColumnIndex = dataSolve.Columns.Count - 1; int iPosX = 0; foreach (DataGridViewRow dgvr in dataRowCollection) { if (dgvr.Index == dataRowCollection.Count - 1) // if it was a last row in datagrid, it contains needs { // We need to exclude last column foreach (DataGridViewCell dgvc in dgvr.Cells) { if (dgvc.ColumnIndex == 0) { continue; // Skip first column of row } if (dgvc.ColumnIndex == iLastColumnIndex) { break; // Just exit } lNeeds.Add(Convert.ToUInt32(dgvc.Value)); // All our needs filled } } else { List <CTransportCell> lTransportCells = new List <CTransportCell>(); int iPosY = 0; foreach (DataGridViewCell dgvc in dgvr.Cells) { if (dgvc.ColumnIndex == 0) { continue; // Skip first column of row } if (dgvc.ColumnIndex == iLastColumnIndex) // if it was a last column of row, we add those values to list of storage { lStorage.Add(Convert.ToUInt32(dgvc.Value)); } else { // Else, we need to fill our List<List<CTransportCell>> CTransportCell cell = new CTransportCell(Convert.ToUInt32(dgvc.Value), iPosX, iPosY); if (cell.iTariff == 0) { cell.bArtificial = true; } lTransportCells.Add(cell); iPosY++; } } lTable.Add(lTransportCells); } iPosX++; } }
public override bool Equals(object obj) { if (obj is CTransportCell == false) { return(false); } CTransportCell target = obj as CTransportCell; return(iActualValue == target.iActualValue && iTariff == target.iTariff && bArtificial == target.bArtificial && bZeroValue == target.bZeroValue && iPosX == target.iPosX && iPosY == target.iPosY && bCorner == target.bCorner && iDiff == target.iDiff && bStarter == target.bStarter && bIsPathCell == target.bIsPathCell); }
public void Solve() { ResourceAllocation(); while (bOptimalPlan == false) { ClearAllCustomData(); PotencialRedistribution(); bOptimalPlan = true; List <CTransportCell> lNonOptimal = new List <CTransportCell>(); foreach (List <CTransportCell> lCTC in lTable) { foreach (CTransportCell ctc in lCTC) { if (ctc.iActualValue != null) { continue; } int iPosX = ctc.iPosX; int iPosY = ctc.iPosY; int iRes = (int)lUKoef[iPosX] + (int)lVKoef[iPosY] - (int)ctc.iTariff; if (iRes > 0) { ctc.iDiff = iRes; lNonOptimal.Add(ctc); if (bOptimalPlan) { bOptimalPlan = false; } } } } if (bOptimalPlan) { break; } int iMax = lNonOptimal.Max(x => x.iDiff); var result = lNonOptimal.Select(x => x).Where(x => x.iDiff == iMax); CTransportCell startCell = result.OrderBy(x => x.iTariff).FirstOrDefault(); startCell.bStarter = true; startCell.bCorner = true; startCell.bSign = true; lCorners.Add(startCell); // Check lCorners on actual info FindCorners(); // After corners checked, we need to order and show path to them. FindPath(); OutPutInDataGrid(true, true); // Change values, depending on +(true) or -(false) on bSign MakeChanges(); } OutPutInDataGrid(true, false); }
private void PotencialRedistribution() { int iIndexOfRowWithMaxValues = FindRowWithMaxValues(); // It finds index of row which contains maximum values // This row will be with potencial U = 0 lUKoef = new int?[lStorage.Count]; lVKoef = new int?[lNeeds.Count]; lUKoef[iIndexOfRowWithMaxValues] = 0; for (int i = 0; i < lTable[iIndexOfRowWithMaxValues].Count; ++i) { uint?iValue = lTable[iIndexOfRowWithMaxValues][i].iActualValue; uint iTariff = lTable[iIndexOfRowWithMaxValues][i].iTariff; if (iValue != null) { lVKoef[i] = (int?)(iTariff); } } // NEED TO REMAKE bool bMode = true; int iOldUKoefCount = lUKoef.Select(x => x).Where(y => y != null).ToList().Count; int iOldVKoefCount = lVKoef.Select(x => x).Where(y => y != null).ToList().Count; while (lUKoef.Any(x => x == null) || lVKoef.Any(x => x == null)) { int iNewUKoefCount = iOldUKoefCount; int iNewVKoefCount = iOldVKoefCount; if (bMode) // Horizontal moving { for (int i = 0; i < lVKoef.Length; ++i) { int?koef = lVKoef[i]; if (koef != null) { for (int j = 0; j < lTable.Count; ++j) { if (lTable[j][i].iActualValue != null) { if (lUKoef[j] != null) { continue; } int iTariff = (int)(lTable[j][i].iTariff); int?UTariff = iTariff - koef; lUKoef[j] = UTariff; iNewUKoefCount++; } } } } } else { for (int i = 0; i < lUKoef.Length; ++i) { int?koef = lUKoef[i]; if (koef != null) { for (int j = 0; j < lTable[i].Count; ++j) { if (lTable[i][j].iActualValue != null) { if (lVKoef[j] != null) { continue; } int iTariff = (int)(lTable[i][j].iTariff); int?VTariff = iTariff - koef; lVKoef[j] = VTariff; iNewVKoefCount++; } } } } } if (iOldUKoefCount == iNewUKoefCount && iOldVKoefCount == iNewVKoefCount) { // черт, мы попали в цикл // нужно найти пустые клетки, имеющие хотя бы один потенциал в строке/столбце Func <CTransportCell> GetFictiveCell = delegate() { foreach (List <CTransportCell> lCTC in lTable) { foreach (CTransportCell cTC in lCTC) { if (cTC.iActualValue == null) { if ((lUKoef[cTC.iPosX] == null && lVKoef[cTC.iPosY] != null) || (lUKoef[cTC.iPosX] != null && lVKoef[cTC.iPosY] == null)) { return(cTC); } } } } return(null); }; CTransportCell fictive = GetFictiveCell(); fictive.bZeroValue = true; fictive.iActualValue = 0; fictive.bCorner = true; lCorners.Add(fictive); int iTariff = (int)fictive.iTariff; if (lUKoef[fictive.iPosX] == null) { lUKoef[fictive.iPosX] = iTariff - lVKoef[fictive.iPosY]; iNewUKoefCount++; bMode = false; } else { lVKoef[fictive.iPosY] = iTariff - lUKoef[fictive.iPosX]; iNewVKoefCount++; bMode = true; } iOldUKoefCount = iNewUKoefCount; iOldVKoefCount = iNewVKoefCount; continue; } iOldUKoefCount = iNewUKoefCount; iOldVKoefCount = iNewVKoefCount; bMode = !bMode; } }
private void FindPath() { lPath = new List <CTransportCell>(); lCorners = lCorners.OrderByDescending(x => x.bStarter).ToList(); Stack <CTransportCell> sCTC = new Stack <CTransportCell>(); sCTC.Push(lCorners[0]); while (lCorners.Any(x => x.bSign == null)) { CTransportCell ctc = sCTC.Pop(); sCTC.Push(ctc); int iPosX = ctc.iPosX; int iPosY = ctc.iPosY; // By rows CTransportCell ctcPartner = lCorners.Find(x => x.iPosX == iPosX && x.iPosY != iPosY); // Set sign for teammates on rows if (ctcPartner.bSign == null) { if (ctc.bSign == true) { ctcPartner.bSign = false; } else if (ctc.bSign == false) { ctcPartner.bSign = true; } sCTC.Push(ctcPartner); } int iCount; if (iPosY < ctcPartner.iPosY) { iCount = ctcPartner.iPosY - iPosY; lPath.AddRange(lTable[iPosX].GetRange(iPosY, iCount)); } else { iCount = iPosY - ctcPartner.iPosY; lPath.AddRange(lTable[iPosX].GetRange(ctcPartner.iPosY, iCount)); } // By columns ctcPartner = lCorners.Find(x => x.iPosY == iPosY && x.iPosX != iPosX); // Set sign for teaammates on columns if (ctcPartner.bSign == null) { if (ctc.bSign == true) { ctcPartner.bSign = false; } else if (ctc.bSign == false) { ctcPartner.bSign = true; } sCTC.Push(ctcPartner); } if (iPosX < ctcPartner.iPosX) // наша ячейка выше чем вторая { for (int i = iPosX; i <= ctcPartner.iPosX; ++i) { lPath.Add(lTable[i][iPosY]); } } else // наша ячейка ниже искомой { for (int i = ctcPartner.iPosX; i <= iPosX; ++i) { lPath.Add(lTable[i][iPosY]); } } } /* * foreach (CTransportCell ctc in lCorners) * { * int iPosX = ctc.iPosX; * int iPosY = ctc.iPosY; * * // By rows * CTransportCell ctcPartner = lCorners.Find(x => x.iPosX == iPosX && x.iPosY != iPosY); * * // Set sign for teammates on rows * if (ctcPartner.bSign == null) * { * if (ctc.bSign == true) * ctcPartner.bSign = false; * else if (ctc.bSign == false) * ctcPartner.bSign = true; * } * * int iCount; * if (iPosY < ctcPartner.iPosY) * { * iCount = ctcPartner.iPosY - iPosY; * lPath.AddRange(lTable[iPosX].GetRange(iPosY, iCount)); * } * else * { * iCount = iPosY - ctcPartner.iPosY; * lPath.AddRange(lTable[iPosX].GetRange(ctcPartner.iPosY, iCount)); * } * * // By columns * ctcPartner = lCorners.Find(x => x.iPosY == iPosY && x.iPosX != iPosX); * * // Set sign for teaammates on columns * if (ctcPartner.bSign == null) * { * if (ctc.bSign == true) * ctcPartner.bSign = false; * else if (ctc.bSign == false) * ctcPartner.bSign = true; * } * * if (iPosX < ctcPartner.iPosX) // наша ячейка выше чем вторая * { * for (int i = iPosX; i <= ctcPartner.iPosX; ++i) * { * lPath.Add(lTable[i][iPosY]); * } * } * else // наша ячейка ниже искомой * { * for (int i = ctcPartner.iPosX; i <= iPosX; ++i) * { * lPath.Add(lTable[i][iPosY]); * } * } * } */ // Distinct in List lPath = lPath.Distinct().ToList(); foreach (CTransportCell ctc in lPath) { // make it a path cell ctc.bIsPathCell = true; } }