Помощь - Поиск - Пользователи - Календарь
Полная версия: Задача по электротехнике
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Иваныч
Задача такова:
Надо соединить 3 кнопки, 3 лампочки и 1звонок так, чтобы
при нажатии кнопки1 ( Кн1 ) загарается лампочка1 ( Л1 ) и звенит звонок,
при нажатии Кн2 загарается Л2 и звенит звонок,
и при нажатии Кн3 загарается Л3 и звени звонок.

Главная загвостка в том, что Лампочки(в последовательности) и звонок должны работать в полную силу.
Напряжение 220В
Кнопки с самовозвратом, 4 контактные (2 контакта на вкл состояние, и 2 на выкл)
Нельзя добавлять ничего лишнего(т.е конденсаторы, рэле, сопротивление и таму подобное)

Это всё будет ставится якобы в камуналке
Lapp
Ко всем, кто находит удовольствие в решении чисто программистских задач, просьба - дочитать этот мессадж до конца smile.gif.

Цитата(Иваныч @ 30.11.2008 19:12) *
Это всё будет ставится якобы в камуналке

Н-да.. smile.gif
Первой моей реакцией на эту тему было, ессно, перенести ее в Физику. Но потом я подумал, что возможно, что нужно не просто представить решение, а сделать способ нахождения такой схемы - то есть, программу smile.gif. И еще я подумал, что прога-то будет несложная. Ну, я и написал ее. А потом, счастливо улыбаясь, запустил... smile.gif

И тут я понял, что мне не увидеть результатов. По крайней мере - живым smile.gif. Способ не включал в себя никаких научных достижений, а был основан на полном переборе вариантов, и оценка времени его выполнения скромно зашкаливала за сотни лет (очень грубая оценка).. И тогда я бросил эту задачу, и даже не стал писать ответ в тему.

Но потом она снова попалась мне на глаза, и я понял, что мне не уйти от нее smile.gif. И я решил пооптимизировать.. Возможностей для этого оказалось достаточно. И через некоторое время я смог получить ответ в упрощенном варианте (квартира с двумя жильцами smile.gif). Интересно, что программа нашла не то решение, которое я придумал своим мозгом (без помощи электроники). Вот это решение, найденное моим лаптопом меньше, чем за минуту (проу прощения за качество камеры в моем телефоне):

Вместе с неизменными атрибутами: Нажмите для просмотра прикрепленного файла

Ниже привожу саму программу. Написана на Obect Pascal, хотя это не очень существенно (никаких виртуальных методов). Приглашаю всех желающих приложить руку к ее оптимизации. Комментарии включены самые ограниченные, но я опишу подробно, если кто-то проявит интерес (и если сами не разберетесь smile.gif). Если кто-то предложит другой метод - более эффективный - ваще будет здорово smile.gif. Но в любом случае постарайтесь не ограничиваться словами..
Критика также принимается в любом (приличном) виде.
Желаю успеха!

uses
  CRT;

var
  n: integer; // Суммарное число контактов всех элементов
  t: integer; // Номер следующего соединения при сборке

type
  tVolt= (None,v1,v2);                  // Напряжение: не подано, v1, v2
  tPin= array[1..255] of byte;          // Массив выводов

  tElement= object
    mp: integer;                        // Число выводов
    Pin: ^tPin;                         // Выводы
    procedure Clear;                    // Отсоединение от всех шин
    procedure Connect(p,b: byte);       // Параметры: вывод, шина
    function Connected: string;         // Возвращает строку номеров шин по пинам
    constructor Create(ip: integer);
  end;

  // Устройство с двумя выводами (лампа, звонок)
  tDevice= object(tElement)
    function Active: boolean;           // Возвращает true, если на приборе есть полное напряжение
    constructor Create;
  end;

  // Переключатель с двумя парами контактов
  tSwitch= object(tElement)
    Pos: byte;                          // Состояние переключателя: 0, 1
    procedure Connect(p,b:byte);
    constructor Create;
  end;

  // Источник (батарея или розетка)
  tPower= object(tElement)              // Напряжение на выводах
    Volt: array[1..2]of tVolt;
    procedure Connect(p,b: byte);
    constructor Create;
  end;

