Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 4 308

/ вопрос открыт /

Доброго времени суток, уважаемые эксперты!
Возникла проблема в поиске минимакса и максимини по платежной матрице. Если матрица не квадртаная, то результаты иногда (особенно если строк больше) получаются некорректными. хотелось бы узнать в чем тут проблема?
Код прилагаю.

Приложение:
  1. procedure TMainForm.Button1Click(Sender: TObject);
  2.  
  3. const
  4. MinLongint:Longint=-2147483647;
  5. MaxLongint:Longint=2147483647;
  6. var
  7.  
  8. MinMaxA:Array[1..500] of Longint;
  9. MaxMinB:Array[1..500] of Longint;
  10. Index:Integer;
  11. IndexA:Integer;
  12. IndexB:Integer;
  13. MaxA:Integer;
  14. MaxB:Integer;
  15. Min:Longint;
  16. Max:Longint;
  17. MaxOptimalA:Integer;
  18. MaxOptimalB:Integer;
  19. ExMinMaxA:Array[1..500] of Longint;
  20. ExMaxMinB:Array[1..500] of Longint;
  21. Strategia:Array[1..500,1..500] of Longint;
  22. begin
  23.  
  24. For Index:=1 to 500 do
  25. begin
  26. ExMinMaxA[Index]:=0;
  27. ExMaxMinB[Index]:=0;
  28. end;
  29.  
  30. MaxA:=Grid.ColCount-1;
  31. MaxB:=Grid.RowCount-1;
  32.  
  33.  
  34. For IndexA:=1 to MaxA do
  35. For IndexB:=1 to MaxB do
  36. Strategia[IndexA, IndexB]:=StrToInt(Grid.Cells[IndexA, IndexB]);
  37.  
  38.  
  39.  
  40. For IndexA:=1 to MaxA do
  41. begin
  42. Min:=MinLongint;
  43. Max:=MaxLongint;
  44. For IndexB:=1 to MaxB do
  45. begin
  46. if Strategia[IndexB,IndexA] < Max Then
  47. begin
  48. Max:=Strategia[Indexb, IndexA];
  49. MinMaxA[IndexA]:=Max;
  50. end;
  51. if Strategia[IndexA, IndexB] > Min then
  52. begin
  53. Min:=Strategia[IndexA, Indexb];
  54. MaxMinB[IndexA]:=Min;
  55. end;
  56. end;
  57. end;
  58.  
  59.  
  60. for Index:=1 to MaxA do
  61. for IndexA:=1 to MaxB do
  62. Grid.Cells[Index, IndexA]:='';
  63.  
  64.  
  65. Index:=0;
  66. Min:=MinLongint;
  67. Max:=MaxLongint;
  68.  
  69.  
  70. For IndexA:=1 to MaxA do
  71. begin
  72. if MinMaxA[IndexA] >Min then
  73. Min:=MinMaxA[IndexA];
  74.  
  75. if MaxMinB[IndexA] < Max then
  76. Max:=MaxMinB[IndexA]
  77. end;
  78. Memo1.Lines[0]:= IntToStr(Min);
  79. Memo2.Lines[0]:= IntToStr(Max);
  80.  
  81.  
  82. for IndexA:=1 to MaxA do
  83. if MinMaxA[IndexA]= Min then
  84. begin
  85. Index:=Index+1;
  86. for IndexB:=1 to MaxA do
  87. begin
  88. Grid.Cells[IndexB, IndexA]:=IntToStr(Strategia[IndexB, IndexA]);
  89. ExMinMaxA[Index]:=IndexA;
  90. end;
  91. end;
  92.  
  93. MaxOptimalA:=Index;
  94. Index:=0;
  95.  
  96. for IndexB:=1 to MaxB do
  97. if MaxMinB[IndexB]= Max then
  98. begin
  99. Index:=Index+1;
  100. for IndexA:=1 to MaxB do
  101. begin
  102. Grid.Cells[IndexB, IndexA]:=IntToStr(Strategia[IndexB, IndexA]);
  103. ExMaxMinB[Index]:=IndexB;
  104. end;
  105. end;
  106.  
  107. MaxOptimalB:=Index;
  108.  
  109.  
  110. end;
  111. end.
  112.  
  113. end.


