Консультация № 185284
23.01.2012, 23:31
62.96 руб.
25.01.2012, 18:09
0 8 1
Здравствуйте! Прошу помощи в следующем вопросе:
1. Решить задачу, методом поиска с возвратом, используя рекурсивный или нерекурсивный вариант.
2. Решить те же задачи с помощью жадного алгоритма (можно вручную).
3. Обосновать возможность решения данных задач методом динамического программирования.

Задача о ладьях. На клетках шахматной доски размера 9*9 написаны числа. Расставить на доске 9 ладей, чтобы они не били друг друга, а сумма накрытых ими чисел была максимальной.

27 12 23 20 22 21 34 25 13
30 12 19 26 21 35 34 12 32
27 12 28 17 25 16 36 35 13
18 23 24 33 20 22 20 34 17
14 18 29 36 20 26 36 25 20
12 15 19 23 13 15 33 34 25
29 27 32 19 33 21 16 15 14
33 33 17 18 13 22 17 31 23
27 12 29 35 25 15 23 33 27

Язык программирования - Pascal

Обсуждение

давно
Академик
320937
2216
23.01.2012, 23:42
общий
Доброго времени суток! Какой максимально возможный срок? Насколько Вы готовы увеличить стоимость вопроса? Здесь целая курсовая работа.
давно
Старший Модератор
31795
6196
24.01.2012, 11:50
общий
Цитата: 329287
Решить задачу, методом поиска с возвратом, используя рекурсивный или нерекурсивный вариант.

Это нужно делать на паскале?
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

давно
Профессионал
304622
583
25.01.2012, 17:58
общий
это ответ
Здравствуйте, кирюша!

1. Вот текст программы с комментариями.
[code h=200]const
coin:array [1..9,1..9]of integer=(
(27,12,23,20,22,21,34,25,13),
(30,12,19,26,21,35,34,12,32),
(27,12,28,17,25,16,36,35,13),
(18,23,24,33,20,22,20,34,17),
(14,18,29,36,20,26,36,25,20),
(12,15,19,23,13,15,33,34,25),
(29,27,32,19,33,21,16,15,14),
(33,33,17,18,13,22,17,31,23),
(27,12,29,35,25,15,23,33,27)
);
var
rook,max:array[1..9]of integer;{массивы горизонталей тур (текущий и наилучший)}
rows:array[1..9]of boolean; {признак незанятости горизонтали}
sum_max:integer; {сумма накрытых чисел для наилучшей расстановки}


procedure p(a,sum:integer);
var
s:integer;
begin
for s:=1 to 9 do {перебираем горизонтали}
if rows[s] then {если она незанята}
begin
rook[a]:=s; {занимаем}
rows[s]:=false;
if a<9 then p(a+1,sum+coin[a,rook[a]]) {если непоследняя, то переходим к следующей}
{ (увеличивая сумму)}
else if sum+coin[a,rook[a]]>sum_max then {иначе сравниваем текущую расстановку }
begin {c наилучшей}
sum_max:=sum+coin[a,rook[a]];
max:=rook;
end;
rook[a]:=0; {освобождаем горизонталь}
rows[s]:=true;
end;
end;

var i:integer;

begin{main}
for i:=1 to 9 do
begin
rook[i]:=0;
rows[i]:=true;
end;
sum_max:=0;
p(1,0);
for i:=1 to 9 do write(i:3,':',max[i],'=',coin[i,max[i]]);
writeln;
writeln('Sum:',sum_max);
readln;
end.{main}[/code]

Результат:
Код:
  1:1=27  2:6=35  3:7=36  4:8=34  5:4=36  6:9=25  7:5=33  8:2=33  9:3=29
Sum:288


2. Здесь жадный алгоритм, вероятно, реализуется так:
а) находим на доске ячейку с самым большим числом и ставим ладью;
б) вычёркиваем горизонталь и вертикаль;
с) в оставшихся ячейках находим самое большое число;
и т.д.

В прикреплённом файле весь процесс показан в excel таблице. Сумма составила 277. Т.е. меньше, чем в рекурсивном алгоритме, в котором происходит полный перебор всех вариантов.