var
  Bus: array[1..255]of tVolt;           // Массив шин (соединительных проводов)
  Shorting: boolean;                    // Индицирует состояние короткого замыкания в схеме

  procedure tElement.Clear;
  var
    i: byte;
  begin
    for i:=1 to mp do Pin^[i]:=0
  end;

  procedure tElement.Connect(p,b: byte);
  begin
    if p<=mp then Pin^[p]:=b;
    Inc(t);
  end;

  function tElement.Connected: string;
  var
    i: integer;
    s,t: string;
  begin
    s:='';
    for i:=1 to mp do begin
      Str(Pin^[i]:5,t);
      s:=s+t;
    end;
    Connected:=s
  end;

  constructor tElement.Create(ip: integer);
  var
    i: integer;
  begin
    mp:=ip;
    Inc(n,mp);
    GetMem(Pin,mp);
    for i:=1 to mp do Pin^[i]:=0;
  end;

  constructor tDevice.Create;
  begin
    tElement.Create(2);
  end;

  function tDevice.Active: boolean;
  begin
    Active:=(Pin^[1]>0)and(Pin^[2]>0)and(Bus[Pin^[1]]<>None)and(Bus[Pin^[2]]<>None)and(Bus[Pin^[1]]<>Bus[Pin^[2]])
  end;

  constructor tSwitch.Create;
  begin
    tElement.Create(4);
  end;

  procedure tSwitch.Connect(p,b:byte);
  var
    i:byte;
  begin
    tElement.Connect(p,b);
    case p of
      1,2: i:=Pin^[3-p];
      3,4: i:=Pin^[7-p]
    end;
    if Pos=(p-1)div 2 then begin
      if i>0 then
        if Bus[b]=None then Bus[b]:=Bus[i]
        else if Bus[i]=None then Bus[i]:=Bus[b]
        else Shorting:=Shorting or(Bus[b]<>Bus[i]);
    end
  end;

  constructor tPower.Create;
  begin
    tElement.Create(2);
    Volt[1]:=v1;
    Volt[2]:=v2
  end;

  procedure tPower.Connect(p,b: byte);
  begin
    tElement.Connect(p,b);
    if Bus[b]=None then Bus[b]:=Volt[p] else Shorting:=Bus[b]<>Volt[p]
  end;

const
  nn=100;  // Максимально возможное суммарное число контактов всех элементов
  m= 2;    // Число ламп (равно числу переключателей)

var
  Lamp: array[1..m]of tDevice;
  Switch: array[1..m]of tSwitch;
  Bell: tDevice;
  Power: tPower;
  Sw: tSwitch;
  c: array[1..nn]of integer;
  Correct: boolean;
  k: integer;


procedure Show;
var
  i: integer;
begin
  for i:=1 to n do Write(c[i]:3);
  WriteLn
end;

// Перебор всех возможных комбинаций подключений
procedure Next;
var
  i,j: integer;
  b: boolean;
begin
  repeat
    b:=false;
    repeat
      i:=0;
      repeat
        Inc(i);
        if c[i]=k then c[i]:=1 else Inc(c[i])
      until (c[i]<>1)or(i=n);
      if Odd(i) and(c[i]=c[i+1]) then for j:=1 to i-1 do c[j]:=k else b:=true
    until b;
    for j:=1 to (i-1)div 2*2 do if Odd(j) then c[j]:=2;
    j:=0;
    for i:=1 to n do if c[i]=k then begin
      Inc(j);
      if j=2 then break
    end
  until j>1
end;

var
  s: string;
  i,j,p,a,t0: byte;
  h: char;
  Debug: boolean;