Mr.Slade Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Mr.Slade (статус: Посетитель)
Вопрос отправлен: 10 июня 2010, 20:33
Состояние вопроса: открыт, ответов: 1.

Ответ #1. Отвечает эксперт: Мережников Андрей

Здравствуйте, Mr.Slade!
во-первых, очень плохо использовать для имен переменных зарезервированные слова (например, min,max). во-вторых, нумерация столбцов и строк в stringgrid начинается с 0, а не с 1. в-третьих, перепутаны знаки сравнения в условиях. Должно быть if ...> Max then ... и if ...< Min then ... Кроме того, переменные MaxLongint и MinLongint - абсолютно лишние. Вам же надо найти минимальное и максимальное значение в строке, зачем сравнивать с минимальным и максимальным значением целых чисел? Надо присвоить переменным Max и Min значение первого сравниваемого столбца из соответствующей строки и сравнивать остальные значения с ним.

Ответ отправил: Мережников Андрей (статус: Абитуриент)
Время отправки: 10 июня 2010, 22:00
Оценка за ответ: 5

Комментарий к оценке: спасибо, но почему же идеально работает в квадратных матрицах?
"очень плохо использовать для имен переменных зарезервированные слова (например, min,max)" - это может быть причиной багов при неквадратных матрицах?

Мини-форум вопроса