Кстати, на первой же ладье имеется нексолько ячеек с максимальным значением 36. Однако, перебор вариантов тут уже не делается. Идея жадного алгоритма -- накидать всё побыстрее и попроще. Результат будет не самый-самый лучший, но достаточно большой в любой практической задаче.
Прикрепленные файлы:
5
давно
Профессионал
304622
583
25.01.2012, 18:01
общий
С решением по пункту 3. мне ещё надо разбираться. Если вам это ещё надо -- пишите.
Неизвестный
25.01.2012, 18:03
общий
к сожалению это простая лабораторная работа,задачу надо сделать на паскале.
Неизвестный
25.01.2012, 18:31
общий
[q=304622][/q]
мне достаточно того что вы сделали , огромное спасибо.
давно
Старший Модератор
31795
6196
25.01.2012, 19:11
общий
25.01.2012, 19:34
Всем:
[code h=200]const
coin:array [1..9,1..9]of integer=(
(27,12,23,20,22,21,34,25,13),
(30,12,19,26,21,35,34,12,32),
(27,12,28,17,25,16,36,35,13),
(18,23,24,33,20,22,20,34,17),
(14,18,29,36,20,26,36,25,20),
(12,15,19,23,13,15,33,34,25),
(29,27,32,19,33,21,16,15,14),
(33,33,17,18,13,22,17,31,23),
(27,12,29,35,25,15,23,33,27)
);
var
m_x,m_y,w,x,y,z:integer;
lin,row:array[1..9]of boolean;
begin
{A}
writeln('row 1:9;col 1:9');
for z:=1 to 9 do
begin
lin[z]:=true;
row[z]:=true;
end;
w:=0;
for z:=1 to 9 do
begin
m_x:=0;repeat inc(m_x) until lin[m_x];
m_y:=0;repeat inc(m_y) until lin[m_y];
for y:=1 to 9 do
if row[y] then
for x:=1 to 9 do
if lin[x] then
if coin[x,y]>coin[m_x,m_y]then
begin
m_y:=y;
m_x:=x;
end;
row[m_y]:=false;
lin[m_x]:=false;
write(m_x:3,':',m_y,'=',coin[m_x,m_y]);
w:=w+coin[m_x,m_y];
end;
writeln(' s:=',w);
{B}
writeln('col 1:9;row 1:9');
for z:=1 to 9 do
begin
lin[z]:=true;
row[z]:=true;
end;
w:=0;
for z:=1 to 9 do
begin
m_x:=0;repeat inc(m_x) until lin[m_x];
m_y:=0;repeat inc(m_y) until row[m_y];
for x:=1 to 9 do
if lin[x] then
for y:=1 to 9 do
if row[y] then
if coin[x,y]>coin[m_x,m_y]then
begin
m_y:=y;
m_x:=x;
end;
row[m_y]:=false;
lin[m_x]:=false;
write(m_x:3,':',m_y,'=',coin[m_x,m_y]);
w:=w+coin[m_x,m_y];
end;
writeln(' s:=',w);

{C}
writeln('row 9:1;col 9:1');
for z:=1 to 9 do
begin
lin[z]:=true;
row[z]:=true;
end;
w:=0;
for z:=1 to 9 do
begin
m_x:=0;repeat inc(m_x) until lin[m_x];
m_y:=0;repeat inc(m_y) until lin[m_y];
for y:=9 downto 1 do
if row[y] then
for x:=9 downto 1 do
if lin[x] then
if coin[x,y]>coin[m_x,m_y]then
begin
m_y:=y;
m_x:=x;
end;
row[m_y]:=false;
lin[m_x]:=false;
write(m_x:3,':',m_y,'=',coin[m_x,m_y]);
w:=w+coin[m_x,m_y];
end;
writeln(' s:=',w);
{D}
writeln('col 9:1; row 9:1');
for z:=1 to 9 do
begin
lin[z]:=true;
row[z]:=true;
end;
w:=0;
for z:=1 to 9 do
begin
m_x:=0;repeat inc(m_x) until lin[m_x];
m_y:=0;repeat inc(m_y) until row[m_y];
for x:=9 downto 1 do
if lin[x] then
for y:=9 downto 1 do
if row[y] then
if coin[x,y]>coin[m_x,m_y]then
begin
m_y:=y;
m_x:=x;
end;
row[m_y]:=false;
lin[m_x]:=false;
write(m_x:3,':',m_y,'=',coin[m_x,m_y]);
w:=w+coin[m_x,m_y];
end;
writeln(' s:=',w);
readln;
end.{}[/code]
жадный алгоритм(который предложил Сергей) с 4-мя стратегиями поиска максимальных элементов:
по строкам, по столбцам, с возрастанием индекса поиска и его убыванием.


Судя по всему и полный перебор не дает полной гарантии.


нашел ошибку в своем коде:
Код:
      m_x:=0;repeat inc(m_x) until lin[m_x];
m_y:=0;repeat inc(m_y) until lin[m_y];

из-за этого учитывались у же вычеркнутые линии.
Об авторе:
Мне безразлично, что Вы думаете о обо мне, но я рад за Вас - Вы начали думать.

Неизвестный
26.01.2012, 16:02
общий
большое спасибо и за ваш вариант
Форма ответа