begin
  Debug:=true;
  Power.Create;
  for i:=1 to m do begin
    Lamp[i].Create;
    Switch[i].Create;
  end;
  Bell.Create;
  Power.Connect(1,2);
  Power.Connect(2,1);
  k:=2;
  repeat
    Inc(k);
    WriteLn('Buses: ',k);
    // Начальная конфигурация соединений
    c[1]:=k;
    c[2]:=1;
    c[3]:=k;
    for i:=3 to n do c[i]:=i mod 2+1;
    // Основной цикл перебора
    repeat
      if Debug or KeyPressed then begin
        h:=ReadKey;
        if h=#13 then Debug:=not Debug;
        Show
      end;
      // Разборка схемы
      for i:=1 to m do Lamp[i].Clear;
      Bell.Clear;
      // Сборка схемы (лампы и звонок)
      t:=1;
      for i:=1 to m do begin
        Lamp[i].Connect(1,c[t]);
        Lamp[i].Connect(2,c[t]);
      end;
      Bell.Connect(1,c[t]);
      Bell.Connect(2,c[t]);
      t0:=t;
      Shorting:=false;
      Correct:=true;
      // Цикл по состояниям кнопок (0 - ничего не нажато)
      for a:=0 to m do if not Shorting then begin
        for i:=3 to k do Bus[i]:=None;
        for i:=1 to m do if i=a then Switch[i].Pos:=1 else Switch[i].Pos:=0;
        for i:=1 to m do Switch[i].Clear;
        for j:=1 to m do begin
          t:=t0;
          for i:=1 to m do {if not Shorting then} begin
            Switch[i].Connect(1,c[t]);
            Switch[i].Connect(2,c[t]);
            Switch[i].Connect(3,c[t]);
            Switch[i].Connect(4,c[t]);
          end
        end;
        Correct:=Correct and not Shorting;
        // Проверка работы схемы
        for i:=1 to m do Correct:=Correct and (Lamp[i].Active=(a=i));
        Correct:=Correct and (Bell.Active=(a>0))
      end;
      if not Correct then Next;
    until Correct or (c[n-1]=3) or (h=#27)
  until Correct or (h=#27);
  if Correct then begin
    Show;
    WriteLn('Power:   ',Power.Connected);
    for j:=1 to m do begin
      WriteLn('Lamp',j,':   ',Lamp[j].Connected);
      WriteLn('Switch',j,': ',Switch[j].Connected);
    end;
    WriteLn('Bell:    ',Bell.Connected)
  end
  else WriteLn('Interrupted')
end.

P.S.
Время, может, не самое подходящее - типа сессия близко, но - who cares? smile.gif

P.P.S.
А не такая и мелкая, как мне казалось - рука устала елозить мышой, пока метил ее..
xds
Мое решение (интуитивное). Подходит для любого количества жильцов.

Нажмите для просмотра прикрепленного файла
andriano
Хочу отметить, что в условии не оговорено ни одного из следующих условий:
1. Возможности функционирования схемы при нажатии нескольких кнопок одновременно.
2. Сотношения между напряжением в сети и номинальными напряжениями лампочек и звонка.
Предлагаю схему:
Три цепочки из лампочки и последовательно соединенного с ней звонка включены в параллель.
Вся эта конструкция последовательно соединена со звонком.
При этом, естественно, номинальные токи лампочки и звонка должны быть равны, а напряжение в сети - сумме их номинальных напряжений.
Режим одновременного нажатия на кнопки схема не предусматривает так же, как и оба варианта, опубликованные ранее.
Достоинства схемы:
1. Легкость обобщения на произвольное количество лампочек и кнопок.
2. В конструкции допустимо использование "стандартных" кнопок, т.е. имеющих лишь одну пару контактов на замыкание (без размыкающих контактов).
Схема не лишена недостатков, в частности, перегрузка звонка в нештатном режиме работы (при замыкании нескольких кнопок одновременно). Но мне это кажется меньшим недостатком, чем то, что опережение замыкания перед размыканием (в штатном режиме) ведет к КЗ.
Lapp
Узнаю "раннего" andriano, готового спорить до бесконечности из-за никому неинтересных деталей.. smile.gif

Цитата(andriano @ 12.12.2008 23:35) *
Хочу отметить, что в условии не оговорено ни одного из следующих условий:
1. Возможности функционирования схемы при нажатии нескольких кнопок одновременно.
2. Сотношения между напряжением в сети и номинальными напряжениями лампочек и звонка.
... а также стандарты на изоляцию проводов, типы ламп и девичья фамилия бабушек жильцов.. smile.gif
Хорошо, я оговорю.
1. Одновременное нажатие кнопок запрещено и грозит выплатой полной стоимости оборудования (даже в случае его сохранности), плюс штраф в размере 2.71828 минимальных зарплат.
2. Номинальное значение напряжения ламп и звонка в точности равно напряжению в сети.
И добавлю от себя (по просьбе электрика Васи) еще один пункт:
3.14. ПАЛЬЦЫ В РИЗЕТКИ НЕСУВАТЬ!!!!!
smile.gif

Цитата(andriano @ 12.12.2008 23:35) *
Предлагаю схему:
Три цепочки из лампочки и последовательно соединенного с ней звонка включены в параллель.
Вся эта конструкция последовательно соединена со звонком.
При этом, естественно, номинальные токи лампочки и звонка должны быть равны, а напряжение в сети - сумме их номинальных напряжений.
Режим одновременного нажатия на кнопки схема не предусматривает так же, как и оба варианта, опубликованные ранее.
Ты лучше нарисуй, хотя мне уже не нравятся слово "последовательно" и подозреваемая мной множественность звонков..

Цитата(andriano @ 12.12.2008 23:35) *
Достоинства схемы:
1. Легкость обобщения на произвольное количество лампочек и кнопок.
Схема xds делает это с блеском.

Цитата(andriano @ 12.12.2008 23:35) *
2. В конструкции допустимо использование "стандартных" кнопок, т.е. имеющих лишь одну пару контактов на замыкание (без размыкающих контактов).
... ибо контакты на размыкание безумно дороги в производстве, что особенно существенно при гигантских масштабах нашего Проекта.. smile.gif

Цитата(andriano @ 12.12.2008 23:35) *
Схема не лишена недостатков, в частности, перегрузка звонка в нештатном режиме работы (при замыкании нескольких кнопок одновременно). Но мне это кажется меньшим недостатком, чем то, что опережение замыкания перед размыканием (в штатном режиме) ведет к КЗ.
Если таковые (двойные) кнопки выпускаются производством, они должны быть сертифицированы и гарантированы от подобных нештатных ситуаций.

Ладно, хватит шутить - andriano, ты правда не видишь, что задача имеет чисто академический характер? Решение привел xds, решение правильное и т.д. и т.п.. Но!

Но мне очень жаль, что никто из ответивших не понял меня.. sad.gif
Задача провисела тут несколько дней, и ни у кого не появилось мысли ее решить. Стоило же мне сказать, что задача в этом разделе может нести в себе другой смысл - как тут же появились желающие пофлудить физикой в паскалевском разделе..

Моя программа - не Бог весть какое чудо, но она все же вносит некоторое разнообразие в бесконечные "расставить сторки по.." Она решает только эту конкретную задачу, причем за непозволительно большое время, но все же дает некоторое понятие о неких других задачах, которые могут решаться программным способом. Я надеялся на дискуссию именно по программированию, а не по физике (когда я начал решать ее программно, я как бы заблокировал себе мысли об обычном решении). Что ж, не вышло.. Наверное, надо действительно перенести тему в Физику, а свой пост опубликовать отдельно в FAQ - хотя, я не назвал бы этот вопрос часто задаваемым.. я подумаю. Чего и вам желаю..

Take it easy! smile.gif
andriano
Цитата(Lapp @ 13.12.2008 0:35) *

Узнаю "раннего" andriano, готового спорить до бесконечности из-за никому неинтересных деталей.. smile.gif
...
Но мне очень жаль, что никто из ответивших не понял меня.. sad.gif
...
Задача провисела тут несколько дней, и ни у кого не появилось мысли ее решить.
...
Я надеялся на дискуссию
...

Вопрос о том, кто именно готов обсуждать никому не интересные детали, конечно, интересен, но ответ на него, на мой взгляд, не столь однозначен.

Я честно попытался прочитать программу, но, увы, не преуспел в этом.
Виной этому:
1. Во-первых - моя лень.
2. Во-вторых - то, что стиль написания несколько отличается от того, к которому я привык:
var
  n: integer; // Суммарное число контактов всех элементов

Я бы не стал называть глобальную переменную однобуквенным идентификатором, но это в данном случае неважно, по крайней мере. на данном этапе еще не помешало погиманию, а вот это:
  t: integer; // Номер следующего соединения при сборке

я действительно не могу понять. Из 4-х слов понимаю смысл только первого. Что такое соединение? Каким образом они нумеруются? (хотя бы в пределах одной схемы или в процессе перебора по разным вариантам схем) Что такое сборка?
type
  tVolt= (None,v1,v2);                  // Напряжение: не подано, v1, v2

Правильно ли я перевел на "свой" язык?
type
  tVolt= (None, LoV, HiV);                  // Напряжение на контакте: не подключен, низкий уровень, высокий уровень


  tPin= array[1..255] of byte;          // Массив выводов
Как соотносятся между собой выводы и контакты?
Что означает каждое из 255 вариантов значения вывода?
    constructor Create(ip: integer);

Что обозначает входная переменная?
    Pos: byte;                          // Состояние переключателя: 0, 1

Почему переменная, принимающая только два значения, имеет тип byte, а не boolean?
И какой цифре соответствует состояние "замкнуто", а какой "разомкнуто"? (интуитивно кажется 1 и 0 соответственно, но хотелось бы знать наверняка)

И, на мой взгляд, в программе катастрофически не хватает комментариев: мне представляется, что КАЖДЫЙ заголовок процедуры или функции должен сопровождать описанием ее назначения, а также описанием каждого из параметров.
Общая доля комментариев в коде, если не ошибаюсь, должно составлять около 30%.

Прошу понять меня правильно: я не высказываю претензий к автору, я пытаюсь объяснить, почему я не стал разбираться в этой программе. (т.к. автор высказывает претензии ко мне - почему не прочитал и не разобрался?)
-Владимир-
Схема не будет работать. При включении любой из кнопок, гореть будут все лампочки так как питание будет проходить через лампочки.
-Ваня-
Цитата(xds @ 12.12.2008 17:55) *

Мое решение (интуитивное). Подходит для любого количества жильцов.

Нажмите для просмотра прикрепленного файла


схема работает, автору респект)
Гость
Цитата(-Ваня- @ 7.09.2019 2:42) *

Цитата(xds @ 12.12.2008 17:55) *

Мое решение (интуитивное). Подходит для любого количества жильцов.

Нажмите для просмотра прикрепленного файла


схема работает, автору респект)


Валерий.
Очень интересно! Это схему задачу я решал в 1973 году на Дальнем Востоке.
Просидел над ней целый месяц.
В конце концов решил её и на этом принципе мы построили много схем по управлению компрессорами.
Тогда не было ни компьютеров, не Pascal.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.