Всего сообщений: 19; последнее сообщение — 11 июня 2010, 11:21; участников в обсуждении: 3.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 10 июня 2010, 22:01 [#1]:

Почему-то половину ответа проглотило, дописываю:
if ... < Min then ... Кроме того, переменные MaxLongint и MinLongint - абсолютно лишние. Вам же надо найти минимальное и максимальное значение в строке, зачем сравнивать с минимальным и максимальным значением целых чисел? Надо присвоить переменным Max и Min значение первого сравниваемого столбца из соответствующей строки и сравнивать остальные значения с ним.
min@y™

min@y™ (статус: Доктор наук), 10 июня 2010, 22:02 [#2]:

В чём задача-то заключается? Что с матрицей надо сделать?
Код не смотрел, ибо, хотя форматирование похоже на моё, однако комментарев 0 целых - хрен десятых. А это не есть комильфо.

Вообще, ты поставь себя на место тех людей, которые читают вопрос. Ты бы стал разбираться в таком коде?
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 10 июня 2010, 22:13 [#3]:

Цитата (Мережников Андрей):

это может быть причиной багов при неквадратных матрицах?

Бывает, когда программы, написанные с ошибкой, правильно работают на некоторых наборах данных. Точную причину можно определить только прогоняя в отладчике и смотря значения переменных.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 10 июня 2010, 22:19 [#4]:

вообще, судя по алгоритму - в переменную Max в итоге заносится минимальное значение, а в Min, наоборот - максимальное. Да, еще - массив Strategia дальше в программе используется? Если нет, то зачем он вообще нужен? Можно работать напрямую с stringgrid, не расходуя лишнего память. Если все-таки нужен, то лучше сделать его динамическим, как и массивы MaxMinB и MinMaxA.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 10 июня 2010, 22:21 [#5]:

Программа в режиме отладки в Delphi запускается по F8 (или через меню - пошаговое выполнение). Либо в программе делается точка останова, запускается на выполнение как обычно. А затем в пошаговом режиме проверяется нужный участок кода
Ерёмин А.А.

Ерёмин А.А. (статус: *Администратор), 10 июня 2010, 23:15 [#6]:

Цитата (Мережников Андрей):

Почему-то половину ответа проглотило

Потому что знак "меньше" - знак открывающего тега. Привет от браузера. Достаточно поставить после него пробел и он будет воспринят правильно. Ответ поправил.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 10 июня 2010, 23:46 [#7]:

to Ерёмин - спасибо. Я догадался, после того, как несколько раз пришлось исправлять сообщение в мини-форуме :-) Жаль только ответы корректировать нельзя. И не очень удобно стало, что список вопросов - зацикленный. С последнего попадаешь на первый.
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 10 июня 2010, 23:58 [#8]:

как конкретно пробовали. "код в студию"!
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 11 июня 2010, 00:00 [#9]:

и уточните все-таки задачу. Что конкретно надо найти? Минимальное значение среди максимальных в строках или максимальное среди минимальных в строках?
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 11 июня 2010, 00:29 [#10]:

понятно. значит так:
var mn_s,mx_s:Longint;
....
//ищем минимальное в строках
//если в stringgrid нулевые строки и столбцы заполнены
//значениями, то 2 надо заменить на 1, а 1 на 0
for IndexB:=2 to MaxB
do begin
mn_s:=Strategia[1,IndexB];
for IndexA:=1 to MaxA
do if Strategia[IndexA,IndexB] < mn_s
then begin
mn_s:=Strategia[IndexA,IndexB];
MaxMinB[IndexB]:=mn_s;
end;
end;
//ищем максимальное в столбцах
for IndexA:=2 to MaxA
do begin
mx_s:=Strategia[IndexA,1];
for IndexB:=1 to MaxB
do if Strategia[IndexA,IndexB] > mx_s
then begin
mx_s:=Strategia[IndexA,IndexB];
MinMaxA[IndexA]:=mx_s;
end;
end;
//ищем максимум среди минимумов
mx_s:=MaxMinB[1];
for IndexB:=2 to MaxB
do if MaxMinB[IndexB] > mx_s
then mx_s:=MaxMinB[IndexB];
//ищем минимум среди максимумов
mn_s:=MinMaxA[1];
for IndexA:=2 to MaxA
do if MinMaxA[IndexA] < mn_s
then mn_s:=MinMaxA[IndexA];

не совсем понятно зачем опять из Strategia переписывать значения в stringgrid
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 11 июня 2010, 00:38 [#11]:

вывод можно сделать проще, если при поиске минмаксов и максминов запомнить соответственно номер столбца и номер строки
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 11 июня 2010, 00:43 [#12]:

хотя, такой вариант (с запоминанием) сработает только если минмакс или максмин в единственном числе
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 11 июня 2010, 01:00 [#13]:

//ищем максимум среди минимумов
IndexB:=1;
for Index:=2 to MaxB
do if MaxMinB[Index] > MaxMinB[IndexB]
   then IndexB:=Index;
 
//ищем минимум среди максимумов
IndexA:=1;
for Index:=2 to MaxA
do if MinMaxA[Index] < MinMaxA[IndexA]
then IndexA:=Index;
//соответственно:
//MaxMinB[IndexB]  - первый максимум среди минимумов
//IndexB - номер строки, содержащей максимум
//MinMaxA[IndexA] - первый минимум среди максимумов
//IndexA - номер столбца, содержащего минимум
 
пришлите код, который получился после изменений
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 11 июня 2010, 06:05 [#14]:

после вставки предложенного кода в своей программе везде замените Max на mx_s, а Min на mn_s
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 11 июня 2010, 06:07 [#15]:

там, где сделан вывод в таблицу. переменные Max и Min удалите совсем. Объявление констант тоже можно выкинуть - оно лишнее. Все, удачи. Во сколько сдача? По московскому времени?
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 11 июня 2010, 11:13 [#16]:

в том исходнике, который Вы прислали - остались Min и Max
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 11 июня 2010, 11:16 [#17]:

 for IndexB:=1 to MaxB do
    if MaxMinB[IndexB]= Max then
      begin
        Index:=Index+1;
        for IndexA:=1 to MaxB do
          begin
            Grid.Cells[IndexB, IndexA]:=IntToStr(Strategia[IndexB, IndexA]); //в этой строке, на мой взгляд наод IndexA
и IndexB поменять местами
            ExMaxMinB[Index]:=IndexB; {получение оптимальных номеров столбцов для игрока В}
          end;
      end;
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 11 июня 2010, 11:18 [#18]:

если сделали запоминание НОМЕРА строки с максимумом и НОМЕРА столбца с минимумо, то цикл по заполнению грида надо тоже изменить
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 11 июня 2010, 11:21 [#19]:

на такие:
//заполнение строки
for Index:=1 to MaxA
do grid.cells[Index,IndexB]:=IntToStr(Strategia[Index,IndexB]);
//заполнение столбца
for Index:=1 to MaxB
do grid.cells[IndexA,Index]:=IntToStr(Strategia[IndexA,Index]);

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:50
Выполнено за 0.04 сек.