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++;
            }
        }
Ejemplo n.º 2
0
        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;
            }
        }